aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoraoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4>2009-06-17 10:27:49 +0000
committeraoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4>2009-06-17 10:27:49 +0000
commit06e86747c0b068eb5457813104fe1baaeb3b29ae (patch)
tree6054bcf3f15222324c7882c2d0a382aaaa3f11b7
parent2d50973e39b598f96b008af8bbb27e74ae40d436 (diff)
* rtl.def (VALUE): Move up. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/var-tracking-assignments-branch@148594 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--ChangeLog62
-rw-r--r--MAINTAINERS4
-rw-r--r--Makefile.def5
-rw-r--r--Makefile.in986
-rw-r--r--Makefile.tpl5
-rw-r--r--boehm-gc/ChangeLog4
-rw-r--r--boehm-gc/win32_threads.c6
-rwxr-xr-xconfig.guess53
-rwxr-xr-xconfig.sub4
-rw-r--r--config/ChangeLog4
-rw-r--r--config/plugins.m411
-rwxr-xr-xconfigure306
-rw-r--r--configure.ac131
-rw-r--r--contrib/ChangeLog4
-rw-r--r--fixincludes/ChangeLog21
-rw-r--r--fixincludes/fixincl.x346
-rw-r--r--fixincludes/inclhack.def166
-rw-r--r--fixincludes/tests/base/stdint.h35
-rw-r--r--fixincludes/tests/base/sys/int_const.h17
-rw-r--r--fixincludes/tests/base/sys/int_limits.h24
-rw-r--r--gcc/ChangeLog4926
-rw-r--r--gcc/ChangeLog.vta5
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/Makefile.in188
-rw-r--r--gcc/ada/ChangeLog294
-rw-r--r--gcc/ada/adaint.c8
-rw-r--r--gcc/ada/back_end.adb28
-rw-r--r--gcc/ada/freeze.adb4
-rw-r--r--gcc/ada/g-cgi.adb7
-rw-r--r--gcc/ada/g-cgi.ads4
-rw-r--r--gcc/ada/gcc-interface/Make-lang.in42
-rw-r--r--gcc/ada/gcc-interface/Makefile.in24
-rw-r--r--gcc/ada/gcc-interface/ada-tree.h82
-rw-r--r--gcc/ada/gcc-interface/decl.c970
-rw-r--r--gcc/ada/gcc-interface/gigi.h16
-rw-r--r--gcc/ada/gcc-interface/lang-specs.h1
-rw-r--r--gcc/ada/gcc-interface/misc.c29
-rw-r--r--gcc/ada/gcc-interface/trans.c134
-rw-r--r--gcc/ada/gcc-interface/utils.c161
-rw-r--r--gcc/ada/gcc-interface/utils2.c387
-rw-r--r--gcc/ada/lib.ads6
-rw-r--r--gcc/ada/scng.adb3
-rw-r--r--gcc/ada/sem_attr.adb10
-rw-r--r--gcc/ada/sem_warn.adb6
-rw-r--r--gcc/ada/sfn_scan.adb3
-rw-r--r--gcc/ada/switch.adb34
-rw-r--r--gcc/ada/switch.ads18
-rw-r--r--gcc/ada/tracebak.c6
-rw-r--r--gcc/alias.c21
-rw-r--r--gcc/attribs.c32
-rw-r--r--gcc/auto-inc-dec.c64
-rw-r--r--gcc/basic-block.h6
-rw-r--r--gcc/bitmap.c19
-rw-r--r--gcc/builtins.c238
-rw-r--r--gcc/builtins.def1
-rw-r--r--gcc/c-common.c608
-rw-r--r--gcc/c-common.h68
-rw-r--r--gcc/c-convert.c3
-rw-r--r--gcc/c-decl.c1284
-rw-r--r--gcc/c-format.c2
-rw-r--r--gcc/c-gimplify.c5
-rw-r--r--gcc/c-omp.c86
-rw-r--r--gcc/c-opts.c11
-rw-r--r--gcc/c-parser.c748
-rw-r--r--gcc/c-pragma.c27
-rw-r--r--gcc/c-semantics.c11
-rw-r--r--gcc/c-tree.h154
-rw-r--r--gcc/c-typeck.c1105
-rw-r--r--gcc/c.opt6
-rw-r--r--gcc/calls.c2
-rw-r--r--gcc/cfgcleanup.c44
-rw-r--r--gcc/cfgexpand.c49
-rw-r--r--gcc/cfglayout.c14
-rw-r--r--gcc/cfgrtl.c22
-rw-r--r--gcc/cgraph.c52
-rw-r--r--gcc/cgraph.h22
-rw-r--r--gcc/cgraphunit.c16
-rw-r--r--gcc/collect2-aix.c371
-rw-r--r--gcc/collect2-aix.h301
-rw-r--r--gcc/collect2.c54
-rw-r--r--gcc/combine-stack-adj.c2
-rw-r--r--gcc/combine.c29
-rw-r--r--gcc/common.opt40
-rw-r--r--gcc/config.gcc31
-rw-r--r--gcc/config.in19
-rw-r--r--gcc/config/alpha/alpha-protos.h5
-rw-r--r--gcc/config/alpha/alpha.c248
-rw-r--r--gcc/config/alpha/alpha.h35
-rw-r--r--gcc/config/alpha/alpha.md239
-rw-r--r--gcc/config/alpha/predicates.md6
-rw-r--r--gcc/config/alpha/x-alpha2
-rw-r--r--gcc/config/arc/arc.c19
-rw-r--r--gcc/config/arc/arc.h5
-rw-r--r--gcc/config/arc/arc.md337
-rw-r--r--gcc/config/arm/arm-modes.def4
-rw-r--r--gcc/config/arm/arm-protos.h6
-rw-r--r--gcc/config/arm/arm.c192
-rw-r--r--gcc/config/arm/arm.h41
-rw-r--r--gcc/config/arm/arm.md504
-rw-r--r--gcc/config/arm/constraints.md30
-rw-r--r--gcc/config/arm/ieee754-df.S7
-rw-r--r--gcc/config/arm/ieee754-sf.S7
-rw-r--r--gcc/config/arm/lib1funcs.asm21
-rw-r--r--gcc/config/arm/linux-eabi.h16
-rw-r--r--gcc/config/arm/neon.md46
-rw-r--r--gcc/config/arm/predicates.md12
-rw-r--r--gcc/config/arm/t-arm6
-rw-r--r--gcc/config/arm/t-linux-eabi4
-rw-r--r--gcc/config/arm/t-pe7
-rw-r--r--gcc/config/arm/t-wince-pe5
-rw-r--r--gcc/config/arm/thumb2.md238
-rw-r--r--gcc/config/avr/avr-protos.h7
-rw-r--r--gcc/config/avr/avr.c55
-rw-r--r--gcc/config/avr/avr.h16
-rw-r--r--gcc/config/avr/avr.md276
-rw-r--r--gcc/config/avr/libgcc.S2
-rw-r--r--gcc/config/bfin/bfin-protos.h1
-rw-r--r--gcc/config/bfin/bfin.c45
-rw-r--r--gcc/config/bfin/bfin.h36
-rw-r--r--gcc/config/bfin/bfin.md286
-rw-r--r--gcc/config/bfin/predicates.md8
-rw-r--r--gcc/config/cris/cris.c22
-rw-r--r--gcc/config/cris/cris.md130
-rw-r--r--gcc/config/crx/crx-protos.h5
-rw-r--r--gcc/config/crx/crx.c61
-rw-r--r--gcc/config/crx/crx.h21
-rw-r--r--gcc/config/crx/crx.md79
-rw-r--r--gcc/config/darwin.h34
-rw-r--r--gcc/config/darwin9.h2
-rw-r--r--gcc/config/fr30/fr30.c6
-rw-r--r--gcc/config/fr30/fr30.h10
-rw-r--r--gcc/config/fr30/fr30.md176
-rw-r--r--gcc/config/freebsd-stdint.h56
-rw-r--r--gcc/config/frv/frv-protos.h6
-rw-r--r--gcc/config/frv/frv.c83
-rw-r--r--gcc/config/frv/frv.h76
-rw-r--r--gcc/config/frv/frv.md330
-rw-r--r--gcc/config/frv/predicates.md18
-rw-r--r--gcc/config/h8300/h8300-protos.h4
-rw-r--r--gcc/config/h8300/h8300.c42
-rw-r--r--gcc/config/h8300/h8300.h18
-rw-r--r--gcc/config/h8300/h8300.md495
-rw-r--r--gcc/config/i386/biarch32.h29
-rw-r--r--gcc/config/i386/cpuid.h1
-rw-r--r--gcc/config/i386/cygming.opt4
-rw-r--r--gcc/config/i386/driver-i386.c125
-rw-r--r--gcc/config/i386/i386-protos.h3
-rw-r--r--gcc/config/i386/i386.c963
-rw-r--r--gcc/config/i386/i386.h68
-rw-r--r--gcc/config/i386/i386.md1354
-rw-r--r--gcc/config/i386/i386.opt8
-rw-r--r--gcc/config/i386/ia32intrin.h230
-rw-r--r--gcc/config/i386/linux.h6
-rw-r--r--gcc/config/i386/mingw-tls.c233
-rw-r--r--gcc/config/i386/mmx.md63
-rw-r--r--gcc/config/i386/msformat-c.c24
-rw-r--r--gcc/config/i386/predicates.md28
-rw-r--r--gcc/config/i386/sol2.h8
-rw-r--r--gcc/config/i386/sse.md328
-rw-r--r--gcc/config/i386/t-cygming8
-rw-r--r--gcc/config/i386/t-cygwin8
-rw-r--r--gcc/config/i386/t-gthr-win324
-rw-r--r--gcc/config/i386/t-i3865
-rw-r--r--gcc/config/i386/t-interix3
-rw-r--r--gcc/config/i386/t-netware3
-rw-r--r--gcc/config/i386/t-nwld6
-rw-r--r--gcc/config/i386/winnt.c19
-rw-r--r--gcc/config/i386/x-cygwin2
-rw-r--r--gcc/config/i386/x-darwin2
-rw-r--r--gcc/config/i386/x-i3862
-rw-r--r--gcc/config/i386/x-mingw322
-rw-r--r--gcc/config/i386/x86-64.h13
-rw-r--r--gcc/config/i386/x86intrin.h2
-rw-r--r--gcc/config/ia64/div.md703
-rw-r--r--gcc/config/ia64/hpux.h2
-rw-r--r--gcc/config/ia64/ia64-protos.h12
-rw-r--r--gcc/config/ia64/ia64.c76
-rw-r--r--gcc/config/ia64/ia64.h2
-rw-r--r--gcc/config/ia64/ia64.md1453
-rw-r--r--gcc/config/ia64/ia64.opt4
-rw-r--r--gcc/config/ia64/predicates.md5
-rw-r--r--gcc/config/ia64/t-ia647
-rw-r--r--gcc/config/ia64/vect.md18
-rw-r--r--gcc/config/iq2000/iq2000-protos.h3
-rw-r--r--gcc/config/iq2000/iq2000.c79
-rw-r--r--gcc/config/iq2000/iq2000.h21
-rw-r--r--gcc/config/iq2000/iq2000.md400
-rw-r--r--gcc/config/iq2000/predicates.md8
-rw-r--r--gcc/config/m32c/cond.md102
-rw-r--r--gcc/config/m32c/m32c-protos.h5
-rw-r--r--gcc/config/m32c/m32c.c95
-rw-r--r--gcc/config/m32c/m32c.h4
-rw-r--r--gcc/config/m32c/m32c.md3
-rw-r--r--gcc/config/m32c/t-m32c4
-rw-r--r--gcc/config/m32r/m32r-protos.h1
-rw-r--r--gcc/config/m32r/m32r.c233
-rw-r--r--gcc/config/m32r/m32r.h16
-rw-r--r--gcc/config/m32r/m32r.md443
-rw-r--r--gcc/config/m32r/predicates.md42
-rw-r--r--gcc/config/m68hc11/m68hc11-protos.h2
-rw-r--r--gcc/config/m68hc11/m68hc11.c37
-rw-r--r--gcc/config/m68hc11/m68hc11.h17
-rw-r--r--gcc/config/m68hc11/m68hc11.md297
-rw-r--r--gcc/config/m68k/constraints.md10
-rw-r--r--gcc/config/m68k/linux.h7
-rw-r--r--gcc/config/m68k/m68k-devices.def16
-rw-r--r--gcc/config/m68k/m68k-protos.h8
-rw-r--r--gcc/config/m68k/m68k.c723
-rw-r--r--gcc/config/m68k/m68k.h23
-rw-r--r--gcc/config/m68k/m68k.md604
-rw-r--r--gcc/config/m68k/m68k.opt4
-rw-r--r--gcc/config/m68k/predicates.md27
-rw-r--r--gcc/config/m68k/t-uclinux4
-rw-r--r--gcc/config/mcore/mcore-protos.h6
-rw-r--r--gcc/config/mcore/mcore.c68
-rw-r--r--gcc/config/mcore/mcore.md340
-rw-r--r--gcc/config/mips/mips-protos.h7
-rw-r--r--gcc/config/mips/mips-ps-3d.md2
-rw-r--r--gcc/config/mips/mips.c194
-rw-r--r--gcc/config/mips/mips.h88
-rw-r--r--gcc/config/mips/mips.md379
-rw-r--r--gcc/config/mips/predicates.md6
-rw-r--r--gcc/config/mips/x-native2
-rw-r--r--gcc/config/mmix/mmix-protos.h2
-rw-r--r--gcc/config/mmix/mmix.c77
-rw-r--r--gcc/config/mmix/mmix.h9
-rw-r--r--gcc/config/mmix/mmix.md250
-rw-r--r--gcc/config/mmix/predicates.md5
-rw-r--r--gcc/config/mn10300/mn10300-protos.h1
-rw-r--r--gcc/config/mn10300/mn10300.c31
-rw-r--r--gcc/config/mn10300/mn10300.h28
-rw-r--r--gcc/config/mn10300/mn10300.md204
-rw-r--r--gcc/config/moxie/constraints.md52
-rw-r--r--gcc/config/moxie/crti.asm40
-rw-r--r--gcc/config/moxie/crtn.asm34
-rw-r--r--gcc/config/moxie/moxie-protos.h28
-rw-r--r--gcc/config/moxie/moxie.c480
-rw-r--r--gcc/config/moxie/moxie.h576
-rw-r--r--gcc/config/moxie/moxie.md447
-rw-r--r--gcc/config/moxie/predicates.md55
-rw-r--r--gcc/config/moxie/sfp-machine.h52
-rw-r--r--gcc/config/moxie/t-moxie20
-rw-r--r--gcc/config/moxie/t-moxie-softfp9
-rw-r--r--gcc/config/pa/constraints.md2
-rw-r--r--gcc/config/pa/pa-hpux.h6
-rw-r--r--gcc/config/pa/pa-hpux10.h6
-rw-r--r--gcc/config/pa/pa-hpux11.h3
-rw-r--r--gcc/config/pa/pa-protos.h3
-rw-r--r--gcc/config/pa/pa.c84
-rw-r--r--gcc/config/pa/pa.h12
-rw-r--r--gcc/config/pa/pa.md531
-rw-r--r--gcc/config/pdp11/pdp11-protos.h3
-rw-r--r--gcc/config/pdp11/pdp11.c37
-rw-r--r--gcc/config/pdp11/pdp11.h5
-rw-r--r--gcc/config/pdp11/pdp11.md522
-rw-r--r--gcc/config/picochip/picochip-protos.h1
-rw-r--r--gcc/config/picochip/picochip.c11
-rw-r--r--gcc/config/picochip/picochip.h12
-rw-r--r--gcc/config/picochip/picochip.md113
-rw-r--r--gcc/config/rs6000/aix.h18
-rw-r--r--gcc/config/rs6000/aix43.h14
-rw-r--r--gcc/config/rs6000/aix51.h12
-rw-r--r--gcc/config/rs6000/aix52.h12
-rw-r--r--gcc/config/rs6000/aix53.h12
-rw-r--r--gcc/config/rs6000/aix61.h12
-rw-r--r--gcc/config/rs6000/crtresfpr.asm2
-rw-r--r--gcc/config/rs6000/crtresgpr.asm2
-rw-r--r--gcc/config/rs6000/crtresxfpr.asm42
-rw-r--r--gcc/config/rs6000/crtresxgpr.asm42
-rw-r--r--gcc/config/rs6000/crtsavfpr.asm2
-rw-r--r--gcc/config/rs6000/crtsavgpr.asm2
-rw-r--r--gcc/config/rs6000/eabi.asm4
-rw-r--r--gcc/config/rs6000/linux64.h5
-rw-r--r--gcc/config/rs6000/ppc-asm.h21
-rw-r--r--gcc/config/rs6000/predicates.md10
-rw-r--r--gcc/config/rs6000/rs6000-c.c35
-rw-r--r--gcc/config/rs6000/rs6000-protos.h7
-rw-r--r--gcc/config/rs6000/rs6000.c487
-rw-r--r--gcc/config/rs6000/rs6000.h75
-rw-r--r--gcc/config/rs6000/rs6000.md307
-rw-r--r--gcc/config/rs6000/sysv4.h4
-rw-r--r--gcc/config/rs6000/t-aix522
-rw-r--r--gcc/config/rs6000/t-rs60007
-rw-r--r--gcc/config/rs6000/x-darwin3
-rw-r--r--gcc/config/rs6000/x-darwin643
-rw-r--r--gcc/config/rs6000/x-rs60002
-rw-r--r--gcc/config/rs6000/xcoff.h7
-rw-r--r--gcc/config/s390/2064.md36
-rw-r--r--gcc/config/s390/2084.md126
-rw-r--r--gcc/config/s390/constraints.md36
-rw-r--r--gcc/config/s390/fixdfdi.h12
-rw-r--r--gcc/config/s390/libgcc-glibc.ver2
-rw-r--r--gcc/config/s390/predicates.md8
-rw-r--r--gcc/config/s390/s390-modes.def28
-rw-r--r--gcc/config/s390/s390-protos.h5
-rw-r--r--gcc/config/s390/s390.c426
-rw-r--r--gcc/config/s390/s390.h46
-rw-r--r--gcc/config/s390/s390.md232
-rw-r--r--gcc/config/s390/tpf-unwind.h26
-rw-r--r--gcc/config/score/score-conv.h5
-rw-r--r--gcc/config/score/score-protos.h1
-rw-r--r--gcc/config/score/score.c31
-rw-r--r--gcc/config/score/score.h10
-rw-r--r--gcc/config/score/score.md124
-rw-r--r--gcc/config/score/score3.c19
-rw-r--r--gcc/config/score/score3.h4
-rw-r--r--gcc/config/score/score7.c19
-rw-r--r--gcc/config/score/score7.h4
-rw-r--r--gcc/config/score/t-score-elf6
-rw-r--r--gcc/config/sh/predicates.md73
-rw-r--r--gcc/config/sh/sh-protos.h11
-rw-r--r--gcc/config/sh/sh.c982
-rw-r--r--gcc/config/sh/sh.h524
-rw-r--r--gcc/config/sh/sh.md1672
-rw-r--r--gcc/config/sh/sh.opt8
-rw-r--r--gcc/config/sh/symbian.c8
-rw-r--r--gcc/config/sh/t-sh3
-rw-r--r--gcc/config/sh/t-symbian8
-rw-r--r--gcc/config/sparc/sparc-protos.h10
-rw-r--r--gcc/config/sparc/sparc.c290
-rw-r--r--gcc/config/sparc/sparc.h32
-rw-r--r--gcc/config/sparc/sparc.md917
-rw-r--r--gcc/config/spu/predicates.md16
-rw-r--r--gcc/config/spu/spu-c.c4
-rw-r--r--gcc/config/spu/spu-protos.h15
-rw-r--r--gcc/config/spu/spu.c706
-rw-r--r--gcc/config/spu/spu.h16
-rw-r--r--gcc/config/spu/spu.md596
-rw-r--r--gcc/config/spu/t-spu-elf6
-rw-r--r--gcc/config/stormy16/stormy16-protos.h3
-rw-r--r--gcc/config/stormy16/stormy16.c54
-rw-r--r--gcc/config/stormy16/stormy16.h21
-rw-r--r--gcc/config/stormy16/stormy16.md105
-rw-r--r--gcc/config/t-darwin14
-rw-r--r--gcc/config/t-sol26
-rw-r--r--gcc/config/t-vxworks2
-rw-r--r--gcc/config/v850/t-v8507
-rw-r--r--gcc/config/v850/t-v850e3
-rw-r--r--gcc/config/v850/v850.c7
-rw-r--r--gcc/config/v850/v850.md302
-rw-r--r--gcc/config/vax/vax-protos.h4
-rw-r--r--gcc/config/vax/vax.c62
-rw-r--r--gcc/config/vax/vax.h11
-rw-r--r--gcc/config/vax/vax.md81
-rw-r--r--gcc/config/x-darwin2
-rw-r--r--gcc/config/x-hpux2
-rw-r--r--gcc/config/x-linux2
-rw-r--r--gcc/config/x-solaris2
-rw-r--r--gcc/config/xtensa/predicates.md3
-rw-r--r--gcc/config/xtensa/xtensa-protos.h5
-rw-r--r--gcc/config/xtensa/xtensa.c85
-rw-r--r--gcc/config/xtensa/xtensa.h18
-rw-r--r--gcc/config/xtensa/xtensa.md77
-rwxr-xr-xgcc/configure101
-rw-r--r--gcc/configure.ac38
-rw-r--r--gcc/coverage.c54
-rw-r--r--gcc/cp/ChangeLog510
-rw-r--r--gcc/cp/Make-lang.in17
-rw-r--r--gcc/cp/call.c866
-rw-r--r--gcc/cp/class.c40
-rw-r--r--gcc/cp/cp-gimplify.c15
-rw-r--r--gcc/cp/cp-objcp-common.h2
-rw-r--r--gcc/cp/cp-tree.h100
-rw-r--r--gcc/cp/cvt.c37
-rw-r--r--gcc/cp/decl.c130
-rw-r--r--gcc/cp/decl2.c58
-rw-r--r--gcc/cp/error.c29
-rw-r--r--gcc/cp/except.c13
-rw-r--r--gcc/cp/g++spec.c18
-rw-r--r--gcc/cp/init.c265
-rw-r--r--gcc/cp/lex.c6
-rw-r--r--gcc/cp/mangle.c15
-rw-r--r--gcc/cp/method.c19
-rw-r--r--gcc/cp/name-lookup.c47
-rw-r--r--gcc/cp/name-lookup.h7
-rw-r--r--gcc/cp/optimize.c7
-rw-r--r--gcc/cp/parser.c678
-rw-r--r--gcc/cp/pt.c549
-rw-r--r--gcc/cp/rtti.c42
-rw-r--r--gcc/cp/semantics.c168
-rw-r--r--gcc/cp/tree.c136
-rw-r--r--gcc/cp/typeck.c294
-rw-r--r--gcc/cp/typeck2.c41
-rw-r--r--gcc/cse.c240
-rw-r--r--gcc/dbxout.c89
-rw-r--r--gcc/dce.c7
-rw-r--r--gcc/debug.c9
-rw-r--r--gcc/debug.h6
-rw-r--r--gcc/defaults.h175
-rw-r--r--gcc/df-core.c33
-rw-r--r--gcc/df-problems.c28
-rw-r--r--gcc/diagnostic.c14
-rw-r--r--gcc/diagnostic.h1
-rw-r--r--gcc/doc/c-tree.texi8
-rw-r--r--gcc/doc/contrib.texi7
-rw-r--r--gcc/doc/extend.texi70
-rw-r--r--gcc/doc/gccint.texi2
-rw-r--r--gcc/doc/gimple.texi43
-rw-r--r--gcc/doc/gty.texi8
-rw-r--r--gcc/doc/install.texi71
-rw-r--r--gcc/doc/invoke.texi297
-rw-r--r--gcc/doc/md.texi315
-rw-r--r--gcc/doc/passes.texi94
-rw-r--r--gcc/doc/plugins.texi141
-rw-r--r--gcc/doc/rtl.texi8
-rw-r--r--gcc/doc/tm.texi267
-rw-r--r--gcc/doc/tree-ssa.texi35
-rw-r--r--gcc/dojump.c58
-rw-r--r--gcc/dse.c1
-rw-r--r--gcc/dummy-checksum.c4
-rw-r--r--gcc/dwarf2.h9
-rw-r--r--gcc/dwarf2asm.c4
-rw-r--r--gcc/dwarf2out.c725
-rw-r--r--gcc/dwarf2out.h2
-rw-r--r--gcc/emit-rtl.c10
-rw-r--r--gcc/emutls.c10
-rw-r--r--gcc/errors.c3
-rw-r--r--gcc/except.c306
-rw-r--r--gcc/except.h49
-rw-r--r--gcc/expmed.c124
-rw-r--r--gcc/expr.c107
-rw-r--r--gcc/expr.h6
-rw-r--r--gcc/final.c151
-rw-r--r--gcc/fold-const.c146
-rw-r--r--gcc/fortran/ChangeLog630
-rw-r--r--gcc/fortran/Make-lang.in15
-rw-r--r--gcc/fortran/arith.c47
-rw-r--r--gcc/fortran/array.c3
-rw-r--r--gcc/fortran/check.c456
-rw-r--r--gcc/fortran/decl.c75
-rw-r--r--gcc/fortran/dump-parse-tree.c101
-rw-r--r--gcc/fortran/expr.c59
-rw-r--r--gcc/fortran/f95-lang.c24
-rw-r--r--gcc/fortran/gfortran.h21
-rw-r--r--gcc/fortran/gfortran.texi556
-rw-r--r--gcc/fortran/gfortranspec.c19
-rw-r--r--gcc/fortran/interface.c174
-rw-r--r--gcc/fortran/intrinsic.c482
-rw-r--r--gcc/fortran/intrinsic.h15
-rw-r--r--gcc/fortran/intrinsic.texi312
-rw-r--r--gcc/fortran/io.c101
-rw-r--r--gcc/fortran/ioparm.def1
-rw-r--r--gcc/fortran/iso-c-binding.def48
-rw-r--r--gcc/fortran/iso-fortran-env.def14
-rw-r--r--gcc/fortran/lang.opt2
-rw-r--r--gcc/fortran/libgfortran.h4
-rw-r--r--gcc/fortran/match.c81
-rw-r--r--gcc/fortran/misc.c13
-rw-r--r--gcc/fortran/module.c14
-rw-r--r--gcc/fortran/openmp.c19
-rw-r--r--gcc/fortran/options.c11
-rw-r--r--gcc/fortran/parse.c21
-rw-r--r--gcc/fortran/primary.c7
-rw-r--r--gcc/fortran/resolve.c219
-rw-r--r--gcc/fortran/simplify.c1263
-rw-r--r--gcc/fortran/st.c5
-rw-r--r--gcc/fortran/symbol.c37
-rw-r--r--gcc/fortran/trans-array.c257
-rw-r--r--gcc/fortran/trans-array.h17
-rw-r--r--gcc/fortran/trans-common.c18
-rw-r--r--gcc/fortran/trans-decl.c465
-rw-r--r--gcc/fortran/trans-expr.c92
-rw-r--r--gcc/fortran/trans-intrinsic.c190
-rw-r--r--gcc/fortran/trans-io.c115
-rw-r--r--gcc/fortran/trans-openmp.c61
-rw-r--r--gcc/fortran/trans-stmt.c248
-rw-r--r--gcc/fortran/trans-types.c149
-rw-r--r--gcc/fortran/trans-types.h1
-rw-r--r--gcc/fortran/trans.c32
-rw-r--r--gcc/fortran/trans.h2
-rw-r--r--gcc/function.c260
-rw-r--r--gcc/function.h8
-rw-r--r--gcc/gbl-ctors.h4
-rw-r--r--gcc/gcc-plugin.h51
-rw-r--r--gcc/gcc.c16
-rw-r--r--gcc/gcov.c40
-rw-r--r--gcc/gcse.c78
-rw-r--r--gcc/genattrtab.c5
-rw-r--r--gcc/genchecksum.c6
-rw-r--r--gcc/gengtype.c106
-rw-r--r--gcc/genopinit.c5
-rw-r--r--gcc/ggc-common.c49
-rw-r--r--gcc/ggc-page.c5
-rw-r--r--gcc/ggc-zone.c5
-rw-r--r--gcc/ggc.h9
-rw-r--r--gcc/gimple-iterator.c2
-rw-r--r--gcc/gimple-low.c10
-rw-r--r--gcc/gimple-pretty-print.c37
-rw-r--r--gcc/gimple.c40
-rw-r--r--gcc/gimple.def11
-rw-r--r--gcc/gimple.h130
-rw-r--r--gcc/gimplify.c89
-rw-r--r--gcc/graphite.c63
-rw-r--r--gcc/graphite.h4
-rw-r--r--gcc/gstab.h7
-rw-r--r--gcc/gthr-win32.h5
-rw-r--r--gcc/haifa-sched.c4
-rw-r--r--gcc/hooks.c7
-rw-r--r--gcc/hooks.h2
-rw-r--r--gcc/hwint.h2
-rw-r--r--gcc/ifcvt.c6
-rw-r--r--gcc/insn-notes.def4
-rw-r--r--gcc/ipa-cp.c17
-rw-r--r--gcc/ipa-inline.c562
-rw-r--r--gcc/ipa-prop.c98
-rw-r--r--gcc/ipa-pure-const.c2
-rw-r--r--gcc/ipa-reference.c4
-rw-r--r--gcc/ipa-struct-reorg.c5
-rw-r--r--gcc/ipa-utils.h3
-rw-r--r--gcc/ira-build.c3
-rw-r--r--gcc/ira-conflicts.c10
-rw-r--r--gcc/java/ChangeLog41
-rw-r--r--gcc/java/Make-lang.in21
-rw-r--r--gcc/java/builtins.c5
-rw-r--r--gcc/java/class.c101
-rw-r--r--gcc/java/constants.c5
-rw-r--r--gcc/java/decl.c278
-rw-r--r--gcc/java/except.c6
-rw-r--r--gcc/java/expr.c29
-rw-r--r--gcc/java/java-gimplify.c2
-rw-r--r--gcc/java/java-tree.h6
-rw-r--r--gcc/java/jcf-io.c7
-rw-r--r--gcc/java/jcf-parse.c16
-rw-r--r--gcc/java/resource.c14
-rw-r--r--gcc/java/typeck.c8
-rw-r--r--gcc/java/verify.h12
-rw-r--r--gcc/jump.c40
-rw-r--r--gcc/langhooks-def.h5
-rw-r--r--gcc/langhooks.c12
-rw-r--r--gcc/langhooks.h12
-rw-r--r--gcc/matrix-reorg.c1
-rw-r--r--gcc/mips-tdump.c2
-rw-r--r--gcc/mips-tfile.c13
-rw-r--r--gcc/objc/ChangeLog64
-rw-r--r--gcc/objc/Make-lang.in8
-rw-r--r--gcc/objc/objc-act.c270
-rw-r--r--gcc/objc/objc-act.h4
-rw-r--r--gcc/objcp/ChangeLog28
-rw-r--r--gcc/objcp/Make-lang.in11
-rw-r--r--gcc/objcp/objcp-decl.c6
-rw-r--r--gcc/objcp/objcp-decl.h16
-rw-r--r--gcc/omega.c10
-rw-r--r--gcc/omega.h8
-rw-r--r--gcc/omp-low.c69
-rw-r--r--gcc/optabs.c415
-rw-r--r--gcc/optabs.h48
-rw-r--r--gcc/opth-gen.awk4
-rw-r--r--gcc/opts.c9
-rw-r--r--gcc/output.h11
-rw-r--r--gcc/params.def65
-rw-r--r--gcc/params.h12
-rw-r--r--gcc/passes.c25
-rw-r--r--gcc/plugin.c46
-rw-r--r--gcc/plugin.h6
-rw-r--r--gcc/predict.c4
-rw-r--r--gcc/print-rtl.c2
-rw-r--r--gcc/print-tree.c2
-rw-r--r--gcc/real.c161
-rw-r--r--gcc/real.h5
-rw-r--r--gcc/recog.c36
-rw-r--r--gcc/reg-notes.def35
-rw-r--r--gcc/reg-stack.c24
-rw-r--r--gcc/reginfo.c4
-rw-r--r--gcc/regstat.c3
-rw-r--r--gcc/reload.c4
-rw-r--r--gcc/reorg.c119
-rw-r--r--gcc/resource.c36
-rw-r--r--gcc/resource.h7
-rw-r--r--gcc/rtl.def18
-rw-r--r--gcc/rtl.h8
-rw-r--r--gcc/sdbout.c5
-rw-r--r--gcc/sel-sched-ir.c4
-rw-r--r--gcc/sel-sched.c22
-rw-r--r--gcc/simplify-rtx.c16
-rw-r--r--gcc/statistics.c14
-rw-r--r--gcc/stmt.c7
-rw-r--r--gcc/stor-layout.c3
-rw-r--r--gcc/store-motion.c1
-rw-r--r--gcc/stub-objc.c4
-rw-r--r--gcc/system.h7
-rw-r--r--gcc/target-def.h12
-rw-r--r--gcc/target.h30
-rw-r--r--gcc/targhooks.c30
-rw-r--r--gcc/targhooks.h9
-rw-r--r--gcc/testsuite/ChangeLog1146
-rw-r--r--gcc/testsuite/ada/acats/tests/c3/c38202a.ada5
-rw-r--r--gcc/testsuite/ada/acats/tests/c5/c59002c.ada7
-rw-r--r--gcc/testsuite/g++.dg/abi/mangle11.C4
-rw-r--r--gcc/testsuite/g++.dg/abi/mangle12.C4
-rw-r--r--gcc/testsuite/g++.dg/abi/mangle17.C8
-rw-r--r--gcc/testsuite/g++.dg/abi/mangle20-2.C4
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/auto14.C29
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/auto15.C13
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/defaulted10.C14
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/enum3.C17
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/explicit1.C58
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/explicit2.C29
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/initlist13.C5
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/initlist15.C17
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/initlist16.C12
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/initlist17.C9
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/initlist18.C19
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/initlist19.C8
-rw-r--r--gcc/testsuite/g++.dg/debug/dwarf2/nested-1.C29
-rw-r--r--gcc/testsuite/g++.dg/ext/dllexport2.C52
-rw-r--r--gcc/testsuite/g++.dg/ext/dllexport2a.cc21
-rw-r--r--gcc/testsuite/g++.dg/ext/packed6.C2
-rw-r--r--gcc/testsuite/g++.dg/ext/vector16.C11
-rw-r--r--gcc/testsuite/g++.dg/init/ref15.C4
-rw-r--r--gcc/testsuite/g++.dg/opt/memcpy1.C2
-rw-r--r--gcc/testsuite/g++.dg/other/pr40446.C46
-rw-r--r--gcc/testsuite/g++.dg/plugin/attribute_plugin-test-1.C16
-rw-r--r--gcc/testsuite/g++.dg/plugin/attribute_plugin.c66
-rw-r--r--gcc/testsuite/g++.dg/plugin/dumb_plugin.c12
-rw-r--r--gcc/testsuite/g++.dg/plugin/plugin.exp1
-rw-r--r--gcc/testsuite/g++.dg/plugin/selfassign.c9
-rw-r--r--gcc/testsuite/g++.dg/pr37742.C2
-rw-r--r--gcc/testsuite/g++.dg/template/access11.C2
-rw-r--r--gcc/testsuite/g++.dg/template/canon-type-1.C18
-rw-r--r--gcc/testsuite/g++.dg/template/canon-type-2.C18
-rw-r--r--gcc/testsuite/g++.dg/template/canon-type-3.C20
-rw-r--r--gcc/testsuite/g++.dg/template/canon-type-4.C22
-rw-r--r--gcc/testsuite/g++.dg/template/canon-type-5.C22
-rw-r--r--gcc/testsuite/g++.dg/template/canon-type-6.C22
-rw-r--r--gcc/testsuite/g++.dg/template/canon-type-7.C21
-rw-r--r--gcc/testsuite/g++.dg/template/dtor6.C16
-rw-r--r--gcc/testsuite/g++.dg/template/dtor7.C24
-rw-r--r--gcc/testsuite/g++.dg/template/error38.C2
-rw-r--r--gcc/testsuite/g++.dg/template/error41.C12
-rw-r--r--gcc/testsuite/g++.dg/template/error42.C20
-rw-r--r--gcc/testsuite/g++.dg/template/spec36.C16
-rw-r--r--gcc/testsuite/g++.dg/template/typedef18.C24
-rw-r--r--gcc/testsuite/g++.dg/template/typedef19.C21
-rw-r--r--gcc/testsuite/g++.dg/template/typedef20.C27
-rw-r--r--gcc/testsuite/g++.dg/torture/20070621-1.C2
-rw-r--r--gcc/testsuite/g++.dg/torture/pr31579.C2
-rw-r--r--gcc/testsuite/g++.dg/torture/pr32950.C19
-rw-r--r--gcc/testsuite/g++.dg/torture/pr34222.C2
-rw-r--r--gcc/testsuite/g++.dg/torture/pr34850.C2
-rw-r--r--gcc/testsuite/g++.dg/torture/pr40102.C41
-rw-r--r--gcc/testsuite/g++.dg/torture/pr40323.C68
-rw-r--r--gcc/testsuite/g++.dg/torture/pr40335.C16
-rw-r--r--gcc/testsuite/g++.dg/torture/pr40389.C84
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/pr22444.C4
-rw-r--r--gcc/testsuite/g++.dg/warn/Wcast-qual2.C167
-rw-r--r--gcc/testsuite/g++.dg/warn/Wstrict-aliasing-float-ref-int-obj.C4
-rw-r--r--gcc/testsuite/g++.dg/warn/Wswitch-3.C37
-rw-r--r--gcc/testsuite/g++.dg/warn/Wunused-label-1.C28
-rw-r--r--gcc/testsuite/g++.dg/warn/Wunused-label-2.C13
-rw-r--r--gcc/testsuite/g++.dg/warn/Wunused-label-3.C51
-rw-r--r--gcc/testsuite/g++.dg/warn/pr16302.C76
-rw-r--r--gcc/testsuite/g++.dg/warn/skip-1.C17
-rw-r--r--gcc/testsuite/g++.dg/warn/translate-ice-1.C45
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/array1.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/crash64.C4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/new3.C2
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20000211-1.c2
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20010328-1.c2
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20030320-1.c2
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20030405-1.c2
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20030902-1.c2
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20060202-1.c2
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20080613-1.c2
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20090518-1.c6
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20090519-1.c11
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/920428-2.c2
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/980329-1.c2
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/980816-1.c2
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr32584.c7
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr33173.c2
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr33382.c2
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr34334.c2
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr34688.c2
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr35043.c2
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr37669.c2
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr39834.c13
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr39999.c18
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr40035.c20
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr40204.c14
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr40233.c10
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr40252.c6
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr40291.c7
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr40351.c22
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr40432.c17
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/ptr-conv-1.c11
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/sra-1.c75
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20090527-1.c38
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/align-nest.c28
-rw-r--r--gcc/testsuite/gcc.dg/20050629-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds.c30
-rw-r--r--gcc/testsuite/gcc.dg/Wcxx-compat-10.c73
-rw-r--r--gcc/testsuite/gcc.dg/Wcxx-compat-11.c21
-rw-r--r--gcc/testsuite/gcc.dg/Wcxx-compat-12.c10
-rw-r--r--gcc/testsuite/gcc.dg/Wcxx-compat-13.c26
-rw-r--r--gcc/testsuite/gcc.dg/Wcxx-compat-2.c64
-rw-r--r--gcc/testsuite/gcc.dg/Wcxx-compat-9.c21
-rw-r--r--gcc/testsuite/gcc.dg/Wjump-misses-init-1.c156
-rw-r--r--gcc/testsuite/gcc.dg/Wjump-misses-init-2.c52
-rw-r--r--gcc/testsuite/gcc.dg/Wredundant-decls-2.c20
-rw-r--r--gcc/testsuite/gcc.dg/Wshadow-3.c80
-rw-r--r--gcc/testsuite/gcc.dg/Wstrict-aliasing-converted-assigned.c4
-rw-r--r--gcc/testsuite/gcc.dg/Wstrict-aliasing-float-ptr-int-obj.c6
-rw-r--r--gcc/testsuite/gcc.dg/Wswitch-enum-error.c2
-rw-r--r--gcc/testsuite/gcc.dg/Wswitch-error.c2
-rw-r--r--gcc/testsuite/gcc.dg/Wswitch.c4
-rw-r--r--gcc/testsuite/gcc.dg/Wunused-label-1.c13
-rw-r--r--gcc/testsuite/gcc.dg/array-10.c42
-rw-r--r--gcc/testsuite/gcc.dg/asm-wide-1.c18
-rw-r--r--gcc/testsuite/gcc.dg/builtin-object-size-2.c10
-rw-r--r--gcc/testsuite/gcc.dg/builtin-object-size-4.c10
-rw-r--r--gcc/testsuite/gcc.dg/builtin-object-size-6.c435
-rw-r--r--gcc/testsuite/gcc.dg/builtin-object-size-7.c71
-rw-r--r--gcc/testsuite/gcc.dg/builtin-unreachable-1.c17
-rw-r--r--gcc/testsuite/gcc.dg/builtin-unreachable-2.c20
-rw-r--r--gcc/testsuite/gcc.dg/builtins-30.c18
-rw-r--r--gcc/testsuite/gcc.dg/c90-const-expr-5.c8
-rw-r--r--gcc/testsuite/gcc.dg/c90-const-expr-8.c28
-rw-r--r--gcc/testsuite/gcc.dg/c99-tag-3.c22
-rw-r--r--gcc/testsuite/gcc.dg/c99-vla-jump-1.c14
-rw-r--r--gcc/testsuite/gcc.dg/c99-vla-jump-2.c4
-rw-r--r--gcc/testsuite/gcc.dg/c99-vla-jump-3.c4
-rw-r--r--gcc/testsuite/gcc.dg/c99-vla-jump-4.c4
-rw-r--r--gcc/testsuite/gcc.dg/c99-vla-jump-5.c8
-rw-r--r--gcc/testsuite/gcc.dg/cast-function-1.c8
-rw-r--r--gcc/testsuite/gcc.dg/cast-qual-3.c167
-rw-r--r--gcc/testsuite/gcc.dg/compat/struct-layout-1_generate.c2
-rw-r--r--gcc/testsuite/gcc.dg/cpp/19940712-1.c5
-rw-r--r--gcc/testsuite/gcc.dg/cpp/Wmissingdirs.c2
-rw-r--r--gcc/testsuite/gcc.dg/cpp/Wsignprom.c2
-rw-r--r--gcc/testsuite/gcc.dg/cpp/Wtrigraphs-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/cpp/Wtrigraphs.c2
-rw-r--r--gcc/testsuite/gcc.dg/cpp/arith-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/cpp/arith-3.c2
-rw-r--r--gcc/testsuite/gcc.dg/cpp/assert2.c2
-rw-r--r--gcc/testsuite/gcc.dg/cpp/cpp.exp2
-rw-r--r--gcc/testsuite/gcc.dg/cpp/escape-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/cpp/escape.c2
-rw-r--r--gcc/testsuite/gcc.dg/cpp/extratokens.c2
-rw-r--r--gcc/testsuite/gcc.dg/cpp/extratokens2.c2
-rw-r--r--gcc/testsuite/gcc.dg/cpp/if-mpar.c1
-rw-r--r--gcc/testsuite/gcc.dg/cpp/include2.c2
-rw-r--r--gcc/testsuite/gcc.dg/cpp/include2a.c4
-rw-r--r--gcc/testsuite/gcc.dg/cpp/line3.c12
-rw-r--r--gcc/testsuite/gcc.dg/cpp/macspace1.c2
-rw-r--r--gcc/testsuite/gcc.dg/cpp/macspace2.c2
-rw-r--r--gcc/testsuite/gcc.dg/cpp/missing-header-1.c3
-rw-r--r--gcc/testsuite/gcc.dg/cpp/poison.c3
-rw-r--r--gcc/testsuite/gcc.dg/cpp/pr29612-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/cpp/pr36674.i12
-rw-r--r--gcc/testsuite/gcc.dg/cpp/redef2.c2
-rw-r--r--gcc/testsuite/gcc.dg/cpp/strify2.c2
-rw-r--r--gcc/testsuite/gcc.dg/cpp/syshdr.c3
-rw-r--r--gcc/testsuite/gcc.dg/cpp/sysmac2.c2
-rw-r--r--gcc/testsuite/gcc.dg/cpp/tr-warn1.c2
-rw-r--r--gcc/testsuite/gcc.dg/cpp/tr-warn3.c2
-rw-r--r--gcc/testsuite/gcc.dg/cpp/tr-warn4.c2
-rw-r--r--gcc/testsuite/gcc.dg/cpp/tr-warn5.c2
-rw-r--r--gcc/testsuite/gcc.dg/cpp/tr-warn6.c2
-rw-r--r--gcc/testsuite/gcc.dg/cpp/trad/trad.exp2
-rw-r--r--gcc/testsuite/gcc.dg/cpp/unc4.c1
-rw-r--r--gcc/testsuite/gcc.dg/cpp/undef2.c4
-rw-r--r--gcc/testsuite/gcc.dg/dll-6.c52
-rw-r--r--gcc/testsuite/gcc.dg/dll-6a.c21
-rw-r--r--gcc/testsuite/gcc.dg/dll-7.c52
-rw-r--r--gcc/testsuite/gcc.dg/dll-7a.c21
-rw-r--r--gcc/testsuite/gcc.dg/dremf-type-compat-2.c6
-rw-r--r--gcc/testsuite/gcc.dg/dremf-type-compat-3.c6
-rw-r--r--gcc/testsuite/gcc.dg/enum-compat-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/falign-labels-1.c39
-rw-r--r--gcc/testsuite/gcc.dg/func-ptr-conv-1.c44
-rw-r--r--gcc/testsuite/gcc.dg/gomp/for-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/gomp/pr27415.c8
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-4.c2
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipacost-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipacost-2.c6
-rw-r--r--gcc/testsuite/gcc.dg/ipa/modif-1.c5
-rw-r--r--gcc/testsuite/gcc.dg/label-decl-2.c3
-rw-r--r--gcc/testsuite/gcc.dg/memcpy-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/nofixed-point-2.c3
-rw-r--r--gcc/testsuite/gcc.dg/old-style-prom-2.c6
-rw-r--r--gcc/testsuite/gcc.dg/old-style-prom-3.c6
-rw-r--r--gcc/testsuite/gcc.dg/optimize-bswapdi-1.c28
-rw-r--r--gcc/testsuite/gcc.dg/optimize-bswapsi-1.c35
-rw-r--r--gcc/testsuite/gcc.dg/overflow-warn-1.c18
-rw-r--r--gcc/testsuite/gcc.dg/pch/counter-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/pch/valid-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/pch/valid-2.c4
-rw-r--r--gcc/testsuite/gcc.dg/pch/warn-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/plugin/ggcplug-test-1.c12
-rw-r--r--gcc/testsuite/gcc.dg/plugin/ggcplug.c112
-rw-r--r--gcc/testsuite/gcc.dg/plugin/one_time-test-1.c8
-rw-r--r--gcc/testsuite/gcc.dg/plugin/one_time_plugin.c60
-rw-r--r--gcc/testsuite/gcc.dg/plugin/plugin.exp5
-rw-r--r--gcc/testsuite/gcc.dg/plugin/selfassign.c9
-rw-r--r--gcc/testsuite/gcc.dg/pr15698-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/pr16302.c76
-rw-r--r--gcc/testsuite/gcc.dg/pr20368-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/pr33667.c2
-rw-r--r--gcc/testsuite/gcc.dg/pr40172-1.c31
-rw-r--r--gcc/testsuite/gcc.dg/pr40172-2.c16
-rw-r--r--gcc/testsuite/gcc.dg/pr40172-3.c17
-rw-r--r--gcc/testsuite/gcc.dg/pr40340-1.c24
-rw-r--r--gcc/testsuite/gcc.dg/pr40340-2.c16
-rw-r--r--gcc/testsuite/gcc.dg/pr40340-3.c15
-rw-r--r--gcc/testsuite/gcc.dg/pr40340-4.c16
-rw-r--r--gcc/testsuite/gcc.dg/pr40340-5.c17
-rw-r--r--gcc/testsuite/gcc.dg/pr40340.h31
-rw-r--r--gcc/testsuite/gcc.dg/prefetch-loop-arrays-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/sibcall-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/sibcall-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/sibcall-3.c2
-rw-r--r--gcc/testsuite/gcc.dg/sibcall-4.c2
-rw-r--r--gcc/testsuite/gcc.dg/sibcall-6.c6
-rw-r--r--gcc/testsuite/gcc.dg/simd-1b.c2
-rw-r--r--gcc/testsuite/gcc.dg/stmt-expr-label-1.c3
-rw-r--r--gcc/testsuite/gcc.dg/stmt-expr-label-2.c6
-rw-r--r--gcc/testsuite/gcc.dg/stmt-expr-label-3.c3
-rw-r--r--gcc/testsuite/gcc.dg/struct/wo_prof_escape_substr_pointer.c4
-rw-r--r--gcc/testsuite/gcc.dg/torture/builtin-math-5.c46
-rw-r--r--gcc/testsuite/gcc.dg/torture/builtin-math-6.c167
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr39204.c2
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr40328.c11
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20041122-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/col-1.c17
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/flatten-2.c9
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/flatten-3.c79
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/fre-vce-1.c35
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/inline-3.c30
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/loop-36.c6
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr36908.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr38250.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr40087.c30
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/prefetch-5.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pta-escape-1.c37
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pta-escape-2.c38
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pta-escape-3.c42
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/sra-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/sra-2.c4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/sra-3.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/sra-4.c4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/sra-5.c74
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/sra-6.c40
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/sra-7.c13
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-10.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-14.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-15.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-24.c34
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-25.c18
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-26.c18
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-27.c25
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-7.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-8.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-9.c2
-rw-r--r--gcc/testsuite/gcc.dg/va-arg-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-1.c62
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-10.c53
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-11.c52
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-13.c49
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-14.c50
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-15.c54
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-16.c71
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-17.c60
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-18.c49
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-19.c56
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-2.c59
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-20.c68
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-21.c68
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-22.c67
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-3.c45
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-4.c41
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-5.c53
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-6.c51
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-7.c52
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-8.c50
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-9.c53
-rw-r--r--gcc/testsuite/gcc.dg/vect/costmodel/i386/costmodel-vect-31.c5
-rw-r--r--gcc/testsuite/gcc.dg/vect/costmodel/i386/costmodel-vect-33.c3
-rw-r--r--gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-vect-31.c6
-rw-r--r--gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-vect-33.c3
-rw-r--r--gcc/testsuite/gcc.dg/vect/no-scevccp-outer-8.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-31.c5
-rw-r--r--gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-64.c5
-rw-r--r--gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-66.c5
-rw-r--r--gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-68.c5
-rw-r--r--gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-69.c9
-rw-r--r--gcc/testsuite/gcc.dg/vect/no-tree-reassoc-bb-slp-12.c53
-rw-r--r--gcc/testsuite/gcc.dg/vect/no-vfa-vect-43.c42
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr18400.c1
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr25413.c6
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr31699.c1
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr40238.c35
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr40254.c39
-rw-r--r--gcc/testsuite/gcc.dg/vect/slp-25.c5
-rw-r--r--gcc/testsuite/gcc.dg/vect/slp-3.c5
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-109.c3
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-26.c4
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-28.c6
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-33.c6
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-40.c7
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-42.c29
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-44.c7
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-46.c7
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-50.c13
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-54.c5
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-58.c5
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-70.c7
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-76.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-87.c7
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-88.c7
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-89.c5
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-91.c5
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-92.c5
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-93.c5
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-95.c5
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-96.c4
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-align-1.c3
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-align-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-iv-10.c1
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-multitypes-1.c10
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-multitypes-4.c6
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-nest-cycle-1.c48
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-nest-cycle-2.c48
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-nest-cycle-3.c57
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-outer-1a.c8
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-outer-4f.c1
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-outer-4g.c1
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-outer-4k.c1
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-outer-4l.c1
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect.exp11
-rw-r--r--gcc/testsuite/gcc.dg/vector-4.c11
-rw-r--r--gcc/testsuite/gcc.dg/vla-8.c6
-rw-r--r--gcc/testsuite/gcc.target/arm/neon-modes-1.c14
-rw-r--r--gcc/testsuite/gcc.target/arm/neon-vmla-1.c10
-rw-r--r--gcc/testsuite/gcc.target/arm/neon-vmls-1.c10
-rw-r--r--gcc/testsuite/gcc.target/arm/thumb2-mul-space-2.c15
-rw-r--r--gcc/testsuite/gcc.target/arm/thumb2-mul-space-3.c17
-rw-r--r--gcc/testsuite/gcc.target/arm/thumb2-mul-space.c10
-rw-r--r--gcc/testsuite/gcc.target/arm/thumb2-mul-speed.c27
-rw-r--r--gcc/testsuite/gcc.target/i386/align-main-1.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/align-main-2.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/crc32-1.c23
-rw-r--r--gcc/testsuite/gcc.target/i386/crc32-2.c9
-rw-r--r--gcc/testsuite/gcc.target/i386/excess-precision-1.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/excess-precision-2.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/excess-precision-3.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/excess-precision-4.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/excess-precision-5.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/excess-precision-6.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/movbe-1.c18
-rw-r--r--gcc/testsuite/gcc.target/i386/movbe-2.c19
-rw-r--r--gcc/testsuite/gcc.target/i386/pr37216.c17
-rw-r--r--gcc/testsuite/gcc.target/i386/pr39543-2.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/stackalign/pr39146.c13
-rw-r--r--gcc/testsuite/gcc.target/ia64/mfused-madd-vect.c33
-rw-r--r--gcc/testsuite/gcc.target/ia64/mfused-madd.c64
-rw-r--r--gcc/testsuite/gcc.target/ia64/mno-fused-madd-vect.c31
-rw-r--r--gcc/testsuite/gcc.target/ia64/mno-fused-madd.c64
-rw-r--r--gcc/testsuite/gcc.target/m68k/tls-gd-xgot.c13
-rw-r--r--gcc/testsuite/gcc.target/m68k/tls-gd.c13
-rw-r--r--gcc/testsuite/gcc.target/m68k/tls-ie-xgot.c13
-rw-r--r--gcc/testsuite/gcc.target/m68k/tls-ie.c13
-rw-r--r--gcc/testsuite/gcc.target/m68k/tls-ld-xgot-xtls.c14
-rw-r--r--gcc/testsuite/gcc.target/m68k/tls-ld-xgot.c14
-rw-r--r--gcc/testsuite/gcc.target/m68k/tls-ld-xtls.c14
-rw-r--r--gcc/testsuite/gcc.target/m68k/tls-ld.c14
-rw-r--r--gcc/testsuite/gcc.target/m68k/tls-le-xtls.c13
-rw-r--r--gcc/testsuite/gcc.target/m68k/tls-le.c13
-rw-r--r--gcc/testsuite/gcc.target/mips/const-anchor-1.c10
-rw-r--r--gcc/testsuite/gcc.target/mips/const-anchor-2.c9
-rw-r--r--gcc/testsuite/gcc.target/mips/extend-1.c14
-rw-r--r--gcc/testsuite/gcc.target/mips/octeon-exts-2.c5
-rw-r--r--gcc/testsuite/gcc.target/mips/octeon-exts-5.c5
-rw-r--r--gcc/testsuite/gcc.target/mips/octeon-exts-6.c14
-rw-r--r--gcc/testsuite/gcc.target/powerpc/altivec-30.c32
-rw-r--r--gcc/testsuite/gcc.target/powerpc/altivec-31.c29
-rw-r--r--gcc/testsuite/gcc.target/powerpc/altivec-types-1.c2
-rw-r--r--gcc/testsuite/gcc.target/x86_64/abi/asm-support.S2
-rw-r--r--gcc/testsuite/gfortran.dg/array_memset_2.f906
-rw-r--r--gcc/testsuite/gfortran.dg/backspace_11.f9024
-rw-r--r--gcc/testsuite/gfortran.dg/bind_c_usage_18.f906
-rw-r--r--gcc/testsuite/gfortran.dg/bound_4.f906
-rw-r--r--gcc/testsuite/gfortran.dg/bounds_check_14.f906
-rw-r--r--gcc/testsuite/gfortran.dg/bounds_check_fail_3.f9012
-rw-r--r--gcc/testsuite/gfortran.dg/bounds_check_fail_4.f9012
-rw-r--r--gcc/testsuite/gfortran.dg/bounds_check_strlen_8.f9040
-rw-r--r--gcc/testsuite/gfortran.dg/c_f_pointer_shape_tests_4.f03115
-rw-r--r--gcc/testsuite/gfortran.dg/c_f_pointer_shape_tests_4_driver.c46
-rw-r--r--gcc/testsuite/gfortran.dg/c_kind_int128_test1.f0310
-rw-r--r--gcc/testsuite/gfortran.dg/c_kind_int128_test2.f032
-rw-r--r--gcc/testsuite/gfortran.dg/c_kind_params.f9024
-rw-r--r--gcc/testsuite/gfortran.dg/c_kind_tests_2.f038
-rw-r--r--gcc/testsuite/gfortran.dg/c_kinds.c17
-rw-r--r--gcc/testsuite/gfortran.dg/count_init_expr.f0315
-rw-r--r--gcc/testsuite/gfortran.dg/data_value_1.f9014
-rw-r--r--gcc/testsuite/gfortran.dg/debug/pr35154-dwarf2.f1
-rw-r--r--gcc/testsuite/gfortran.dg/debug/pr37738.f1
-rw-r--r--gcc/testsuite/gfortran.dg/default_format_1.f902
-rw-r--r--gcc/testsuite/gfortran.dg/default_format_denormal_1.f902
-rw-r--r--gcc/testsuite/gfortran.dg/dot_product_1.f0311
-rw-r--r--gcc/testsuite/gfortran.dg/dummy_procedure_1.f904
-rw-r--r--gcc/testsuite/gfortran.dg/duplicate_type_2.f906
-rw-r--r--gcc/testsuite/gfortran.dg/duplicate_type_3.f9048
-rw-r--r--gcc/testsuite/gfortran.dg/elemental_dependency_1.f906
-rw-r--r--gcc/testsuite/gfortran.dg/erf_2.F9052
-rw-r--r--gcc/testsuite/gfortran.dg/erfc_scaled_2.f9014
-rw-r--r--gcc/testsuite/gfortran.dg/func_decl_2.f906
-rw-r--r--gcc/testsuite/gfortran.dg/hollerith.f906
-rw-r--r--gcc/testsuite/gfortran.dg/hollerith6.f9035
-rw-r--r--gcc/testsuite/gfortran.dg/hollerith7.f9052
-rw-r--r--gcc/testsuite/gfortran.dg/hollerith_f95.f907
-rw-r--r--gcc/testsuite/gfortran.dg/interface_20.f902
-rw-r--r--gcc/testsuite/gfortran.dg/interface_21.f902
-rw-r--r--gcc/testsuite/gfortran.dg/interface_26.f902
-rw-r--r--gcc/testsuite/gfortran.dg/interface_27.f9041
-rw-r--r--gcc/testsuite/gfortran.dg/interface_28.f9043
-rw-r--r--gcc/testsuite/gfortran.dg/interface_29.f9052
-rw-r--r--gcc/testsuite/gfortran.dg/interop_params.f032
-rw-r--r--gcc/testsuite/gfortran.dg/intrinsic_argument_conformance_2.f906
-rw-r--r--gcc/testsuite/gfortran.dg/is_iostat_end_eor_2.f9039
-rw-r--r--gcc/testsuite/gfortran.dg/leadz_trailz_1.f90133
-rw-r--r--gcc/testsuite/gfortran.dg/leadz_trailz_2.f9036
-rw-r--r--gcc/testsuite/gfortran.dg/matmul_8.f0312
-rw-r--r--gcc/testsuite/gfortran.dg/nan_5.f9028
-rw-r--r--gcc/testsuite/gfortran.dg/negative_unit.f19
-rw-r--r--gcc/testsuite/gfortran.dg/negative_unit_int8.f16
-rw-r--r--gcc/testsuite/gfortran.dg/newunit_1.f9020
-rw-r--r--gcc/testsuite/gfortran.dg/nullify_4.f908
-rw-r--r--gcc/testsuite/gfortran.dg/pack_assign_1.f908
-rw-r--r--gcc/testsuite/gfortran.dg/pack_vector_1.f9010
-rw-r--r--gcc/testsuite/gfortran.dg/pr25923.f902
-rw-r--r--gcc/testsuite/gfortran.dg/pr39865.f9084
-rw-r--r--gcc/testsuite/gfortran.dg/proc_decl_1.f902
-rw-r--r--gcc/testsuite/gfortran.dg/proc_decl_7.f902
-rw-r--r--gcc/testsuite/gfortran.dg/proc_decl_8.f902
-rw-r--r--gcc/testsuite/gfortran.dg/proc_ptr_11.f909
-rw-r--r--gcc/testsuite/gfortran.dg/proc_ptr_15.f908
-rw-r--r--gcc/testsuite/gfortran.dg/proc_ptr_18.f9025
-rw-r--r--gcc/testsuite/gfortran.dg/proc_ptr_19.f9035
-rw-r--r--gcc/testsuite/gfortran.dg/proc_ptr_comp_10.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/proc_ptr_comp_8.f9058
-rw-r--r--gcc/testsuite/gfortran.dg/proc_ptr_comp_9.f9037
-rw-r--r--gcc/testsuite/gfortran.dg/proc_ptr_result_1.f909
-rw-r--r--gcc/testsuite/gfortran.dg/product_init_expr.f0366
-rw-r--r--gcc/testsuite/gfortran.dg/reshape_order_5.f9016
-rw-r--r--gcc/testsuite/gfortran.dg/reshape_shape_1.f9014
-rw-r--r--gcc/testsuite/gfortran.dg/reshape_zerosize_2.f9011
-rw-r--r--gcc/testsuite/gfortran.dg/spread_init_expr.f0317
-rw-r--r--gcc/testsuite/gfortran.dg/string_1.f9014
-rw-r--r--gcc/testsuite/gfortran.dg/string_2.f9012
-rw-r--r--gcc/testsuite/gfortran.dg/string_3.f9019
-rw-r--r--gcc/testsuite/gfortran.dg/sum_init_expr.f0366
-rw-r--r--gcc/testsuite/gfortran.dg/transpose_3.f0310
-rw-r--r--gcc/testsuite/gfortran.dg/unpack_init_expr.f0315
-rw-r--r--gcc/testsuite/gfortran.dg/vect/vect-2.f909
-rw-r--r--gcc/testsuite/gfortran.dg/vect/vect-3.f9011
-rw-r--r--gcc/testsuite/gfortran.dg/vect/vect-4.f907
-rw-r--r--gcc/testsuite/gfortran.dg/vect/vect-5.f907
-rw-r--r--gcc/testsuite/gfortran.dg/vector_subscript_4.f902
-rw-r--r--gcc/testsuite/gfortran.dg/zero_sized_1.f9012
-rw-r--r--gcc/testsuite/gfortran.dg/zero_sized_5.f902
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/compile/pr40413.f9046
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/compile/pr40421.f18
-rw-r--r--gcc/testsuite/gnat.dg/addr6.adb31
-rw-r--r--gcc/testsuite/gnat.dg/align_max.adb137
-rw-r--r--gcc/testsuite/gnat.dg/alignment6.adb2
-rw-r--r--gcc/testsuite/gnat.dg/loop_optimization6.adb25
-rw-r--r--gcc/testsuite/gnat.dg/loop_optimization6.ads4
-rw-r--r--gcc/testsuite/gnat.dg/misaligned_nest.adb26
-rw-r--r--gcc/testsuite/gnat.dg/nested_float_packed.ads24
-rw-r--r--gcc/testsuite/gnat.dg/oconst1.adb18
-rw-r--r--gcc/testsuite/gnat.dg/oconst1.ads25
-rw-r--r--gcc/testsuite/gnat.dg/oconst2.adb15
-rw-r--r--gcc/testsuite/gnat.dg/oconst2.ads23
-rw-r--r--gcc/testsuite/gnat.dg/oconst3.adb16
-rw-r--r--gcc/testsuite/gnat.dg/oconst3.ads26
-rw-r--r--gcc/testsuite/gnat.dg/oconst4.adb24
-rw-r--r--gcc/testsuite/gnat.dg/oconst4.ads66
-rw-r--r--gcc/testsuite/gnat.dg/oconst5.adb15
-rw-r--r--gcc/testsuite/gnat.dg/oconst5.ads27
-rw-r--r--gcc/testsuite/gnat.dg/oconst6.ads18
-rw-r--r--gcc/testsuite/gnat.dg/pack9.adb2
-rw-r--r--gcc/testsuite/gnat.dg/specs/rep_clause3.ads36
-rw-r--r--gcc/testsuite/gnat.dg/specs/root-level_1-level_2.ads7
-rw-r--r--gcc/testsuite/gnat.dg/specs/root-level_1.ads14
-rw-r--r--gcc/testsuite/gnat.dg/specs/root-level_2.ads9
-rw-r--r--gcc/testsuite/gnat.dg/specs/root.ads9
-rw-r--r--gcc/testsuite/gnat.dg/test_oconst.adb13
-rw-r--r--gcc/testsuite/lib/gcc-dg.exp54
-rw-r--r--gcc/testsuite/lib/gfortran-dg.exp16
-rw-r--r--gcc/testsuite/lib/target-supports.exp63
-rw-r--r--gcc/timevar.def2
-rw-r--r--gcc/toplev.c42
-rw-r--r--gcc/toplev.h15
-rw-r--r--gcc/tree-call-cdce.c2
-rw-r--r--gcc/tree-cfg.c167
-rw-r--r--gcc/tree-chrec.c23
-rw-r--r--gcc/tree-complex.c1
-rw-r--r--gcc/tree-data-ref.c158
-rw-r--r--gcc/tree-data-ref.h3
-rw-r--r--gcc/tree-dfa.c35
-rw-r--r--gcc/tree-eh.c72
-rw-r--r--gcc/tree-flow-inline.h15
-rw-r--r--gcc/tree-flow.h25
-rw-r--r--gcc/tree-inline.c84
-rw-r--r--gcc/tree-inline.h5
-rw-r--r--gcc/tree-mudflap.c29
-rw-r--r--gcc/tree-nested.c35
-rw-r--r--gcc/tree-nomudflap.c2
-rw-r--r--gcc/tree-object-size.c208
-rw-r--r--gcc/tree-outof-ssa.c70
-rw-r--r--gcc/tree-parloops.c37
-rw-r--r--gcc/tree-pass.h14
-rw-r--r--gcc/tree-predcom.c50
-rw-r--r--gcc/tree-pretty-print.c232
-rw-r--r--gcc/tree-profile.c4
-rw-r--r--gcc/tree-scalar-evolution.c97
-rw-r--r--gcc/tree-sra.c4825
-rw-r--r--gcc/tree-ssa-alias.c376
-rw-r--r--gcc/tree-ssa-alias.h62
-rw-r--r--gcc/tree-ssa-ccp.c148
-rw-r--r--gcc/tree-ssa-copy.c73
-rw-r--r--gcc/tree-ssa-copyrename.c14
-rw-r--r--gcc/tree-ssa-dce.c4
-rw-r--r--gcc/tree-ssa-dom.c43
-rw-r--r--gcc/tree-ssa-forwprop.c57
-rw-r--r--gcc/tree-ssa-live.c48
-rw-r--r--gcc/tree-ssa-loop-im.c4
-rw-r--r--gcc/tree-ssa-loop-ivopts.c127
-rw-r--r--gcc/tree-ssa-loop-niter.c109
-rw-r--r--gcc/tree-ssa-loop-prefetch.c144
-rw-r--r--gcc/tree-ssa-math-opts.c383
-rw-r--r--gcc/tree-ssa-operands.c84
-rw-r--r--gcc/tree-ssa-operands.h4
-rw-r--r--gcc/tree-ssa-phiprop.c2
-rw-r--r--gcc/tree-ssa-pre.c107
-rw-r--r--gcc/tree-ssa-propagate.c10
-rw-r--r--gcc/tree-ssa-sccvn.c447
-rw-r--r--gcc/tree-ssa-sccvn.h13
-rw-r--r--gcc/tree-ssa-structalias.c531
-rw-r--r--gcc/tree-ssa.c12
-rw-r--r--gcc/tree-switch-conversion.c9
-rw-r--r--gcc/tree-vect-data-refs.c348
-rw-r--r--gcc/tree-vect-loop-manip.c26
-rw-r--r--gcc/tree-vect-loop.c301
-rw-r--r--gcc/tree-vect-patterns.c21
-rw-r--r--gcc/tree-vect-slp.c515
-rw-r--r--gcc/tree-vect-stmts.c369
-rw-r--r--gcc/tree-vectorizer.c110
-rw-r--r--gcc/tree-vectorizer.h116
-rw-r--r--gcc/tree-vrp.c43
-rw-r--r--gcc/tree.c256
-rw-r--r--gcc/tree.def9
-rw-r--r--gcc/tree.h117
-rw-r--r--gcc/unwind-dw2-fde.c20
-rw-r--r--gcc/unwind-dw2.c27
-rw-r--r--gcc/varasm.c776
-rw-r--r--gcc/vec.c2
-rw-r--r--gcc/vec.h18
-rw-r--r--gcc/vmsdbgout.c11
-rw-r--r--gcc/xcoffout.c3
-rw-r--r--gcc/xcoffout.h2
-rw-r--r--gnattools/ChangeLog8
-rw-r--r--gnattools/Makefile.in2
-rw-r--r--include/ChangeLog17
-rw-r--r--include/ansidecl.h48
-rw-r--r--include/dyn-string.h15
-rw-r--r--include/fibheap.h11
-rw-r--r--libcpp/ChangeLog38
-rw-r--r--libcpp/directives.c8
-rw-r--r--libcpp/files.c15
-rw-r--r--libcpp/include/cpp-id-data.h8
-rw-r--r--libcpp/include/cpplib.h15
-rw-r--r--libcpp/include/line-map.h11
-rw-r--r--libcpp/include/mkdeps.h8
-rw-r--r--libcpp/include/symtab.h9
-rw-r--r--libcpp/init.c17
-rw-r--r--libcpp/internal.h8
-rw-r--r--libcpp/lex.c6
-rw-r--r--libdecnumber/ChangeLog9
-rw-r--r--libdecnumber/decContext.h8
-rw-r--r--libdecnumber/decDPD.h8
-rw-r--r--libdecnumber/decNumber.h8
-rw-r--r--libdecnumber/dpd/decimal128.h8
-rw-r--r--libdecnumber/dpd/decimal32.h8
-rw-r--r--libdecnumber/dpd/decimal64.h8
-rw-r--r--libffi/ChangeLog402
-rw-r--r--libffi/Makefile.am12
-rw-r--r--libffi/Makefile.in120
-rw-r--r--libffi/README375
-rwxr-xr-xlibffi/configure81
-rw-r--r--libffi/configure.ac21
-rw-r--r--libffi/doc/libffi.info533
-rw-r--r--libffi/doc/libffi.texi541
-rw-r--r--libffi/doc/stamp-vti4
-rw-r--r--libffi/doc/version.texi4
-rw-r--r--libffi/include/Makefile.in4
-rw-r--r--libffi/include/ffi.h.in29
-rw-r--r--libffi/include/ffi_common.h18
-rw-r--r--libffi/man/Makefile.am8
-rw-r--r--libffi/man/Makefile.in452
-rw-r--r--libffi/man/ffi.331
-rw-r--r--libffi/man/ffi_call.3103
-rw-r--r--libffi/man/ffi_prep_cif.366
-rw-r--r--libffi/src/alpha/ffi.c21
-rw-r--r--libffi/src/alpha/ffitarget.h15
-rw-r--r--libffi/src/alpha/osf.S19
-rw-r--r--libffi/src/arm/ffi.c21
-rw-r--r--libffi/src/arm/ffitarget.h15
-rw-r--r--libffi/src/arm/sysv.S17
-rw-r--r--libffi/src/closures.c42
-rw-r--r--libffi/src/cris/ffitarget.h15
-rw-r--r--libffi/src/debug.c15
-rw-r--r--libffi/src/dlmalloc.c8
-rw-r--r--libffi/src/frv/ffi.c22
-rw-r--r--libffi/src/frv/ffitarget.h15
-rw-r--r--libffi/src/ia64/ffi.c21
-rw-r--r--libffi/src/ia64/ffitarget.h15
-rw-r--r--libffi/src/ia64/ia64_flags.h15
-rw-r--r--libffi/src/ia64/unix.S23
-rw-r--r--libffi/src/java_raw_api.c19
-rw-r--r--libffi/src/m32r/ffi.c5
-rw-r--r--libffi/src/m68k/ffitarget.h15
-rw-r--r--libffi/src/m68k/sysv.S23
-rw-r--r--libffi/src/mips/ffi.c39
-rw-r--r--libffi/src/mips/ffitarget.h28
-rw-r--r--libffi/src/mips/n32.S15
-rw-r--r--libffi/src/mips/o32.S15
-rw-r--r--libffi/src/pa/ffi.c20
-rw-r--r--libffi/src/pa/ffitarget.h15
-rw-r--r--libffi/src/pa/hpux32.S3
-rw-r--r--libffi/src/pa/linux.S5
-rw-r--r--libffi/src/powerpc/ffi.c20
-rw-r--r--libffi/src/powerpc/ffi_darwin.c6
-rw-r--r--libffi/src/powerpc/ffitarget.h15
-rw-r--r--libffi/src/powerpc/linux64.S20
-rw-r--r--libffi/src/powerpc/linux64_closure.S30
-rw-r--r--libffi/src/powerpc/ppc_closure.S26
-rw-r--r--libffi/src/powerpc/sysv.S50
-rw-r--r--libffi/src/prep_cif.c15
-rw-r--r--libffi/src/raw_api.c21
-rw-r--r--libffi/src/s390/ffi.c5
-rw-r--r--libffi/src/s390/ffitarget.h15
-rw-r--r--libffi/src/s390/sysv.S16
-rw-r--r--libffi/src/sh/ffi.c23
-rw-r--r--libffi/src/sh/ffitarget.h15
-rw-r--r--libffi/src/sh/sysv.S15
-rw-r--r--libffi/src/sh64/ffi.c35
-rw-r--r--libffi/src/sh64/ffitarget.h15
-rw-r--r--libffi/src/sh64/sysv.S16
-rw-r--r--libffi/src/sparc/ffi.c23
-rw-r--r--libffi/src/sparc/ffitarget.h15
-rw-r--r--libffi/src/sparc/v8.S17
-rw-r--r--libffi/src/sparc/v9.S17
-rw-r--r--libffi/src/types.c15
-rw-r--r--libffi/src/x86/darwin.S18
-rw-r--r--libffi/src/x86/darwin64.S3
-rw-r--r--libffi/src/x86/ffi.c444
-rw-r--r--libffi/src/x86/ffi64.c22
-rw-r--r--libffi/src/x86/ffitarget.h49
-rw-r--r--libffi/src/x86/freebsd.S458
-rw-r--r--libffi/src/x86/sysv.S18
-rw-r--r--libffi/src/x86/unix64.S20
-rw-r--r--libffi/src/x86/win32.S322
-rw-r--r--libffi/src/x86/win64.S462
-rw-r--r--libffi/testsuite/Makefile.in4
-rw-r--r--libffi/testsuite/lib/libffi-dg.exp7
-rw-r--r--libffi/testsuite/libffi.call/closure_fn0.c22
-rw-r--r--libffi/testsuite/libffi.call/closure_fn1.c22
-rw-r--r--libffi/testsuite/libffi.call/closure_fn2.c22
-rw-r--r--libffi/testsuite/libffi.call/closure_fn3.c22
-rw-r--r--libffi/testsuite/libffi.call/closure_fn4.c22
-rw-r--r--libffi/testsuite/libffi.call/closure_fn5.c21
-rw-r--r--libffi/testsuite/libffi.call/closure_fn6.c22
-rw-r--r--libffi/testsuite/libffi.call/closure_loc_fn0.c95
-rw-r--r--libffi/testsuite/libffi.call/closure_stdcall.c64
-rw-r--r--libffi/testsuite/libffi.call/cls_12byte.c16
-rw-r--r--libffi/testsuite/libffi.call/cls_16byte.c16
-rw-r--r--libffi/testsuite/libffi.call/cls_18byte.c16
-rw-r--r--libffi/testsuite/libffi.call/cls_19byte.c16
-rw-r--r--libffi/testsuite/libffi.call/cls_1_1byte.c16
-rw-r--r--libffi/testsuite/libffi.call/cls_20byte.c16
-rw-r--r--libffi/testsuite/libffi.call/cls_20byte1.c16
-rw-r--r--libffi/testsuite/libffi.call/cls_24byte.c16
-rw-r--r--libffi/testsuite/libffi.call/cls_2byte.c16
-rw-r--r--libffi/testsuite/libffi.call/cls_3_1byte.c16
-rw-r--r--libffi/testsuite/libffi.call/cls_3byte1.c16
-rw-r--r--libffi/testsuite/libffi.call/cls_3byte2.c16
-rw-r--r--libffi/testsuite/libffi.call/cls_4_1byte.c16
-rw-r--r--libffi/testsuite/libffi.call/cls_4byte.c16
-rw-r--r--libffi/testsuite/libffi.call/cls_5_1_byte.c16
-rw-r--r--libffi/testsuite/libffi.call/cls_5byte.c16
-rw-r--r--libffi/testsuite/libffi.call/cls_64byte.c16
-rw-r--r--libffi/testsuite/libffi.call/cls_6_1_byte.c16
-rw-r--r--libffi/testsuite/libffi.call/cls_6byte.c16
-rw-r--r--libffi/testsuite/libffi.call/cls_7_1_byte.c16
-rw-r--r--libffi/testsuite/libffi.call/cls_7byte.c16
-rw-r--r--libffi/testsuite/libffi.call/cls_8byte.c16
-rw-r--r--libffi/testsuite/libffi.call/cls_9byte1.c16
-rw-r--r--libffi/testsuite/libffi.call/cls_9byte2.c16
-rw-r--r--libffi/testsuite/libffi.call/cls_align_double.c16
-rw-r--r--libffi/testsuite/libffi.call/cls_align_float.c16
-rw-r--r--libffi/testsuite/libffi.call/cls_align_longdouble.c16
-rw-r--r--libffi/testsuite/libffi.call/cls_align_longdouble_split.c134
-rw-r--r--libffi/testsuite/libffi.call/cls_align_longdouble_split2.c117
-rw-r--r--libffi/testsuite/libffi.call/cls_align_pointer.c28
-rw-r--r--libffi/testsuite/libffi.call/cls_align_sint16.c16
-rw-r--r--libffi/testsuite/libffi.call/cls_align_sint32.c16
-rw-r--r--libffi/testsuite/libffi.call/cls_align_sint64.c22
-rw-r--r--libffi/testsuite/libffi.call/cls_align_uint16.c16
-rw-r--r--libffi/testsuite/libffi.call/cls_align_uint32.c16
-rw-r--r--libffi/testsuite/libffi.call/cls_align_uint64.c22
-rw-r--r--libffi/testsuite/libffi.call/cls_dbls_struct.c66
-rw-r--r--libffi/testsuite/libffi.call/cls_double.c16
-rw-r--r--libffi/testsuite/libffi.call/cls_double_va.c56
-rw-r--r--libffi/testsuite/libffi.call/cls_float.c17
-rw-r--r--libffi/testsuite/libffi.call/cls_longdouble.c105
-rw-r--r--libffi/testsuite/libffi.call/cls_longdouble_va.c57
-rw-r--r--libffi/testsuite/libffi.call/cls_multi_schar.c16
-rw-r--r--libffi/testsuite/libffi.call/cls_multi_sshort.c16
-rw-r--r--libffi/testsuite/libffi.call/cls_multi_sshortchar.c16
-rw-r--r--libffi/testsuite/libffi.call/cls_multi_uchar.c16
-rw-r--r--libffi/testsuite/libffi.call/cls_multi_ushort.c16
-rw-r--r--libffi/testsuite/libffi.call/cls_multi_ushortchar.c16
-rw-r--r--libffi/testsuite/libffi.call/cls_pointer.c74
-rw-r--r--libffi/testsuite/libffi.call/cls_pointer_stack.c140
-rw-r--r--libffi/testsuite/libffi.call/cls_schar.c16
-rw-r--r--libffi/testsuite/libffi.call/cls_sint.c16
-rw-r--r--libffi/testsuite/libffi.call/cls_sshort.c16
-rw-r--r--libffi/testsuite/libffi.call/cls_uchar.c16
-rw-r--r--libffi/testsuite/libffi.call/cls_uint.c16
-rw-r--r--libffi/testsuite/libffi.call/cls_ulonglong.c24
-rw-r--r--libffi/testsuite/libffi.call/cls_ushort.c16
-rw-r--r--libffi/testsuite/libffi.call/err_bad_abi.c37
-rw-r--r--libffi/testsuite/libffi.call/err_bad_typedef.c25
-rw-r--r--libffi/testsuite/libffi.call/ffitest.h11
-rw-r--r--libffi/testsuite/libffi.call/float2.c3
-rw-r--r--libffi/testsuite/libffi.call/nested_struct.c16
-rw-r--r--libffi/testsuite/libffi.call/nested_struct1.c16
-rw-r--r--libffi/testsuite/libffi.call/nested_struct10.c16
-rw-r--r--libffi/testsuite/libffi.call/nested_struct2.c16
-rw-r--r--libffi/testsuite/libffi.call/nested_struct3.c16
-rw-r--r--libffi/testsuite/libffi.call/nested_struct4.c16
-rw-r--r--libffi/testsuite/libffi.call/nested_struct5.c16
-rw-r--r--libffi/testsuite/libffi.call/nested_struct6.c16
-rw-r--r--libffi/testsuite/libffi.call/nested_struct7.c16
-rw-r--r--libffi/testsuite/libffi.call/nested_struct8.c16
-rw-r--r--libffi/testsuite/libffi.call/nested_struct9.c16
-rw-r--r--libffi/testsuite/libffi.call/problem1.c16
-rw-r--r--libffi/testsuite/libffi.call/return_ldl.c2
-rw-r--r--libffi/testsuite/libffi.call/return_ll1.c2
-rw-r--r--libffi/testsuite/libffi.call/stret_large.c145
-rw-r--r--libffi/testsuite/libffi.call/stret_large2.c148
-rw-r--r--libffi/testsuite/libffi.call/stret_medium.c124
-rw-r--r--libffi/testsuite/libffi.call/stret_medium2.c124
-rw-r--r--libffi/testsuite/libffi.special/ffitestcxx.h10
-rw-r--r--libffi/testsuite/libffi.special/unwindtest.cc26
-rw-r--r--libgcc/ChangeLog14
-rw-r--r--libgcc/config.host11
-rw-r--r--libgfortran/ChangeLog82
-rw-r--r--libgfortran/Makefile.am1
-rw-r--r--libgfortran/Makefile.in21
-rw-r--r--libgfortran/config.h.in6
-rwxr-xr-xlibgfortran/configure111
-rw-r--r--libgfortran/configure.ac1
-rw-r--r--libgfortran/fmain.c4
-rw-r--r--libgfortran/gfortran.map7
-rw-r--r--libgfortran/intrinsics/bit_intrinsics.c138
-rw-r--r--libgfortran/intrinsics/date_and_time.c41
-rw-r--r--libgfortran/intrinsics/iso_c_binding.c62
-rw-r--r--libgfortran/io/format.c13
-rw-r--r--libgfortran/io/io.h8
-rw-r--r--libgfortran/io/list_read.c5
-rw-r--r--libgfortran/io/open.c9
-rw-r--r--libgfortran/io/transfer.c2
-rw-r--r--libgfortran/io/unit.c50
-rw-r--r--libgfortran/io/write_float.def9
-rw-r--r--libgfortran/libgfortran.h3
-rw-r--r--libgfortran/runtime/main.c47
-rw-r--r--libgomp/ChangeLog19
-rw-r--r--libgomp/Makefile.am5
-rw-r--r--libgomp/Makefile.in5
-rw-r--r--libgomp/team.c2
-rw-r--r--libgomp/testsuite/libgomp.fortran/fortran.exp8
-rw-r--r--libiberty/ChangeLog43
-rw-r--r--libiberty/config.h-vms22
-rw-r--r--libiberty/cp-demangle.c8
-rw-r--r--libiberty/fibheap.c10
-rw-r--r--libiberty/makefile.vms18
-rw-r--r--libiberty/pex-win32.c22
-rw-r--r--libiberty/snprintf.c16
-rw-r--r--libiberty/testsuite/test-demangle.c10
-rw-r--r--libiberty/vsnprintf.c16
-rw-r--r--libjava/classpath/ChangeLog.gcj10
-rw-r--r--libjava/classpath/tools/classes/gnu/classpath/tools/doclets/htmldoclet/HtmlDoclet.classbin80179 -> 79930 bytes
-rw-r--r--libjava/classpath/tools/classes/gnu/classpath/tools/gjdoc/Main.classbin29564 -> 29338 bytes
-rw-r--r--libjava/classpath/tools/gnu/classpath/tools/doclets/htmldoclet/HtmlDoclet.java15
-rw-r--r--libjava/classpath/tools/gnu/classpath/tools/gjdoc/Main.java11
-rw-r--r--libstdc++-v3/ChangeLog484
-rw-r--r--libstdc++-v3/Makefile.am3
-rw-r--r--libstdc++-v3/Makefile.in4
-rw-r--r--libstdc++-v3/acinclude.m42
-rw-r--r--libstdc++-v3/config/abi/pre/gnu.ver4
-rw-r--r--libstdc++-v3/config/locale/generic/c_locale.cc4
-rw-r--r--libstdc++-v3/config/locale/gnu/c_locale.cc21
-rwxr-xr-xlibstdc++-v3/configure17460
-rw-r--r--libstdc++-v3/crossconfig.m410
-rw-r--r--libstdc++-v3/doc/xml/manual/status_cxx200x.xml61
-rw-r--r--libstdc++-v3/include/Makefile.am2
-rw-r--r--libstdc++-v3/include/Makefile.in2
-rw-r--r--libstdc++-v3/include/bits/forward_list.h16
-rw-r--r--libstdc++-v3/include/bits/locale_classes.h3
-rw-r--r--libstdc++-v3/include/bits/move.h14
-rw-r--r--libstdc++-v3/include/bits/random.h485
-rw-r--r--libstdc++-v3/include/bits/random.tcc379
-rw-r--r--libstdc++-v3/include/bits/shared_ptr.h9
-rw-r--r--libstdc++-v3/include/bits/stl_bvector.h4
-rw-r--r--libstdc++-v3/include/bits/stl_construct.h25
-rw-r--r--libstdc++-v3/include/bits/stl_deque.h16
-rw-r--r--libstdc++-v3/include/bits/stl_list.h16
-rw-r--r--libstdc++-v3/include/bits/stl_map.h18
-rw-r--r--libstdc++-v3/include/bits/stl_multimap.h18
-rw-r--r--libstdc++-v3/include/bits/stl_multiset.h18
-rw-r--r--libstdc++-v3/include/bits/stl_pair.h12
-rw-r--r--libstdc++-v3/include/bits/stl_queue.h26
-rw-r--r--libstdc++-v3/include/bits/stl_set.h16
-rw-r--r--libstdc++-v3/include/bits/stl_stack.h12
-rw-r--r--libstdc++-v3/include/bits/stl_tree.h8
-rw-r--r--libstdc++-v3/include/bits/stl_vector.h16
-rw-r--r--libstdc++-v3/include/bits/unique_ptr.h26
-rw-r--r--libstdc++-v3/include/debug/deque16
-rw-r--r--libstdc++-v3/include/debug/formatter.h31
-rw-r--r--libstdc++-v3/include/debug/list16
-rw-r--r--libstdc++-v3/include/debug/map.h20
-rw-r--r--libstdc++-v3/include/debug/multimap.h20
-rw-r--r--libstdc++-v3/include/debug/multiset.h18
-rw-r--r--libstdc++-v3/include/debug/set.h18
-rw-r--r--libstdc++-v3/include/debug/unordered_map32
-rw-r--r--libstdc++-v3/include/debug/unordered_set28
-rw-r--r--libstdc++-v3/include/debug/vector16
-rw-r--r--libstdc++-v3/include/ext/memory12
-rw-r--r--libstdc++-v3/include/ext/pb_ds/detail/debug_map_base.hpp18
-rw-r--r--libstdc++-v3/include/ext/pb_ds/detail/gp_hash_table_map_/resize_fn_imps.hpp2
-rw-r--r--libstdc++-v3/include/ext/pb_ds/detail/ov_tree_map_/erase_fn_imps.hpp4
-rw-r--r--libstdc++-v3/include/ext/pb_ds/detail/ov_tree_map_/ov_tree_map_.hpp2
-rw-r--r--libstdc++-v3/include/ext/throw_allocator.h402
-rw-r--r--libstdc++-v3/include/ext/vstring.h20
-rw-r--r--libstdc++-v3/include/std/istream9
-rw-r--r--libstdc++-v3/include/std/mutex26
-rw-r--r--libstdc++-v3/include/std/ostream5
-rw-r--r--libstdc++-v3/include/std/system_error22
-rw-r--r--libstdc++-v3/include/std/thread18
-rw-r--r--libstdc++-v3/include/std/tuple24
-rw-r--r--libstdc++-v3/include/tr1_impl/functional19
-rw-r--r--libstdc++-v3/include/tr1_impl/hashtable8
-rw-r--r--libstdc++-v3/include/tr1_impl/unordered_map26
-rw-r--r--libstdc++-v3/include/tr1_impl/unordered_set26
-rw-r--r--libstdc++-v3/libsupc++/Makefile.am2
-rw-r--r--libstdc++-v3/libsupc++/Makefile.in2
-rw-r--r--libstdc++-v3/libsupc++/eh_ptr.cc6
-rw-r--r--libstdc++-v3/libsupc++/exception1
-rw-r--r--libstdc++-v3/libsupc++/exception_ptr.h24
-rw-r--r--libstdc++-v3/libsupc++/initializer_list42
-rw-r--r--libstdc++-v3/libsupc++/nested_exception.h177
-rw-r--r--libstdc++-v3/python/Makefile.am60
-rw-r--r--libstdc++-v3/python/Makefile.in516
-rw-r--r--libstdc++-v3/python/hook.in55
-rw-r--r--libstdc++-v3/python/libstdcxx/__init__.py1
-rw-r--r--libstdc++-v3/python/libstdcxx/v6/__init__.py1
-rw-r--r--libstdc++-v3/python/libstdcxx/v6/printers.py640
-rw-r--r--libstdc++-v3/src/Makefile.am1
-rw-r--r--libstdc++-v3/src/Makefile.in20
-rw-r--r--libstdc++-v3/src/compatibility.cc23
-rw-r--r--libstdc++-v3/src/debug.cc36
-rw-r--r--libstdc++-v3/src/localename.cc37
-rw-r--r--libstdc++-v3/src/mutex.cc4
-rw-r--r--libstdc++-v3/src/throw_allocator.cc95
-rw-r--r--libstdc++-v3/testsuite/18_support/exception_ptr/40296.cc30
-rw-r--r--libstdc++-v3/testsuite/18_support/exception_ptr/current_exception.cc6
-rw-r--r--libstdc++-v3/testsuite/18_support/exception_ptr/move.cc45
-rw-r--r--libstdc++-v3/testsuite/18_support/initializer_list/requirements/explicit_instantiation.cc24
-rw-r--r--libstdc++-v3/testsuite/18_support/initializer_list/requirements/typedefs.cc34
-rw-r--r--libstdc++-v3/testsuite/18_support/nested_exception/cons.cc (renamed from libstdc++-v3/testsuite/20_util/shared_ptr/modifiers/swap_rvalue.cc)38
-rw-r--r--libstdc++-v3/testsuite/18_support/nested_exception/nested_ptr.cc71
-rw-r--r--libstdc++-v3/testsuite/18_support/nested_exception/rethrow_if_nested.cc110
-rw-r--r--libstdc++-v3/testsuite/18_support/nested_exception/rethrow_nested.cc53
-rw-r--r--libstdc++-v3/testsuite/18_support/nested_exception/throw_with_nested.cc79
-rw-r--r--libstdc++-v3/testsuite/19_diagnostics/error_code/operators/bool.cc4
-rw-r--r--libstdc++-v3/testsuite/19_diagnostics/error_code/operators/bool_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/19_diagnostics/error_condition/operators/bool.cc4
-rw-r--r--libstdc++-v3/testsuite/19_diagnostics/error_condition/operators/bool_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/20_util/function/null_pointer_comparisons.cc44
-rw-r--r--libstdc++-v3/testsuite/20_util/function/requirements/explicit_instantiation.cc26
-rw-r--r--libstdc++-v3/testsuite/20_util/shared_ptr/observers/bool_conv.cc16
-rw-r--r--libstdc++-v3/testsuite/20_util/unique_ptr/assign/assign_neg.cc6
-rw-r--r--libstdc++-v3/testsuite/20_util/unique_ptr/modifiers/reset_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/40160.cc24
-rw-r--r--libstdc++-v3/testsuite/22_locale/locale/cons/40184.cc60
-rw-r--r--libstdc++-v3/testsuite/23_containers/deque/cons/1.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/deque/cons/2.cc4
-rw-r--r--libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/assign_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/insert_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/headers/forward_list/synopsis.cc6
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/14340.cc4
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/23781.cc5
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/capacity/1.cc17
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/capacity/29134.cc3
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/check_construct_destroy.cc29
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/cons/1.cc43
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/cons/2.cc44
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/cons/3.cc26
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/cons/4.cc20
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/cons/5.cc17
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/cons/6.cc15
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/cons/7.cc15
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/cons/8.cc26
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/cons/9.cc19
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/cons/clear_allocator.cc3
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/init-list.cc34
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/invalidation/1.cc18
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/invalidation/2.cc21
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/invalidation/3.cc20
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/invalidation/4.cc21
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/modifiers/1.cc72
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/modifiers/2.cc63
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/modifiers/3.cc61
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/modifiers/insert/25288.cc29
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/modifiers/swap/1.cc26
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/modifiers/swap/2.cc46
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/modifiers/swap/3.cc46
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/moveable.cc32
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/operations/1.cc19
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/operations/2.cc21
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/operations/3.cc27
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/operations/4.cc24
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/operations/5.cc23
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/pthread1.cc19
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/pthread5.cc13
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/requirements/citerators.cc4
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/requirements/dr438/assign_neg.cc5
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor.cc3
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_1_neg.cc5
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_2_neg.cc5
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/requirements/dr438/insert_neg.cc5
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/requirements/partial_specialization/1.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/40192.cc28
-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/26_numerics/random/discrete_distribution/cons/num_xbound_fun.cc5
-rw-r--r--libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/cons/initlist_fun.cc8
-rw-r--r--libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/cons/num_xbound_fun.cc8
-rw-r--r--libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/cons/initlist_fun.cc8
-rw-r--r--libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/cons/num_xbound_fun.cc8
-rw-r--r--libstdc++-v3/testsuite/29_atomics/atomic_address/cons/aggregate.cc4
-rw-r--r--libstdc++-v3/testsuite/30_threads/headers/mutex/types_std_c++0x.cc3
-rw-r--r--libstdc++-v3/testsuite/30_threads/thread/swap/1.cc39
-rw-r--r--libstdc++-v3/testsuite/30_threads/thread/swap/2.cc112
-rw-r--r--libstdc++-v3/testsuite/ext/array_allocator/check_delete.cc33
-rw-r--r--libstdc++-v3/testsuite/ext/array_allocator/check_new.cc33
-rw-r--r--libstdc++-v3/testsuite/ext/bitmap_allocator/check_delete.cc32
-rw-r--r--libstdc++-v3/testsuite/ext/bitmap_allocator/check_new.cc32
-rw-r--r--libstdc++-v3/testsuite/ext/debug_allocator/check_delete.cc33
-rw-r--r--libstdc++-v3/testsuite/ext/debug_allocator/check_new.cc33
-rw-r--r--libstdc++-v3/testsuite/ext/malloc_allocator/check_delete.cc33
-rw-r--r--libstdc++-v3/testsuite/ext/malloc_allocator/check_new.cc33
-rw-r--r--libstdc++-v3/testsuite/ext/malloc_allocator/deallocate_global.cc45
-rw-r--r--libstdc++-v3/testsuite/ext/malloc_allocator/deallocate_local.cc40
-rw-r--r--libstdc++-v3/testsuite/ext/mt_allocator/check_delete.cc31
-rw-r--r--libstdc++-v3/testsuite/ext/mt_allocator/check_new.cc31
-rw-r--r--libstdc++-v3/testsuite/ext/mt_allocator/deallocate_global-2.cc41
-rw-r--r--libstdc++-v3/testsuite/ext/mt_allocator/deallocate_global-4.cc41
-rw-r--r--libstdc++-v3/testsuite/ext/mt_allocator/deallocate_global_thread-1.cc41
-rw-r--r--libstdc++-v3/testsuite/ext/mt_allocator/deallocate_global_thread-3.cc41
-rw-r--r--libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local-2.cc41
-rw-r--r--libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local-4.cc41
-rw-r--r--libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local-6.cc40
-rw-r--r--libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local-8.cc40
-rw-r--r--libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local_thread-1.cc41
-rw-r--r--libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local_thread-3.cc41
-rw-r--r--libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local_thread-5.cc41
-rw-r--r--libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local_thread-7.cc40
-rw-r--r--libstdc++-v3/testsuite/ext/new_allocator/check_delete.cc33
-rw-r--r--libstdc++-v3/testsuite/ext/new_allocator/check_new.cc33
-rw-r--r--libstdc++-v3/testsuite/ext/new_allocator/deallocate_global.cc39
-rw-r--r--libstdc++-v3/testsuite/ext/new_allocator/deallocate_local.cc51
-rw-r--r--libstdc++-v3/testsuite/ext/pool_allocator/check_delete.cc32
-rw-r--r--libstdc++-v3/testsuite/ext/pool_allocator/check_new.cc32
-rw-r--r--libstdc++-v3/testsuite/ext/rope/40299.cc27
-rw-r--r--libstdc++-v3/testsuite/ext/throw_allocator/check_delete.cc33
-rw-r--r--libstdc++-v3/testsuite/ext/throw_allocator/check_new.cc33
-rw-r--r--libstdc++-v3/testsuite/ext/throw_allocator/deallocate_global.cc42
-rw-r--r--libstdc++-v3/testsuite/ext/throw_allocator/deallocate_local.cc35
-rw-r--r--libstdc++-v3/testsuite/lib/libstdc++.exp3
-rw-r--r--libstdc++-v3/testsuite/util/common_type/assoc/common_type.hpp14
-rw-r--r--libstdc++-v3/testsuite/util/regression/rand/assoc/container_rand_regression_test.tcc108
-rw-r--r--libstdc++-v3/testsuite/util/regression/rand/assoc/rand_regression_test.hpp4
-rw-r--r--libstdc++-v3/testsuite/util/regression/rand/priority_queue/container_rand_regression_test.tcc48
-rw-r--r--libstdc++-v3/testsuite/util/regression/rand/priority_queue/rand_regression_test.hpp4
-rw-r--r--libstdc++-v3/testsuite/util/replacement_memory_operators.h110
-rw-r--r--libstdc++-v3/testsuite/util/testsuite_allocator.h27
-rw-r--r--libstdc++-v3/testsuite/util/testsuite_hooks.cc2
-rw-r--r--libstdc++-v3/testsuite/util/testsuite_hooks.h20
1605 files changed, 85008 insertions, 34501 deletions
diff --git a/ChangeLog b/ChangeLog
index 8a89aefcdd9..96e02a9a80d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,9 +1,71 @@
+2009-06-15 Ryan Mansfield <rmansfield@qnx.com>
+
+ * configure.ac: Define is_elf for QNX Neutrino targets.
+ * configure: Regenerate.
+
+2009-06-09 Ghassan Shobaki <ghassan.shobaki@amd.com>
+
+ * MAINTAINERS: Added my name to the write-after-approval list
+
+2009-06-08 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * configure.ac: Detect MPC in default directory.
+ * configure: Regenerate.
+
+2009-06-03 Jerome Guitton <guitton@adacore.com>
+ Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ * Makefile.tpl (all): Avoid a trailing backslash.
+ * Makefile.in: Regenerate.
+
+2009-06-03 Ben Elliston <bje@au.ibm.com>
+
+ * config.sub, config.guess: Update from upstream sources.
+
+2009-06-02 Richard Sandiford <r.sandiford@uk.ibm.com>
+
+ * configure.ac (powerpc-*-aix*, rs6000-*-aix*): Add target-newlib
+ to noconfdirs.
+ * configure: Regenerate.
+
+2009-06-02 Alexandre Oliva <aoliva@redhat.com>
+
+ * Makefile.tpl ([+compare-target+]): Compare all stage
+ directories, rather than just gcc.
+ * Makefile.in: Rebuilt.
+
+2009-06-01 Doug Kwan <dougkwan@google.com>
+
+ * configure.ac: Support gold for target arm*-*-*.
+ * configure: Regenerate.
+
+2009-05-29 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.def: Add MPC support and dependencies.
+ * configure.ac: Likewise. Reorganize GMP/MPFR checks.
+
+ * Makefile.in, configure: Regenerate.
+
2009-05-27 Alexandre Oliva <aoliva@redhat.com>
* Makefile.tpl (all): Avoid harmless warning in make all when
gcc-bootstrap is enabled but stage_last does not exist.
* Makefile.in: Rebuilt.
+2009-05-24 Nicolas Roche <roche@adacore.com>
+
+ * Makefile.tpl (compare-target): Skip ./ada/*tools directories.
+ * Makefile.in: Regenerate.
+
+2009-05-21 Denis Chertykov <chertykov@gmail.com>
+
+ * MAINTAINERS: Update my e-mail address.
+
+2009-05-21 Dave Korn <dave.korn.cygwin@gmail.com>
+
+ * configure.ac (cygwin noconfigdirs): Remove libgcj.
+ * configure: Regenerate.
+
2009-05-18 Alexandre Oliva <aoliva@redhat.com>
PR other/40159
diff --git a/MAINTAINERS b/MAINTAINERS
index 25cebf611a6..9860e313000 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -44,7 +44,7 @@ alpha port Richard Henderson rth@redhat.com
arm port Nick Clifton nickc@redhat.com
arm port Richard Earnshaw richard.earnshaw@arm.com
arm port Paul Brook paul@codesourcery.com
-avr port Denis Chertykov denisc@overta.ru
+avr port Denis Chertykov chertykov@gmail.com
avr port Anatoly Sokolov aesok@post.ru
bfin port Bernd Schmidt bernd.schmidt@analog.com
cris port Hans-Peter Nilsson hp@axis.com
@@ -74,6 +74,7 @@ mips port Richard Sandiford rdsandiford@googlemail.com
mmix port Hans-Peter Nilsson hp@bitrange.com
mn10300 port Jeff Law law@redhat.com
mn10300 port Alexandre Oliva aoliva@redhat.com
+moxie port Anthony Green green@moxielogic.com
pdp11 port Paul Koning ni1d@arrl.net
picochip port Hariharan Sandanagobalane hariharan@picochip.com
picochip port Daniel Towner dant@picochip.com
@@ -435,6 +436,7 @@ Dodji Seketeli dseketel@redhat.com
Svein Seldal svein@dev.seldal.com
Thiemo Seufer ths@networkno.de
Mark Shinwell shinwell@codesourcery.com
+Ghassan Shobaki ghassan.shobaki@amd.com
Johannes Singler singler@ira.uka.de
Franz Sirl franz.sirl-kernel@lauterbach.com
Jan Sjodin jan.sjodin@amd.com
diff --git a/Makefile.def b/Makefile.def
index 86cf7588da5..0fb4c78d499 100644
--- a/Makefile.def
+++ b/Makefile.def
@@ -69,6 +69,9 @@ host_modules= { module= mpfr; lib_path=.libs; bootstrap=true;
no_install= true;
host="none-${host_vendor}-${host_os}";
target="none-${host_vendor}-${host_os}"; };
+host_modules= { module= mpc; lib_path=.libs; bootstrap=true;
+ extra_configure_flags='--disable-shared @extra_mpc_gmp_configure_flags@ @extra_mpc_mpfr_configure_flags@';
+ no_install= true; };
host_modules= { module= ppl; lib_path=.libs; bootstrap=true;
extra_configure_flags='--disable-shared --with-libgmp-prefix=$$r/$(HOST_SUBDIR)/gmp/ --with-libgmpxx-prefix=$$r/$(HOST_SUBDIR)/gmp/';
no_install= true;
@@ -312,6 +315,7 @@ dependencies = { module=all-gcc; on=all-libiberty; hard=true; };
dependencies = { module=all-gcc; on=all-gmp; };
dependencies = { module=all-gcc; on=all-intl; };
dependencies = { module=all-gcc; on=all-mpfr; };
+dependencies = { module=all-gcc; on=all-mpc; };
dependencies = { module=all-gcc; on=all-ppl; };
dependencies = { module=all-gcc; on=all-cloog; };
dependencies = { module=all-gcc; on=all-build-texinfo; };
@@ -337,6 +341,7 @@ dependencies = { module=all-fixincludes; on=all-libiberty; };
dependencies = { module=all-gnattools; on=all-target-libada; };
dependencies = { module=configure-mpfr; on=all-gmp; };
+dependencies = { module=configure-mpc; on=all-mpfr; };
dependencies = { module=configure-ppl; on=all-gmp; };
dependencies = { module=configure-ppl; on=all-mpfr; };
dependencies = { module=configure-cloog; on=all-ppl; };
diff --git a/Makefile.in b/Makefile.in
index 50b10d38844..078669266ca 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -506,7 +506,7 @@ TARGET_LIB_PATH_libgomp = $$r/$(TARGET_SUBDIR)/libgomp/.libs:
# This is the list of directories that may be needed in RPATH_ENVVAR
# so that programs built for the host machine work.
-HOST_LIB_PATH = $(HOST_LIB_PATH_bfd)$(HOST_LIB_PATH_opcodes)$(HOST_LIB_PATH_gmp)$(HOST_LIB_PATH_mpfr)$(HOST_LIB_PATH_ppl)$(HOST_LIB_PATH_cloog)
+HOST_LIB_PATH = $(HOST_LIB_PATH_bfd)$(HOST_LIB_PATH_opcodes)$(HOST_LIB_PATH_gmp)$(HOST_LIB_PATH_mpfr)$(HOST_LIB_PATH_mpc)$(HOST_LIB_PATH_ppl)$(HOST_LIB_PATH_cloog)
# Define HOST_LIB_PATH_gcc here, for the sake of TARGET_LIB_PATH, ouch
@if gcc
@@ -534,6 +534,11 @@ HOST_LIB_PATH_mpfr = \
$$r/$(HOST_SUBDIR)/mpfr/.libs:$$r/$(HOST_SUBDIR)/prev-mpfr/.libs:
@endif mpfr
+@if mpc
+HOST_LIB_PATH_mpc = \
+ $$r/$(HOST_SUBDIR)/mpc/.libs:$$r/$(HOST_SUBDIR)/prev-mpc/.libs:
+@endif mpc
+
@if ppl
HOST_LIB_PATH_ppl = \
$$r/$(HOST_SUBDIR)/ppl/.libs:$$r/$(HOST_SUBDIR)/prev-ppl/.libs:
@@ -769,6 +774,7 @@ configure-host: \
maybe-configure-gettext \
maybe-configure-gmp \
maybe-configure-mpfr \
+ maybe-configure-mpc \
maybe-configure-ppl \
maybe-configure-cloog \
maybe-configure-gnuserv \
@@ -862,8 +868,9 @@ all:
$(MAKE) $(RECURSE_FLAGS_TO_PASS) all-host all-target \
@if gcc-bootstrap
; \
- fi
+ fi \
@endif gcc-bootstrap
+ && :
.PHONY: all-build
@@ -917,6 +924,9 @@ all-host: maybe-all-gmp
@if mpfr-no-bootstrap
all-host: maybe-all-mpfr
@endif mpfr-no-bootstrap
+@if mpc-no-bootstrap
+all-host: maybe-all-mpc
+@endif mpc-no-bootstrap
@if ppl-no-bootstrap
all-host: maybe-all-ppl
@endif ppl-no-bootstrap
@@ -1052,6 +1062,7 @@ info-host: maybe-info-gawk
info-host: maybe-info-gettext
info-host: maybe-info-gmp
info-host: maybe-info-mpfr
+info-host: maybe-info-mpc
info-host: maybe-info-ppl
info-host: maybe-info-cloog
info-host: maybe-info-gnuserv
@@ -1162,6 +1173,7 @@ dvi-host: maybe-dvi-gawk
dvi-host: maybe-dvi-gettext
dvi-host: maybe-dvi-gmp
dvi-host: maybe-dvi-mpfr
+dvi-host: maybe-dvi-mpc
dvi-host: maybe-dvi-ppl
dvi-host: maybe-dvi-cloog
dvi-host: maybe-dvi-gnuserv
@@ -1272,6 +1284,7 @@ pdf-host: maybe-pdf-gawk
pdf-host: maybe-pdf-gettext
pdf-host: maybe-pdf-gmp
pdf-host: maybe-pdf-mpfr
+pdf-host: maybe-pdf-mpc
pdf-host: maybe-pdf-ppl
pdf-host: maybe-pdf-cloog
pdf-host: maybe-pdf-gnuserv
@@ -1382,6 +1395,7 @@ html-host: maybe-html-gawk
html-host: maybe-html-gettext
html-host: maybe-html-gmp
html-host: maybe-html-mpfr
+html-host: maybe-html-mpc
html-host: maybe-html-ppl
html-host: maybe-html-cloog
html-host: maybe-html-gnuserv
@@ -1492,6 +1506,7 @@ TAGS-host: maybe-TAGS-gawk
TAGS-host: maybe-TAGS-gettext
TAGS-host: maybe-TAGS-gmp
TAGS-host: maybe-TAGS-mpfr
+TAGS-host: maybe-TAGS-mpc
TAGS-host: maybe-TAGS-ppl
TAGS-host: maybe-TAGS-cloog
TAGS-host: maybe-TAGS-gnuserv
@@ -1602,6 +1617,7 @@ install-info-host: maybe-install-info-gawk
install-info-host: maybe-install-info-gettext
install-info-host: maybe-install-info-gmp
install-info-host: maybe-install-info-mpfr
+install-info-host: maybe-install-info-mpc
install-info-host: maybe-install-info-ppl
install-info-host: maybe-install-info-cloog
install-info-host: maybe-install-info-gnuserv
@@ -1712,6 +1728,7 @@ install-pdf-host: maybe-install-pdf-gawk
install-pdf-host: maybe-install-pdf-gettext
install-pdf-host: maybe-install-pdf-gmp
install-pdf-host: maybe-install-pdf-mpfr
+install-pdf-host: maybe-install-pdf-mpc
install-pdf-host: maybe-install-pdf-ppl
install-pdf-host: maybe-install-pdf-cloog
install-pdf-host: maybe-install-pdf-gnuserv
@@ -1822,6 +1839,7 @@ install-html-host: maybe-install-html-gawk
install-html-host: maybe-install-html-gettext
install-html-host: maybe-install-html-gmp
install-html-host: maybe-install-html-mpfr
+install-html-host: maybe-install-html-mpc
install-html-host: maybe-install-html-ppl
install-html-host: maybe-install-html-cloog
install-html-host: maybe-install-html-gnuserv
@@ -1932,6 +1950,7 @@ installcheck-host: maybe-installcheck-gawk
installcheck-host: maybe-installcheck-gettext
installcheck-host: maybe-installcheck-gmp
installcheck-host: maybe-installcheck-mpfr
+installcheck-host: maybe-installcheck-mpc
installcheck-host: maybe-installcheck-ppl
installcheck-host: maybe-installcheck-cloog
installcheck-host: maybe-installcheck-gnuserv
@@ -2042,6 +2061,7 @@ mostlyclean-host: maybe-mostlyclean-gawk
mostlyclean-host: maybe-mostlyclean-gettext
mostlyclean-host: maybe-mostlyclean-gmp
mostlyclean-host: maybe-mostlyclean-mpfr
+mostlyclean-host: maybe-mostlyclean-mpc
mostlyclean-host: maybe-mostlyclean-ppl
mostlyclean-host: maybe-mostlyclean-cloog
mostlyclean-host: maybe-mostlyclean-gnuserv
@@ -2152,6 +2172,7 @@ clean-host: maybe-clean-gawk
clean-host: maybe-clean-gettext
clean-host: maybe-clean-gmp
clean-host: maybe-clean-mpfr
+clean-host: maybe-clean-mpc
clean-host: maybe-clean-ppl
clean-host: maybe-clean-cloog
clean-host: maybe-clean-gnuserv
@@ -2262,6 +2283,7 @@ distclean-host: maybe-distclean-gawk
distclean-host: maybe-distclean-gettext
distclean-host: maybe-distclean-gmp
distclean-host: maybe-distclean-mpfr
+distclean-host: maybe-distclean-mpc
distclean-host: maybe-distclean-ppl
distclean-host: maybe-distclean-cloog
distclean-host: maybe-distclean-gnuserv
@@ -2372,6 +2394,7 @@ maintainer-clean-host: maybe-maintainer-clean-gawk
maintainer-clean-host: maybe-maintainer-clean-gettext
maintainer-clean-host: maybe-maintainer-clean-gmp
maintainer-clean-host: maybe-maintainer-clean-mpfr
+maintainer-clean-host: maybe-maintainer-clean-mpc
maintainer-clean-host: maybe-maintainer-clean-ppl
maintainer-clean-host: maybe-maintainer-clean-cloog
maintainer-clean-host: maybe-maintainer-clean-gnuserv
@@ -2536,6 +2559,7 @@ check-host: \
maybe-check-gettext \
maybe-check-gmp \
maybe-check-mpfr \
+ maybe-check-mpc \
maybe-check-ppl \
maybe-check-cloog \
maybe-check-gnuserv \
@@ -2672,6 +2696,7 @@ install-host-nogcc: \
maybe-install-gettext \
maybe-install-gmp \
maybe-install-mpfr \
+ maybe-install-mpc \
maybe-install-ppl \
maybe-install-cloog \
maybe-install-gnuserv \
@@ -2749,6 +2774,7 @@ install-host: \
maybe-install-gettext \
maybe-install-gmp \
maybe-install-mpfr \
+ maybe-install-mpc \
maybe-install-ppl \
maybe-install-cloog \
maybe-install-gnuserv \
@@ -17410,6 +17436,872 @@ maintainer-clean-mpfr:
+.PHONY: configure-mpc maybe-configure-mpc
+maybe-configure-mpc:
+@if gcc-bootstrap
+configure-mpc: stage_current
+@endif gcc-bootstrap
+@if mpc
+maybe-configure-mpc: configure-mpc
+configure-mpc:
+ @r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ test ! -f $(HOST_SUBDIR)/mpc/Makefile || exit 0; \
+ $(SHELL) $(srcdir)/mkinstalldirs $(HOST_SUBDIR)/mpc ; \
+ $(HOST_EXPORTS) \
+ echo Configuring in $(HOST_SUBDIR)/mpc; \
+ cd "$(HOST_SUBDIR)/mpc" || exit 1; \
+ case $(srcdir) in \
+ /* | [A-Za-z]:[\\/]*) topdir=$(srcdir) ;; \
+ *) topdir=`echo $(HOST_SUBDIR)/mpc/ | \
+ sed -e 's,\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \
+ esac; \
+ srcdiroption="--srcdir=$${topdir}/mpc"; \
+ libsrcdir="$$s/mpc"; \
+ $(SHELL) $${libsrcdir}/configure \
+ $(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \
+ --target=${target_alias} $${srcdiroption} --disable-shared @extra_mpc_gmp_configure_flags@ @extra_mpc_mpfr_configure_flags@ \
+ || exit 1
+@endif mpc
+
+
+
+.PHONY: configure-stage1-mpc maybe-configure-stage1-mpc
+maybe-configure-stage1-mpc:
+@if mpc-bootstrap
+maybe-configure-stage1-mpc: configure-stage1-mpc
+configure-stage1-mpc:
+ @[ $(current_stage) = stage1 ] || $(MAKE) stage1-start
+ @$(SHELL) $(srcdir)/mkinstalldirs $(HOST_SUBDIR)/mpc
+ @r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ TFLAGS="$(STAGE1_TFLAGS)"; \
+ test ! -f $(HOST_SUBDIR)/mpc/Makefile || exit 0; \
+ $(HOST_EXPORTS) \
+ CFLAGS="$(STAGE1_CFLAGS)"; export CFLAGS; \
+ CXXFLAGS="$(STAGE1_CFLAGS)"; export CXXFLAGS; \
+ LIBCFLAGS="$(LIBCFLAGS)"; export LIBCFLAGS; \
+ echo Configuring stage 1 in $(HOST_SUBDIR)/mpc ; \
+ $(SHELL) $(srcdir)/mkinstalldirs $(HOST_SUBDIR)/mpc ; \
+ cd $(HOST_SUBDIR)/mpc || exit 1; \
+ case $(srcdir) in \
+ /* | [A-Za-z]:[\\/]*) topdir=$(srcdir) ;; \
+ *) topdir=`echo $(HOST_SUBDIR)/mpc/ | \
+ sed -e 's,\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \
+ esac; \
+ srcdiroption="--srcdir=$${topdir}/mpc"; \
+ libsrcdir="$$s/mpc"; \
+ $(SHELL) $${libsrcdir}/configure \
+ $(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \
+ --target=${target_alias} $${srcdiroption} \
+ $(STAGE1_CONFIGURE_FLAGS) \
+ --disable-shared @extra_mpc_gmp_configure_flags@ @extra_mpc_mpfr_configure_flags@
+@endif mpc-bootstrap
+
+.PHONY: configure-stage2-mpc maybe-configure-stage2-mpc
+maybe-configure-stage2-mpc:
+@if mpc-bootstrap
+maybe-configure-stage2-mpc: configure-stage2-mpc
+configure-stage2-mpc:
+ @[ $(current_stage) = stage2 ] || $(MAKE) stage2-start
+ @$(SHELL) $(srcdir)/mkinstalldirs $(HOST_SUBDIR)/mpc
+ @r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ TFLAGS="$(STAGE2_TFLAGS)"; \
+ test ! -f $(HOST_SUBDIR)/mpc/Makefile || exit 0; \
+ $(HOST_EXPORTS) \
+ $(POSTSTAGE1_HOST_EXPORTS) \
+ CFLAGS="$(STAGE2_CFLAGS)"; export CFLAGS; \
+ CXXFLAGS="$(STAGE2_CFLAGS)"; export CXXFLAGS; \
+ LIBCFLAGS="$(STAGE2_CFLAGS)"; export LIBCFLAGS; \
+ echo Configuring stage 2 in $(HOST_SUBDIR)/mpc ; \
+ $(SHELL) $(srcdir)/mkinstalldirs $(HOST_SUBDIR)/mpc ; \
+ cd $(HOST_SUBDIR)/mpc || exit 1; \
+ case $(srcdir) in \
+ /* | [A-Za-z]:[\\/]*) topdir=$(srcdir) ;; \
+ *) topdir=`echo $(HOST_SUBDIR)/mpc/ | \
+ sed -e 's,\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \
+ esac; \
+ srcdiroption="--srcdir=$${topdir}/mpc"; \
+ libsrcdir="$$s/mpc"; \
+ $(SHELL) $${libsrcdir}/configure \
+ $(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \
+ --target=${target_alias} $${srcdiroption} \
+ --with-build-libsubdir=$(HOST_SUBDIR) \
+ $(STAGE2_CONFIGURE_FLAGS) \
+ --disable-shared @extra_mpc_gmp_configure_flags@ @extra_mpc_mpfr_configure_flags@
+@endif mpc-bootstrap
+
+.PHONY: configure-stage3-mpc maybe-configure-stage3-mpc
+maybe-configure-stage3-mpc:
+@if mpc-bootstrap
+maybe-configure-stage3-mpc: configure-stage3-mpc
+configure-stage3-mpc:
+ @[ $(current_stage) = stage3 ] || $(MAKE) stage3-start
+ @$(SHELL) $(srcdir)/mkinstalldirs $(HOST_SUBDIR)/mpc
+ @r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ TFLAGS="$(STAGE3_TFLAGS)"; \
+ test ! -f $(HOST_SUBDIR)/mpc/Makefile || exit 0; \
+ $(HOST_EXPORTS) \
+ $(POSTSTAGE1_HOST_EXPORTS) \
+ CFLAGS="$(STAGE3_CFLAGS)"; export CFLAGS; \
+ CXXFLAGS="$(STAGE3_CFLAGS)"; export CXXFLAGS; \
+ LIBCFLAGS="$(STAGE3_CFLAGS)"; export LIBCFLAGS; \
+ echo Configuring stage 3 in $(HOST_SUBDIR)/mpc ; \
+ $(SHELL) $(srcdir)/mkinstalldirs $(HOST_SUBDIR)/mpc ; \
+ cd $(HOST_SUBDIR)/mpc || exit 1; \
+ case $(srcdir) in \
+ /* | [A-Za-z]:[\\/]*) topdir=$(srcdir) ;; \
+ *) topdir=`echo $(HOST_SUBDIR)/mpc/ | \
+ sed -e 's,\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \
+ esac; \
+ srcdiroption="--srcdir=$${topdir}/mpc"; \
+ libsrcdir="$$s/mpc"; \
+ $(SHELL) $${libsrcdir}/configure \
+ $(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \
+ --target=${target_alias} $${srcdiroption} \
+ --with-build-libsubdir=$(HOST_SUBDIR) \
+ $(STAGE3_CONFIGURE_FLAGS) \
+ --disable-shared @extra_mpc_gmp_configure_flags@ @extra_mpc_mpfr_configure_flags@
+@endif mpc-bootstrap
+
+.PHONY: configure-stage4-mpc maybe-configure-stage4-mpc
+maybe-configure-stage4-mpc:
+@if mpc-bootstrap
+maybe-configure-stage4-mpc: configure-stage4-mpc
+configure-stage4-mpc:
+ @[ $(current_stage) = stage4 ] || $(MAKE) stage4-start
+ @$(SHELL) $(srcdir)/mkinstalldirs $(HOST_SUBDIR)/mpc
+ @r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ TFLAGS="$(STAGE4_TFLAGS)"; \
+ test ! -f $(HOST_SUBDIR)/mpc/Makefile || exit 0; \
+ $(HOST_EXPORTS) \
+ $(POSTSTAGE1_HOST_EXPORTS) \
+ CFLAGS="$(STAGE4_CFLAGS)"; export CFLAGS; \
+ CXXFLAGS="$(STAGE4_CFLAGS)"; export CXXFLAGS; \
+ LIBCFLAGS="$(STAGE4_CFLAGS)"; export LIBCFLAGS; \
+ echo Configuring stage 4 in $(HOST_SUBDIR)/mpc ; \
+ $(SHELL) $(srcdir)/mkinstalldirs $(HOST_SUBDIR)/mpc ; \
+ cd $(HOST_SUBDIR)/mpc || exit 1; \
+ case $(srcdir) in \
+ /* | [A-Za-z]:[\\/]*) topdir=$(srcdir) ;; \
+ *) topdir=`echo $(HOST_SUBDIR)/mpc/ | \
+ sed -e 's,\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \
+ esac; \
+ srcdiroption="--srcdir=$${topdir}/mpc"; \
+ libsrcdir="$$s/mpc"; \
+ $(SHELL) $${libsrcdir}/configure \
+ $(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \
+ --target=${target_alias} $${srcdiroption} \
+ --with-build-libsubdir=$(HOST_SUBDIR) \
+ $(STAGE4_CONFIGURE_FLAGS) \
+ --disable-shared @extra_mpc_gmp_configure_flags@ @extra_mpc_mpfr_configure_flags@
+@endif mpc-bootstrap
+
+.PHONY: configure-stageprofile-mpc maybe-configure-stageprofile-mpc
+maybe-configure-stageprofile-mpc:
+@if mpc-bootstrap
+maybe-configure-stageprofile-mpc: configure-stageprofile-mpc
+configure-stageprofile-mpc:
+ @[ $(current_stage) = stageprofile ] || $(MAKE) stageprofile-start
+ @$(SHELL) $(srcdir)/mkinstalldirs $(HOST_SUBDIR)/mpc
+ @r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ TFLAGS="$(STAGEprofile_TFLAGS)"; \
+ test ! -f $(HOST_SUBDIR)/mpc/Makefile || exit 0; \
+ $(HOST_EXPORTS) \
+ $(POSTSTAGE1_HOST_EXPORTS) \
+ CFLAGS="$(STAGEprofile_CFLAGS)"; export CFLAGS; \
+ CXXFLAGS="$(STAGEprofile_CFLAGS)"; export CXXFLAGS; \
+ LIBCFLAGS="$(STAGEprofile_CFLAGS)"; export LIBCFLAGS; \
+ echo Configuring stage profile in $(HOST_SUBDIR)/mpc ; \
+ $(SHELL) $(srcdir)/mkinstalldirs $(HOST_SUBDIR)/mpc ; \
+ cd $(HOST_SUBDIR)/mpc || exit 1; \
+ case $(srcdir) in \
+ /* | [A-Za-z]:[\\/]*) topdir=$(srcdir) ;; \
+ *) topdir=`echo $(HOST_SUBDIR)/mpc/ | \
+ sed -e 's,\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \
+ esac; \
+ srcdiroption="--srcdir=$${topdir}/mpc"; \
+ libsrcdir="$$s/mpc"; \
+ $(SHELL) $${libsrcdir}/configure \
+ $(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \
+ --target=${target_alias} $${srcdiroption} \
+ --with-build-libsubdir=$(HOST_SUBDIR) \
+ $(STAGEprofile_CONFIGURE_FLAGS) \
+ --disable-shared @extra_mpc_gmp_configure_flags@ @extra_mpc_mpfr_configure_flags@
+@endif mpc-bootstrap
+
+.PHONY: configure-stagefeedback-mpc maybe-configure-stagefeedback-mpc
+maybe-configure-stagefeedback-mpc:
+@if mpc-bootstrap
+maybe-configure-stagefeedback-mpc: configure-stagefeedback-mpc
+configure-stagefeedback-mpc:
+ @[ $(current_stage) = stagefeedback ] || $(MAKE) stagefeedback-start
+ @$(SHELL) $(srcdir)/mkinstalldirs $(HOST_SUBDIR)/mpc
+ @r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ TFLAGS="$(STAGEfeedback_TFLAGS)"; \
+ test ! -f $(HOST_SUBDIR)/mpc/Makefile || exit 0; \
+ $(HOST_EXPORTS) \
+ $(POSTSTAGE1_HOST_EXPORTS) \
+ CFLAGS="$(STAGEfeedback_CFLAGS)"; export CFLAGS; \
+ CXXFLAGS="$(STAGEfeedback_CFLAGS)"; export CXXFLAGS; \
+ LIBCFLAGS="$(STAGEfeedback_CFLAGS)"; export LIBCFLAGS; \
+ echo Configuring stage feedback in $(HOST_SUBDIR)/mpc ; \
+ $(SHELL) $(srcdir)/mkinstalldirs $(HOST_SUBDIR)/mpc ; \
+ cd $(HOST_SUBDIR)/mpc || exit 1; \
+ case $(srcdir) in \
+ /* | [A-Za-z]:[\\/]*) topdir=$(srcdir) ;; \
+ *) topdir=`echo $(HOST_SUBDIR)/mpc/ | \
+ sed -e 's,\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \
+ esac; \
+ srcdiroption="--srcdir=$${topdir}/mpc"; \
+ libsrcdir="$$s/mpc"; \
+ $(SHELL) $${libsrcdir}/configure \
+ $(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \
+ --target=${target_alias} $${srcdiroption} \
+ --with-build-libsubdir=$(HOST_SUBDIR) \
+ $(STAGEfeedback_CONFIGURE_FLAGS) \
+ --disable-shared @extra_mpc_gmp_configure_flags@ @extra_mpc_mpfr_configure_flags@
+@endif mpc-bootstrap
+
+
+
+
+
+.PHONY: all-mpc maybe-all-mpc
+maybe-all-mpc:
+@if gcc-bootstrap
+all-mpc: stage_current
+@endif gcc-bootstrap
+@if mpc
+TARGET-mpc=all
+maybe-all-mpc: all-mpc
+all-mpc: configure-mpc
+ @r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(HOST_EXPORTS) \
+ (cd $(HOST_SUBDIR)/mpc && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) $(EXTRA_HOST_FLAGS) \
+ $(TARGET-mpc))
+@endif mpc
+
+
+
+.PHONY: all-stage1-mpc maybe-all-stage1-mpc
+.PHONY: clean-stage1-mpc maybe-clean-stage1-mpc
+maybe-all-stage1-mpc:
+maybe-clean-stage1-mpc:
+@if mpc-bootstrap
+maybe-all-stage1-mpc: all-stage1-mpc
+all-stage1: all-stage1-mpc
+TARGET-stage1-mpc = $(TARGET-mpc)
+all-stage1-mpc: configure-stage1-mpc
+ @[ $(current_stage) = stage1 ] || $(MAKE) stage1-start
+ @r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ TFLAGS="$(STAGE1_TFLAGS)"; \
+ $(HOST_EXPORTS) \
+ cd $(HOST_SUBDIR)/mpc && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) \
+ CFLAGS="$(STAGE1_CFLAGS)" \
+ CXXFLAGS="$(STAGE1_CFLAGS)" \
+ LIBCFLAGS="$(LIBCFLAGS)" \
+ CFLAGS_FOR_TARGET="$(CFLAGS_FOR_TARGET)" \
+ CXXFLAGS_FOR_TARGET="$(CXXFLAGS_FOR_TARGET)" \
+ LIBCFLAGS_FOR_TARGET="$(LIBCFLAGS_FOR_TARGET)" \
+ $(EXTRA_HOST_FLAGS) \
+ TFLAGS="$(STAGE1_TFLAGS)" \
+ $(TARGET-stage1-mpc)
+
+maybe-clean-stage1-mpc: clean-stage1-mpc
+clean-stage1: clean-stage1-mpc
+clean-stage1-mpc:
+ @if [ $(current_stage) = stage1 ]; then \
+ [ -f $(HOST_SUBDIR)/mpc/Makefile ] || exit 0; \
+ else \
+ [ -f $(HOST_SUBDIR)/stage1-mpc/Makefile ] || exit 0; \
+ $(MAKE) stage1-start; \
+ fi; \
+ cd $(HOST_SUBDIR)/mpc && \
+ $(MAKE) $(EXTRA_HOST_FLAGS) \
+ clean
+@endif mpc-bootstrap
+
+
+.PHONY: all-stage2-mpc maybe-all-stage2-mpc
+.PHONY: clean-stage2-mpc maybe-clean-stage2-mpc
+maybe-all-stage2-mpc:
+maybe-clean-stage2-mpc:
+@if mpc-bootstrap
+maybe-all-stage2-mpc: all-stage2-mpc
+all-stage2: all-stage2-mpc
+TARGET-stage2-mpc = $(TARGET-mpc)
+all-stage2-mpc: configure-stage2-mpc
+ @[ $(current_stage) = stage2 ] || $(MAKE) stage2-start
+ @r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ TFLAGS="$(STAGE2_TFLAGS)"; \
+ $(HOST_EXPORTS) \
+ $(POSTSTAGE1_HOST_EXPORTS) \
+ cd $(HOST_SUBDIR)/mpc && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) \
+ CFLAGS="$(STAGE2_CFLAGS)" \
+ CXXFLAGS="$(STAGE2_CFLAGS)" \
+ LIBCFLAGS="$(STAGE2_CFLAGS)" \
+ CFLAGS_FOR_TARGET="$(CFLAGS_FOR_TARGET)" \
+ CXXFLAGS_FOR_TARGET="$(CXXFLAGS_FOR_TARGET)" \
+ LIBCFLAGS_FOR_TARGET="$(LIBCFLAGS_FOR_TARGET)" \
+ $(EXTRA_HOST_FLAGS) $(POSTSTAGE1_FLAGS_TO_PASS) \
+ TFLAGS="$(STAGE2_TFLAGS)" \
+ $(TARGET-stage2-mpc)
+
+maybe-clean-stage2-mpc: clean-stage2-mpc
+clean-stage2: clean-stage2-mpc
+clean-stage2-mpc:
+ @if [ $(current_stage) = stage2 ]; then \
+ [ -f $(HOST_SUBDIR)/mpc/Makefile ] || exit 0; \
+ else \
+ [ -f $(HOST_SUBDIR)/stage2-mpc/Makefile ] || exit 0; \
+ $(MAKE) stage2-start; \
+ fi; \
+ cd $(HOST_SUBDIR)/mpc && \
+ $(MAKE) $(EXTRA_HOST_FLAGS) \
+ $(POSTSTAGE1_FLAGS_TO_PASS) \
+ clean
+@endif mpc-bootstrap
+
+
+.PHONY: all-stage3-mpc maybe-all-stage3-mpc
+.PHONY: clean-stage3-mpc maybe-clean-stage3-mpc
+maybe-all-stage3-mpc:
+maybe-clean-stage3-mpc:
+@if mpc-bootstrap
+maybe-all-stage3-mpc: all-stage3-mpc
+all-stage3: all-stage3-mpc
+TARGET-stage3-mpc = $(TARGET-mpc)
+all-stage3-mpc: configure-stage3-mpc
+ @[ $(current_stage) = stage3 ] || $(MAKE) stage3-start
+ @r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ TFLAGS="$(STAGE3_TFLAGS)"; \
+ $(HOST_EXPORTS) \
+ $(POSTSTAGE1_HOST_EXPORTS) \
+ cd $(HOST_SUBDIR)/mpc && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) \
+ CFLAGS="$(STAGE3_CFLAGS)" \
+ CXXFLAGS="$(STAGE3_CFLAGS)" \
+ LIBCFLAGS="$(STAGE3_CFLAGS)" \
+ CFLAGS_FOR_TARGET="$(CFLAGS_FOR_TARGET)" \
+ CXXFLAGS_FOR_TARGET="$(CXXFLAGS_FOR_TARGET)" \
+ LIBCFLAGS_FOR_TARGET="$(LIBCFLAGS_FOR_TARGET)" \
+ $(EXTRA_HOST_FLAGS) $(POSTSTAGE1_FLAGS_TO_PASS) \
+ TFLAGS="$(STAGE3_TFLAGS)" \
+ $(TARGET-stage3-mpc)
+
+maybe-clean-stage3-mpc: clean-stage3-mpc
+clean-stage3: clean-stage3-mpc
+clean-stage3-mpc:
+ @if [ $(current_stage) = stage3 ]; then \
+ [ -f $(HOST_SUBDIR)/mpc/Makefile ] || exit 0; \
+ else \
+ [ -f $(HOST_SUBDIR)/stage3-mpc/Makefile ] || exit 0; \
+ $(MAKE) stage3-start; \
+ fi; \
+ cd $(HOST_SUBDIR)/mpc && \
+ $(MAKE) $(EXTRA_HOST_FLAGS) \
+ $(POSTSTAGE1_FLAGS_TO_PASS) \
+ clean
+@endif mpc-bootstrap
+
+
+.PHONY: all-stage4-mpc maybe-all-stage4-mpc
+.PHONY: clean-stage4-mpc maybe-clean-stage4-mpc
+maybe-all-stage4-mpc:
+maybe-clean-stage4-mpc:
+@if mpc-bootstrap
+maybe-all-stage4-mpc: all-stage4-mpc
+all-stage4: all-stage4-mpc
+TARGET-stage4-mpc = $(TARGET-mpc)
+all-stage4-mpc: configure-stage4-mpc
+ @[ $(current_stage) = stage4 ] || $(MAKE) stage4-start
+ @r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ TFLAGS="$(STAGE4_TFLAGS)"; \
+ $(HOST_EXPORTS) \
+ $(POSTSTAGE1_HOST_EXPORTS) \
+ cd $(HOST_SUBDIR)/mpc && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) \
+ CFLAGS="$(STAGE4_CFLAGS)" \
+ CXXFLAGS="$(STAGE4_CFLAGS)" \
+ LIBCFLAGS="$(STAGE4_CFLAGS)" \
+ CFLAGS_FOR_TARGET="$(CFLAGS_FOR_TARGET)" \
+ CXXFLAGS_FOR_TARGET="$(CXXFLAGS_FOR_TARGET)" \
+ LIBCFLAGS_FOR_TARGET="$(LIBCFLAGS_FOR_TARGET)" \
+ $(EXTRA_HOST_FLAGS) $(POSTSTAGE1_FLAGS_TO_PASS) \
+ TFLAGS="$(STAGE4_TFLAGS)" \
+ $(TARGET-stage4-mpc)
+
+maybe-clean-stage4-mpc: clean-stage4-mpc
+clean-stage4: clean-stage4-mpc
+clean-stage4-mpc:
+ @if [ $(current_stage) = stage4 ]; then \
+ [ -f $(HOST_SUBDIR)/mpc/Makefile ] || exit 0; \
+ else \
+ [ -f $(HOST_SUBDIR)/stage4-mpc/Makefile ] || exit 0; \
+ $(MAKE) stage4-start; \
+ fi; \
+ cd $(HOST_SUBDIR)/mpc && \
+ $(MAKE) $(EXTRA_HOST_FLAGS) \
+ $(POSTSTAGE1_FLAGS_TO_PASS) \
+ clean
+@endif mpc-bootstrap
+
+
+.PHONY: all-stageprofile-mpc maybe-all-stageprofile-mpc
+.PHONY: clean-stageprofile-mpc maybe-clean-stageprofile-mpc
+maybe-all-stageprofile-mpc:
+maybe-clean-stageprofile-mpc:
+@if mpc-bootstrap
+maybe-all-stageprofile-mpc: all-stageprofile-mpc
+all-stageprofile: all-stageprofile-mpc
+TARGET-stageprofile-mpc = $(TARGET-mpc)
+all-stageprofile-mpc: configure-stageprofile-mpc
+ @[ $(current_stage) = stageprofile ] || $(MAKE) stageprofile-start
+ @r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ TFLAGS="$(STAGEprofile_TFLAGS)"; \
+ $(HOST_EXPORTS) \
+ $(POSTSTAGE1_HOST_EXPORTS) \
+ cd $(HOST_SUBDIR)/mpc && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) \
+ CFLAGS="$(STAGEprofile_CFLAGS)" \
+ CXXFLAGS="$(STAGEprofile_CFLAGS)" \
+ LIBCFLAGS="$(STAGEprofile_CFLAGS)" \
+ CFLAGS_FOR_TARGET="$(CFLAGS_FOR_TARGET)" \
+ CXXFLAGS_FOR_TARGET="$(CXXFLAGS_FOR_TARGET)" \
+ LIBCFLAGS_FOR_TARGET="$(LIBCFLAGS_FOR_TARGET)" \
+ $(EXTRA_HOST_FLAGS) $(POSTSTAGE1_FLAGS_TO_PASS) \
+ TFLAGS="$(STAGEprofile_TFLAGS)" \
+ $(TARGET-stageprofile-mpc)
+
+maybe-clean-stageprofile-mpc: clean-stageprofile-mpc
+clean-stageprofile: clean-stageprofile-mpc
+clean-stageprofile-mpc:
+ @if [ $(current_stage) = stageprofile ]; then \
+ [ -f $(HOST_SUBDIR)/mpc/Makefile ] || exit 0; \
+ else \
+ [ -f $(HOST_SUBDIR)/stageprofile-mpc/Makefile ] || exit 0; \
+ $(MAKE) stageprofile-start; \
+ fi; \
+ cd $(HOST_SUBDIR)/mpc && \
+ $(MAKE) $(EXTRA_HOST_FLAGS) \
+ $(POSTSTAGE1_FLAGS_TO_PASS) \
+ clean
+@endif mpc-bootstrap
+
+
+.PHONY: all-stagefeedback-mpc maybe-all-stagefeedback-mpc
+.PHONY: clean-stagefeedback-mpc maybe-clean-stagefeedback-mpc
+maybe-all-stagefeedback-mpc:
+maybe-clean-stagefeedback-mpc:
+@if mpc-bootstrap
+maybe-all-stagefeedback-mpc: all-stagefeedback-mpc
+all-stagefeedback: all-stagefeedback-mpc
+TARGET-stagefeedback-mpc = $(TARGET-mpc)
+all-stagefeedback-mpc: configure-stagefeedback-mpc
+ @[ $(current_stage) = stagefeedback ] || $(MAKE) stagefeedback-start
+ @r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ TFLAGS="$(STAGEfeedback_TFLAGS)"; \
+ $(HOST_EXPORTS) \
+ $(POSTSTAGE1_HOST_EXPORTS) \
+ cd $(HOST_SUBDIR)/mpc && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) \
+ CFLAGS="$(STAGEfeedback_CFLAGS)" \
+ CXXFLAGS="$(STAGEfeedback_CFLAGS)" \
+ LIBCFLAGS="$(STAGEfeedback_CFLAGS)" \
+ CFLAGS_FOR_TARGET="$(CFLAGS_FOR_TARGET)" \
+ CXXFLAGS_FOR_TARGET="$(CXXFLAGS_FOR_TARGET)" \
+ LIBCFLAGS_FOR_TARGET="$(LIBCFLAGS_FOR_TARGET)" \
+ $(EXTRA_HOST_FLAGS) $(POSTSTAGE1_FLAGS_TO_PASS) \
+ TFLAGS="$(STAGEfeedback_TFLAGS)" \
+ $(TARGET-stagefeedback-mpc)
+
+maybe-clean-stagefeedback-mpc: clean-stagefeedback-mpc
+clean-stagefeedback: clean-stagefeedback-mpc
+clean-stagefeedback-mpc:
+ @if [ $(current_stage) = stagefeedback ]; then \
+ [ -f $(HOST_SUBDIR)/mpc/Makefile ] || exit 0; \
+ else \
+ [ -f $(HOST_SUBDIR)/stagefeedback-mpc/Makefile ] || exit 0; \
+ $(MAKE) stagefeedback-start; \
+ fi; \
+ cd $(HOST_SUBDIR)/mpc && \
+ $(MAKE) $(EXTRA_HOST_FLAGS) \
+ $(POSTSTAGE1_FLAGS_TO_PASS) \
+ clean
+@endif mpc-bootstrap
+
+
+
+
+
+.PHONY: check-mpc maybe-check-mpc
+maybe-check-mpc:
+@if mpc
+maybe-check-mpc: check-mpc
+
+check-mpc:
+ @: $(MAKE); $(unstage)
+ @r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(HOST_EXPORTS) \
+ (cd $(HOST_SUBDIR)/mpc && \
+ $(MAKE) $(FLAGS_TO_PASS) check)
+
+@endif mpc
+
+.PHONY: install-mpc maybe-install-mpc
+maybe-install-mpc:
+@if mpc
+maybe-install-mpc: install-mpc
+
+install-mpc:
+
+@endif mpc
+
+# Other targets (info, dvi, pdf, etc.)
+
+.PHONY: maybe-info-mpc info-mpc
+maybe-info-mpc:
+@if mpc
+maybe-info-mpc: info-mpc
+
+info-mpc: \
+ configure-mpc
+ @[ -f ./mpc/Makefile ] || exit 0; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(HOST_EXPORTS) \
+ for flag in $(EXTRA_HOST_FLAGS) ; do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+ done; \
+ echo "Doing info in mpc" ; \
+ (cd $(HOST_SUBDIR)/mpc && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+ "RANLIB=$${RANLIB}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+ info) \
+ || exit 1
+
+@endif mpc
+
+.PHONY: maybe-dvi-mpc dvi-mpc
+maybe-dvi-mpc:
+@if mpc
+maybe-dvi-mpc: dvi-mpc
+
+dvi-mpc: \
+ configure-mpc
+ @[ -f ./mpc/Makefile ] || exit 0; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(HOST_EXPORTS) \
+ for flag in $(EXTRA_HOST_FLAGS) ; do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+ done; \
+ echo "Doing dvi in mpc" ; \
+ (cd $(HOST_SUBDIR)/mpc && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+ "RANLIB=$${RANLIB}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+ dvi) \
+ || exit 1
+
+@endif mpc
+
+.PHONY: maybe-pdf-mpc pdf-mpc
+maybe-pdf-mpc:
+@if mpc
+maybe-pdf-mpc: pdf-mpc
+
+pdf-mpc: \
+ configure-mpc
+ @[ -f ./mpc/Makefile ] || exit 0; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(HOST_EXPORTS) \
+ for flag in $(EXTRA_HOST_FLAGS) ; do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+ done; \
+ echo "Doing pdf in mpc" ; \
+ (cd $(HOST_SUBDIR)/mpc && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+ "RANLIB=$${RANLIB}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+ pdf) \
+ || exit 1
+
+@endif mpc
+
+.PHONY: maybe-html-mpc html-mpc
+maybe-html-mpc:
+@if mpc
+maybe-html-mpc: html-mpc
+
+html-mpc: \
+ configure-mpc
+ @[ -f ./mpc/Makefile ] || exit 0; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(HOST_EXPORTS) \
+ for flag in $(EXTRA_HOST_FLAGS) ; do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+ done; \
+ echo "Doing html in mpc" ; \
+ (cd $(HOST_SUBDIR)/mpc && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+ "RANLIB=$${RANLIB}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+ html) \
+ || exit 1
+
+@endif mpc
+
+.PHONY: maybe-TAGS-mpc TAGS-mpc
+maybe-TAGS-mpc:
+@if mpc
+maybe-TAGS-mpc: TAGS-mpc
+
+TAGS-mpc: \
+ configure-mpc
+ @[ -f ./mpc/Makefile ] || exit 0; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(HOST_EXPORTS) \
+ for flag in $(EXTRA_HOST_FLAGS) ; do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+ done; \
+ echo "Doing TAGS in mpc" ; \
+ (cd $(HOST_SUBDIR)/mpc && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+ "RANLIB=$${RANLIB}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+ TAGS) \
+ || exit 1
+
+@endif mpc
+
+.PHONY: maybe-install-info-mpc install-info-mpc
+maybe-install-info-mpc:
+@if mpc
+maybe-install-info-mpc: install-info-mpc
+
+install-info-mpc: \
+ configure-mpc \
+ info-mpc
+ @[ -f ./mpc/Makefile ] || exit 0; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(HOST_EXPORTS) \
+ for flag in $(EXTRA_HOST_FLAGS) ; do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+ done; \
+ echo "Doing install-info in mpc" ; \
+ (cd $(HOST_SUBDIR)/mpc && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+ "RANLIB=$${RANLIB}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+ install-info) \
+ || exit 1
+
+@endif mpc
+
+.PHONY: maybe-install-pdf-mpc install-pdf-mpc
+maybe-install-pdf-mpc:
+@if mpc
+maybe-install-pdf-mpc: install-pdf-mpc
+
+install-pdf-mpc: \
+ configure-mpc \
+ pdf-mpc
+ @[ -f ./mpc/Makefile ] || exit 0; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(HOST_EXPORTS) \
+ for flag in $(EXTRA_HOST_FLAGS) ; do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+ done; \
+ echo "Doing install-pdf in mpc" ; \
+ (cd $(HOST_SUBDIR)/mpc && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+ "RANLIB=$${RANLIB}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+ install-pdf) \
+ || exit 1
+
+@endif mpc
+
+.PHONY: maybe-install-html-mpc install-html-mpc
+maybe-install-html-mpc:
+@if mpc
+maybe-install-html-mpc: install-html-mpc
+
+install-html-mpc: \
+ configure-mpc \
+ html-mpc
+ @[ -f ./mpc/Makefile ] || exit 0; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(HOST_EXPORTS) \
+ for flag in $(EXTRA_HOST_FLAGS) ; do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+ done; \
+ echo "Doing install-html in mpc" ; \
+ (cd $(HOST_SUBDIR)/mpc && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+ "RANLIB=$${RANLIB}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+ install-html) \
+ || exit 1
+
+@endif mpc
+
+.PHONY: maybe-installcheck-mpc installcheck-mpc
+maybe-installcheck-mpc:
+@if mpc
+maybe-installcheck-mpc: installcheck-mpc
+
+installcheck-mpc: \
+ configure-mpc
+ @[ -f ./mpc/Makefile ] || exit 0; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(HOST_EXPORTS) \
+ for flag in $(EXTRA_HOST_FLAGS) ; do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+ done; \
+ echo "Doing installcheck in mpc" ; \
+ (cd $(HOST_SUBDIR)/mpc && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+ "RANLIB=$${RANLIB}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+ installcheck) \
+ || exit 1
+
+@endif mpc
+
+.PHONY: maybe-mostlyclean-mpc mostlyclean-mpc
+maybe-mostlyclean-mpc:
+@if mpc
+maybe-mostlyclean-mpc: mostlyclean-mpc
+
+mostlyclean-mpc:
+ @[ -f ./mpc/Makefile ] || exit 0; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(HOST_EXPORTS) \
+ for flag in $(EXTRA_HOST_FLAGS) ; do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+ done; \
+ echo "Doing mostlyclean in mpc" ; \
+ (cd $(HOST_SUBDIR)/mpc && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+ "RANLIB=$${RANLIB}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+ mostlyclean) \
+ || exit 1
+
+@endif mpc
+
+.PHONY: maybe-clean-mpc clean-mpc
+maybe-clean-mpc:
+@if mpc
+maybe-clean-mpc: clean-mpc
+
+clean-mpc:
+ @[ -f ./mpc/Makefile ] || exit 0; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(HOST_EXPORTS) \
+ for flag in $(EXTRA_HOST_FLAGS) ; do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+ done; \
+ echo "Doing clean in mpc" ; \
+ (cd $(HOST_SUBDIR)/mpc && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+ "RANLIB=$${RANLIB}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+ clean) \
+ || exit 1
+
+@endif mpc
+
+.PHONY: maybe-distclean-mpc distclean-mpc
+maybe-distclean-mpc:
+@if mpc
+maybe-distclean-mpc: distclean-mpc
+
+distclean-mpc:
+ @[ -f ./mpc/Makefile ] || exit 0; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(HOST_EXPORTS) \
+ for flag in $(EXTRA_HOST_FLAGS) ; do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+ done; \
+ echo "Doing distclean in mpc" ; \
+ (cd $(HOST_SUBDIR)/mpc && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+ "RANLIB=$${RANLIB}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+ distclean) \
+ || exit 1
+
+@endif mpc
+
+.PHONY: maybe-maintainer-clean-mpc maintainer-clean-mpc
+maybe-maintainer-clean-mpc:
+@if mpc
+maybe-maintainer-clean-mpc: maintainer-clean-mpc
+
+maintainer-clean-mpc:
+ @[ -f ./mpc/Makefile ] || exit 0; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(HOST_EXPORTS) \
+ for flag in $(EXTRA_HOST_FLAGS) ; do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+ done; \
+ echo "Doing maintainer-clean in mpc" ; \
+ (cd $(HOST_SUBDIR)/mpc && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+ "RANLIB=$${RANLIB}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+ maintainer-clean) \
+ || exit 1
+
+@endif mpc
+
+
+
.PHONY: configure-ppl maybe-configure-ppl
maybe-configure-ppl:
@if gcc-bootstrap
@@ -51522,6 +52414,11 @@ stage1-start::
mkdir stage1-mpfr; \
mv stage1-mpfr mpfr
@endif mpfr
+@if mpc
+ @cd $(HOST_SUBDIR); [ -d stage1-mpc ] || \
+ mkdir stage1-mpc; \
+ mv stage1-mpc mpc
+@endif mpc
@if ppl
@cd $(HOST_SUBDIR); [ -d stage1-ppl ] || \
mkdir stage1-ppl; \
@@ -51607,6 +52504,11 @@ stage1-end::
cd $(HOST_SUBDIR); mv mpfr stage1-mpfr ; \
fi
@endif mpfr
+@if mpc
+ @if test -d $(HOST_SUBDIR)/mpc ; then \
+ cd $(HOST_SUBDIR); mv mpc stage1-mpc ; \
+ fi
+@endif mpc
@if ppl
@if test -d $(HOST_SUBDIR)/ppl ; then \
cd $(HOST_SUBDIR); mv ppl stage1-ppl ; \
@@ -51742,6 +52644,12 @@ stage2-start::
mv stage2-mpfr mpfr ; \
mv stage1-mpfr prev-mpfr || test -f stage1-lean
@endif mpfr
+@if mpc
+ @cd $(HOST_SUBDIR); [ -d stage2-mpc ] || \
+ mkdir stage2-mpc; \
+ mv stage2-mpc mpc ; \
+ mv stage1-mpc prev-mpc || test -f stage1-lean
+@endif mpc
@if ppl
@cd $(HOST_SUBDIR); [ -d stage2-ppl ] || \
mkdir stage2-ppl; \
@@ -51844,6 +52752,12 @@ stage2-end::
mv prev-mpfr stage1-mpfr ; : ; \
fi
@endif mpfr
+@if mpc
+ @if test -d $(HOST_SUBDIR)/mpc ; then \
+ cd $(HOST_SUBDIR); mv mpc stage2-mpc ; \
+ mv prev-mpc stage1-mpc ; : ; \
+ fi
+@endif mpc
@if ppl
@if test -d $(HOST_SUBDIR)/ppl ; then \
cd $(HOST_SUBDIR); mv ppl stage2-ppl ; \
@@ -52012,6 +52926,12 @@ stage3-start::
mv stage3-mpfr mpfr ; \
mv stage2-mpfr prev-mpfr || test -f stage2-lean
@endif mpfr
+@if mpc
+ @cd $(HOST_SUBDIR); [ -d stage3-mpc ] || \
+ mkdir stage3-mpc; \
+ mv stage3-mpc mpc ; \
+ mv stage2-mpc prev-mpc || test -f stage2-lean
+@endif mpc
@if ppl
@cd $(HOST_SUBDIR); [ -d stage3-ppl ] || \
mkdir stage3-ppl; \
@@ -52114,6 +53034,12 @@ stage3-end::
mv prev-mpfr stage2-mpfr ; : ; \
fi
@endif mpfr
+@if mpc
+ @if test -d $(HOST_SUBDIR)/mpc ; then \
+ cd $(HOST_SUBDIR); mv mpc stage3-mpc ; \
+ mv prev-mpc stage2-mpc ; : ; \
+ fi
+@endif mpc
@if ppl
@if test -d $(HOST_SUBDIR)/ppl ; then \
cd $(HOST_SUBDIR); mv ppl stage3-ppl ; \
@@ -52219,7 +53145,7 @@ compare:
$(do-compare) > /dev/null 2>&1; \
if test $$? -eq 1; then \
case $$file in \
- gcc/cc*-checksum$(objext) | ./libgcc/* ) \
+ gcc/cc*-checksum$(objext) | ./libgcc/* | ./gcc/ada/*tools/*) \
echo warning: $$file differs ;; \
*) \
echo $$file differs >> .bad_compare ;; \
@@ -52338,6 +53264,12 @@ stage4-start::
mv stage4-mpfr mpfr ; \
mv stage3-mpfr prev-mpfr || test -f stage3-lean
@endif mpfr
+@if mpc
+ @cd $(HOST_SUBDIR); [ -d stage4-mpc ] || \
+ mkdir stage4-mpc; \
+ mv stage4-mpc mpc ; \
+ mv stage3-mpc prev-mpc || test -f stage3-lean
+@endif mpc
@if ppl
@cd $(HOST_SUBDIR); [ -d stage4-ppl ] || \
mkdir stage4-ppl; \
@@ -52440,6 +53372,12 @@ stage4-end::
mv prev-mpfr stage3-mpfr ; : ; \
fi
@endif mpfr
+@if mpc
+ @if test -d $(HOST_SUBDIR)/mpc ; then \
+ cd $(HOST_SUBDIR); mv mpc stage4-mpc ; \
+ mv prev-mpc stage3-mpc ; : ; \
+ fi
+@endif mpc
@if ppl
@if test -d $(HOST_SUBDIR)/ppl ; then \
cd $(HOST_SUBDIR); mv ppl stage4-ppl ; \
@@ -52545,7 +53483,7 @@ compare3:
$(do-compare3) > /dev/null 2>&1; \
if test $$? -eq 1; then \
case $$file in \
- gcc/cc*-checksum$(objext) | ./libgcc/* ) \
+ gcc/cc*-checksum$(objext) | ./libgcc/* | ./gcc/ada/*tools/*) \
echo warning: $$file differs ;; \
*) \
echo $$file differs >> .bad_compare ;; \
@@ -52652,6 +53590,12 @@ stageprofile-start::
mv stageprofile-mpfr mpfr ; \
mv stage1-mpfr prev-mpfr || test -f stage1-lean
@endif mpfr
+@if mpc
+ @cd $(HOST_SUBDIR); [ -d stageprofile-mpc ] || \
+ mkdir stageprofile-mpc; \
+ mv stageprofile-mpc mpc ; \
+ mv stage1-mpc prev-mpc || test -f stage1-lean
+@endif mpc
@if ppl
@cd $(HOST_SUBDIR); [ -d stageprofile-ppl ] || \
mkdir stageprofile-ppl; \
@@ -52754,6 +53698,12 @@ stageprofile-end::
mv prev-mpfr stage1-mpfr ; : ; \
fi
@endif mpfr
+@if mpc
+ @if test -d $(HOST_SUBDIR)/mpc ; then \
+ cd $(HOST_SUBDIR); mv mpc stageprofile-mpc ; \
+ mv prev-mpc stage1-mpc ; : ; \
+ fi
+@endif mpc
@if ppl
@if test -d $(HOST_SUBDIR)/ppl ; then \
cd $(HOST_SUBDIR); mv ppl stageprofile-ppl ; \
@@ -52899,6 +53849,12 @@ stagefeedback-start::
mv stagefeedback-mpfr mpfr ; \
mv stageprofile-mpfr prev-mpfr || test -f stageprofile-lean
@endif mpfr
+@if mpc
+ @cd $(HOST_SUBDIR); [ -d stagefeedback-mpc ] || \
+ mkdir stagefeedback-mpc; \
+ mv stagefeedback-mpc mpc ; \
+ mv stageprofile-mpc prev-mpc || test -f stageprofile-lean
+@endif mpc
@if ppl
@cd $(HOST_SUBDIR); [ -d stagefeedback-ppl ] || \
mkdir stagefeedback-ppl; \
@@ -53001,6 +53957,12 @@ stagefeedback-end::
mv prev-mpfr stageprofile-mpfr ; : ; \
fi
@endif mpfr
+@if mpc
+ @if test -d $(HOST_SUBDIR)/mpc ; then \
+ cd $(HOST_SUBDIR); mv mpc stagefeedback-mpc ; \
+ mv prev-mpc stageprofile-mpc ; : ; \
+ fi
+@endif mpc
@if ppl
@if test -d $(HOST_SUBDIR)/ppl ; then \
cd $(HOST_SUBDIR); mv ppl stagefeedback-ppl ; \
@@ -53313,6 +54275,14 @@ all-stage3-gcc: maybe-all-stage3-mpfr
all-stage4-gcc: maybe-all-stage4-mpfr
all-stageprofile-gcc: maybe-all-stageprofile-mpfr
all-stagefeedback-gcc: maybe-all-stagefeedback-mpfr
+all-gcc: maybe-all-mpc
+
+all-stage1-gcc: maybe-all-stage1-mpc
+all-stage2-gcc: maybe-all-stage2-mpc
+all-stage3-gcc: maybe-all-stage3-mpc
+all-stage4-gcc: maybe-all-stage4-mpc
+all-stageprofile-gcc: maybe-all-stageprofile-mpc
+all-stagefeedback-gcc: maybe-all-stagefeedback-mpc
all-gcc: maybe-all-ppl
all-stage1-gcc: maybe-all-stage1-ppl
@@ -53453,6 +54423,14 @@ configure-stage3-mpfr: maybe-all-stage3-gmp
configure-stage4-mpfr: maybe-all-stage4-gmp
configure-stageprofile-mpfr: maybe-all-stageprofile-gmp
configure-stagefeedback-mpfr: maybe-all-stagefeedback-gmp
+configure-mpc: maybe-all-mpfr
+
+configure-stage1-mpc: maybe-all-stage1-mpfr
+configure-stage2-mpc: maybe-all-stage2-mpfr
+configure-stage3-mpc: maybe-all-stage3-mpfr
+configure-stage4-mpc: maybe-all-stage4-mpfr
+configure-stageprofile-mpc: maybe-all-stageprofile-mpfr
+configure-stagefeedback-mpc: maybe-all-stagefeedback-mpfr
configure-ppl: maybe-all-gmp
configure-stage1-ppl: maybe-all-stage1-gmp
diff --git a/Makefile.tpl b/Makefile.tpl
index 2209d95b208..a5094f61816 100644
--- a/Makefile.tpl
+++ b/Makefile.tpl
@@ -628,8 +628,9 @@ all:
$(MAKE) $(RECURSE_FLAGS_TO_PASS) all-host all-target \
@if gcc-bootstrap
; \
- fi
+ fi \
@endif gcc-bootstrap
+ && :
.PHONY: all-build
[+ FOR build_modules +]
@@ -1435,7 +1436,7 @@ do-clean: clean-stage[+id+]
$(do-[+compare-target+]) > /dev/null 2>&1; \
if test $$? -eq 1; then \
case $$file in \
- gcc/cc*-checksum$(objext) | ./libgcc/* ) \
+ gcc/cc*-checksum$(objext) | ./libgcc/* | ./gcc/ada/*tools/*) \
echo warning: $$file differs ;; \
*) \
echo $$file differs >> .bad_compare ;; \
diff --git a/boehm-gc/ChangeLog b/boehm-gc/ChangeLog
index ed6ee543650..d2a80cc1fcb 100644
--- a/boehm-gc/ChangeLog
+++ b/boehm-gc/ChangeLog
@@ -1,3 +1,7 @@
+2009-05-17 Dave Korn <dave.korn.cygwin@gmail.com>
+
+ * win32_threads.c (GC_get_thread_stack_base): Implement for Cygwin.
+
2009-03-01 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
* configure: Regenerate.
diff --git a/boehm-gc/win32_threads.c b/boehm-gc/win32_threads.c
index ba53d86fbd1..ffb34e0a8b1 100644
--- a/boehm-gc/win32_threads.c
+++ b/boehm-gc/win32_threads.c
@@ -753,6 +753,12 @@ int GC_pthread_detach(pthread_t thread)
return result;
}
+GC_PTR GC_get_thread_stack_base()
+{
+ extern GC_PTR _tlsbase __asm__ ("%fs:4");
+ return _tlsbase;
+}
+
#else /* !CYGWIN32 */
/*
diff --git a/config.guess b/config.guess
index b8cdd22573d..7c480734b7c 100755
--- a/config.guess
+++ b/config.guess
@@ -1,10 +1,10 @@
#! /bin/sh
# Attempt to guess a canonical system name.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
# Free Software Foundation, Inc.
-timestamp='2009-02-03'
+timestamp='2009-06-03'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -324,6 +324,9 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
case `/usr/bin/uname -p` in
sparc) echo sparc-icl-nx7; exit ;;
esac ;;
+ s390x:SunOS:*:*)
+ echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
sun4H:SunOS:5.*:*)
echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
@@ -819,6 +822,9 @@ EOF
[345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
echo i${UNAME_MACHINE}-pc-mks
exit ;;
+ 8664:Windows_NT:*)
+ echo x86_64-pc-mks
+ exit ;;
i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
# How do we know it's Interix rather than the generic POSIX subsystem?
# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
@@ -879,40 +885,17 @@ EOF
m68*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
- mips:Linux:*:*)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #undef CPU
- #undef mips
- #undef mipsel
- #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
- CPU=mipsel
- #else
- #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
- CPU=mips
- #else
- CPU=
- #endif
- #endif
-EOF
- eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
- /^CPU/{
- s: ::g
- p
- }'`"
- test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
- ;;
- mips64:Linux:*:*)
+ mips:Linux:*:* | mips64:Linux:*:*)
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#undef CPU
- #undef mips64
- #undef mips64el
+ #undef ${UNAME_MACHINE}
+ #undef ${UNAME_MACHINE}el
#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
- CPU=mips64el
+ CPU=${UNAME_MACHINE}el
#else
#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
- CPU=mips64
+ CPU=${UNAME_MACHINE}
#else
CPU=
#endif
@@ -998,14 +981,6 @@ EOF
elf32-i386)
TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
;;
- a.out-i386-linux)
- echo "${UNAME_MACHINE}-pc-linux-gnuaout"
- exit ;;
- "")
- # Either a pre-BFD a.out linker (linux-gnuoldld) or
- # one that does not give us useful --help.
- echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
- exit ;;
esac
# Determine whether the default compiler is a.out or elf
eval $set_cc_for_build
@@ -1115,7 +1090,7 @@ EOF
pc:*:*:*)
# Left here for compatibility:
# uname -m prints for DJGPP always 'pc', but it prints nothing about
- # the processor, so we play safe by assuming i386.
+ # the processor, so we play safe by assuming i586.
# Note: whatever this is, it MUST be the same as what config.sub
# prints for the "djgpp" host, or else GDB configury will decide that
# this is a cross-build.
diff --git a/config.sub b/config.sub
index a39437d0158..67a635efec8 100755
--- a/config.sub
+++ b/config.sub
@@ -1,10 +1,10 @@
#! /bin/sh
# Configuration validation subroutine script.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
# Free Software Foundation, Inc.
-timestamp='2009-04-17'
+timestamp='2009-06-03'
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
diff --git a/config/ChangeLog b/config/ChangeLog
index e1ca63e7471..d2b51c3ce5e 100644
--- a/config/ChangeLog
+++ b/config/ChangeLog
@@ -1,3 +1,7 @@
+2009-05-26 Rafael Avila de Espindola <espindola@google.com>
+
+ * plugins.m4: New.
+
2009-05-12 Alexandre Oliva <aoliva@redhat.com>
* multi.m4: Save CXX, GFORTRAN and GCJ in config.status.
diff --git a/config/plugins.m4 b/config/plugins.m4
new file mode 100644
index 00000000000..7ee8412aa37
--- /dev/null
+++ b/config/plugins.m4
@@ -0,0 +1,11 @@
+AC_DEFUN([AC_PLUGINS],
+[
+AC_ARG_ENABLE([plugins],
+AS_HELP_STRING([--enable-plugins], [Enable support for plugins (defaults no)]),
+[case "${enableval}" in
+ yes | "") plugins=yes ;;
+ no) plugins=no ;;
+ *) plugins=yes ;;
+ esac],
+[plugins=no])
+])
diff --git a/configure b/configure
index dd525c807ba..5931086f2aa 100755
--- a/configure
+++ b/configure
@@ -272,7 +272,7 @@ PACKAGE_STRING=
PACKAGE_BUGREPORT=
ac_unique_file="move-if-change"
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS TOPLEVEL_CONFIGURE_ARGUMENTS build build_cpu build_vendor build_os build_noncanonical host_noncanonical target_noncanonical host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LN LN_S build_libsubdir build_subdir host_subdir target_subdir CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CXX CXXFLAGS ac_ct_CXX GNATBIND ac_ct_GNATBIND GNATMAKE ac_ct_GNATMAKE do_compare gmplibs gmpinc extra_mpfr_configure_flags ppllibs pplinc clooglibs clooginc stage1_languages SYSROOT_CFLAGS_FOR_TARGET DEBUG_PREFIX_CFLAGS_FOR_TARGET CFLAGS_FOR_TARGET CXXFLAGS_FOR_TARGET RPATH_ENVVAR GCC_SHLIB_SUBDIR tooldir build_tooldir CONFIGURE_GDB_TK GDB_TK INSTALL_GDB_TK build_configargs build_configdirs host_configargs configdirs target_configargs AR_FOR_BUILD AS_FOR_BUILD CC_FOR_BUILD CFLAGS_FOR_BUILD CXXFLAGS_FOR_BUILD CXX_FOR_BUILD DLLTOOL_FOR_BUILD GCJ_FOR_BUILD GFORTRAN_FOR_BUILD LDFLAGS_FOR_BUILD LD_FOR_BUILD NM_FOR_BUILD RANLIB_FOR_BUILD WINDMC_FOR_BUILD WINDRES_FOR_BUILD config_shell YACC BISON M4 LEX FLEX MAKEINFO EXPECT RUNTEST AR AS DLLTOOL LD LIPO NM RANLIB STRIP WINDRES WINDMC OBJCOPY OBJDUMP CC_FOR_TARGET CXX_FOR_TARGET GCC_FOR_TARGET GCJ_FOR_TARGET GFORTRAN_FOR_TARGET AR_FOR_TARGET AS_FOR_TARGET DLLTOOL_FOR_TARGET LD_FOR_TARGET LIPO_FOR_TARGET NM_FOR_TARGET OBJDUMP_FOR_TARGET RANLIB_FOR_TARGET STRIP_FOR_TARGET WINDRES_FOR_TARGET WINDMC_FOR_TARGET RAW_CXX_FOR_TARGET FLAGS_FOR_TARGET COMPILER_AS_FOR_TARGET COMPILER_LD_FOR_TARGET COMPILER_NM_FOR_TARGET MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT stage1_cflags stage1_checking stage2_werror_flag datarootdir docdir pdfdir htmldir LIBOBJS LTLIBOBJS'
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS TOPLEVEL_CONFIGURE_ARGUMENTS build build_cpu build_vendor build_os build_noncanonical host_noncanonical target_noncanonical host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LN LN_S build_libsubdir build_subdir host_subdir target_subdir CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CXX CXXFLAGS ac_ct_CXX GNATBIND ac_ct_GNATBIND GNATMAKE ac_ct_GNATMAKE do_compare gmplibs gmpinc extra_mpfr_configure_flags extra_mpc_gmp_configure_flags extra_mpc_mpfr_configure_flags ppllibs pplinc clooglibs clooginc stage1_languages SYSROOT_CFLAGS_FOR_TARGET DEBUG_PREFIX_CFLAGS_FOR_TARGET CFLAGS_FOR_TARGET CXXFLAGS_FOR_TARGET RPATH_ENVVAR GCC_SHLIB_SUBDIR tooldir build_tooldir CONFIGURE_GDB_TK GDB_TK INSTALL_GDB_TK build_configargs build_configdirs host_configargs configdirs target_configargs AR_FOR_BUILD AS_FOR_BUILD CC_FOR_BUILD CFLAGS_FOR_BUILD CXXFLAGS_FOR_BUILD CXX_FOR_BUILD DLLTOOL_FOR_BUILD GCJ_FOR_BUILD GFORTRAN_FOR_BUILD LDFLAGS_FOR_BUILD LD_FOR_BUILD NM_FOR_BUILD RANLIB_FOR_BUILD WINDMC_FOR_BUILD WINDRES_FOR_BUILD config_shell YACC BISON M4 LEX FLEX MAKEINFO EXPECT RUNTEST AR AS DLLTOOL LD LIPO NM RANLIB STRIP WINDRES WINDMC OBJCOPY OBJDUMP CC_FOR_TARGET CXX_FOR_TARGET GCC_FOR_TARGET GCJ_FOR_TARGET GFORTRAN_FOR_TARGET AR_FOR_TARGET AS_FOR_TARGET DLLTOOL_FOR_TARGET LD_FOR_TARGET LIPO_FOR_TARGET NM_FOR_TARGET OBJDUMP_FOR_TARGET RANLIB_FOR_TARGET STRIP_FOR_TARGET WINDRES_FOR_TARGET WINDMC_FOR_TARGET RAW_CXX_FOR_TARGET FLAGS_FOR_TARGET COMPILER_AS_FOR_TARGET COMPILER_LD_FOR_TARGET COMPILER_NM_FOR_TARGET MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT stage1_cflags stage1_checking stage2_werror_flag datarootdir docdir pdfdir htmldir LIBOBJS LTLIBOBJS'
ac_subst_files='serialization_dependencies host_makefile_frag target_makefile_frag alphaieee_frag ospace_frag'
ac_pwd=`pwd`
@@ -956,6 +956,12 @@ Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
--with-build-libsubdir=DIR Directory where to find libraries for build system
+ --with-mpc=PATH specify prefix directory for installed MPC package.
+ Equivalent to --with-mpc-include=PATH/include
+ plus --with-mpc-lib=PATH/lib
+ --with-mpc-include=PATH
+ specify directory for installed MPC include files
+ --with-mpc-lib=PATH specify directory for the installed MPC library
--with-mpfr-dir=PATH this option has been REMOVED
--with-mpfr=PATH specify prefix directory for installed MPFR package.
Equivalent to --with-mpfr-include=PATH/include
@@ -1887,7 +1893,7 @@ build_tools="build-texinfo build-byacc build-flex build-bison build-m4 build-fix
# these libraries are used by various programs built for the host environment
#
-host_libs="intl mmalloc libiberty opcodes bfd readline tcl tk itcl libgui zlib libcpp libdecnumber gmp mpfr ppl cloog libiconv"
+host_libs="intl mmalloc libiberty opcodes bfd readline tcl tk itcl libgui zlib libcpp libdecnumber gmp mpfr mpc ppl cloog libiconv"
# these tools are built for the host environment
# Note, the powerpc-eabi build depends on sim occurring before gdb in order to
@@ -2064,7 +2070,7 @@ if test "${ENABLE_GOLD}" = "yes"; then
case "${target}" in
*-*-elf* | *-*-sysv4* | *-*-unixware* | *-*-eabi* | hppa*64*-*-hpux* \
| *-*-linux* | frv-*-uclinux* | *-*-irix5* | *-*-irix6* \
- | *-*-netbsd* | *-*-openbsd* | *-*-freebsd* | *-*-solaris2*)
+ | *-*-netbsd* | *-*-openbsd* | *-*-freebsd* | *-*-solaris2* | *-*-nto*)
case "${target}" in
*-*-linux*aout* | *-*-linux*oldld*)
;;
@@ -2077,7 +2083,7 @@ if test "${ENABLE_GOLD}" = "yes"; then
if test "$is_elf" = "yes"; then
# Check for target supported by gold.
case "${target}" in
- i?86-*-* | x86_64-*-* | sparc*-*-* | powerpc*-*-*)
+ i?86-*-* | x86_64-*-* | sparc*-*-* | powerpc*-*-* | arm*-*-*)
configdirs="`echo " ${configdirs} " | sed -e 's/ ld / gold /'`"
;;
esac
@@ -2496,7 +2502,7 @@ case "${target}" in
;;
*-*-cygwin*)
target_configdirs="$target_configdirs target-libtermcap target-winsup"
- noconfigdirs="$noconfigdirs target-gperf target-libgloss ${libgcj}"
+ noconfigdirs="$noconfigdirs target-gperf target-libgloss"
# always build newlib if winsup directory is present.
if test -d "$srcdir/winsup/cygwin"; then
skipdirs=`echo " ${skipdirs} " | sed -e 's/ target-newlib / /'`
@@ -2566,7 +2572,7 @@ case "${target}" in
;;
powerpc-*-aix*)
# copied from rs6000-*-* entry
- noconfigdirs="$noconfigdirs gprof target-libgloss target-libssp ${libgcj}"
+ noconfigdirs="$noconfigdirs gprof target-libgloss target-libssp target-newlib ${libgcj}"
;;
powerpc*-*-winnt* | powerpc*-*-pe* | ppc*-*-pe)
target_configdirs="$target_configdirs target-winsup"
@@ -2593,7 +2599,7 @@ case "${target}" in
noconfigdirs="$noconfigdirs target-newlib gprof ${libgcj}"
;;
rs6000-*-aix*)
- noconfigdirs="$noconfigdirs gprof target-libgloss target-libssp ${libgcj}"
+ noconfigdirs="$noconfigdirs gprof target-libgloss target-libssp target-newlib ${libgcj}"
;;
rs6000-*-*)
noconfigdirs="$noconfigdirs gprof ${libgcj}"
@@ -4498,10 +4504,54 @@ do_compare="$gcc_cv_prog_cmp_skip"
-# Check for GMP and MPFR
+# Check for GMP, MPFR and MPC
gmplibs="-lmpfr -lgmp"
gmpinc=
have_gmp=no
+mpclibs=-lmpc
+mpcinc=
+have_mpc=no
+
+# Specify a location for mpc
+# check for this first so it ends up on the link line before mpfr.
+
+# Check whether --with-mpc or --without-mpc was given.
+if test "${with_mpc+set}" = set; then
+ withval="$with_mpc"
+
+fi;
+
+# Check whether --with-mpc_include or --without-mpc_include was given.
+if test "${with_mpc_include+set}" = set; then
+ withval="$with_mpc_include"
+
+fi;
+
+# Check whether --with-mpc_lib or --without-mpc_lib was given.
+if test "${with_mpc_lib+set}" = set; then
+ withval="$with_mpc_lib"
+
+fi;
+
+if test "x$with_mpc" != x; then
+ mpclibs="-L$with_mpc/lib -lmpc"
+ mpcinc="-I$with_mpc/include $mpcinc"
+fi
+if test "x$with_mpc_include" != x; then
+ mpcinc="-I$with_mpc_include $mpcinc"
+fi
+if test "x$with_mpc_lib" != x; then
+ mpclibs="-L$with_mpc_lib -lmpc"
+fi
+if test "x$with_mpc$with_mpc_include$with_mpc_lib" = x && test -d ${srcdir}/mpc; then
+ mpclibs='-L$$r/$(HOST_SUBDIR)/mpc/src/.libs -L$$r/$(HOST_SUBDIR)/mpc/src/_libs -lmpc'
+ mpcinc='-I$$s/mpc/src '"$mpcinc"
+ # Do not test the mpc version. Assume that it is sufficient, since
+ # it is in the source tree, and the library has not been built yet
+ # but it would be included on the link line in the version check below
+ # hence making the test fail.
+ have_mpc=yes
+fi
# Specify a location for mpfr
# check for this first so it ends up on the link line before gmp.
@@ -4548,6 +4598,7 @@ fi
if test "x$with_mpfr$with_mpfr_include$with_mpfr_lib" = x && test -d ${srcdir}/mpfr; then
gmplibs='-L$$r/$(HOST_SUBDIR)/mpfr/.libs -L$$r/$(HOST_SUBDIR)/mpfr/_libs '"$gmplibs"
gmpinc='-I$$r/$(HOST_SUBDIR)/mpfr -I$$s/mpfr '"$gmpinc"
+ extra_mpc_mpfr_configure_flags='--with-mpfr-include=$$s/mpfr'
# Do not test the mpfr version. Assume that it is sufficient, since
# it is in the source tree, and the library has not been built yet
# but it would be included on the link line in the version check below
@@ -4601,6 +4652,7 @@ if test "x$with_gmp$with_gmp_include$with_gmp_lib" = x && test -d ${srcdir}/gmp;
gmplibs='-L$$r/$(HOST_SUBDIR)/gmp/.libs -L$$r/$(HOST_SUBDIR)/gmp/_libs '"$gmplibs"
gmpinc='-I$$r/$(HOST_SUBDIR)/gmp -I$$s/gmp '"$gmpinc"
extra_mpfr_configure_flags='--with-gmp-build=$$r/$(HOST_SUBDIR)/gmp'
+ extra_mpc_gmp_configure_flags='--with-gmp-include=$$r/$(HOST_SUBDIR)/gmp'
# Do not test the gmp version. Assume that it is sufficient, since
# it is in the source tree, and the library has not been built yet
# but it would be included on the link line in the version check below
@@ -4668,9 +4720,8 @@ echo "${ECHO_T}no" >&6; have_gmp=no
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ # If we have GMP, check the MPFR version.
if test x"$have_gmp" = xyes; then
- saved_LIBS="$LIBS"
- LIBS="$LIBS $gmplibs"
echo "$as_me:$LINENO: checking for correct version of mpfr.h" >&5
echo $ECHO_N "checking for correct version of mpfr.h... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
@@ -4688,22 +4739,14 @@ main ()
#if MPFR_VERSION < MPFR_VERSION_NUM(2,3,1)
choke me
#endif
- mpfr_t n;
- mpfr_t x;
- int t;
- mpfr_init (n);
- mpfr_init (x);
- mpfr_atan2 (n, n, x, GMP_RNDN);
- mpfr_erfc (n, x, GMP_RNDN);
- mpfr_subnormalize (x, t, GMP_RNDN);
;
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
@@ -4717,7 +4760,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -4738,7 +4781,137 @@ main ()
#if MPFR_VERSION < MPFR_VERSION_NUM(2,3,2)
choke me
#endif
- mpfr_t n; mpfr_init(n);
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+echo "$as_me:$LINENO: result: buggy but acceptable" >&5
+echo "${ECHO_T}buggy but acceptable" >&6
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; have_gmp=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+
+ # Check for the MPC header version.
+ if test x"$have_mpc" != xyes ; then
+ CFLAGS="$CFLAGS $mpcinc"
+ echo "$as_me:$LINENO: checking for the correct version of mpc.h" >&5
+echo $ECHO_N "checking for the correct version of mpc.h... $ECHO_C" >&6
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <mpc.h>
+int
+main ()
+{
+
+ #if MPC_VERSION < MPC_VERSION_NUM (0,6,0)
+ choke me
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; have_mpc=maybe
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; have_mpc=no; mpclibs= ; mpcinc=
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+
+ # Now check the MPFR library.
+ if test x"$have_gmp" = xyes; then
+ saved_LIBS="$LIBS"
+ LIBS="$LIBS $gmplibs"
+ echo "$as_me:$LINENO: checking for the correct version of the gmp/mpfr libraries" >&5
+echo $ECHO_N "checking for the correct version of the gmp/mpfr libraries... $ECHO_C" >&6
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <gmp.h>
+ #include <mpfr.h>
+int
+main ()
+{
+
+ mpfr_t n;
+ mpfr_t x;
+ int t;
+ mpfr_init (n);
+ mpfr_init (x);
+ mpfr_atan2 (n, n, x, GMP_RNDN);
+ mpfr_erfc (n, x, GMP_RNDN);
+ mpfr_subnormalize (x, t, GMP_RNDN);
;
return 0;
@@ -4772,22 +4945,87 @@ else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
-echo "$as_me:$LINENO: result: buggy but acceptable" >&5
-echo "${ECHO_T}buggy but acceptable" >&6
+echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; have_gmp=no
fi
rm -f conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
+ LIBS="$saved_LIBS"
+ fi
+
+ if test x"$have_mpc" = xmaybe; then
+ saved_LIBS="$LIBS"
+ LIBS="$LIBS $mpclibs $gmplibs"
+ echo "$as_me:$LINENO: checking for the correct version of the mpc library" >&5
+echo $ECHO_N "checking for the correct version of the mpc library... $ECHO_C" >&6
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <mpc.h>
+int
+main ()
+{
+
+ mpc_t n;
+ mpc_init2 (n, 53);
+ mpc_set_ui_ui (n, 1, 1, MPC_RNDNN);
+ mpc_sin (n, n, MPC_RNDNN);
+ mpc_cos (n, n, MPC_RNDNN);
+ mpc_tan (n, n, MPC_RNDNN);
+ mpc_sinh (n, n, MPC_RNDNN);
+ mpc_cosh (n, n, MPC_RNDNN);
+ mpc_tanh (n, n, MPC_RNDNN);
+ mpc_exp (n, n, MPC_RNDNN);
+ mpc_log (n, n, MPC_RNDNN);
+ mpc_sqrt (n, n, MPC_RNDNN);
+ mpc_proj (n, n, MPC_RNDNN);
+ mpc_neg (n, n, MPC_RNDNN);
+ mpc_sqr (n, n, MPC_RNDNN);
+ mpc_clear (n);
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; have_mpc=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; have_gmp=no
+echo "${ECHO_T}no" >&6; have_mpc=no; mpclibs= ; mpcinc=
fi
rm -f conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
- LIBS="$saved_LIBS"
+ LIBS="$saved_LIBS"
fi
+
CFLAGS="$saved_CFLAGS"
if test x$have_gmp != xyes; then
@@ -4811,7 +5049,17 @@ They may be located in separate packages." >&2;}
fi
fi
-# Flags needed for both GMP and/or MPFR
+if test x$have_mpc != xyes ; then
+ mpcinc=
+ mpclibs=
+fi
+
+gmpinc="$mpcinc $gmpinc"
+gmplibs="$mpclibs $gmplibs"
+
+# Flags needed for both GMP, MPFR and/or MPC.
+
+
@@ -13262,6 +13510,8 @@ s,@do_compare@,$do_compare,;t t
s,@gmplibs@,$gmplibs,;t t
s,@gmpinc@,$gmpinc,;t t
s,@extra_mpfr_configure_flags@,$extra_mpfr_configure_flags,;t t
+s,@extra_mpc_gmp_configure_flags@,$extra_mpc_gmp_configure_flags,;t t
+s,@extra_mpc_mpfr_configure_flags@,$extra_mpc_mpfr_configure_flags,;t t
s,@ppllibs@,$ppllibs,;t t
s,@pplinc@,$pplinc,;t t
s,@clooglibs@,$clooglibs,;t t
diff --git a/configure.ac b/configure.ac
index a1e11c65071..e6c82685243 100644
--- a/configure.ac
+++ b/configure.ac
@@ -158,7 +158,7 @@ build_tools="build-texinfo build-byacc build-flex build-bison build-m4 build-fix
# these libraries are used by various programs built for the host environment
#
-host_libs="intl mmalloc libiberty opcodes bfd readline tcl tk itcl libgui zlib libcpp libdecnumber gmp mpfr ppl cloog libiconv"
+host_libs="intl mmalloc libiberty opcodes bfd readline tcl tk itcl libgui zlib libcpp libdecnumber gmp mpfr mpc ppl cloog libiconv"
# these tools are built for the host environment
# Note, the powerpc-eabi build depends on sim occurring before gdb in order to
@@ -305,7 +305,7 @@ if test "${ENABLE_GOLD}" = "yes"; then
case "${target}" in
*-*-elf* | *-*-sysv4* | *-*-unixware* | *-*-eabi* | hppa*64*-*-hpux* \
| *-*-linux* | frv-*-uclinux* | *-*-irix5* | *-*-irix6* \
- | *-*-netbsd* | *-*-openbsd* | *-*-freebsd* | *-*-solaris2*)
+ | *-*-netbsd* | *-*-openbsd* | *-*-freebsd* | *-*-solaris2* | *-*-nto*)
case "${target}" in
*-*-linux*aout* | *-*-linux*oldld*)
;;
@@ -318,7 +318,7 @@ if test "${ENABLE_GOLD}" = "yes"; then
if test "$is_elf" = "yes"; then
# Check for target supported by gold.
case "${target}" in
- i?86-*-* | x86_64-*-* | sparc*-*-* | powerpc*-*-*)
+ i?86-*-* | x86_64-*-* | sparc*-*-* | powerpc*-*-* | arm*-*-*)
configdirs="`echo " ${configdirs} " | sed -e 's/ ld / gold /'`"
;;
esac
@@ -731,7 +731,7 @@ case "${target}" in
;;
*-*-cygwin*)
target_configdirs="$target_configdirs target-libtermcap target-winsup"
- noconfigdirs="$noconfigdirs target-gperf target-libgloss ${libgcj}"
+ noconfigdirs="$noconfigdirs target-gperf target-libgloss"
# always build newlib if winsup directory is present.
if test -d "$srcdir/winsup/cygwin"; then
skipdirs=`echo " ${skipdirs} " | sed -e 's/ target-newlib / /'`
@@ -801,7 +801,7 @@ case "${target}" in
;;
powerpc-*-aix*)
# copied from rs6000-*-* entry
- noconfigdirs="$noconfigdirs gprof target-libgloss target-libssp ${libgcj}"
+ noconfigdirs="$noconfigdirs gprof target-libgloss target-libssp target-newlib ${libgcj}"
;;
powerpc*-*-winnt* | powerpc*-*-pe* | ppc*-*-pe)
target_configdirs="$target_configdirs target-winsup"
@@ -828,7 +828,7 @@ case "${target}" in
noconfigdirs="$noconfigdirs target-newlib gprof ${libgcj}"
;;
rs6000-*-aix*)
- noconfigdirs="$noconfigdirs gprof target-libgloss target-libssp ${libgcj}"
+ noconfigdirs="$noconfigdirs gprof target-libgloss target-libssp target-newlib ${libgcj}"
;;
rs6000-*-*)
noconfigdirs="$noconfigdirs gprof ${libgcj}"
@@ -1191,10 +1191,42 @@ fi
ACX_PROG_GNAT
ACX_PROG_CMP_IGNORE_INITIAL
-# Check for GMP and MPFR
+# Check for GMP, MPFR and MPC
gmplibs="-lmpfr -lgmp"
gmpinc=
have_gmp=no
+mpclibs=-lmpc
+mpcinc=
+have_mpc=no
+
+# Specify a location for mpc
+# check for this first so it ends up on the link line before mpfr.
+AC_ARG_WITH(mpc, [ --with-mpc=PATH specify prefix directory for installed MPC package.
+ Equivalent to --with-mpc-include=PATH/include
+ plus --with-mpc-lib=PATH/lib])
+AC_ARG_WITH(mpc_include, [ --with-mpc-include=PATH
+ specify directory for installed MPC include files])
+AC_ARG_WITH(mpc_lib, [ --with-mpc-lib=PATH specify directory for the installed MPC library])
+
+if test "x$with_mpc" != x; then
+ mpclibs="-L$with_mpc/lib -lmpc"
+ mpcinc="-I$with_mpc/include $mpcinc"
+fi
+if test "x$with_mpc_include" != x; then
+ mpcinc="-I$with_mpc_include $mpcinc"
+fi
+if test "x$with_mpc_lib" != x; then
+ mpclibs="-L$with_mpc_lib -lmpc"
+fi
+if test "x$with_mpc$with_mpc_include$with_mpc_lib" = x && test -d ${srcdir}/mpc; then
+ mpclibs='-L$$r/$(HOST_SUBDIR)/mpc/src/.libs -L$$r/$(HOST_SUBDIR)/mpc/src/_libs -lmpc'
+ mpcinc='-I$$s/mpc/src '"$mpcinc"
+ # Do not test the mpc version. Assume that it is sufficient, since
+ # it is in the source tree, and the library has not been built yet
+ # but it would be included on the link line in the version check below
+ # hence making the test fail.
+ have_mpc=yes
+fi
# Specify a location for mpfr
# check for this first so it ends up on the link line before gmp.
@@ -1222,6 +1254,7 @@ fi
if test "x$with_mpfr$with_mpfr_include$with_mpfr_lib" = x && test -d ${srcdir}/mpfr; then
gmplibs='-L$$r/$(HOST_SUBDIR)/mpfr/.libs -L$$r/$(HOST_SUBDIR)/mpfr/_libs '"$gmplibs"
gmpinc='-I$$r/$(HOST_SUBDIR)/mpfr -I$$s/mpfr '"$gmpinc"
+ extra_mpc_mpfr_configure_flags='--with-mpfr-include=$$s/mpfr'
# Do not test the mpfr version. Assume that it is sufficient, since
# it is in the source tree, and the library has not been built yet
# but it would be included on the link line in the version check below
@@ -1255,6 +1288,7 @@ if test "x$with_gmp$with_gmp_include$with_gmp_lib" = x && test -d ${srcdir}/gmp;
gmplibs='-L$$r/$(HOST_SUBDIR)/gmp/.libs -L$$r/$(HOST_SUBDIR)/gmp/_libs '"$gmplibs"
gmpinc='-I$$r/$(HOST_SUBDIR)/gmp -I$$s/gmp '"$gmpinc"
extra_mpfr_configure_flags='--with-gmp-build=$$r/$(HOST_SUBDIR)/gmp'
+ extra_mpc_gmp_configure_flags='--with-gmp-include=$$r/$(HOST_SUBDIR)/gmp'
# Do not test the gmp version. Assume that it is sufficient, since
# it is in the source tree, and the library has not been built yet
# but it would be included on the link line in the version check below
@@ -1274,16 +1308,43 @@ if test -d ${srcdir}/gcc && test "x$have_gmp" = xno; then
#endif
], [AC_MSG_RESULT([yes])], [AC_MSG_RESULT([no]); have_gmp=no])
+ # If we have GMP, check the MPFR version.
if test x"$have_gmp" = xyes; then
- saved_LIBS="$LIBS"
- LIBS="$LIBS $gmplibs"
dnl MPFR 2.3.1 is acceptable, but MPFR 2.3.2 is better.
AC_MSG_CHECKING([for correct version of mpfr.h])
- AC_TRY_LINK([#include <gmp.h>
+ AC_TRY_COMPILE([#include <gmp.h>
#include <mpfr.h>],[
#if MPFR_VERSION < MPFR_VERSION_NUM(2,3,1)
choke me
#endif
+ ], AC_TRY_COMPILE([#include <gmp.h>
+ #include <mpfr.h>],[
+ #if MPFR_VERSION < MPFR_VERSION_NUM(2,3,2)
+ choke me
+ #endif
+ ], [AC_MSG_RESULT([yes])], [AC_MSG_RESULT([buggy but acceptable])]),
+ [AC_MSG_RESULT([no]); have_gmp=no])
+ fi
+
+ # Check for the MPC header version.
+ if test x"$have_mpc" != xyes ; then
+ CFLAGS="$CFLAGS $mpcinc"
+ AC_MSG_CHECKING([for the correct version of mpc.h])
+ AC_TRY_COMPILE([#include <mpc.h>],[
+ #if MPC_VERSION < MPC_VERSION_NUM (0,6,0)
+ choke me
+ #endif
+ ], [AC_MSG_RESULT([yes]); have_mpc=maybe],
+ [AC_MSG_RESULT([no]); have_mpc=no; mpclibs= ; mpcinc= ])
+ fi
+
+ # Now check the MPFR library.
+ if test x"$have_gmp" = xyes; then
+ saved_LIBS="$LIBS"
+ LIBS="$LIBS $gmplibs"
+ AC_MSG_CHECKING([for the correct version of the gmp/mpfr libraries])
+ AC_TRY_LINK([#include <gmp.h>
+ #include <mpfr.h>],[
mpfr_t n;
mpfr_t x;
int t;
@@ -1292,16 +1353,36 @@ if test -d ${srcdir}/gcc && test "x$have_gmp" = xno; then
mpfr_atan2 (n, n, x, GMP_RNDN);
mpfr_erfc (n, x, GMP_RNDN);
mpfr_subnormalize (x, t, GMP_RNDN);
- ], [AC_TRY_LINK([#include <gmp.h>
- #include <mpfr.h>],[
- #if MPFR_VERSION < MPFR_VERSION_NUM(2,3,2)
- choke me
- #endif
- mpfr_t n; mpfr_init(n);
- ], [AC_MSG_RESULT([yes])], [AC_MSG_RESULT([buggy but acceptable])])],
- [AC_MSG_RESULT([no]); have_gmp=no])
- LIBS="$saved_LIBS"
+ ], [AC_MSG_RESULT([yes])], [AC_MSG_RESULT([no]); have_gmp=no])
+ LIBS="$saved_LIBS"
+ fi
+
+ if test x"$have_mpc" = xmaybe; then
+ saved_LIBS="$LIBS"
+ LIBS="$LIBS $mpclibs $gmplibs"
+ AC_MSG_CHECKING([for the correct version of the mpc library])
+ AC_TRY_LINK([#include <mpc.h>],[
+ mpc_t n;
+ mpc_init2 (n, 53);
+ mpc_set_ui_ui (n, 1, 1, MPC_RNDNN);
+ mpc_sin (n, n, MPC_RNDNN);
+ mpc_cos (n, n, MPC_RNDNN);
+ mpc_tan (n, n, MPC_RNDNN);
+ mpc_sinh (n, n, MPC_RNDNN);
+ mpc_cosh (n, n, MPC_RNDNN);
+ mpc_tanh (n, n, MPC_RNDNN);
+ mpc_exp (n, n, MPC_RNDNN);
+ mpc_log (n, n, MPC_RNDNN);
+ mpc_sqrt (n, n, MPC_RNDNN);
+ mpc_proj (n, n, MPC_RNDNN);
+ mpc_neg (n, n, MPC_RNDNN);
+ mpc_sqr (n, n, MPC_RNDNN);
+ mpc_clear (n);
+ ], [AC_MSG_RESULT([yes]); have_mpc=yes],
+ [AC_MSG_RESULT([no]); have_mpc=no; mpclibs= ; mpcinc= ])
+ LIBS="$saved_LIBS"
fi
+
CFLAGS="$saved_CFLAGS"
if test x$have_gmp != xyes; then
@@ -1316,10 +1397,20 @@ They may be located in separate packages.])
fi
fi
-# Flags needed for both GMP and/or MPFR
+if test x$have_mpc != xyes ; then
+ mpcinc=
+ mpclibs=
+fi
+
+gmpinc="$mpcinc $gmpinc"
+gmplibs="$mpclibs $gmplibs"
+
+# Flags needed for both GMP, MPFR and/or MPC.
AC_SUBST(gmplibs)
AC_SUBST(gmpinc)
AC_SUBST(extra_mpfr_configure_flags)
+AC_SUBST(extra_mpc_gmp_configure_flags)
+AC_SUBST(extra_mpc_mpfr_configure_flags)
# Allow host libstdc++ to be specified for static linking with PPL.
AC_ARG_WITH(host-libstdcxx, [ --with-host-libstdcxx=L Use linker arguments L to link with libstdc++
diff --git a/contrib/ChangeLog b/contrib/ChangeLog
index 6ab29eb71d9..072c904b067 100644
--- a/contrib/ChangeLog
+++ b/contrib/ChangeLog
@@ -1,3 +1,7 @@
+2009-06-02 Alexandre Oliva <aoliva@redhat.com>
+
+ * compare-debug: Don't fail just because of .eh_frame differences.
+
2009-04-27 Jakub Jelinek <jakub@redhat.com>
PR testsuite/39807
diff --git a/fixincludes/ChangeLog b/fixincludes/ChangeLog
index a31631df12f..9bdd28d3641 100644
--- a/fixincludes/ChangeLog
+++ b/fixincludes/ChangeLog
@@ -1,3 +1,24 @@
+2009-06-09 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+
+ * inclhack.def (darwin_stdint_1, darwin_stdint_2, darwin_stdint_3,
+ darwin_stdint_4): New fixes.
+ * tests/base/stdint.h: Adjust test results for new fixes.
+ * fixincl.x: Regenerate.
+
+2009-05-29 Eric Botcazou <ebotcazou@adacore.com>
+
+ * inclhack.def (solaris_int_const): New fix.
+ (solaris_int_limits_1): Likewise.
+ (solaris_int_limits_2): Likewise.
+ * fixincl.x: Regenerate.
+ * tests/base/sys/int_const.h: New file.
+ * tests/base/sys/int_limits.h: Likewise.
+
+2009-05-15 Joseph Myers <joseph@codesourcery.com>
+
+ * inclhack.def (glibc_tgmath): Correct bypass.
+ * fixincl.x: Regenerate.
+
2009-04-28 Steve Ellcey <sje@cup.hp.com>
* inclhack.def (hpux11_uint32_c): Remove.
diff --git a/fixincludes/fixincl.x b/fixincludes/fixincl.x
index d8d1fc7dd6e..433740f3028 100644
--- a/fixincludes/fixincl.x
+++ b/fixincludes/fixincl.x
@@ -2,11 +2,11 @@
*
* DO NOT EDIT THIS FILE (fixincl.x)
*
- * It has been AutoGen-ed Tuesday April 28, 2009 at 08:26:48 AM PDT
+ * It has been AutoGen-ed Monday June 8, 2009 at 08:37:38 PM CEST
* From the definitions inclhack.def
* and the template file fixincl
*/
-/* DO NOT SVN-MERGE THIS FILE, EITHER Tue Apr 28 08:26:48 PDT 2009
+/* DO NOT SVN-MERGE THIS FILE, EITHER Mon Jun 8 20:37:38 CEST 2009
*
* You must regenerate it. Use the ./genfixes script.
*
@@ -15,7 +15,7 @@
* certain ANSI-incompatible system header files which are fixed to work
* correctly with ANSI C and placed in a directory that GNU C will search.
*
- * This file contains 188 fixup descriptions.
+ * This file contains 195 fixup descriptions.
*
* See README for more information.
*
@@ -1787,6 +1787,184 @@ static const char* apzDarwin_Private_ExternPatch[] = {
/* * * * * * * * * * * * * * * * * * * * * * * * * *
*
+ * Description of Darwin_Stdint_1 fix
+ */
+tSCC zDarwin_Stdint_1Name[] =
+ "darwin_stdint_1";
+
+/*
+ * File name selection pattern
+ */
+tSCC zDarwin_Stdint_1List[] =
+ "stdint.h\0";
+/*
+ * Machine/OS name selection pattern
+ */
+tSCC* apzDarwin_Stdint_1Machs[] = {
+ "*-*-darwin*",
+ (const char*)NULL };
+
+/*
+ * content selection pattern - do fix if pattern found
+ */
+tSCC zDarwin_Stdint_1Select0[] =
+ "#define UINT8_C\\(v\\)[ \t]+\\(v ## U\\)\n\
+#define UINT16_C\\(v\\)[ \t]+\\(v ## U\\)";
+
+#define DARWIN_STDINT_1_TEST_CT 1
+static tTestDesc aDarwin_Stdint_1Tests[] = {
+ { TT_EGREP, zDarwin_Stdint_1Select0, (regex_t*)NULL }, };
+
+/*
+ * Fix Command Arguments for Darwin_Stdint_1
+ */
+static const char* apzDarwin_Stdint_1Patch[] = {
+ "format",
+ "#define UINT8_C(v)\tv\n\
+#define UINT16_C(v)\tv",
+ (char*)NULL };
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * Description of Darwin_Stdint_2 fix
+ */
+tSCC zDarwin_Stdint_2Name[] =
+ "darwin_stdint_2";
+
+/*
+ * File name selection pattern
+ */
+tSCC zDarwin_Stdint_2List[] =
+ "stdint.h\0";
+/*
+ * Machine/OS name selection pattern
+ */
+tSCC* apzDarwin_Stdint_2Machs[] = {
+ "*-*-darwin*",
+ (const char*)NULL };
+
+/*
+ * content selection pattern - do fix if pattern found
+ */
+tSCC zDarwin_Stdint_2Select0[] =
+ "#if __WORDSIZE == 64\n\
+#define INTPTR_MIN[ \t]+INT64_MIN\n\
+#define INTPTR_MAX[ \t]+INT64_MAX\n\
+#else\n\
+#define INTPTR_MIN[ \t]+INT32_MIN\n\
+#define INTPTR_MAX[ \t]+INT32_MAX\n\
+#endif";
+
+#define DARWIN_STDINT_2_TEST_CT 1
+static tTestDesc aDarwin_Stdint_2Tests[] = {
+ { TT_EGREP, zDarwin_Stdint_2Select0, (regex_t*)NULL }, };
+
+/*
+ * Fix Command Arguments for Darwin_Stdint_2
+ */
+static const char* apzDarwin_Stdint_2Patch[] = {
+ "format",
+ "#if __WORDSIZE == 64\n\
+#define INTPTR_MAX 9223372036854775807L\n\
+#define INTPTR_MIN (-INTPTR_MAX-1)\n\
+#else\n\
+#define INTPTR_MAX 2147483647L\n\
+#define INTPTR_MIN (-INTPTR_MAX-1)\n\
+#endif",
+ (char*)NULL };
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * Description of Darwin_Stdint_3 fix
+ */
+tSCC zDarwin_Stdint_3Name[] =
+ "darwin_stdint_3";
+
+/*
+ * File name selection pattern
+ */
+tSCC zDarwin_Stdint_3List[] =
+ "stdint.h\0";
+/*
+ * Machine/OS name selection pattern
+ */
+tSCC* apzDarwin_Stdint_3Machs[] = {
+ "*-*-darwin*",
+ (const char*)NULL };
+
+/*
+ * content selection pattern - do fix if pattern found
+ */
+tSCC zDarwin_Stdint_3Select0[] =
+ "#if __WORDSIZE == 64\n\
+#define UINTPTR_MAX[ \t]+UINT64_MAX\n\
+#else\n\
+#define UINTPTR_MAX[ \t]+UINT32_MAX\n\
+#endif";
+
+#define DARWIN_STDINT_3_TEST_CT 1
+static tTestDesc aDarwin_Stdint_3Tests[] = {
+ { TT_EGREP, zDarwin_Stdint_3Select0, (regex_t*)NULL }, };
+
+/*
+ * Fix Command Arguments for Darwin_Stdint_3
+ */
+static const char* apzDarwin_Stdint_3Patch[] = {
+ "format",
+ "#if __WORDSIZE == 64\n\
+#define UINTPTR_MAX 18446744073709551615UL\n\
+#else\n\
+#define UINTPTR_MAX 4294967295UL\n\
+#endif",
+ (char*)NULL };
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * Description of Darwin_Stdint_4 fix
+ */
+tSCC zDarwin_Stdint_4Name[] =
+ "darwin_stdint_4";
+
+/*
+ * File name selection pattern
+ */
+tSCC zDarwin_Stdint_4List[] =
+ "stdint.h\0";
+/*
+ * Machine/OS name selection pattern
+ */
+tSCC* apzDarwin_Stdint_4Machs[] = {
+ "*-*-darwin*",
+ (const char*)NULL };
+
+/*
+ * content selection pattern - do fix if pattern found
+ */
+tSCC zDarwin_Stdint_4Select0[] =
+ "#if __WORDSIZE == 64\n\
+#define SIZE_MAX[ \t]+UINT64_MAX\n\
+#else\n\
+#define SIZE_MAX[ \t]+UINT32_MAX\n\
+#endif";
+
+#define DARWIN_STDINT_4_TEST_CT 1
+static tTestDesc aDarwin_Stdint_4Tests[] = {
+ { TT_EGREP, zDarwin_Stdint_4Select0, (regex_t*)NULL }, };
+
+/*
+ * Fix Command Arguments for Darwin_Stdint_4
+ */
+static const char* apzDarwin_Stdint_4Patch[] = {
+ "format",
+ "#if __WORDSIZE == 64\n\
+#define SIZE_MAX 18446744073709551615UL\n\
+#else\n\
+#define SIZE_MAX 4294967295UL\n\
+#endif",
+ (char*)NULL };
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
* Description of Dec_Intern_Asm fix
*/
tSCC zDec_Intern_AsmName[] =
@@ -2282,7 +2460,7 @@ tSCC zGlibc_TgmathSelect0[] =
* content bypass pattern - skip fix if pattern found
*/
tSCC zGlibc_TgmathBypass0[] =
- "__floating_type \\\\\n\
+ "__floating_type\\(type\\) \\\\\n\
.*__builtin_classify_type";
#define GLIBC_TGMATH_TEST_CT 2
@@ -6081,6 +6259,120 @@ static const char* apzSolaris_Once_Init_2Patch[] = {
/* * * * * * * * * * * * * * * * * * * * * * * * * *
*
+ * Description of Solaris_Int_Const fix
+ */
+tSCC zSolaris_Int_ConstName[] =
+ "solaris_int_const";
+
+/*
+ * File name selection pattern
+ */
+tSCC zSolaris_Int_ConstList[] =
+ "sys/int_const.h\0";
+/*
+ * Machine/OS name selection pattern
+ */
+#define apzSolaris_Int_ConstMachs (const char**)NULL
+
+/*
+ * content selection pattern - do fix if pattern found
+ */
+tSCC zSolaris_Int_ConstSelect0[] =
+ "@\\(#\\)int_const.h[ \t]+1.[0-9]+[ \t]+[0-9/]+ SMI";
+
+#define SOLARIS_INT_CONST_TEST_CT 1
+static tTestDesc aSolaris_Int_ConstTests[] = {
+ { TT_EGREP, zSolaris_Int_ConstSelect0, (regex_t*)NULL }, };
+
+/*
+ * Fix Command Arguments for Solaris_Int_Const
+ */
+static const char* apzSolaris_Int_ConstPatch[] = {
+ "format",
+ "#define\tUINT8_C(c)\t(c)\n\
+%1\n\
+#define\tUINT16_C(c)\t(c)",
+ "^#define[ \t]+UINT8_C\\(c\\)[ \t]+__CONCAT__.*\n\
+(/*.**/)\n\
+#define[ \t]+UINT16_C\\(c\\)[ \t]+__CONCAT__.*",
+ (char*)NULL };
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * Description of Solaris_Int_Limits_1 fix
+ */
+tSCC zSolaris_Int_Limits_1Name[] =
+ "solaris_int_limits_1";
+
+/*
+ * File name selection pattern
+ */
+tSCC zSolaris_Int_Limits_1List[] =
+ "sys/int_limits.h\0";
+/*
+ * Machine/OS name selection pattern
+ */
+#define apzSolaris_Int_Limits_1Machs (const char**)NULL
+
+/*
+ * content selection pattern - do fix if pattern found
+ */
+tSCC zSolaris_Int_Limits_1Select0[] =
+ "@\\(#\\)int_limits.h[ \t]+1.[0-9]+[ \t]+[0-9/]+ SMI";
+
+#define SOLARIS_INT_LIMITS_1_TEST_CT 1
+static tTestDesc aSolaris_Int_Limits_1Tests[] = {
+ { TT_EGREP, zSolaris_Int_Limits_1Select0, (regex_t*)NULL }, };
+
+/*
+ * Fix Command Arguments for Solaris_Int_Limits_1
+ */
+static const char* apzSolaris_Int_Limits_1Patch[] = {
+ "format",
+ "#define\tUINT8_MAX\t(255)\n\
+#define\tUINT16_MAX\t(65535)",
+ "^#define[ \t]+UINT8_MAX[ \t]+\\(255U\\)\n\
+#define[ \t]+UINT16_MAX[ \t]+\\(65535U\\)",
+ (char*)NULL };
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * Description of Solaris_Int_Limits_2 fix
+ */
+tSCC zSolaris_Int_Limits_2Name[] =
+ "solaris_int_limits_2";
+
+/*
+ * File name selection pattern
+ */
+tSCC zSolaris_Int_Limits_2List[] =
+ "sys/int_limits.h\0";
+/*
+ * Machine/OS name selection pattern
+ */
+#define apzSolaris_Int_Limits_2Machs (const char**)NULL
+
+/*
+ * content selection pattern - do fix if pattern found
+ */
+tSCC zSolaris_Int_Limits_2Select0[] =
+ "@\\(#\\)int_limits.h[ \t]+1.[0-9]+[ \t]+[0-9/]+ SMI";
+
+#define SOLARIS_INT_LIMITS_2_TEST_CT 1
+static tTestDesc aSolaris_Int_Limits_2Tests[] = {
+ { TT_EGREP, zSolaris_Int_Limits_2Select0, (regex_t*)NULL }, };
+
+/*
+ * Fix Command Arguments for Solaris_Int_Limits_2
+ */
+static const char* apzSolaris_Int_Limits_2Patch[] = {
+ "format",
+ "#define\t%1_FAST16_%2 %132_%2",
+ "^#define[ \t]+(INT|UINT)_FAST16_(MAX|MIN)[ \t](INT|UINT)16.*",
+ (char*)NULL };
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
* Description of Solaris_Stdio_Tag fix
*/
tSCC zSolaris_Stdio_TagName[] =
@@ -7619,9 +7911,9 @@ static const char* apzX11_SprintfPatch[] = {
*
* List of all fixes
*/
-#define REGEX_COUNT 230
+#define REGEX_COUNT 237
#define MACH_LIST_SIZE_LIMIT 181
-#define FIX_COUNT 188
+#define FIX_COUNT 195
/*
* Enumerate the fixes
@@ -7669,6 +7961,10 @@ typedef enum {
DARWIN_EXTERNC_FIXIDX,
DARWIN_GCC4_BREAKAGE_FIXIDX,
DARWIN_PRIVATE_EXTERN_FIXIDX,
+ DARWIN_STDINT_1_FIXIDX,
+ DARWIN_STDINT_2_FIXIDX,
+ DARWIN_STDINT_3_FIXIDX,
+ DARWIN_STDINT_4_FIXIDX,
DEC_INTERN_ASM_FIXIDX,
DJGPP_WCHAR_H_FIXIDX,
ECD_CURSOR_FIXIDX,
@@ -7777,6 +8073,9 @@ typedef enum {
SOLARIS_RWLOCK_INIT_1_FIXIDX,
SOLARIS_ONCE_INIT_1_FIXIDX,
SOLARIS_ONCE_INIT_2_FIXIDX,
+ SOLARIS_INT_CONST_FIXIDX,
+ SOLARIS_INT_LIMITS_1_FIXIDX,
+ SOLARIS_INT_LIMITS_2_FIXIDX,
SOLARIS_STDIO_TAG_FIXIDX,
STATSSWTCH_FIXIDX,
STDIO_STDARG_H_FIXIDX,
@@ -8028,6 +8327,26 @@ tFixDesc fixDescList[ FIX_COUNT ] = {
DARWIN_PRIVATE_EXTERN_TEST_CT, FD_MACH_ONLY | FD_SUBROUTINE,
aDarwin_Private_ExternTests, apzDarwin_Private_ExternPatch, 0 },
+ { zDarwin_Stdint_1Name, zDarwin_Stdint_1List,
+ apzDarwin_Stdint_1Machs,
+ DARWIN_STDINT_1_TEST_CT, FD_MACH_ONLY | FD_SUBROUTINE,
+ aDarwin_Stdint_1Tests, apzDarwin_Stdint_1Patch, 0 },
+
+ { zDarwin_Stdint_2Name, zDarwin_Stdint_2List,
+ apzDarwin_Stdint_2Machs,
+ DARWIN_STDINT_2_TEST_CT, FD_MACH_ONLY | FD_SUBROUTINE,
+ aDarwin_Stdint_2Tests, apzDarwin_Stdint_2Patch, 0 },
+
+ { zDarwin_Stdint_3Name, zDarwin_Stdint_3List,
+ apzDarwin_Stdint_3Machs,
+ DARWIN_STDINT_3_TEST_CT, FD_MACH_ONLY | FD_SUBROUTINE,
+ aDarwin_Stdint_3Tests, apzDarwin_Stdint_3Patch, 0 },
+
+ { zDarwin_Stdint_4Name, zDarwin_Stdint_4List,
+ apzDarwin_Stdint_4Machs,
+ DARWIN_STDINT_4_TEST_CT, FD_MACH_ONLY | FD_SUBROUTINE,
+ aDarwin_Stdint_4Tests, apzDarwin_Stdint_4Patch, 0 },
+
{ zDec_Intern_AsmName, zDec_Intern_AsmList,
apzDec_Intern_AsmMachs,
DEC_INTERN_ASM_TEST_CT, FD_MACH_ONLY,
@@ -8568,6 +8887,21 @@ tFixDesc fixDescList[ FIX_COUNT ] = {
SOLARIS_ONCE_INIT_2_TEST_CT, FD_MACH_ONLY | FD_SUBROUTINE,
aSolaris_Once_Init_2Tests, apzSolaris_Once_Init_2Patch, 0 },
+ { zSolaris_Int_ConstName, zSolaris_Int_ConstList,
+ apzSolaris_Int_ConstMachs,
+ SOLARIS_INT_CONST_TEST_CT, FD_MACH_ONLY | FD_SUBROUTINE,
+ aSolaris_Int_ConstTests, apzSolaris_Int_ConstPatch, 0 },
+
+ { zSolaris_Int_Limits_1Name, zSolaris_Int_Limits_1List,
+ apzSolaris_Int_Limits_1Machs,
+ SOLARIS_INT_LIMITS_1_TEST_CT, FD_MACH_ONLY | FD_SUBROUTINE,
+ aSolaris_Int_Limits_1Tests, apzSolaris_Int_Limits_1Patch, 0 },
+
+ { zSolaris_Int_Limits_2Name, zSolaris_Int_Limits_2List,
+ apzSolaris_Int_Limits_2Machs,
+ SOLARIS_INT_LIMITS_2_TEST_CT, FD_MACH_ONLY | FD_SUBROUTINE,
+ aSolaris_Int_Limits_2Tests, apzSolaris_Int_Limits_2Patch, 0 },
+
{ zSolaris_Stdio_TagName, zSolaris_Stdio_TagList,
apzSolaris_Stdio_TagMachs,
SOLARIS_STDIO_TAG_TEST_CT, FD_MACH_ONLY,
diff --git a/fixincludes/inclhack.def b/fixincludes/inclhack.def
index f77845f77d2..f9845cc74f5 100644
--- a/fixincludes/inclhack.def
+++ b/fixincludes/inclhack.def
@@ -1023,6 +1023,108 @@ fix = {
/*
+ * Darwin headers have a stdint.h that defines UINT8_C and UINT16_C to
+ * unsigned constants.
+ */
+fix = {
+ hackname = darwin_stdint_1;
+ mach = "*-*-darwin*";
+ files = stdint.h;
+ c_fix = format;
+ c_fix_arg = "#define UINT8_C(v)\tv\n#define UINT16_C(v)\tv";
+ select = "#define UINT8_C\\(v\\)[ \t]+\\(v ## U\\)\n"
+ "#define UINT16_C\\(v\\)[ \t]+\\(v ## U\\)";
+ test_text = "#define UINT8_C(v) (v ## U)\n"
+ "#define UINT16_C(v) (v ## U)";
+};
+
+
+/*
+ * Darwin headers have a stdint.h that defines INTPTR_MIN and INTPTR_MAX
+ * with wrong types.
+ */
+fix = {
+ hackname = darwin_stdint_2;
+ mach = "*-*-darwin*";
+ files = stdint.h;
+ c_fix = format;
+ c_fix_arg = "#if __WORDSIZE == 64\n"
+ "#define INTPTR_MAX 9223372036854775807L\n"
+ "#define INTPTR_MIN (-INTPTR_MAX-1)\n"
+ "#else\n"
+ "#define INTPTR_MAX 2147483647L\n"
+ "#define INTPTR_MIN (-INTPTR_MAX-1)\n"
+ "#endif";
+ select = "#if __WORDSIZE == 64\n"
+ "#define INTPTR_MIN[ \t]+INT64_MIN\n"
+ "#define INTPTR_MAX[ \t]+INT64_MAX\n"
+ "#else\n"
+ "#define INTPTR_MIN[ \t]+INT32_MIN\n"
+ "#define INTPTR_MAX[ \t]+INT32_MAX\n"
+ "#endif";
+ test_text = "#if __WORDSIZE == 64\n"
+ "#define INTPTR_MIN INT64_MIN\n"
+ "#define INTPTR_MAX INT64_MAX\n"
+ "#else\n"
+ "#define INTPTR_MIN INT32_MIN\n"
+ "#define INTPTR_MAX INT32_MAX\n"
+ "#endif";
+};
+
+
+/*
+ * Darwin headers have a stdint.h that defines UINTPTR_MAX with a wrong type.
+ */
+fix = {
+ hackname = darwin_stdint_3;
+ mach = "*-*-darwin*";
+ files = stdint.h;
+ c_fix = format;
+ c_fix_arg = "#if __WORDSIZE == 64\n"
+ "#define UINTPTR_MAX 18446744073709551615UL\n"
+ "#else\n"
+ "#define UINTPTR_MAX 4294967295UL\n"
+ "#endif";
+ select = "#if __WORDSIZE == 64\n"
+ "#define UINTPTR_MAX[ \t]+UINT64_MAX\n"
+ "#else\n"
+ "#define UINTPTR_MAX[ \t]+UINT32_MAX\n"
+ "#endif";
+ test_text = "#if __WORDSIZE == 64\n"
+ "#define UINTPTR_MAX UINT64_MAX\n"
+ "#else\n"
+ "#define UINTPTR_MAX UINT32_MAX\n"
+ "#endif";
+};
+
+
+/*
+ * Darwin headers have a stdint.h that defines SIZE_MAX with a wrong type.
+ */
+fix = {
+ hackname = darwin_stdint_4;
+ mach = "*-*-darwin*";
+ files = stdint.h;
+ c_fix = format;
+ c_fix_arg = "#if __WORDSIZE == 64\n"
+ "#define SIZE_MAX 18446744073709551615UL\n"
+ "#else\n"
+ "#define SIZE_MAX 4294967295UL\n"
+ "#endif";
+ select = "#if __WORDSIZE == 64\n"
+ "#define SIZE_MAX[ \t]+UINT64_MAX\n"
+ "#else\n"
+ "#define SIZE_MAX[ \t]+UINT32_MAX\n"
+ "#endif";
+ test_text = "#if __WORDSIZE == 64\n"
+ "#define SIZE_MAX UINT64_MAX\n"
+ "#else\n"
+ "#define SIZE_MAX UINT32_MAX\n"
+ "#endif";
+};
+
+
+/*
* Fix <c_asm.h> on Digital UNIX V4.0:
* It contains a prototype for a DEC C internal asm() function,
* clashing with gcc's asm keyword. So protect this with __DECC.
@@ -1286,7 +1388,7 @@ fix = {
hackname = glibc_tgmath;
files = tgmath.h;
select = '\(\(\(type\) 0.25\) && \(\(type\) 0.25 - 1\)\)';
- bypass = "__floating_type \\\\\n.*__builtin_classify_type";
+ bypass = "__floating_type\\(type\\) \\\\\n.*__builtin_classify_type";
c_fix = format;
c_fix_arg = "(__builtin_classify_type ((type) 0) == 8 || (__builtin_classify_type ((type) 0) == 9 && __builtin_classify_type (__real__ ((type) 0)) == 8))";
test_text = "# define __floating_type(type) (((type) 0.25) && ((type) 0.25 - 1))";
@@ -3167,6 +3269,68 @@ fix = {
/*
+ * Sun Solaris 10 has a version of sys/int_const.h that defines
+ * UINT8_C and UINT16_C to unsigned constants.
+ */
+fix = {
+ hackname = solaris_int_const;
+ select = '@\(#\)int_const.h' "[ \t]+1.[0-9]+[ \t]+[0-9/]+ SMI";
+ files = sys/int_const.h;
+ c_fix = format;
+ c_fix_arg = "#define\tUINT8_C(c)\t(c)\n"
+ "%1\n"
+ "#define\tUINT16_C(c)\t(c)";
+ c_fix_arg = "^#define[ \t]+UINT8_C\\(c\\)[ \t]+__CONCAT__.*\n"
+ "(/\*.*\*/)\n"
+ "#define[ \t]+UINT16_C\\(c\\)[ \t]+__CONCAT__.*";
+ test_text =
+ '#pragma ident "@(#)int_const.h 1.5 04/09/28 SMI"'"\n"
+ "#define UINT8_C(c) __CONCAT__(c,u)\n"
+ "/* CSTYLED */\n"
+ "#define UINT16_C(c) __CONCAT__(c,u)";
+};
+
+
+/*
+ * Sun Solaris 10 has a version of sys/int_limits.h that defines
+ * UINT8_MAX and UINT16_MAX to unsigned constants.
+ */
+fix = {
+ hackname = solaris_int_limits_1;
+ select = '@\(#\)int_limits.h' "[ \t]+1.[0-9]+[ \t]+[0-9/]+ SMI";
+ files = sys/int_limits.h;
+ c_fix = format;
+ c_fix_arg = "#define\tUINT8_MAX\t(255)\n"
+ "#define\tUINT16_MAX\t(65535)";
+ c_fix_arg = "^#define[ \t]+UINT8_MAX[ \t]+\\(255U\\)\n"
+ "#define[ \t]+UINT16_MAX[ \t]+\\(65535U\\)";
+ test_text =
+ '#pragma ident "@(#)int_limits.h 1.9 04/09/28 SMI"'"\n"
+ "#define UINT8_MAX (255U)\n"
+ "#define UINT16_MAX (65535U)";
+};
+
+
+/*
+ * Sun Solaris 10 has a version of sys/int_limits.h that defines
+ * INT_FAST16 limits to wrong values for sys/int_types.h.
+ */
+fix = {
+ hackname = solaris_int_limits_2;
+ select = '@\(#\)int_limits.h' "[ \t]+1.[0-9]+[ \t]+[0-9/]+ SMI";
+ files = sys/int_limits.h;
+ c_fix = format;
+ c_fix_arg = "#define\t%1_FAST16_%2 %132_%2";
+ c_fix_arg = "^#define[ \t]+(INT|UINT)_FAST16_(MAX|MIN)[ \t](INT|UINT)16.*";
+ test_text =
+ '#pragma ident "@(#)int_limits.h 1.9 04/09/28 SMI"'"\n"
+ "#define INT_FAST16_MAX INT16_MAX\n"
+ "#define UINT_FAST16_MAX UINT16_MAX\n"
+ "#define INT_FAST16_MIN INT16_MIN";
+};
+
+
+/*
* Solaris 2.8 has what appears to be some gross workaround for
* some old version of their c++ compiler. G++ doesn't want it
* either, but doesn't want to be tied to SunPRO version numbers.
diff --git a/fixincludes/tests/base/stdint.h b/fixincludes/tests/base/stdint.h
index 653c5da69e8..35039db4f2b 100644
--- a/fixincludes/tests/base/stdint.h
+++ b/fixincludes/tests/base/stdint.h
@@ -9,6 +9,41 @@
+#if defined( DARWIN_STDINT_1_CHECK )
+#define UINT8_C(c) __UINT8_C(c)
+#define UINT16_C(c) __UINT16_C(c)
+#endif /* DARWIN_STDINT_1_CHECK */
+
+
+#if defined( DARWIN_STDINT_2_CHECK )
+#if __WORDSIZE == 64
+#define INTPTR_MAX 9223372036854775807L
+#define INTPTR_MIN (-INTPTR_MAX-1)
+#else
+#define INTPTR_MAX 2147483647L
+#define INTPTR_MIN (-INTPTR_MAX-1)
+#endif
+#endif /* DARWIN_STDINT_2_CHECK */
+
+
+#if defined( DARWIN_STDINT_3_CHECK )
+#if __WORDSIZE == 64
+#define UINTPTR_MAX 18446744073709551615UL
+#else
+#define UINTPTR_MAX 4294967295UL
+#endif
+#endif /* DARWIN_STDINT_3_CHECK */
+
+
+#if defined( DARWIN_STDINT_4_CHECK )
+#if __WORDSIZE == 64
+#define SIZE_MAX __SIZE_MAX__
+#else
+#define SIZE_MAX __SIZE_MAX__
+#endif
+#endif /* DARWIN_STDINT_4_CHECK */
+
+
#if defined( GLIBC_STDINT_CHECK )
/* This file is part of the GNU C Library. */
# define UINT8_C(c) c
diff --git a/fixincludes/tests/base/sys/int_const.h b/fixincludes/tests/base/sys/int_const.h
new file mode 100644
index 00000000000..7aeb52a79ce
--- /dev/null
+++ b/fixincludes/tests/base/sys/int_const.h
@@ -0,0 +1,17 @@
+/* DO NOT EDIT THIS FILE.
+
+ It has been auto-edited by fixincludes from:
+
+ "fixinc/tests/inc/sys/int_const.h"
+
+ This had to be done to correct non-standard usages in the
+ original, manufacturer supplied header file. */
+
+
+
+#if defined( SOLARIS_INT_CONST_CHECK )
+#pragma ident "@(#)int_const.h 1.5 04/09/28 SMI"
+#define UINT8_C(c) (c)
+/* CSTYLED */
+#define UINT16_C(c) (c)
+#endif /* SOLARIS_INT_CONST_CHECK */
diff --git a/fixincludes/tests/base/sys/int_limits.h b/fixincludes/tests/base/sys/int_limits.h
new file mode 100644
index 00000000000..19acbe50a46
--- /dev/null
+++ b/fixincludes/tests/base/sys/int_limits.h
@@ -0,0 +1,24 @@
+/* DO NOT EDIT THIS FILE.
+
+ It has been auto-edited by fixincludes from:
+
+ "fixinc/tests/inc/sys/int_limits.h"
+
+ This had to be done to correct non-standard usages in the
+ original, manufacturer supplied header file. */
+
+
+
+#if defined( SOLARIS_INT_LIMITS_1_CHECK )
+#pragma ident "@(#)int_limits.h 1.9 04/09/28 SMI"
+#define UINT8_MAX (255)
+#define UINT16_MAX (65535)
+#endif /* SOLARIS_INT_LIMITS_1_CHECK */
+
+
+#if defined( SOLARIS_INT_LIMITS_2_CHECK )
+#pragma ident "@(#)int_limits.h 1.9 04/09/28 SMI"
+#define INT_FAST16_MAX INT32_MAX
+#define UINT_FAST16_MAX UINT32_MAX
+#define INT_FAST16_MIN INT32_MIN
+#endif /* SOLARIS_INT_LIMITS_2_CHECK */
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b19e57cf188..0b736d6b81d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,4 +1,821 @@
-2009-06-11 Jakub Jelinek <jakub@redhat.com>
+2009-06-16 J"orn Rennecke <joern.rennecke@arc.com>
+ Janis Johnson <janis187@us.ibm.com>
+
+ PR target/39254
+ * config/rs6000/rs6000.c (rs6000_emit_move): Don't emit a USE
+ for the symbol ref of a constant that is the source of a move
+ - nor for any other not-obvious-label-ref constants.
+
+2009-06-16 Olatunji Ruwase <tjruwase@google.com>
+
+ * plugin.c(position_pass): Skip newly inserted pass during list
+ traversal to avoid repeated insertion.
+
+2009-06-16 Ian Lance Taylor <iant@google.com>
+
+ * vec.h (VEC_stack_alloc): Define different version if
+ GATHER_STATISTICS is defined, to accept and ignore MEM_STAT.
+ (DEF_VEC_ALLOC_FUNC_P_STACK): Remove MEM_STAT_DECL.
+ (DEF_VEC_ALLOC_FUNC_O_STACK): Likewise.
+ (DEF_VEC_ALLOC_FUNC_I_STACK): Likewise.
+
+2009-06-16 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config.gcc (extra_headers): Add ia32intrin.h for x86.
+
+ * config/i386/i386.c (ix86_builtins): Add IX86_BUILTIN_BSRSI,
+ IX86_BUILTIN_BSRDI. IX86_BUILTIN_RDPMC, IX86_BUILTIN_RDTSC.
+ IX86_BUILTIN_RDTSCP. IX86_BUILTIN_ROLQI, IX86_BUILTIN_ROLHI,
+ IX86_BUILTIN_RORQI and IX86_BUILTIN_RORHI.
+ (ix86_special_builtin_type): Add UINT64_FTYPE_VOID,
+ UINT64_FTYPE_PINT, INT_FTYPE_INT, UINT64_FTYPE_INT,
+ INT64_FTYPE_INT64, UINT16_FTYPE_UINT16_INT and
+ UINT8_FTYPE_UINT8_INT
+ (bdesc_special_args): Add __builtin_ia32_rdtsc and
+ __builtin_ia32_rdtscp.
+ (bdesc_args): Add __builtin_ia32_bsrsi, __builtin_ia32_bsrdi,
+ __builtin_ia32_rolqi, __builtin_ia32_rolhi, __builtin_ia32_rorqi
+ and __builtin_ia32_rorhi,
+ (ix86_init_mmx_sse_builtins): Handle UINT64_FTYPE_VOID,
+ UINT64_FTYPE_PINT, INT_FTYPE_INT, UINT64_FTYPE_INT,
+ INT64_FTYPE_INT64, UINT16_FTYPE_UINT16_INT and
+ UINT8_FTYPE_UINT8_INT.
+ (ix86_expand_args_builtin): Likewise.
+ (ix86_expand_special_args_builtin): Likewise.
+
+ * config/i386/i386.md (UNSPECV_RDTSCP): New.
+ (UNSPECV_RDTSC): Likewise.
+ (UNSPECV_RDPMC): Likewise.
+ (*bsr): Removed to ...
+ (bsr): This
+ (*bsr_rex64): Removed to ...
+ (bsr_rex64): This.
+ (rdpmc): New.
+ (*rdpmc): Likewise.
+ (*rdpmc_rex64): Likewise.
+ (rdtsc): Likewise.
+ (*rdtsc): Likewise.
+ (*rdtsc_rex64): Likewise.
+ (rdtscp): Likewise.
+ (*rdtscp): Likewise.
+ (*rdtscp_rex64): Likewise.
+
+ * config/i386/ia32intrin.h: New.
+
+ * config/i386/x86intrin.h: Include <ia32intrin.h>.
+
+2009-06-16 Ian Lance Taylor <iant@google.com>
+
+ * ira-build.c (copy_info_to_removed_store_destinations):
+ Initialize parent_a.
+
+2009-06-16 Ian Lance Taylor <iant@google.com>
+
+ * c-decl.c (grokdeclarator): Change size_varies to bool.
+
+2009-06-16 Ian Lance Taylor <iant@google.com>
+
+ * sel-sched.c: Make forward declarations of move_op_hooks and
+ fur_hooks explicitly extern.
+
+2009-06-16 Ian Lance Taylor <iant@google.com>
+
+ * df-problems.c (df_byte_lr_alloc): Don't set problem_data to
+ itself.
+ * vec.c (vec_gc_o_reserve_1): Don't set alloc to itself.
+
+2009-06-16 Ian Lance Taylor <iant@google.com>
+
+ * resource.c (mark_referenced_resources): Change
+ include_delayed_effects parameter to bool. Change all callers.
+ (mark_end_of_function_resources): Likewise.
+ * reorg.c (insn_references_resource_p): Likewise.
+ (insn_sets_resource_p): Likewise.
+ * resource.h (mark_referenced_resources): Update declaration.
+ (mark_end_of_function_resources): Update declaration.
+
+2009-06-16 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/aix.h (LIBSTDCXX_STATIC): Remove -lstdc++.
+
+2009-06-16 David Edelsohn <edelsohn@gnu.org>
+
+ * doc/install.texi (*-*-aix): Update explanation of XLC bootstrap.
+ GCC can bootstrap on AIX with GNU Binutils 2.20.
+
+2009-06-16 Ian Lance Taylor <iant@google.com>
+
+ * Makefile.in (tree-vect-stmts.o): Depend upon $(TOPLEV_H).
+
+2009-06-16 Ian Lance Taylor <iant@google.com>
+
+ * toplev.h (floor_log2): If GCC_VERSION >= 3004, declare as static
+ inline, not extern inline.
+ (exact_log2): Likewise.
+ * toplev.c (floor_log2): Only define if GCC_VERSION < 3004. Don't
+ test CLZ_HWI.
+ (exact_log2): Likewise, but don't test CTZ_HWI.
+
+2009-06-16 Ian Lance Taylor <iant@google.com>
+
+ * bitmap.c (bitmap_clear): Don't declare as inline.
+ * gimple.c (gimplify_assign): Likewise.
+ * tree-ssa-sccvn.c (vn_nary_op_compute_hash): Likewise.
+ * haifa-sched.c (insn_cost): Don't declare with HAIFA_INLINE.
+ (sched_scan_info): Remove duplicate definition.
+
+2009-06-16 Ian Lance Taylor <iant@google.com>
+
+ * c-common.c (skip_evaluation): Don't define.
+ (c_inhibit_evaluation_warnings): Define global variable.
+ (overflow_warning): Check c_inhibit_evaluation_warnings rather
+ than skip_evaluation.
+ (convert_and_check, warn_for_div_by_zero): Likewise.
+ * c-common.h (skip_evaluation): Don't declare.
+ (c_inhibit_evaluation_warnings): Declare.
+ * c-parser.c (c_parser_typeof_specifier): Set
+ c_inhibit_evaluation_warnings rather than skip_evaluation.
+ (c_parser_conditional_expression): Likewise.
+ (c_parser_binary_expression): Likewise.
+ (c_parser_sizeof_expression): Likewise.
+ (c_parser_alignof_expression): Likewise.
+ * c-typeck.c (build_indirect_ref): Check
+ c_inhibit_evaluation_warnings rather than skip_evaluation.
+ (build_conditional_expr, build_binary_op): Likewise.
+
+2009-06-16 Richard Guenther <rguenther@suse.de>
+
+ * tree-ssa-alias.c (is_escape_site): Remove.
+ * tree-ssa-alias.h (enum escape_type): Remove.
+ (is_escape_site): Likewise.
+ * tree-ssa-structalias.c (find_func_aliases): Handle escapes
+ via casts and asms without deferring to is_escape_site.
+
+2009-06-16 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/40446
+ * expr.c (expand_expr_real_1) <case VIEW_CONVERT_EXPR>: Don't
+ use gen_lowpart if op0 has complex mode.
+
+2009-06-16 Richard Guenther <rguenther@suse.de>
+
+ * tree-ssa-structalias.c (do_ds_constraint): Stores in global
+ variables add them to ESCAPED.
+ (find_func_aliases): Do not make all indirectly stored values
+ escaped.
+
+2009-06-16 Rafael Avila de Espindola <espindola@google.com>
+
+ * config/i386/winnt.c (i386_pe_encode_section_info): Update call to
+ make_decl_one_only.
+
+2009-06-16 Martin Jambor <mjambor@suse.cz>
+
+ PR tree-optimization/40432
+ * tree-sra.c (sra_modify_assign): When creating VIEW_CONVERT_EXPR,
+ check whether we need to force gimple register operand.
+
+2009-06-16 Martin Jambor <mjambor@suse.cz>
+
+ PR tree-optimization/40413
+ * tree-sra.c (load_assign_lhs_subreplacements): Pass offset to
+ build_ref_for_offset.
+ (propagate_subacesses_accross_link): Fix a typo in a comment.
+
+2009-06-16 Ira Rosen <irar@il.ibm.com>
+
+ * tree-parloops.c (loop_parallel_p): Call vect_is_simple_reduction
+ with additional parameter.
+ * tree-vectorizer.h (enum vect_def_type): Add new value
+ vect_nested_cycle.
+ (enum vect_relevant): Add comments.
+ (vect_is_simple_reduction): Add new argument.
+ * tree-vect-loop.c (vect_analyze_scalar_cycles_1): Add comments.
+ Detect nested cycles.
+ (vect_is_simple_reduction): Update documentation, add an argument to
+ distinguish inner-loop reduction from nested cycle, detect nested
+ cycles, fix printings and indentation, don't swap operands in case
+ of nested cycle.
+ (get_initial_def_for_reduction): Handle subtraction.
+ (vect_create_epilog_for_reduction): Add new argument to specify
+ reduction variable.
+ (vect_finalize_reduction): Handle subtraction, fix comments.
+ (vectorizable_reduction): Handle nested cycles. In case of nested cycle
+ keep track of the reduction variable position. Call
+ vect_is_simple_reduction with additional parameter. Use original
+ statement code in reduction epilogue for nested cycle. Call
+ vect_create_epilog_for_reduction with additional parameter.
+ * tree-vect-patterns.c (vect_recog_dot_prod_pattern): Assert inner-loop
+ vectorization.
+ (vect_recog_widen_sum_pattern): Likewise.
+ * tree-vect-stmts.c (process_use): Distinguish between nested cycles
+ and reductions.
+ (vect_mark_stmts_to_be_vectorized): Likewise.
+ (vect_get_vec_def_for_operand): Handle nested cycles.
+
+2009-06-16 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ * doc/invoke.texi (Debugging Options): Fix option index entries
+ for -fdump-statistics, -frandom-seed add entries for
+ -fdump-tree-original, -fdump-tree-optimized, -frandom-seed.
+ (FRV Options): Fix entries for -mTLS, -mtls.
+ (HPPA Options): Fix entries for -mgnu-ld, -mhp-ld.
+ (i386 and x86-64 Options): Fix entry for -mno-red-zone.
+ (M68hc1x Options): Fix @itemx for -mnominmax.
+ (MCore Options): Fix entry for -mno-lsim.
+ (MMIX Options): Fix entry for -mabi=mmixware.
+ (PDP-11 Options): Fix entry for -mbcopy-builtin.
+
+2009-06-16 Basile Starynkevitch <basile@starynkevitch.net>
+
+ * doc/plugins.texi (Interacting with the GCC Garbage Collector):
+ Mention the plugin mode of gengtype.
+ * doc/gty.texi (Source Files Containing Type Information):
+ Likewise.
+ * gengtype.c: Updated copyright.
+ (plugin_files, nb_plugin_files) Added new static variables.
+ (measure_input_list) Care about plugin_files.
+ (write_rtx_next): Added early return in plugin mode.
+ (create_file): Updated copyright year in generated file. Added
+ asserts.
+ (oprintf): Added early return if NULL outf.
+ (get_output_file_with_visibility): Care of plugin_files.
+ (get_output_file_name): May return null.
+ (write_local): Added early return.
+ (put_mangled_filename): Ditto.
+ (finish_root_table): Added check for base_files.
+ (write_roots): Care about null when plugins.
+ (main): Added plugin mode.
+
+2009-06-15 Ian Lance Taylor <iant@google.com>
+
+ * df-problems.c (df_simulate_one_insn_forwards): Fix braces in
+ switch.
+ * gcov.c (read_count_file): Add braces around variables declared
+ before label.
+
+ * c.opt (Wjump-misses-init): New warning.
+ * c-opts.c (c_common_handle_option): Set warn_jump_misses_init for
+ -Wall and -Wc++-compat if not already set.
+ (c_common_post_options): Clear warn_jump_misses_init if it was not
+ set.
+ * c-decl.c (struct c_binding): Change type field to a union with
+ new label field. Make it the first field in the struct. Update
+ references to type to use u.type instead.
+ (struct c_spot_bindings): Define.
+ (struct c_goto_bindings): Define.
+ (c_goto_bindings_p): Define, along with VECs.
+ (struct c_label_vars): Define.
+ (struct c_scope): Add has_label_bindings field.
+ (bind_label, set_spot_bindings): New static functions.
+ (decl_jump_unsafe, update_spot_bindings): New static functions.
+ (update_label_decls): New static function.
+ (pop_scope): Call update_label_decls. Don't call c_end_vm_scope.
+ Update binding u.label field to shadowed field.
+ (c_binding_start_stmt_expr): New function.
+ (c_binding_end_stmt_expr): New function.
+ (pushdecl): Don't call c_begin_vm_scope.
+ (make_label): Add defining and p_label_vars parameters. Change
+ all callers.
+ (lookup_label): Correct test for whether a label has not yet been
+ defined. Call bind_label rather than bind.
+ (warn_about_goto): New static function.
+ (lookup_label_for_goto): New function.
+ (declare_label): Call bind_label rather than bind.
+ (check_earlier_gotos): New static function.
+ (define_label): Don't give errors about jumping into statement
+ expressions or scopes of variably modified types. Call
+ set_spot_bindings and check_earlier_gotos. Call bind_label
+ instead of bind. Don't set label_context_stack_se or
+ label_context_stack_vm.
+ (c_get_switch_bindings): New function.
+ (c_release_switch_bindings): New function.
+ (c_check_switch_jump_warnings): New function.
+ (start_function): Don't set label_context_stack_se or
+ label_context_stack_vm.
+ (finish_function): Likewise.
+ * c-typeck.c (label_context_stack_se): Don't define.
+ (label_context_stack_vm): Don't define.
+ (c_finish_goto_label): Call lookup_label_for_goto rather than
+ lookup_label. Don't give errors about jumping into a statement
+ expression or the scope of a variably modified type. Don't set
+ label_context_stack_se or label_context_stack_vm.
+ (struct c_switch): Remove blocked_stmt_expr and blocked_vm
+ fields. Add bindings field.
+ (c_start_case): Don't set deleted fields. Set bindings field.
+ (do_case): Rework order of tests. Don't check blocked_stmt_expr
+ or blocked_vm. Call c_check_switch_jump_warnings.
+ (c_finish_case): Don't test blocked_stmt_expr field. Call
+ c_release_switch_bindings.
+ (c_begin_stmt_expr): Don't increment blocked_stmt_expr in
+ c_switch_stack. Don't walk label_context_stack_se labels. Don't
+ set label_context_stack_se. Call c_bindings_start_stmt_expr.
+ (c_finish_stmt_expr): Don't decrement blocked_stmt_expr in
+ c_switch_stack. Don't walk label_context_stack_se labels. Don't
+ set label_context_stack_se. Call c_bindings_end_stmt_expr.
+ (c_begin_vm_scope, c_end_vm_scope): Don't define.
+ * c-tree.h (C_DECL_UNJUMPABLE_STMT_EXPR): Don't define.
+ (C_DECL_UNDEFINABLE_STMT_EXPR): Don't define.
+ (C_DECL_UNJUMPABLE_VM): Don't define.
+ (C_DECL_UNDEFINABLE_VM): Don't define.
+ (struct c_label_list): Don't define.
+ (struct c_label_context_se): Don't define.
+ (struct c_label_context_vm): Don't define.
+ (struct c_spot_bindings): Declare.
+ (c_bindings_start_stmt_expr): Declare.
+ (c_bindings_end_stmt_expr): Declare.
+ (lookup_label_for_goto): Declare.
+ (c_get_switch_bindings, c_release_switch_bindings): Declare.
+ (c_check_switch_jump_warnings): Declare.
+ (label_context_stack_se, label_context_stack_vm): Don't declare.
+ (c_finish_goto_label): Update declaration.
+ (c_begin_vm_scope, c_end_vm_scope): Don't declare.
+ * doc/invoke.texi (Option Summary): Mention -Wjump-misses-init.
+ (Warning Options): Document -Wjump-misses-init.
+
+2009-06-15 Jakub Jelinek <jakub@redhat.com>
+
+ * tree-object-size.c (addr_object_size): Fix a pasto in the last
+ change.
+
+2009-06-15 Rafael Avila de Espindola <espindola@google.com>
+
+ * cgraph.c (cgraph_make_node_local): Use DECL_COMDAT_GROUP.
+
+2009-06-15 Aldy Hernandez <aldyh@redhat.com>
+
+ * except.c (init_eh): Use BUILTINS_LOCATION when calling build_decl.
+
+2009-06-15 Aldy Hernandez <aldyh@redhat.com>
+
+ * tree-eh.c (lower_try_finally_switch): Initialize tf_loc.
+
+2009-06-15 Rafael Avila de Espindola <espindola@google.com>
+
+ * cgraphunit.c (cgraph_function_versioning,save_inline_function_body):
+ Use DECL_COMDAT_GROUP instead of DECL_ONE_ONLY.
+ * cgraph.c (cgraph_create_virtual_clone): Use DECL_COMDAT_GROUP.
+ * config/i386/i386.c (ix86_file_end): Compute DECL_COMDAT_GROUP.
+ * dwarf2asm.c(dw2_force_const_mem): Update call to make_decl_one_only.
+ * langhooks-def.h (lhd_comdat_group, LANG_HOOKS_COMDAT_GROUP): Remove.
+ (LANG_HOOKS_DECLS): Remove LANG_HOOKS_COMDAT_GROUP.
+ * langhooks.c (lhd_comdat_group): Remove.
+ * langhooks.h (lang_hooks_for_decls): Remove comdat_group.
+ * tree.h (DECL_COMDAT_GROUP): New.
+ (DECL_ONE_ONLY): Use DECL_COMDAT_GROUP.
+ (tree_decl_with_vis): Add comdat_group. Remove one_only.
+ (make_decl_one_only): Change signature.
+ * varasm.c (get_emutls_init_templ_addr, emutls_decl): Update call to
+ make_decl_one_only.
+ (make_decl_one_only): Change signature.
+ (default_elf_asm_named_section): Use DECL_COMDAT_GROUP.
+
+2009-06-15 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/40439
+ * tree.c (widest_int_cst_value): Fix bootstrap on 32bit HWI hosts.
+
+2009-06-14 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
+
+ * tree-ssa-math-opts.c: Remove extra divide.
+
+2009-06-14 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
+
+ * config/s390/s390.md ("bswap<mode>2"): Only available on z900.
+
+2009-06-14 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
+
+ * passes.c: Add bswap pass.
+ * tree-pass.h: Add pass_optimize_bswap declaration.
+ * tree-ssa-math-opts.c: Include diagnostics.h for print_gimple_stmt.
+ Include rtl.h, expr.h and optabs.h for optab_handler check.
+ (struct symbolic_number, pass_optimize_bswap): New definition.
+ (do_shift_rotate, verify_symbolic_number_p): New functions.
+ (find_bswap_1, find_bswap, execute_optimize_bswap): New functions.
+ (gate_optimize_bswap): New function.
+ * tree.c (widest_int_cst_value): New function.
+ * tree.h (widest_int_cst_value): Prototype added.
+
+2009-06-14 Steven Bosscher <steven@gcc.gnu.org>
+
+ * cfgcleanup.c (old_insns_match_p): Remove code to substitute
+ REG_EQUAL/REG_EQUIV notes.
+
+2009-06-14 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/40389
+ * gimple.c (walk_stmt_load_store_addr_ops): The LHS of a call
+ has its address taken if NRV was applied and it is addressable.
+ * tree-ssa-structalias.c (get_constraint_for_address_of): New
+ function split out from ...
+ (get_constraint_for_1): ... here.
+ (handle_rhs_call): Use it to mark the return slot escaped if
+ it is addressable and NRV was applied.
+
+2009-06-13 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/rs6000-protos.h (altivec_resolve_overloaded_builtin):
+ Change first argument type to location_t.
+ * config/rs6000/rs6000-c.c (altivec_resolve_overloaded_builtin): Same.
+ Do not set input_location.
+ Use loc instead of input_location throughout.
+
+2009-06-13 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/40421
+ * tree-predcom.c (should_unroll_loop_p): Remove.
+ (tree_predictive_commoning_loop): Use can_unroll_loop_p.
+
+2009-06-13 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ * config/rs6000/rs6000-c.c (altivec_resolve_overloaded_builtin):
+ Add location argument.
+
+2009-06-13 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/alpha/alpha.c (alpha_build_builtin_va_list): Pass location to
+ build_decl.
+ * config/s390/s390.c (s390_build_builtin_va_list): Same.
+ (s390_gimplify_va_arg): Pass location to create_artificial_label.
+ * config/spu/spu-protos.h: Add location to
+ spu_resolve_overloaded_builtin.
+ * config/spu/spu.c (spu_build_builtin_va_list): Pass location to
+ spu_build_builtin_va_list.
+ * config/spu/spu-c.c (spu_resolve_overloaded_builtin): Add location
+ argument. Pass location to build_function_call_vec.
+ * config/sh/sh.c (sh_build_builtin_va_list): Pass location to
+ build_decl.
+ (emit_fpu_switch): Same.
+ (sh_gimplify_va_arg_expr): Pass location to create_artificial_label.
+ * config/xtensa/xtensa.c (xtensa_build_builtin_va_list): Pass location
+ to build_decl and create_artificial_label.
+ (xtensa_gimplify_va_arg_expr): Same.
+ * config/stormy16/stormy16.c (xstormy16_build_builtin_va_list): Same.
+ (xstormy16_gimplify_va_arg_expr): Same.
+ * config/iq2000/iq2000.c (iq2000_expand_prologue): Same.
+ * config/arm/arm.c (arm_build_builtin_va_list): Same.
+ * config/mips/mips.c (mips_build_builtin_va_list): Same.
+ (mips16_build_function_stub): Same.
+ (mips16_build_call_stub): Same.
+
+2009-06-13 Richard Earnshaw <rearnsha@arm.com>
+
+ PR target/40327
+ * arm/constraints.md (Pa, Pb): New constraints.
+ * arm/arm.md (thumb1_addsi3): Support more complex additions. Add a
+ split pattern to deal with them.
+
+2009-06-13 Joerg Sonnenberger <joerg@britannica.bec.de>
+
+ * doc/invoke.texi: Add missing option -Wp,OPTION in list,
+ fix index entry for -Xpreprocessor.
+
+2009-06-12 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/rs6000-c.c (altivec_resolve_overloaded_builtin):
+ Add location argument to build_decl call.
+ * config/rs6000/rs6000.c (rs6000_build_builtin_va_list): Same.
+ (rs6000_init_builtins): Same.
+ (spe_init_builtins): Same.
+ (rs6000_gimplify_va_arg): Add location argument to
+ create_artificial_label call.
+
+2009-06-12 Steven Bosscher <steven@gcc.gnu.org>
+
+ * timevar.def (TV_COMBINE_STACK_ADJUST): New timevar.
+ * combine-stack-adj.c (pass_stack_adjustments): Use it.
+ * Makefile.in: Fix GGC dependency for gcse.o.
+
+2009-06-12 Aldy Hernandez <aldyh@redhat.com>
+
+ * tree-pretty-print.c (dump_generic_node): Dump column numbers.
+ * gimple-pretty-print.c (dump_gimple_stmt): Same.
+ * gimplify.c (gimplify_modify_expr): Set location for GIMPLE_ASSIGNs
+ created.
+ * c-parser.c (c_parser_binary_expression): Use current column while
+ building binary operations.
+ * common.opt (fshow-column): Enable by default.
+ * tree-vrp.c (check_array_ref): Use warning_at.
+ (check_array_bounds): Use location from call back if expr has no
+ location.
+ * tree.h: Add location argument to maybe_fold_*.
+ * tree-ssa-ccp.c (ccp_fold): Pass location to maybe_fold_*.
+ (maybe_fold_offset_to_array_ref): Add location argument and use it.
+ (maybe_fold_offset_to_component_ref): Same.
+ (maybe_fold_offset_to_reference): Same.
+ (maybe_fold_offset_to_address): Same.
+ (maybe_fold_stmt_indirect): Same.
+ (maybe_fold_stmt_addition): Same.
+ (fold_stmt_r): Pass location to maybe_fold_*.
+ (fold_gimple_assign): Same.
+ * c-tree.h: Add location argument to finish_decl,
+ default_function_array_conversion, store_init_value.
+ * c-decl.c (define_label): Use error_at.
+ (c_make_fname_decl): Pass location to finish_decl.
+ (finish_decl): New location argument.
+ (build_compound_literal): Pass location to store_init_value.
+ (grokdeclarator): Pass location to finish_decl.
+ (grokfield): Same.
+ * c-typeck.c (array_to_pointer_conversion): New location argument.
+ (function_to_pointer_conversion): Same.
+ (default_function_array_conversion): Same.
+ (parser_build_unary_op): Pass location to overflow_warning.
+ (parser_build_binary_op): Same. Use warning_at.
+ (build_unary_op): Pass location to array_to_pointer_conversion.
+ (build_c_cast): Pass location to digest_init.
+ (build_modify_expr): New location argument.
+ (convert_for_assignment): Same.
+ (store_init_value): Same.
+ (digest_init): Same.
+ (output_init_element): Pass location to digest_init and
+ array_to_pointer_conversion.
+ (c_finish_return): Pass location to convert_for_assignment.
+ * gimplify.c (gimplify_conversion): Pass location to
+ maybe_fold_offset_to_address.
+ * tree-ssa-forwprop.c (forward_propagate_addr_expr_1): Pass location
+ to maybe_fold_stmt_addition.
+ * c-omp.c (c_finish_omp_atomic): Pass new location to
+ build_modify_expr.
+ (c_finish_omp_for): Same.
+ * c-common.c (overflow_warning): New argument.
+ * c-common.h: New argument to build_modify_expr, overflow_warning.
+ * c-parser.c (c_parser_declaration_or_fndef): Pass location to
+ finish_decl.
+ (c_parser_initializer): Pass location to
+ default_function_array_conversion.
+ (c_parser_initelt): Same.
+ (c_parser_initval): Same.
+ (c_parser_asm_operands): Same.
+ (c_parser_expr_no_commas): Same. Pass location to build_modify_expr.
+ (c_parser_conditional_expression): Same.
+ (c_parser_binary_expression): Add location info to stack. Use it.
+ (c_parser_unary_expression): Pass location to
+ default_function_array_conversion, parser_build_unary_op,
+ build_indirect_ref, c_parser_postfix_expression_after_primary.
+ (c_parser_postfix_expression_after_primary): New location argument.
+ Use it.
+ (c_parser_expression_conv): Pass location to
+ default_function_array_conversion.
+ (c_parser_expr_list): Same.
+ (c_parser_omp_atomic): Same.
+ (c_parser_omp_for_loop): Same.
+ * c-tree.h: (struct c_declarator): Add comment to id_loc.
+ (build_array_declarator): New argument.
+ * c-decl.c (build_array_declarator): Add location argument.
+ (grokdeclarator): Set id_loc for cdk_array.
+ * c-parser.c (c_parser_direct_declarator_inner): Pass location to
+ build_array_declarator.
+ * tree.c (build_omp_clause): Add location argument.
+ * tree.h (OMP_CLAUSE_HAS_LOCATION): New macro.
+ (OMP_CLAUSE_LOCATION): New macro.
+ (struct tree_omp_clause): Add location field.
+ (build_omp_clause): Add argument.
+ * testsuite/gcc.dg/gomp/for-1.c: Fix column.
+ * cp/pt.c (tsubst_omp_for_iterator): Pass location to
+ build_omp_clause.
+ * cp/parser.c (cp_parser_omp_var_list_no_open): Same.
+ (cp_parser_omp_clause_collapse): Same.
+ (cp_parser_omp_clause_default): Same.
+ (cp_parser_omp_clause_if): Same.
+ (cp_parser_omp_clause_nowait): Same.
+ (cp_parser_omp_clause_num_threads): Same.
+ (cp_parser_omp_clause_ordered): Same.
+ (cp_parser_omp_clause_schedule): Same.
+ (cp_parser_omp_clause_untied): Same.
+ (cp_parser_omp_for_loop): Same.
+ (cp_parser_omp_parallel): Pass location to c_split_parallel_clauses.
+ * c-tree.h (c_start_case): Add location argument.
+ (c_process_expr_stmt): Same.
+ (c_finish_goto_*): Same.
+ * tree-parloops.c (initialize_reductions): Pass location to
+ build_omp_clause.
+ (create_parallel_loop): Same.
+ * fortran/trans-openmp.c (gfc_trans_omp_variable_list): Same.
+ (gfc_trans_omp_reduction_list): Same.
+ (gfc_trans_omp_clauses): Same.
+ (gfc_trans_omp_do): Same.
+ * c-typeck.c (c_finish_goto_label): Same.
+ (c_finish_goto_ptr): New location argument.
+ (c_start_case): Same.
+ (emit_side_effect_warnings): Same.
+ (c_process_expr_stmt): Same.
+ (c_finish_stmt_expr): Same.
+ (c_finish_omp_clauses): Use error_at instead of error.
+ * gimplify.c (gimplify_adjust_omp_clauses_1): Pass location to
+ build_omp_clause.
+ * c-omp.c (c_split_parallel_clauses): New location argument.
+ * tree-nested.c (convert_nonlocal_reference_stmt): Pass location
+ to build_omp_clause.
+ (convert_local_reference_stmt): Same.
+ (convert_gimple_call): Same.
+ * c-common.h (c_split_parallel_clauses): New argument.
+ * c-parser.c (c_parser_statement_after_labels): Pass location to
+ c_finish_goto_label.
+ (c_parser_switch_statement): Pass location to c_start_case.
+ (c_parser_for_statement): Pass location to c_finish_expr_stmt,
+ and c_process_expr_stmt.
+ (c_parser_omp_variable_list): Add location argument.
+ (c_parser_omp_clause_collapse): Pass location to
+ build_omp_clause.
+ (c_parser_omp_clause_default): Same.
+ (c_parser_omp_clause_if): Same.
+ (c_parser_omp_clause_num_threads): Same.
+ (-c_parser_omp_clause_ordered): Same.
+ (c_parser_omp_clause_reduction): Pass location to
+ c_parser_omp_variable_list.
+ (c_parser_omp_clause_schedule): Pass location to build_omp_clause.
+ (c_parser_omp_clause_untied): Same.
+ (c_parser_omp_for_loop): Pass location to c_process_expr_stmt.
+ (c_parser_omp_parallel): Pass location to
+ c_split_parallel_clauses.
+
+ * c-tree.h (check_for_loop_decls, undeclared_variable,
+ build_component_ref, build_array_ref, build_external_ref,
+ c_expr_sizeof_expr, c_expr_sizeof_type, parser_build_unary_op,
+ build_conditional_expr, build_compound_expr, c_cast_expr,
+ build_c_cast, build_asm_expr, c_end_compound_stmt, c_finish_stmt_expr,
+ c_finish_return, c_finish_omp_parallel, c_finish_omp_task): New
+ argument.
+ * c-semantics.c (build_stmt): Same.
+ (build_case_label): Same.
+ * c-decl.c (c_finish_incomplete_decl): Pass location on down.
+ (undeclared_variable): New argument.
+ (make_label): Same.
+ (lookup_label): Pass location on down.
+ (define_label): Same.
+ (finish_decl): Same.
+ (build_compound_literal): Same.
+ (finish_struct): Same.
+ (finish_function): Do not set location here.
+ (check_for_loop_decls): New argument.
+ * tree.c (save_expr): Set location.
+ (build_empty_stmt): New argument.
+ * tree.h (build_empty_stmt): New argument to build_empty_stmt.
+ (CAN_HAVE_LOCATION_P): Make sure we have a non empty node.
+ * builtins.c (gimplify_va_arg_expr): Use locations.
+ (expand_builtin_sync_operation): Same.
+ * c-typeck.c (build_component_ref): New argument.
+ (build_array_ref): Same.
+ (build_external_ref): Same.
+ (c_expr_sizeof_expr): Same.
+ (c_expr_sizeof_type): Same.
+ (parser_build_unary_op): Same.
+ (build_conditional_expr): Same.
+ (build_compound_expr): Pass location on down.
+ (build_compound_expr): New argument.
+ (build_c_cast): Same.
+ (c_cast_expr): Same.
+ (build_asm_expr): Same.
+ (c_finish_return): Same.
+ (c_process_expr_stmt): Pass location on down.
+ (c_finish_stmt_expr): New argument.
+ (push_clenaup): Same.
+ (c_finish_omp_parallel): Same.
+ (c_finish_omp_task): Same.
+ * gimplify.c (gimplify_call_expr): Pass location on down.
+ * c-omp.c (c_finish_omp_master): New argument.
+ (c_finish_omp_critical): Same.
+ (c_finish_omp_ordered): Same.
+ (c_finish_omp_barrier): Same.
+ (-c_finish_omp_taskwait): Same.
+ (c_finish_omp_atomic): Same.
+ (c_finish_omp_flush): Same.
+ * tree-inline.c (copy_tree_body_r): Pass location on down.
+ (inline_forbidden_p): Remove use of input_location.
+ * c-gimplify.c (c_build_bind_expr): New argument.
+ * c-common.c (c_common_truthvalue_conversion): Pass location on down.
+ (c_sizeof_or_alignof_type): New argument.
+ (c_alignof_expr): Same.
+ (build_va_arg): Same.
+ (c_add_case_label): Same.
+ * c-common.h (c_sizeof_or_alignof_type, c_alignof_expr,
+ c_sizeof, c_alignof, build_va_arg, build_stmt, build_case_label,
+ c_build_bind_expr, objc_build_selector_expr, objc_build_throw_stmt,
+ c_finish_omp_master, c_finish_omp_critical, c_finish_omp_ordered,
+ c_finish_omp_barrier, c_finish_omp_atomic, c_finish_omp_flush,
+ c_finish_omp_taskwait, c_finish_omp_for, c_split_parallel_clauses):
+ New argument.
+ * stub-objc.c (objc_build_selector_expr): Same.
+ (objc_build_throw_stmt): Same.
+ * c-parser.c (c_parser_declaration_or_fndef): Pass location on down.
+ (c_parser_initelt): Same.
+ (c_parser_compound_statement): Same.
+ (c_parser_compound_statement_nostart): Same.
+ (c_parser_label): Same.
+ (c_parser_statement_after_labels): Same.
+ (c_parser_if_body): Same.
+ (c_parser_else_body): Same.
+ (c_parser_if_statement): Same.
+ (c_parser_switch_statement): Same.
+ (c_parser_while_statement): Same.
+ (c_parser_do_statement): Same.
+ (c_parser_for_statement): Same.
+ (c_parser_asm_statement): Same.
+ (c_parser_conditional_expression): Same.
+ (c_parser_binary_expression): Same.
+ (c_parser_cast_expression): Same.
+ (c_parser_unary_expression): Same.
+ (c_parser_sizeof_expression): Same.
+ (c_parser_alignof_expression): Same.
+ (c_parser_postfix_expression): Same.
+ (c_parser_expression): Same.
+ (c_parser_objc_receiver): Same.
+ (c_parser_omp_variable_list): Same.
+ (c_parser_omp_structured_block): Same.
+ (c_parser_omp_atomic): New argument.
+ (c_parser_omp_barrier): Same.
+ (c_parser_omp_critical): Same.
+ (c_parser_omp_flush): Pass location on down.
+ (c_parser_omp_for_loop): New argument.
+ (c_parser_omp_for): Same.
+ (c_parser_omp_master): Same.
+ (c_parser_omp_ordered): Same.
+ (c_parser_omp_sections_scope): Same.
+ (c_parser_omp_sections): Same.
+ (c_parser_omp_parallel): Same.
+ (c_parser_omp_single): Same.
+ (c_parser_omp_task): Same.
+ (c_parser_omp_taskwait): Pass location on down.
+ (c_parser_omp_construct): Same.
+ (c_parser_omp_threadprivate): Same.
+ * dwarf2asm.c, targhooks.c, optabs.c, tree.c, tree.h, target.h,
+ builtins.c, omp-low.c, cgraphunit.c, tree-call-cdce.c,
+ tree-ssa-alias.c, gimple-low.c, c-tree.h, expr.c, tree-parloops.c,
+ c-decl.c, tree-eh.c, langhooks.c, function.c, stor-layout.c,
+ c-typeck.c, gimplify.c, c-pragma.c, expmed.c, except.c, coverage.c,
+ emit-rtl.c, cfgexpand.c, tree-mudflap.c, varasm.c, tree-nested.c,
+ rtl.h, tree-inline.c, tree-profile.c, c-common.c, c-common.h,
+ tree-switch-conversion.c, tree-cfg.c, ipa-struct-reorg.c, c-parser.c,
+ config/i386/i386.c, stmt.c:
+ Add location argument to the following function definitions and/or
+ function calls: build_decl, objcp_start_struct, objcp_finish_struct,
+ start_struct, finish_struct, PUSH_FIELD, create_artificial_label,
+ cp_make_fname_decl, pushtag, implicitly_declare, c_make_fname_decl,
+ build_compound_literal, parser_xref_tag, resolve_overloaded_builtin,
+ do_case, c_finish_bc_stmt, build_compound_literal,
+ build_function_call.
+ * c-decl.c (build_compound_literal): Add location argument.
+ Make all diagnostic calls use location.
+ (start_struct): Same.
+ (finish_struct): Same.
+ (start_enum): Same.
+ (build_enumerator): Same.
+ (start_function): Same.
+ (grokdeclarator): Make all diagnostic calls use location.
+ (store_parm_decls_oldstyle): Same.
+ * c-typeck.c (build_function_call): Add location argument.
+ Make all diagnostic calls use location.
+ (do_case): Same.
+ (c_finish_bc_stmt): Same.
+ * tree-nested.c (get_trampoline_type): Add argument.
+ Pass location to build_decl.
+ (lookup_tramp_for_decl): Pass location to get_trampoline_type.
+ * rtl.h (RTL_LOCATION): New.
+ * c-common.c (c_add_case_label): Add location argument.
+ Make all diagnostic calls use location.
+ * c-common.h: Add location argument to make_fname_decl, do_case,
+ c_add_case_label, build_function_call, resolve_overloaded_builtin.
+ * c-parser.c (c_parser_enum_specifier): Rename ident_loc to enum_loc.
+ Set it appropriately for every case. Pass enum_loc to start_enum
+ call. Pass value_loc first to build_enumerator. Pass enum_loc to
+ parser_xref_tag.
+ (c_parser_struct_or_union_specifier): Save location. Use it for
+ start_struct, finish_struct, and parser_xref_tag.
+
+2009-06-12 Ian Lance Taylor <iant@google.com>
+
+ * fold-const.c (fold_unary): Rename local variable and to
+ and_expr.
+
+ * c-opts.c (c_common_handle_option): For -Wc++-compat set
+ cpp_opts->warn_cxx_operator_names.
+
+2009-06-12 Andrew Pinski <andrew_pinski@playstation.sony.com>
+
+ PR tree-opt/38865
+ * tree-ssa-sccvn.c (visit_reference_op_load): If vn_reference_lookup
+ is returns NULL and OP is a VCE, look through the VCE.
+
+2009-06-12 Ian Lance Taylor <iant@google.com>
+
+ PR bootstrap/40430
+ * collect2.c (main): Use CONST_CAST2 in code inside #if
+ LINK_ELIMINATE_DUPLICATE_LDIRECTORIES.
+
+2009-06-12 Joey Ye <joey.ye@intel.com>
+
+ PR middle-end/39146
+ * cfgexpand.c (get_decl_align_unit): Update
+ max_used_stack_slot_alignment with align instead of
+ stack_alignment_needed.
+
+ * function.c (assign_stack_local_1): Update
+ max_used_stack_slot_alignment with alignment_in_bits instead
+ of stack_alignment_needed.
+ (locate_and_pad_parm): Don't update max_used_stack_slot_alignment
+ here.
+
+2009-06-12 Jakub Jelinek <jakub@redhat.com>
* dwarf2out.c (last_var_location_insn): New variable.
(dwarf2out_end_epilogue): Clear last_var_location_insn.
@@ -6,7 +823,151 @@
insn. Only change labels if there were any real instructions
in between last note and this one, or if changed sections.
-2009-06-11 Ian Lance Taylor <iant@google.com>
+2009-06-11 Richard Henderson <rth@redhat.com>
+
+ * alpha.c (alpha_expand_prologue): Add a REF_CFA_REGISTER
+ note when storing the frame pointer in a register.
+ (FRP): Don't redefine to nothing for epilogue.
+ (alpha_expand_epilogue): Mark register and sp restores.
+ (unicosmk_gen_dsib): Don't mark weird frame pointer adjust.
+
+ * config/alpha/alpha.c (alpha_emit_setcc): Fix test for
+ when gen_lowpart is needed.
+
+2009-06-11 Richard Henderson <rth@redhat.com>
+
+ * dwarf2out.c (def_cfa_1): Likewise for DW_CFA_cfa_offset.
+
+ * dwarf2out.c (need_data_align_sf_opcode): New.
+ (div_data_align): Move earlier.
+ (def_cfa_1, reg_save): Use it.
+
+2009-06-11 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config/i386/i386.c (OPTION_MASK_ISA_CRC32_SET): New.
+ (OPTION_MASK_ISA_CRC32_UNSET): Likewise.
+ (ix86_handle_option): Handle OPT_mcrc32.
+ (ix86_target_string): Add -mcrc32.
+ (bdesc_args): Enable crc32 builtins with OPTION_MASK_ISA_CRC32.
+
+ * config/i386/i386.h (TARGET_CRC32): New.
+
+ * config/i386/i386.md (sse4_2_crc32<mode>): Also check
+ TARGET_CRC32.
+ (sse4_2_crc32di): Likewise.
+
+ * config/i386/i386.opt (mcrc32: New.
+
+ * doc/invoke.texi: Document -mcrc32.
+
+2009-06-11 Richard Henderson <rth@redhat.com>
+
+ * common.opt (gdwarf-): Accept a version number.
+ * doc/invoke.texi (gdwarf-): Update docs.
+ * opth-gen.awk: Special case -gdwarf+ to OPT_gdwarfplus.
+ * opts.c (common_handle_option) [OPT_gdwarf_]: Verify dwarf
+ version level, and record it.
+
+ * dwarf2.h (DW_CIE_VERSION): Remove.
+ * dwarf2out.c (DWARF_VERSION): Remove.
+ (add_fde_cfi): Skip DW_CFA_set_loc addition for dwarf3.
+ (output_call_frame_info): Use CIE version 3 for dwarf3,
+ or if the return register column is out of range for version 1.
+ (dwarf_stack_op_name): Add all dwarf3 values.
+ (DEBUG_PUBTYPES_SECTION): New.
+ (size_of_die) [dw_val_class_die_ref]: Handle DW_FORM_ref_addr
+ encoding change for dwarf3.
+ (output_die) [dw_val_class_die_ref]: Likewise.
+ (output_compilation_unit_header): Emit correct version for dwarf3.
+ (output_line_info): Likewise.
+ (output_pubnames): Update for DWARF_VERSION removal.
+ (output_aranges): Likewise.
+ (gen_subprogram_die): Emit DW_OP_call_frame_cfa if emitting dwarf3.
+ (dwarf2out_init): Don't ifdef DEBUG_PUBTYPES_SECTION.
+ (dwarf2out_finish): Likewise.
+
+2009-06-11 David Daney <ddaney@caviumnetworks.com>
+
+ * system.h (gcc_assert, gcc_unreachable): Revert accidental commit
+ in r148403.
+
+2009-06-11 David Daney <ddaney@caviumnetworks.com>
+
+ PR c/39252
+ * doc/extend.texi ( __builtin_unreachable): Document new builtin.
+ * builtins.c (expand_builtin_unreachable): New function.
+ (expand_builtin): Handle BUILT_IN_UNREACHABLE case.
+ * builtins.def (BUILT_IN_UNREACHABLE): Add new builtin.
+ * cfgcleanup.c (try_optimize_cfg): Delete empty blocks with no
+ successors.
+ * cfgrtl.c (rtl_verify_flow_info): Handle empty blocks when
+ searching for missing barriers.
+
+2009-06-11 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+
+ * config/darwin.h (LINK_COMMAND_SPEC): Adjust spec to link libcov
+ when -fprofile-generate* was passed.
+ * config/darwin9.h (LINK_COMMAND_SPEC): Likewise.
+
+2009-06-11 Anthony Green <green@moxielogic.com>
+
+ * config/moxie/moxie.md: Define length attribute for all
+ instructions.
+ (rCC): Define.
+ (*b<cond:code>): Support limited branch ranges for new PC-relative
+ branch instructions.
+ * config/moxie/moxie.h (HAS_LONG_UNCOND_BRANCH): Define.
+
+2009-06-11 Jakub Jelinek <jakub@redhat.com>
+
+ * config/i386/i386.c (min_insn_size): Use get_attr_length
+ for normal insns other than TYPE_MULTI, TYPE_OTHER and TYPE_FCMP.
+ For __asm return 0.
+
+ * config/i386/i386.c (ix86_pad_returns): Use emit_jump_insn_before
+ instead of emit_insn_before.
+
+2009-06-10 Ian Lance Taylor <iant@google.com>
+
+ PR bootstrap/40408
+ * graphite.c (add_conditions_to_domain): Change SWITCH_EXPR to
+ GIMPLE_SWITCH.
+
+2009-06-10 Revital Eres <eres@il.ibm.com>
+
+ * passes.c (init_optimization_passes): Reschedule
+ predictive-commoning pass before complete unroll pass.
+
+2009-06-10 Martin Jambor <mjambor@suse.cz>
+
+ * cgraph.c (cgraph_node_can_be_local_p): New function.
+ (cgraph_make_node_local): New function.
+ * cgraph.h (cgraph_node_can_be_local_p): Declare.
+ (cgraph_make_node_local): Declare.
+
+2009-06-10 Nathan Froyd <froydnj@codesourcery.com>
+
+ * tree.h (tree_base): Add packed_flag and user_align fields.
+ Decrease size of spare field.
+ (TYPE_USER_ALIGN): Use user_align from tree_base.
+ (DECL_USER_ALIGN): Likewise.
+ (TYPE_PACKED): Use packed_flag from tree_base.
+ (DECL_PACKED): Likewise.
+ (tree_type): Delete packed_flag and user_align fields. Widen
+ precision field. Widen mode field and shuffle fields to align
+ mode on an 8-bit boundary.
+ (tree_decl_common): Delete decl_flag_1 and user_align fields.
+ Renumber decl_flag_* fields. Fix comments. Widen
+ decl_common_unused field.
+ (DECL_HAS_VALUE_EXPR_P): Adjust for renumbering of decl_flag_*
+ fields.
+ (DECL_EXTERNAL): Likewise.
+ (DECL_BIT_FIELD): Likewise.
+ (DECL_NONADDRESSABLE_P): Likewise.
+ (TYPE_DECL_SUPRESS_DEBUG): Likewise.
+ * config/arm/arm-modes.def (XImode): Make it an INT_MODE.
+
+2009-06-10 Ian Lance Taylor <iant@google.com>
* vec.h (DEF_VEC_ALLOC_I): Use DEF_VEC_NONALLOC_FUNCS_I.
(DEF_VEC_ALLOC_P): Use DEF_VEC_NONALLOC_FUNCS_P.
@@ -67,6 +1028,3915 @@
callers.
(df_mws_verify): Likewise.
+2009-06-10 Alexandre Oliva <aoliva@redhat.com>
+
+ * gcc.c (compare_files): Cast munmap argumento to caddr_t.
+
+2009-06-10 H.J. Lu <hongjiu.lu@intel.com>
+
+ * doc/extend.texi: Add description for __builtin_ia32_crc32di.
+
+2009-06-10 Anthony Green <green@moxielogic.com>
+
+ * config/moxie/crti.asm: New file.
+ * config/moxie/crtn.asm: New file.
+ * config/moxie/moxie.c: New file.
+ * config/moxie/moxie.h: New file.
+ * config/moxie/sfp-machine.h: New file.
+ * config/moxie/moxie-protos.h: New file.
+ * config/moxie/t-moxie: Created.
+ * config/moxie/t-moxie-softfp: Created.
+ * config/moxie/moxie.md: Created.
+ * config/moxie/constraints.md: Created.
+ * config.gcc: Add moxie support.
+ * doc/md.texi (Machine Constraints): Add moxie constraints.
+ * doc/contrib.texi (Contributors): Mention moxie port.
+ * doc/install.texi (Specific): Mention the moxie port.
+
+2009-06-09 Ian Lance Taylor <iant@google.com>
+
+ * system.h (HAVE_DESIGNATED_INITIALIZERS): Don't define if
+ compiling with C++.
+ * optabs.c (optab_table): Only use designated initializers if
+ HAVE_DESIGNATED_INITIALIZERS is defined.
+ (convert_optab_table): Likewise.
+ (init_optabs): Always call init_insn_codes if
+ HAVE_DESIGNATED_INITIALIZERS is not defined.
+
+2009-06-09 Ian Lance Taylor <iant@google.com>
+
+ * targhooks.c (default_builtin_vectorized_function): Change fn
+ parameter to unsigned int.
+ (default_builtin_vectorized_conversion): Change code parameter to
+ unsigned int.
+ (default_builtin_reciprocal): Change fn parameter to unsigned int.
+ * targhooks.h: Update declarations.
+ * config/rs6000/rs6000.c (rs6000_builtin_conversion): Change code
+ parameter to unsigned int.
+
+ * c-typeck.c (comptypes_check_enum_int): New static function.
+ (comptypes_internal): Add enum_and_int_p parameter. Change all
+ callers.
+ (comp_target_types): Add location parameter. Change all callers.
+ (tagged_types_tu_compatible_p): Add enum_and_int_p parameter.
+ Change all callers.
+ (function_types_compatible_p, type_lists_compatible_p): Likewise.
+ (build_conditional_expr): Add colon_loc parameter. Change all
+ callers.
+ (convert_for_assignment): Add location parameter. Change all
+ callers.
+ * c-parser.c (c_parser_conditional_expression): Pass location of
+ colon to build_conditional_expr.
+ * c-tree.h (build_conditional_expr): Update declaration.
+
+2009-06-09 Sebastian Pop <sebastian.pop@amd.com>
+
+ * graphite.c: Revert previous patch.
+
+2009-06-09 Sebastian Pop <sebastian.pop@amd.com>
+
+ PR bootstrap/40103
+ * graphite.c: Remove pragma GCC diagnostic warning "-Wc++-compat".
+
+2009-06-09 Ghassan Shobaki <ghassan.shobaki@amd.com>
+
+ * tree-ssa-loop-prefetch.c
+ (loop_prefetch_arrays): Fixed a portability problem in printf format
+ string.
+
+2009-06-09 Martin Jambor <mjambor@suse.cz>
+
+ PR tree-optimization/40351
+ * tree-sra.c (propagate_subacesses_accross_link): Check that a refrence
+ to a potential artifical subaccess can be constructed.
+
+2009-06-08 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ * config/sh/sh-protos.h (sh_optimization_options): Declare.
+ (sh_override_options): Likewise.
+ * config/sh/sh.c: Include params.h.
+ (sh_optimization_options): New.
+ (sh_override_options): Likewise.
+ * config/sh/sh.c (OPTIMIZATION_OPTIONS): Use sh_optimization_options.
+ (OVERRIDE_OPTIONS): Use sh_override_options.
+
+2009-06-08 Jakub Jelinek <jakub@redhat.com>
+
+ * dwarf2out.c (emit_cfa_remember): New variable.
+ (add_fde_cfi): If emit_cfa_remember, recurse to add
+ DW_CFA_remember_state first.
+ (dwarf2out_begin_epilogue): Don't add_fde_cfi DW_CFA_remember_state,
+ instead just set emit_cfa_remember.
+
+2009-06-08 Jan Hubicka <jh@suse.cz>
+
+ PR debug/40126
+ * dwarf2out.c (dwarf2out_abstract_function): Free decl_loc_table.
+
+2009-06-08 Jan Hubicka <jh@suse.cz>
+
+ PR middle-end/39834
+ * cgraphunit.c (save_inline_function_body): Do not copy transform hooks
+ for saved inline bodies.
+ * ipa-passes.c (do_per_function): Do not add the hoks multiple times
+ for given function.
+
+2009-06-08 Adam Nemet <anemet@caviumnetworks.com>
+
+ * jump.c (returnjump_p): Handle delayed branches. Add missing
+ function comment.
+
+2009-06-08 Jan Hubicka <jh@suse.cz>
+
+ PR middle-end/40102
+ * cgraph.c (cgraph_create_edge_including_clones): Also asume that the
+ original node might've been modified.
+ * tree-inline.c (copy_bb): Do not assume that all clones are the same.
+
+2009-06-08 Jakub Jelinek <jakub@redhat.com>
+
+ * tree-object-size.c (addr_object_size): Add OSI argument.
+ Handle also INDIRECT_REF with SSA_NAME inside of it as base address.
+ (compute_builtin_object_size, expr_object_size): Adjust callers.
+ (plus_stmt_object_size): Call addr_object_size instead of
+ compute_builtin_object_size.
+
+2009-06-08 Ghassan Shobaki <ghassan.shobaki@amd.com>
+ Dwarakanath Rajagopal <dwarak.rajagopal@amd.com>
+
+ * tree-ssa-loop-prefetch.c
+ (gather_memory_references): Introduced a counter for the number of
+ memory references.
+ (anything_to_prefetch_p): Introduced a counter for the number of
+ prefetches.
+ (is_loop_prefetching_profitable): New function with a cost model
+ for prefetching.
+ (loop_prefetch_arrays): Use the new cost model to determine if
+ prefetching is profitable.
+ * params.def (MIN_INSN_TO_PREFETCH_RATIO,
+ PREFETCH_MIN_INSN_TO_MEM_RATIO): New parameters.
+ * params.h (MIN_INSN_TO_PREFETCH_RATIO,
+ PREFETCH_MIN_INSN_TO_MEM_RATIO): New parameters.
+ * doc/invoke.texi (MIN_INSN_TO_PREFETCH_RATIO,
+ PREFETCH_MIN_INSN_TO_MEM_RATIO): New parameters.
+
+2009-06-08 Michael Matz <matz@suse.de>
+
+ PR debug/40012
+ * cfgexpand.c (set_rtl): Store place also in DECL_RTL, if all
+ partitions use the same.
+ (expand_one_var): Deal with DECL_RTL sometimes begin set also
+ for basevars of SSA_NAMEs.
+ (expand_used_vars): Reset TREE_USED for basevars of SSA_NAMEs,
+ to not expand them twice.
+ (gimple_expand_cfg): Clear DECL_RTL for those decls that have
+ multiple places.
+
+2009-06-08 Alexandre Oliva <aoliva@redhat.com>
+
+ * common.opt (fcompare-debug=, fcompare-debug-second): New.
+ (fdump-final-insns=, gtoggle): New.
+ * doc/invoke.texi: Document them.
+ * final.c (rest_of_clean_state): Dump final insn stream.
+ * gcc.c (invoke_as): Hook in -fcompare-debug.
+ (static_spec_functions): Add compare-debug-dump-opt,
+ compare-debug-self-opt and compare-debug-auxbase-opt.
+ (compare_debug, compare_debug_second, compare_debug_opt): New.
+ (switches_debug_check, n_switches_debug_check): New.
+ (debug_auxbase_opt, debug_check_temp_file): New.
+ (process_command): Handle -fno-compare-debug, -fcompare-debug and
+ -fcompare-debug=*.
+ (do_self_spec): Handle arguments after switches.
+ (do_spec_1): Add .gk extension to temp file basenames for compare.
+ (check_live_switch): Take SWITCH_IGNORE into account, and earlier.
+ (cc1_options): Use it instead of normal auxbase computation for
+ the second compare-debug compilation.
+ (compare_files): New.
+ (main): Set up and implement compare debug mode.
+ (compare_debug_dump_opt_spec_function): New.
+ (compare_debug_self_opt_spec_function): New.
+ (compare_debug_auxbase_opt_spec_function): New.
+ * toplev.c (process_options): Handle flag_gtoggle,
+ flag_dump_final_insns.
+ * coverage.c (coverage_begin_output): Don't overwrite .gcno file
+ during -fcompare-debug-second compilation.
+
+2009-06-07 Ian Lance Taylor <iant@google.com>
+
+ * dwarf2.h (enum dwarf_location_atom): Add
+ INTERNAL_DW_OP_tls_addr.
+ * dwarf2out.c (INTERNAL_DW_OP_tls_addr): Don't #define.
+
+ * c-common.c (c_do_switch_warnings): Don't exit early for -Wswitch
+ with no default node. Change warning with %H to warning_at.
+ Don't clear warn_switch around case checking.
+ * doc/invoke.texi (Warning Options): Clarify distinction between
+ -Wswitch and -Wswitch-enum.
+
+2009-06-07 Bernhard Reutner-Fischer <aldot@gcc.gnu.org>
+
+ * tree-pass.h (TODO_update_ssa_any): Document internal use only.
+
+2009-06-07 Bernhard Reutner-Fischer <aldot@gcc.gnu.org>
+
+ * gbl-ctors.h: Add header guard.
+
+2009-06-07 Bernhard Reutner-Fischer <aldot@gcc.gnu.org>
+
+ * tree-flow.h (make_value_handle, set_value_handle, sort_vuses,
+ sort_vuses_heap, vn_lookup_or_add, vn_lookup_or_add_with_stmt,
+ vn_lookup_or_add_with_vuses, vn_add, vn_add_with_vuses,
+ vn_lookup_with_stmt, vn_lookup, vn_lookup_with_vuses): Remove
+ prototypes for removed functions.
+ (expressions_equal_p): Move to ...
+ * tree-ssa-sccvn.h: ... here and ...
+ * matrix-reorg.c: ... adjust includes.
+
+2009-06-07 Bernhard Reutner-Fischer <aldot@gcc.gnu.org>
+
+ * ipa-struct-reorg.c (do_reorg_1): Fix whitespace in dump output.
+
+2009-06-07 Bernhard Reutner-Fischer <aldot@gcc.gnu.org>
+
+ * c-decl.c (finish_decl): Use bool for variable was_incomplete.
+ (finish_function): Remove erroneous whitespace.
+
+2009-06-07 Bernhard Reutner-Fischer <aldot@gcc.gnu.org>
+
+ * tree-cfg.c (gimple_merge_blocks): Commentary typo fix.
+ (verify_stmts): Print statement who's gimple_bb is set to a wrong BB
+
+2009-06-07 Bernhard Reutner-Fischer <aldot@gcc.gnu.org>
+
+ * errors.c (internal_error): Commentary typo fix.
+ * gimple-iterator.c (gsi_insert_seq_on_edge): Ditto.
+ * tree-ssa-pre.c: Ditto.
+
+2009-06-07 Bernhard Reutner-Fischer <aldot@gcc.gnu.org>
+
+ * basic-block.h (ENTRY_BLOCK, EXIT_BLOCK): Document that neither of
+ them is supposed to hold actual statements.
+
+2009-06-06 Ian Lance Taylor <iant@google.com>
+
+ * doc/extend.texi (Attribute Syntax): Document that C++ labels on
+ empty statements can now have attributes.
+
+2009-06-05 Shujing Zhao <pearly.zhao@oracle.com>
+
+ * config/mips/mips.c: Use REG_P and CONST_INT_P where applicable.
+ * config/mips/mips.md: Ditto.
+
+2009-06-05 Nathan Froyd <froydnj@codesourcery.com>
+
+ * config/rs6000/eabi.asm (__eabi_convert): Don't define if
+ _RELOCATABLE.
+ (__eabi_uconvert): Likewise.
+
+2009-06-05 Nathan Froyd <froydnj@codesourcery.com>
+
+ * config/rs6000/ppc-asm.h: Protect auto-host.h inclusion and
+ CFI_* definitions with IN_GCC.
+
+2009-06-05 David Edelsohn <edelsohn@gnu.org>
+
+ * xcoffout.h (xcoffout_source_line): Update prototype.
+
+2009-06-05 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtins.c (do_mpc_ckconv, do_mpc_arg1): Use
+ mpc_realref/mpc_imagref instead of MPC_RE/MPC_IM.
+
+2009-06-05 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/40340
+ * tree-ssa-live.c (remove_unused_scope_block_p): Don't prune
+ inlined_function_outer_scope_p blocks for artificial inlines
+ even at -g0/-g1.
+ * tree.c (tree_nonartificial_location): Rewrite using
+ block_nonartificial_location.
+
+2009-06-05 Revital Eres <eres@il.ibm.com>
+ Leehod Baruch <leehod@il.ibm.com>
+
+ * expr.c (expand_assignment): Expand MISALIGNED_INDIRECT_REF.
+ (expand_expr_real_1): Remove comment.
+ * tree-vect-data-refs.c (vect_enhance_data_refs_alignment):
+ Vectorize misaligned access when the target supports it.
+ (vect_supportable_dr_alignment): Check for unaligned access
+ support.
+ * tree-vect-stmts.c (vectorizable_store): Generate misaligned store
+ and remove asset.
+
+2009-06-05 Julian Brown <julian@codesourcery.com>
+
+ * config/arm/ieee754-df.S (cmpdf2): Avoid writing below SP.
+ * config/arm/ieee754-sf.S (cmpsf2): Likewise.
+
+2009-06-05 Richard Guenther <rguenther@suse.de>
+
+ PR bootstrap/40350
+ * dwarf2out.c (dwarf2out_begin_function): Mark discriminator
+ as possibly unused.
+
+2009-06-05 Jakub Jelinek <jakub@redhat.com>
+
+ * config/s390/s390.c (global_not_special_regno_p): New static inline.
+ (save_gprs): Don't tell unwinder when a global register is saved.
+ (s390_emit_epilogue): Emit needed epilogue unwind info.
+
+2009-06-05 Alexandre Oliva <aoliva@redhat.com>
+
+ * dwarf2out.c (deferred_asm_name): New.
+ (add_name_and_src_coords_attributes): Defer creation of
+ DW_AT_MIPS_linkage_name attribute if DECL_ASSEMBLER_NAME was not
+ computed yet.
+ (move_linkage_attr): New.
+ (dwarf2out_finish): Revisit deferrals and emit attributes at the
+ right place.
+
+2009-06-05 Alexandre Oliva <aoliva@redhat.com>
+
+ * tree-nested.c (finalize_nesting_tree_1): Declare the
+ frame_decl in the binding tree.
+
+2009-06-04 Cary Coutant <ccoutant@google.com>
+
+ * basic-block.h (struct basic_block_def): Add discriminator field.
+ * dbxout.c (dbxout_source_line): Add new parameter. Change all
+ callers.
+ * debug.c (do_nothing_debug_hooks): Add additional entry.
+ (debug_nothing_int_charstar_int): New function.
+ * debug.h (struct gcc_debug_hooks): Add parameter to source_line
+ hook.
+ (debug_nothing_int_charstar_int): New declaration.
+ * dwarf2out.c (dwarf2out_source_line): Add new parameter. Write
+ discriminator value in .loc directive.
+ * final.c (last_discriminator): New variable.
+ (discriminator): New variable.
+ (final_start_function): Initialize above variables, pass current
+ discriminator to debug hook.
+ (notice_source_line): Check for discriminator change.
+ * gimple-pretty-print.c (dump_bb_header): Print discriminator value.
+ * sdbout.c (sdbout_source_line): New parameter.
+ * tree-cfg.c (struct locus_discrim_map): New structure type.
+ (discriminator_per_locus): New hash table.
+ (build_gimple_cfg): Allocate and free discriminator hash table.
+ (make_edges): Call assign_discriminator.
+ (locus_map_hash): New function.
+ (locus_map_eq): New function.
+ (next_discriminator_for_locus): New function.
+ (same_line_p): New function.
+ (assign_discriminator): New function.
+ (make_cond_expr_edges): Call assign_discriminator.
+ (make_gimple_switch_edges): Likewise.
+ (first_non_label_stmt): New function.
+ * vmsdbgout.c (vmsdbgout_source_line): Add new parameter. Change
+ all callers.
+ * xcoffout.c (xcoffout_source_line): Add new parameter.
+
+ * configure.ac (gcc_cv_as_discriminator): New configury check for
+ gas support for discriminator.
+ * configure: Regenerate.
+ * config.in: Regenerate.
+
+2009-06-04 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
+
+ * config/arm/arm.c (thumb2_legitimate_index_p): Initialize
+ val after checking for integers.
+
+2009-06-04 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/i386/i386.h (X86_64_MS_REGPARM_MAX): Rename from
+ X64_REGPARM_MAX.
+ (REGPARM_MAX): Use X86_64_MS_REGPARM_MAX.
+ (X86_64_MS_SSE_REGPARM_MAX): Rename from X64_SSE_REGPARM_MAX.
+ (SSE_REGPARM_MAX): Use X86_64_MS_SSE_REGPARM_MAX.
+ * config/i386/i386.c: Use X86_64_MS_REGPARM_MAX instead of
+ X64_REGPARM_MAX. Use X86_64_MS_SSE_REGPARM_MAX instead of
+ X64_SSE_REGPARM_MAX.
+ * config/i386/i386.md: Use X86_64_MS_SSE_REGPARM_MAX instead of
+ X64_SSE_REGPARM_MAX.
+
+2009-06-04 Alexandre Oliva <aoliva@redhat.com>
+
+ * gcc.c (report_times_to_file): New.
+ (execute): Implement it.
+ (process_command): Support -time=.
+ * doc/invoke.texi: Document it.
+
+2009-06-04 Alexandre Oliva <aoliva@redhat.com>
+
+ * tree-ssa-live.c (remove_unused_scope_block_p): Keep variables
+ that have value exprs.
+
+2009-06-04 Alexandre Oliva <aoliva@redhat.com>
+
+ * dwarf2asm.c (dw2_force_const_mem): Defer creation of
+ declarations for constants until...
+ (dw2_output_indirect_constant_1): ... this point.
+
+2009-06-04 Richard Earnshaw <rearnsha@arm.com>
+
+ PR target/10242
+ * arm.md (arm_addsi3): Don't try to split an add with an
+ eliminable register until after reload has completed.
+
+2009-06-03 Ian Lance Taylor <iant@google.com>
+
+ * dummy-checksum.c (executable_checksum): Use EXPORTED_CONST.
+ * genattrtab.c (write_length_unit_log): Likewise.
+ * genchecksum.c (dosum): Likewise.
+ * gengtype.c (write_rtx_next): Likewise.
+ (finish_root_table, write_roots): Likewise.
+ * gimple.c (gimple_ops_offset_): Likewise.
+ * tree-nomudflap.c (gt_ggc_r_gt_tree_mudflap_h): Likewise.
+ * config/arc/arc.c (arc_attribute_table): Likewise.
+ * config/arm/arm.c (arm_attribute_table): Likewise.
+ * config/avr/avr.c (avr_attribute_table): Likewise.
+ * config/crx/crx.c (crx_attribute_table): Likewise.
+ * config/m32r/m32r.c (m32r_attribute_table): Likewise.
+ * config/m68hc11/m68hc11.c (m68hc11_attribute_table): Likewise.
+ * config/mcore/mcore.c (mcore_attribute_table): Likewise.
+ * config/rs6000/rs6000.c (rs6000_attribute_table): Likewise.
+ * config/sh/sh.c (sh_attribute_table): Likewise.
+ * config/sparc/sparc.c (sparc_attribute_table): Likewise.
+ * config/spu/spu.c (spu_attribute_table): Likewise.
+ * config/v850/v850.c (v850_attribute_table): Likewise.
+
+ * config/alpha/alpha.c (vms_attribute_table): Make static.
+ * config/bfin/bfin.c (bfin_attribute_table): Likewise.
+ * config/h8300/h8300.c (h8300_attribute_table): Likewise.
+ * config/mips/mips.c (mips_attribute_table): Likewise.
+
+ * Makefile.in (dummy-checksum.o): Depend upon $(CONFIG_H) and
+ $(SYSTEM_H).
+ (cc1-checksum.o): Likewise.
+
+2009-06-03 Steve Ellcey <sje@cup.hp.com>
+
+ * config/ia64/vect.md (*movv2sf_internal): Handle big endian case.
+
+2009-06-03 Jakub Jelinek <jakub@redhat.com>
+
+ * config/rs6000/rs6000.c (rs6000_emit_stack_reset): Return generated
+ insn if it is changing sp. Use gen_add3_insn instead of
+ conditionally gen_addsi3 and gen_adddi3.
+ (offset_below_red_zone_p): New static inline function.
+ (rs6000_emit_epilogue): Emit needed epilogue unwind info.
+ Use gen_add3_insn instead of conditionally gen_addsi3 and gen_adddi3.
+ * config/rs6000/ppc-asm.h: Include auto-host.h.
+ (CFI_STARTPROC, CFI_ENDPROC, CFI_DEF_CFA_REGISTER, CFI_OFFSET,
+ CFI_RESTORE): Define.
+ * config/rs6000/crtresxgpr.asm: Add unwind info.
+ * config/rs6000/crtresxfpr.asm: Likewise.
+ * config/rs6000/crtresgpr.asm: Likewise.
+ * config/rs6000/crtresfpr.asm: Likewise.
+ * config/rs6000/crtsavgpr.asm: Likewise.
+ * config/rs6000/crtsavfpr.asm: Likewise.
+
+ * dwarf2out.c (output_cfi_directive): Pass 1 instead of
+ 0 to second argument of DWARF2_FRAME_REG_OUT macros.
+
+2009-06-03 Julian Brown <julian@codesourcery.com>
+
+ * config/arm/arm.c (arm_hard_regno_mode_ok): Permit values of four
+ words or less (including TImode) in core registers.
+
+2009-06-03 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/40328
+ * fold-const.c (fold_convert): Fold the build COMPLEX_EXPR.
+
+2009-06-03 Andrey Belevantsev <abel@ispras.ru>
+
+ * statistics.c (statistics_counter_event): Do not record event
+ in pass dump if its number == -1.
+ (curr_statistics_hash): Add assert that we never get passes
+ with static number == -1.
+
+2009-06-03 Richard Guenther <rguenther@suse.de>
+ Andrey Belevantsev <abel@ispras.ru>
+
+ * cfgexpand.c (discover_nonconstant_array_refs_r): Make only
+ non-BLKmode arrays addressable.
+
+2009-06-03 Maxim Kuvyrkov <maxim@codesourcery.com>
+
+ * config/m68k/linux.h (HAVE_GAS_BALIGN_AND_P2ALIGN): Move to ...
+ * config/m68k/m68k.h: ... here.
+ * testsuite/gcc.dg/falign-labels.c (dg-options): Don't restrict for
+ m68k and fido.
+
+2009-06-03 Martin Jambor <mjambor@suse.cz>
+
+ PR tree-optimization/40323
+ * ipa-prop.c (get_ssa_def_if_simple_copy): Break if not single
+ assignment.
+
+2009-06-03 Richard Guenther <rguenther@suse.de>
+
+ * tree-ssa-sccvn.c (copy_reference_ops_from_ref): Use DECL_SIZE
+ consistently.
+
+2009-06-03 Shujing Zhao <pearly.zhao@oracle.com>
+
+ * config/sh/predicates.md: Use REG_P, MEM_P, CONST_INT_P, LABEL_P,
+ JUMP_P, CALL_P, NONJUMP_INSN_P, NOTE_P, BARRIER_P and
+ JUMP_TABLE_DATA_P where applicable.
+ * config/sh/sh.c: Ditto.
+ * config/sh/sh.h: Ditto.
+ * config/sh/sh.md: Ditto.
+ * config/sh/symbian.c: Ditto.
+
+2009-06-03 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/i386/driver-i386.c (describe_cache): Optimize
+ concatenation of strings. Use snprintf instead of sprintf.
+ (host_detect_local_cpu): Ditto. Ignore -march and -mtune for native
+ target when not compiling with GCC.
+
+2009-06-02 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ * config/sh/sh.c: Revert last change.
+ (sh_expand_epilogue): Emit a blockage insn before the frame
+ pointer adjustment unconditionally.
+
+2009-06-02 Richard Sandiford <r.sandiford@uk.ibm.com>
+
+ * config/pa/pa-hpux.h (LINK_SPEC): Remove "%<fwhole-program".
+ * config/pa/pa-hpux10.h (LINK_SPEC): Likewise.
+ * config/pa/pa-hpux11.h (LINK_SPEC): Likewise.
+ * gcc.c (set_collect_gcc_options): Don't add -fwhole-program
+ to COLLECT_GCC_OPTIONS.
+
+2009-06-02 Richard Sandiford <r.sandiford@uk.ibm.com>
+
+ * collect2.c (target_system_root): New variable.
+ (main): Handle --sysroot=.
+ (ignore_library): Strip the sysroot from the library path.
+
+2009-06-02 Richard Sandiford <r.sandiford@uk.ibm.com>
+
+ * Makefile.in (COLLECT2_OBJS): Add collect2-aix.o.
+ (collect2.o): Depend on collect2-aix.h.
+ (collect2-aix.o): New rule.
+ * collect2-aix.h: New file.
+ * collect2-aix.c: Likewise.
+ * collect2.c: Include collect2-aix.h. Don't undefine
+ OBJECT_FORMAT_COFF if CROSS_AIX_SUPPORT is defined.
+ Guard native includes with #ifndef CROSS_DIRECTORY_STRUCTURE.
+ Use TARGET_AIX_VERSION instead of _AIX51.
+ * config/rs6000/aix43.h (TARGET_AIX_VERSION): Define.
+ * config/rs6000/aix51.h (TARGET_AIX_VERSION): Likewise.
+ * config/rs6000/aix52.h (TARGET_AIX_VERSION): Likewise.
+ * config/rs6000/aix53.h (TARGET_AIX_VERSION): Likewise.
+ * config/rs6000/aix61.h (TARGET_AIX_VERSION): Likewise.
+
+2009-06-02 Richard Sandiford <r.sandiford@uk.ibm.com>
+
+ * collect2.c (ignore_library): Avoid premature post-increment
+ and null deference.
+
+2009-06-02 Richard Sandiford <r.sandiford@uk.ibm.com>
+
+ * Makefile.in (libgcc.mvars): Add TARGET_SYSTEM_ROOT.
+ * config/rs6000/aix.h (LINK_SYSCALLS_SPEC): Add %R to the
+ !CROSS_DIRECTORY_STRUCTURE alternative and use it for
+ CROSS_DIRECTORY_STRUCTURE too.
+ (LINK_LIBG_SPEC): Likewise.
+ (LIB_SPEC): Add %R to sysroot paths.
+ * config/rs6000/aix43.h (CPP_SPEC): Add %R to sysroot paths.
+ (CPLUSPLUS_CPP_SPEC, LIB_SPEC): Likewise.
+ * config/rs6000/aix51.h: As for aix43.h.
+ * config/rs6000/aix52.h: Likewise.
+ * config/rs6000/aix53.h: Likewise.
+ * config/rs6000/aix61.h: Likewise.
+ * config/rs6000/t-aix52 (SHLIB_LINK): Add $(TARGET_SYSTEM_ROOT)
+ to the beginning of sysroot paths.
+
+2009-06-02 Alexandre Oliva <aoliva@redhat.com>
+
+ * print_rtl (print_rtx): Don't print modes in EXPR_LISTs and
+ INSN_LISTs that are out of the REG_NOTE range.
+
+2009-06-02 Alexandre Oliva <aoliva@redhat.com>
+
+ * loop-unroll.c (struct iv_to_split): Add pointer to next.
+ (struct var_to_expand): Likewise.
+ (struct opt_info): Add head and tail for linked lists of the above.
+ (analyze_insn_to_expand_var): Initialize next.
+ (analyze_iv_to_split_insn): Likewise.
+ (analyze_insns_in_loop): Create linked lists.
+ (allocate_basic_variable): Simplify for use without hash table.
+ (insert_var_expansion_initialization): Likewise, make it type-safer.
+ (combine_var_copies_in_loop_exit): Likewise.
+ (apply_opt_in_copies): Walk lists rather than hash tables.
+ (release_var_copies): Simplified and inlined by hand into...
+ (free_opt_info): ... this function.
+
+2009-06-02 Richard Guenther <rguenther@suse.de>
+
+ * tree-ssa-sccvn.c (copy_reference_ops_from_ref): Use DECL_SIZE
+ for field decls.
+
+2009-06-02 Alexandre Oliva <aoliva@redhat.com>
+
+ * cfgexpand.c (gimple_expand_cfg): Discard the source location
+ only for builtins that are not overridden.
+
+2009-06-02 Alexandre Oliva <aoliva@redhat.com>
+
+ * gengtype.c (adjust_field_rtx_def): Add NOTE_INSN_DELETED_LABEL's
+ label string.
+
+2009-06-02 Alexandre Oliva <aoliva@redhat.com>
+
+ * df-core.c (df_ref_debug): Honor -fdump-noaddr.
+
+2009-06-02 Alexandre Oliva <aoliva@redhat.com>
+
+ * combine.c (move_deaths): Compare LUIDs within the same BB only.
+
+2009-06-02 Alexandre Oliva <aoliva@redhat.com>
+
+ * common.opt (fdump-unnumbered-links): New.
+ * doc/invoke.texi (-fdump-unnumbered-links): Document it.
+ * print-rtl.c (flag_dump_unnumbered_links): New.
+ (print_rtx): Test it.
+
+2009-06-02 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.c (arm_get_frame_offsets): Prefer using r3 for padding a
+ push/pop multiple to 8-byte alignment.
+
+2009-06-01 Jakub Jelinek <jakub@redhat.com>
+
+ * config/i386/i386.c (queued_cfa_restores): New static variable.
+ (ix86_add_cfa_restore_note, ix86_add_queued_cfa_restore_notes): New
+ functions.
+ (pro_epilogue_adjust_stack): Call ix86_add_queued_cfa_restore_notes.
+ (ix86_emit_restore_reg_using_pop): Add RED_OFFSET argument.
+ Set RTX_FRAME_RELATED_P immediately after adding a REG_CFA_* note.
+ Call ix86_add_cfa_restore_note instead of adding REG_CFA_OFFSET
+ note unconditionally.
+ (ix86_emit_restore_regs_using_mov): Likewise.
+ (ix86_emit_restore_sse_regs_using_mov): Likewise.
+ (ix86_emit_restore_regs_using_pop): Add RED_OFFSET argument, pass
+ it through to ix86_emit_restore_reg_using_pop.
+ (ix86_emit_leave): Add RED_OFFSET argument. Call
+ ix86_add_queued_cfa_restore_notes. Call ix86_add_cfa_restore_note
+ instead of adding REG_CFA_OFFSET note unconditionally.
+ (ix86_expand_epilogue): Compute RED_OFFSET, pass it down to
+ the above functions. Call ix86_add_queued_cfa_restore_notes when
+ needed.
+
+ * dwarf2out.c (dwarf2out_cfi_label): Add FORCE argument, if true,
+ force output of the label even for dwarf2out_do_cfi_asm.
+ (add_fde_cfi): If -g2 and above and cfi might change CFA,
+ force creation of CFI label and chain DW_CFA_set_loc jumping to it
+ for convert_cfa_to_fb_loc_list. Adjust other dwarf2out_cfi_label
+ caller.
+ (dwarf2out_stack_adjust, dwarf2out_frame_debug,
+ dwarf2out_begin_epilogue, dwarf2out_frame_debug_restore_state): Adjust
+ dwarf2out_cfi_label callers.
+ * tree.h (dwarf2out_cfi_label): Adjust prototype.
+ * config/arm/arm.c (thumb_pushpop, thumb1_output_function_prologue):
+ Adjust dwarf2out_cfi_label callers.
+ * config/vax/vax.c (vax_output_function_prologue): Likewise.
+
+ * config/i386/i386.h (struct machine_cfa_state,
+ struct machine_function): Guard with ifndef USED_FOR_TARGET
+ instead of not IN_LIBGCC2 and not in IN_TARGET_LIBS.
+
+ PR other/40024
+ * emutls.c (__emutls_get_address): Change arr->size to mean number
+ of allocated arr->data entries instead of # of slots + 1.
+
+ PR middle-end/40316
+ * recog.c (peep2_reinit_state): New function.
+ (peephole2_init_state): Use it at the end of a basic block and also
+ when seeing a RTX_FRAME_RELATED_P insn.
+
+2009-06-01 Steve Ellcey <sje@cup.hp.com>
+
+ * ia64.md (floatdirf2, fix_truncrfdi, floatunsdirf,
+ fixuns_truncrfdi2): New.
+ (fix_truncxfdi2_alts, fixuns_truncxfdi2_alts,
+ *nmaddsf4_alts, *nmadddf4_alts, *nmadddf4_truncsf_alts,
+ *mulxf3_alts, *mulxf3_truncsf_alts, *mulxf3_truncdf_alts,
+ *maddxf4_alts, *maddxf4_alts_truncsf, *maddxf4_alts_truncdf,
+ *nmaddxf4_alts, *nmaddxf4_truncsf_alts, *nmaddxf4_truncdf_alts,
+ *recip_approx): Remove.
+ (divsi3 modsi3, udivsi3, umodsi3, divsi3_internal, divdi3,
+ moddi3, udivdi3, umoddi3, divdi3_internal_lat, divdi3_internal_thr,
+ divsf3, sqrtsf2, divdf3, sqrtdf2, divxf3, sqrtxf2): Modify and
+ move to div.md.
+ * div.md (fix_truncrfdi2_alts, fixuns_truncrfdi2_alt,
+ setf_exp_rf): New.
+
+2009-06-01 Ian Lance Taylor <iant@google.com>
+
+ * attribs.c (register_attribute): Use CONST_CAST.
+ * collect2.c (main): Use CONST_CAST2.
+ (scan_prog_file): Likewise.
+ * gcc.c (process_command, main): Likewise.
+ * toplev.c (toplev_main): Likewise.
+
+ * c-typeck.c (handle_warn_cast_qual): New static function,
+ partially broken out of build_c_cast.
+ (build_c_cast): Call handle_warn_cast_qual.
+ * doc/invoke.texi (Warning Options): Document new effect of
+ -Wcast-qual.
+
+2009-06-01 Aldy Hernandez <aldyh@redhat.com>
+
+ * diagnostic.c (diagnostic_build_prefix): Always print columns.
+ (diagnostic_report_current_module): Print columns.
+ * common.opt (flag_show_column): Enable by default.
+
+2009-06-01 Luis Machado <luisgpm@br.ibm.com>
+
+ * alias.c (find_base_term): Check for NULL term before returning.
+
+2009-06-01 Maxim Kuvyrkov <maxim@codesourcery.com>
+
+ Revert due to PR40320:
+ 2009-06-01 Maxim Kuvyrkov <maxim@codesourcery.com>
+ * calls.c (emit_library_call_value_1): Don't force_operand for move
+ and push insns.
+
+2009-06-01 Olivier Hainque <hainque@adacore.com>
+ Eric Botcazou <ebotcazou@adacore.com>
+
+ * tree.h (CONSTRUCTOR_BITFIELD_P): True if NODE, a FIELD_DECL, is
+ to be processed as a bitfield for constructor output purposes.
+ * output.h (initializer_constant_valid_for_bitfield_p): Declare
+ new function.
+ * varasm.c (oc_local_state): New type, output_constructor
+ local state to support communication with helpers.
+ (oc_outer_state): New type, output_constructor outer state of
+ relevance in recursive calls.
+ (output_constructor_array_range): New output_constructor helper,
+ extracted code for an array range element.
+ (output_constructor_regular_field): New output_constructor helper,
+ extracted code for an element that is not a bitfield.
+ (output_constructor_bitfield): New output_constructor helper,
+ extracted code for a bitfield element. Accept an OUTER state
+ argument for recursive processing. Recurse on record or array
+ CONSTRUCTOR values, possibly past noop conversions.
+ (initializer_constant_valid_for_bitfield_p): New predicate. Whether
+ VALUE is a valid constant-valued expression for use in a static
+ bit-field initializer.
+ (output_constructor): Rework to use helpers. Accept and honor an
+ OUTER state argument for recursive calls. Return total size. Be
+ prepared for nested constructors initializing bitfields.
+ (output_constant): Feed OUTER in calls to output_constructor.
+
+2009-06-01 Maxim Kuvyrkov <maxim@codesourcery.com>
+
+ * calls.c (emit_library_call_value_1): Don't force_operand for move
+ and push insns.
+
+2009-06-01 Nick Clifton <nickc@redhat.com>
+
+ * doc/invoke.texi (IA-64 Options): Fix typo.
+
+2009-06-01 Ira Rosen <irar@il.ibm.com>
+
+ PR tree-optimization/39129
+ * tree-vect-loop-manip.c (conservative_cost_threshold): Change the
+ printed message.
+ (vect_do_peeling_for_loop_bound): Use
+ LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT and
+ LOOP_REQUIRES_VERSIONING_FOR_ALIAS macros.
+ (vect_loop_versioning): Likewise.
+ (vect_create_cond_for_alias_checks): Fix indentation.
+ * tree-vectorizer.h (struct _loop_vec_info): Fix indentation of the
+ macros.
+ (LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT): Define.
+ (LOOP_REQUIRES_VERSIONING_FOR_ALIAS): Likewise.
+ * tree-vect-loop.c (vect_analyze_loop_form): Change "too many BBs" to
+ "control flow in loop".
+ (vect_estimate_min_profitable_iters): Use
+ LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT and
+ LOOP_REQUIRES_VERSIONING_FOR_ALIAS macros.
+ * tree-vect-data-refs.c (vect_enhance_data_refs_alignment): Likewise.
+ (vect_create_data_ref_ptr): Don't mention array dimension in printing.
+ * tree-vect-stmts.c (vectorizable_store): Replace the check that the
+ statement belongs to a group of strided accesses with the exact code
+ check.
+ (vectorizable_load): Likewise.
+ * tree-vect-slp.c (vect_analyze_slp_instance): Spell out "basic block".
+ (vect_slp_analyze_bb, vect_slp_transform_bb): Likewise.
+
+2009-06-01 Gerald Pfeifer <gerald@pfeifer.com>
+
+ * config/freebsd-stdint.h: New file.
+ * config.gcc (*-*-freebsd): Set use_gcc_stdint=wrap.
+ Add freebsd-stdint.h to tm_file.
+
+2009-06-01 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm/thumb2.md (thumb2_zero_extendhidi2): New insn and split.
+ (thumb2_extendhidi2): Likewise.
+
+2009-05-31 Ian Lance Taylor <iant@google.com>
+
+ * regstat.c (regstat_n_sets_and_refs): Remove duplicate definition.
+
+2009-05-31 Ian Lance Taylor <iant@google.com>
+
+ * Makefile.in (except.o): Depend upon gt-except.h, not gt-$(EXCEPT_H).
+ (ipa-cp.o): Depend upon $(FIBHEAP_H) and $(PARAMS_H).
+ (ipa-reference.o): Depend upon gt-ipa-reference.h.
+
+2009-05-31 Jason Merrill <jason@redhat.com>
+
+ * tree-pretty-print.c (print_call_name): Take the callee, not the
+ call itself. Make non-static. Use dump_function_name for functions.
+ (dump_generic_node): Adjust.
+ * diagnostic.h: Declare print_call_name.
+ * gimple-pretty-print.c (dump_gimple_call): Use it.
+
+2009-05-31 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ * config/sh/sh.md (ashldi3_std): New define_expand.
+ (ashldi3): Use it.
+
+2009-05-31 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ PR target/40313
+ * config/sh/sh.c: Include debug.h.
+ (sh_expand_epilogue): Emit a blockage insn before the frame
+ pointer adjustment also when dwarf2out_do_frame returns true.
+
+2009-05-31 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm/thumb2.md (thumb2_extendsidi2): Add a split sub-pattern.
+ (thumb2_extendqidi2): New pattern.
+
+2009-05-31 Ira Rosen <irar@il.ibm.com>
+
+ * tree-vect-loop-manip.c (slpeel_update_phi_nodes_for_guard1): Don't
+ mark phis for renaming.
+ * tree-vectorizer.c (vect_memsyms_to_rename): Remove.
+ (vectorize_loops): Don't allocate and free vect_memsyms_to_rename.
+ Call mark_sym_for_renaming.
+ * tree-vectorizer.h (vect_memsyms_to_rename): Remove.
+ * tree-vect-loop.c (vect_transform_loop): Remove
+ vect_memsyms_to_rename initialization and a call to
+ mark_set_for_renaming.
+
+2009-05-31 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/40304
+ * config/i386/i386.c (pro_epilogue_adjust_stack): Mark insns
+ frame related even if !set_cfa && style < 0.
+
+2009-05-30 Kai Tietz <kai.tietz@onevision.com>
+
+ * config/i386/mingw-tls.c: New file.
+ * config/i386/t-gthr-win32 (LIB2FUNCS_EXTRA): Add mingw-tls.c file.
+ * gthr-win32.h (MINGW32_SUPPORTS_MT_EH): Define it for targets
+ defining _WIN32 but not __CYGWIN__.
+
+2009-05-29 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * configure.ac: Add MPC support.
+
+ * config.in, configure: Regenerate.
+
+2009-05-29 Richard Henderson <rth@redhat.com>
+
+ * cfgcleanup.c (try_crossjump_to_edge): Only skip past
+ NOTE_INSN_BASIC_BLOCK.
+ * cfglayout.c (duplicate_insn_chain): Copy epilogue insn marks.
+ Duplicate NOTE_INSN_EPILOGUE_BEG notes.
+ * cfgrtl.c (can_delete_note_p): Allow NOTE_INSN_EPILOGUE_BEG
+ to be deleted.
+ * dwarf2out.c (struct cfa_loc): Change indirect field to bitfield,
+ add in_use field.
+ (add_cfi): Disable check redefining cfa away from drap.
+ (lookup_cfa_1): Add remember argument; handle remember/restore.
+ (lookup_cfa): Pass remember argument.
+ (cfa_remember): New.
+ (compute_barrier_args_size_1): Remove sibcall check.
+ (dwarf2out_frame_debug_def_cfa): New.
+ (dwarf2out_frame_debug_adjust_cfa): New.
+ (dwarf2out_frame_debug_cfa_offset): New.
+ (dwarf2out_frame_debug_cfa_register): New.
+ (dwarf2out_frame_debug_cfa_restore): New.
+ (dwarf2out_frame_debug): Handle REG_CFA_* notes.
+ (dwarf2out_begin_epilogue): New.
+ (dwarf2out_frame_debug_restore_state): New.
+ (dw_cfi_oprnd1_desc): Handle DW_CFA_remember_state,
+ DW_CFA_restore_state.
+ (output_cfi_directive): Likewise.
+ (convert_cfa_to_fb_loc_list): Likewise.
+ (dw_cfi_oprnd1_desc): Handle DW_CFA_restore.
+ * dwarf2out.h: Update.
+ * emit-rtl.c (try_split): Don't split RTX_FRAME_RELATED_P.
+ (copy_insn_1): Early out for null.
+ * final.c (final_scan_insn): Call dwarf2out_begin_epilogue
+ and dwarf2out_frame_debug_restore_state.
+ * function.c (prologue, epilogue, sibcall_epilogue): Remove.
+ (prologue_insn_hash, epilogue_insn_hash): New.
+ (free_after_compilation): Adjust freeing accordingly.
+ (record_insns): Create hash table if needed; push insns into
+ hash instead of array.
+ (maybe_copy_epilogue_insn): New.
+ (contains): Search hash table instead of array.
+ (sibcall_epilogue_contains): Remove.
+ (thread_prologue_and_epilogue_insns): Split eh_return insns
+ and mark them as epilogues.
+ (reposition_prologue_and_epilogue_notes): Rewrite epilogue
+ scanning in terms of basic blocks.
+ * insn-notes.def (CFA_RESTORE_STATE): New.
+ * jump.c (returnjump_p_1): Accept EH_RETURN.
+ (eh_returnjump_p_1, eh_returnjump_p): New.
+ * reg-notes.def (CFA_DEF_CFA, CFA_ADJUST_CFA, CFA_OFFSET,
+ CFA_REGISTER, CFA_RESTORE): New.
+ * rtl.def (EH_RETURN): New.
+ * rtl.h (eh_returnjump_p, maybe_copy_epilogue_insn): Declare.
+
+ * config/bfin/bfin.md (UNSPEC_VOLATILE_EH_RETURN): Remove.
+ (eh_return_internal): Use eh_return rtx; split w/ epilogue.
+
+ * config/i386/i386.c (gen_push): Update cfa state.
+ (pro_epilogue_adjust_stack): Add set_cfa argument. When true,
+ add a CFA_ADJUST_CFA note.
+ (ix86_dwarf_handle_frame_unspec): Remove.
+ (ix86_expand_prologue): Update cfa state.
+ (ix86_emit_restore_reg_using_pop): New.
+ (ix86_emit_restore_regs_using_pop): New.
+ (ix86_emit_leave): New.
+ (ix86_emit_restore_regs_using_mov): Add CFA_RESTORE notes.
+ (ix86_expand_epilogue): Add notes for unwinding the epilogue.
+ * config/i386/i386.h (struct machine_cfa_state): New.
+ (ix86_cfa_state): New.
+ * config/i386/i386.md (UNSPEC_EH_RETURN): Remove.
+ (eh_return_internal): Merge from eh_return_<mode>,
+ use eh_return rtx, split w/ epilogue.
+
+2009-05-29 Ian Lance Taylor <iant@google.com>
+
+ * builtins.c (validate_gimple_arglist): Don't use va_arg with
+ enum type.
+ * calls.c (emit_library_call_value_1): Likewise.
+
+ * c-typeck.c (c_build_va_arg): New function.
+ * c-tree.h (c_build_va_arg): Declare.
+ * c-parser.c (c_parser_postfix_expression): Call c_build_va_arg
+ instead of build_va_arg.
+
+2009-05-29 Eric Botcazou <ebotcazou@adacore.com>
+
+ * tree-ssa-loop-ivopts.c (strip_offset_1) <MULT_EXPR>: New case.
+ (force_expr_to_var_cost) <NEGATE_EXPR>: Likewise.
+ (ptr_difference_cost): Use affine combinations to compute it.
+ (difference_cost): Likewise.
+ (get_computation_cost_at): Compute more accurate cost for addresses
+ if the ratio is a multiplier allowed in addresses.
+ For non-addresses, consider that an additional offset or symbol is
+ added only once.
+
+2009-05-29 Jakub Jelinek <jakub@redhat.com>
+
+ * config/i386/i386.c (ix86_decompose_address): Avoid useless
+ 0 displacement. Add 0 displacement if base is %[er]bp or %r13.
+
+ * config/i386/i386.md (prefix_data16, prefix_rep): Set to 0 for
+ TYPE_SSE{MULADD,4ARG,IADD1,CVT1} by default.
+ (prefix_rex): For UNIT_MMX don't imply the prefix by default
+ if MODE_DI.
+ (prefix_extra): Default to 2 for TYPE_SSE{MULADD,4ARG} and
+ to 1 for TYPE_SSE{IADD1,CVT1}.
+ (prefix_vex_imm8): Removed.
+ (length_vex): Only pass 1 as second argument to
+ ix86_attr_length_vex_default if prefix_extra is 0.
+ (modrm): For TYPE_INCDEC only set to 0 if not TARGET_64BIT.
+ (length): For prefix vex computation use length_immediate
+ attribute instead of prefix_vex_imm8.
+ (cmpqi_ext_3_insn, cmpqi_ext_3_insn_rex64,
+ addqi_ext_1, addqi_ext_1_rex64, *testqi_ext_0, andqi_ext_0,
+ *andqi_ext_0_cc, *iorqi_ext_0, *xorqi_ext_0, *xorqi_cc_ext_1,
+ *xorqi_cc_ext_1_rex64): Override modrm attribute to 1.
+ (extendsidi2_rex64, extendhidi2, extendqidi2, extendhisi2,
+ *extendhisi2_zext, extendqihi2, extendqisi2, *extendqisi2_zext): Emit
+ a space in between the operands.
+ (*anddi_1_rex64, *andsi_1): Likewise. Override prefix_rex to 1
+ if one operand is 0xff and the other one si, di, bp or sp.
+ (*andhi_1): Override prefix_rex to 1 if one operand is 0xff and the
+ other one si, di, bp or sp.
+ (*btsq, *btrq, *btcq, *btdi_rex64, *btsi): Add mode attribute.
+ (*ffssi_1, *ffsdi_1, ctzsi2, ctzdi2): Add
+ type and mode attributes.
+ (*bsr, *bsr_rex64, *bsrhi): Add type attribute.
+ (*cmpfp_i_mixed, *cmpfp_iu_mixed): For TYPE_SSECOMI, clear
+ prefix_rep attribute and set prefix_data16 attribute iff MODE_DF.
+ (*cmpfp_i_sse, *cmpfp_iu_sse): Clear prefix_rep attribute and set
+ prefix_data16 attribute iff MODE_DF.
+ (*movsi_1): For TYPE_SSEMOV MODE_SI set prefix_data16 attribute.
+ (fix_trunc<mode>di_sse): Set prefix_rex attribute.
+ (*adddi_4_rex64, *addsi_4): Use const128_operand instead of
+ constm128_operand in length_immediate computation.
+ (*addhi_4): Likewise. Fix mode attribute to MODE_HI.
+ (anddi_1_rex64): Use movzbl/movzwl instead of movzbq/movzwq.
+ (*avx_ashlti3, sse2_ashlti3, *avx_lshrti3, sse2_lshrti3): Set
+ length_immediate attribute to 1.
+ (x86_fnstsw_1, x86_fnstcw_1, x86_fldcw_1): Fix length attribute.
+ (*movdi_1_rex64): Override prefix_rex or prefix_data16 attributes
+ for certain alternatives.
+ (*movdf_nointeger, *movdf_integer_rex64, *movdf_integer): Override
+ prefix_data16 attribute if MODE_V1DF.
+ (*avx_setcc<mode>, *sse_setcc<mode>, *sse5_setcc<mode>): Set
+ length_immediate to 1.
+ (set_got_rex64, set_rip_rex64): Remove length attribute, set
+ length_address to 4, set mode attribute to MODE_DI.
+ (set_got_offset_rex64): Likewise. Set length_immediate to 0.
+ (fxam<mode>2_i387): Set length attribute to 4.
+ (*prefetch_sse, *prefetch_sse_rex, *prefetch_3dnow,
+ *prefetch_3dnow_rex): Override length_address attribute.
+ (sse4_2_crc32<mode>): Override prefix_data16 and prefix_rex
+ attributes.
+ * config/i386/predicates.md (ext_QIreg_nomode_operand): New predicate.
+ (constm128_operand): Removed.
+ * config/i386/i386.c (memory_address_length): For
+ disp && !index && !base in 64-bit mode account for SIB byte if
+ print_operand_address can't optimize disp32 into disp32(%rip)
+ and UNSPEC doesn't imply (%rip) addressing. Add 1 to length
+ for fs: or gs: segment.
+ (ix86_attr_length_immediate_default): When checking if shortform
+ is possible, truncate immediate to the length of the non-shortened
+ immediate.
+ (ix86_attr_length_address_default): Ignore MEM_P operands
+ with X constraint.
+ (ix86_attr_length_vex_default): Only check for DImode on
+ GENERAL_REG_P operands.
+ * config/i386/sse.md (<sse>_comi, <sse>_ucomi): Clear
+ prefix_rep attribute, set prefix_data16 attribute iff MODE_DF.
+ (sse_cvttps2pi): Clear prefix_rep attribute.
+ (sse2_cvttps2dq, *sse2_cvtpd2dq, sse2_cvtps2pd): Clear prefix_data16
+ attribute.
+ (*sse2_cvttpd2dq): Don't clear prefix_rep attribute.
+ (*avx_ashr<mode>3, ashr<mode>3, *avx_lshr<mode>3, lshr<mode>3,
+ *avx_ashl<mode>3, ashl<mode>3): Set length_immediate attribute to 1
+ iff operand 2 is const_int_operand.
+ (*vec_dupv4si, avx_shufpd256_1, *avx_shufpd_<mode>,
+ sse2_shufpd_<mode>): Set length_immediate attribute to 1.
+ (sse2_pshufd_1): Likewise. Set prefix attribute to maybe_vex
+ instead of vex.
+ (sse2_pshuflw_1, sse2_pshufhw_1): Set length_immediate to 1 and clear
+ prefix_data16.
+ (sse2_unpckhpd, sse2_unpcklpd, sse2_storehpd, *vec_concatv2df): Set
+ prefix_data16 attribute for movlpd and movhpd instructions.
+ (sse2_loadhpd, sse2_loadlpd, sse2_movsd): Likewise. Override
+ length_immediate for shufpd instruction.
+ (sse2_movntsi, sse3_lddqu): Clear prefix_data16 attribute.
+ (avx_cmpp<avxmodesuffixf2c><mode>3,
+ avx_cmps<ssemodesuffixf2c><mode>3, *avx_maskcmp<mode>3,
+ <sse>_maskcmp<mode>3, <sse>_vmmaskcmp<mode>3,
+ avx_shufps256_1, *avx_shufps_<mode>, sse_shufps_<mode>,
+ *vec_dupv4sf_avx, *vec_dupv4sf): Set length_immediate attribute to 1.
+ (*avx_cvtsi2ssq, *avx_cvtsi2sdq): Set length_vex attribute to 4.
+ (sse_cvtsi2ssq, sse2_cvtsi2sdq): Set prefix_rex attribute to 1.
+ (sse2_cvtpi2pd, sse_loadlps, sse2_storelpd): Override
+ prefix_data16 attribute for the first alternative to 1.
+ (*avx_loadlps): Override length_immediate for the first alternative.
+ (*vec_concatv2sf_avx): Override length_immediate and prefix_extra
+ attributes for second alternative.
+ (*vec_concatv2sf_sse4_1): Override length_immediate and
+ prefix_data16 attributes for second alternative.
+ (*vec_setv4sf_avx, *avx_insertps, vec_extract_lo_<mode>,
+ vec_extract_hi_<mode>, vec_extract_lo_v16hi,
+ vec_extract_hi_v16hi, vec_extract_lo_v32qi,
+ vec_extract_hi_v32qi): Set prefix_extra and length_immediate to 1.
+ (*vec_setv4sf_sse4_1, sse4_1_insertps, *sse4_1_extractps): Set
+ prefix_data16 and length_immediate to 1.
+ (*avx_mulv2siv2di3, *avx_mulv4si3, sse4_2_gtv2di3): Set prefix_extra
+ to 1.
+ (*avx_<code><mode>3, *avx_eq<mode>3, *avx_gt<mode>3): Set
+ prefix_extra attribute for variants that don't have 0f prefix alone.
+ (*avx_pinsr<ssevecsize>): Likewise. Set length_immediate to 1.
+ (*sse4_1_pinsrb, *sse2_pinsrw, *sse4_1_pinsrd, *sse4_1_pextrb,
+ *sse4_1_pextrb_memory, *sse2_pextrw, *sse4_1_pextrw_memory,
+ *sse4_1_pextrd): Set length_immediate to 1.
+ (*sse4_1_pinsrd): Likewise. Set prefix_extra to 1.
+ (*sse4_1_pinsrq, *sse4_1_pextrq): Set prefix_rex and length_immediate
+ to 1.
+ (*vec_extractv2di_1_rex64_avx, *vec_extractv2di_1_rex64,
+ *vec_extractv2di_1_avx, *vec_extractv2di_1_sse2): Override
+ length_immediate to 1 for second alternative.
+ (*vec_concatv2si_avx, *vec_concatv2di_rex64_avx): Override
+ prefix_extra and length_immediate attributes for the first
+ alternative.
+ (vec_concatv2si_sse4_1): Override length_immediate to 1 for the
+ first alternative.
+ (*vec_concatv2di_rex64_sse4_1): Likewise. Override prefix_rex
+ to 1 for the first and third alternative.
+ (*vec_concatv2di_rex64_sse): Override prefix_rex to 1 for the second
+ alternative.
+ (*sse2_maskmovdqu, *sse2_maskmovdqu_rex64): Override length_vex
+ attribute.
+ (*sse_sfence, sse2_mfence, sse2_lfence): Override length_address
+ attribute to 0.
+ (*avx_phaddwv8hi3, *avx_phadddv4si3, *avx_phaddswv8hi3,
+ *avx_phsubwv8hi3, *avx_phsubdv4si3, *avx_phsubswv8hi,
+ *avx_pmaddubsw128, *avx_pmulhrswv8hi3, *avx_pshufbv16qi3,
+ *avx_psign<mode>3): Set prefix_extra attribute to 1.
+ (ssse3_phaddwv4hi3, ssse3_phadddv2si3, ssse3_phaddswv4hi3,
+ ssse3_phsubwv4hi3, ssse3_phsubdv2si3, ssse3_phsubswv4hi3,
+ ssse3_pmaddubsw, *ssse3_pmulhrswv4hi, ssse3_pshufbv8qi3,
+ ssse3_psign<mode>3): Override prefix_rex attribute.
+ (*avx_palignrti): Override prefix_extra and length_immediate to 1.
+ (ssse3_palignrti): Override length_immediate to 1.
+ (ssse3_palignrdi): Override length_immediate to 1, override
+ prefix_rex attribute.
+ (abs<mode>2): Override prefix_rep to 0, override prefix_rex attribute.
+ (sse4a_extrqi): Override length_immediate to 2.
+ (sse4a_insertqi): Likewise. Override prefix_data16 to 0.
+ (sse4a_insertq): Override prefix_data16 to 0.
+ (avx_blendp<avxmodesuffixf2c><avxmodesuffix>,
+ avx_blendvp<avxmodesuffixf2c><avxmodesuffix>,
+ avx_dpp<avxmodesuffixf2c><avxmodesuffix>, *avx_mpsadbw,
+ *avx_pblendvb, *avx_pblendw, avx_roundp<avxmodesuffixf2c>256,
+ avx_rounds<avxmodesuffixf2c>256): Override prefix_extra
+ and length_immediate to 1.
+ (sse4_1_blendp<ssemodesuffixf2c>, sse4_1_dpp<ssemodesuffixf2c>,
+ sse4_2_pcmpestr, sse4_2_pcmpestri, sse4_2_pcmpestrm,
+ sse4_2_pcmpestr_cconly, sse4_2_pcmpistr, sse4_2_pcmpistri,
+ sse4_2_pcmpistrm, sse4_2_pcmpistr_cconly): Override prefix_data16
+ and length_immediate to 1.
+ (sse4_1_blendvp<ssemodesuffixf2c>): Override prefix_data16 to 1.
+ (sse4_1_mpsadbw, sse4_1_pblendw): Override length_immediate to 1.
+ (*avx_packusdw, avx_vtestp<avxmodesuffixf2c><avxmodesuffix>,
+ avx_ptest256): Override prefix_extra to 1.
+ (sse4_1_roundp<ssemodesuffixf2c>, sse4_1_rounds<ssemodesuffixf2c>):
+ Override prefix_data16 and length_immediate to 1.
+ (sse5_pperm_zero_v16qi_v8hi, sse5_pperm_sign_v16qi_v8hi,
+ sse5_pperm_zero_v8hi_v4si, sse5_pperm_sign_v8hi_v4si,
+ sse5_pperm_zero_v4si_v2di, sse5_pperm_sign_v4si_v2di,
+ sse5_vrotl<mode>3, sse5_ashl<mode>3, sse5_lshl<mode>3): Override
+ prefix_data16 to 0 and prefix_extra to 2.
+ (sse5_rotl<mode>3, sse5_rotr<mode>3): Override length_immediate to 1.
+ (sse5_frcz<mode>2, sse5_vmfrcz<mode>2): Don't override prefix_extra
+ attribute.
+ (*sse5_vmmaskcmp<mode>3, sse5_com_tf<mode>3,
+ sse5_maskcmp<mode>3, sse5_maskcmp<mode>3, sse5_maskcmp_uns<mode>3):
+ Override prefix_data16 and prefix_rep to 0, length_immediate to 1
+ and prefix_extra to 2.
+ (sse5_maskcmp_uns2<mode>3, sse5_pcom_tf<mode>3): Override
+ prefix_data16 to 0, length_immediate to 1 and prefix_extra to 2.
+ (*avx_aesenc, *avx_aesenclast, *avx_aesdec, *avx_aesdeclast,
+ avx_vpermilvar<mode>3,
+ avx_vbroadcasts<avxmodesuffixf2c><avxmodesuffix>,
+ avx_vbroadcastss256, avx_vbroadcastf128_p<avxmodesuffixf2c>256,
+ avx_maskloadp<avxmodesuffixf2c><avxmodesuffix>,
+ avx_maskstorep<avxmodesuffixf2c><avxmodesuffix>):
+ Override prefix_extra to 1.
+ (aeskeygenassist, pclmulqdq): Override length_immediate to 1.
+ (*vpclmulqdq, avx_vpermil<mode>, avx_vperm2f128<mode>3,
+ vec_set_lo_<mode>, vec_set_hi_<mode>, vec_set_lo_v16hi,
+ vec_set_hi_v16hi, vec_set_lo_v32qi, vec_set_hi_v32qi): Override
+ prefix_extra and length_immediate to 1.
+ (*avx_vzeroall, avx_vzeroupper, avx_vzeroupper_rex64): Override
+ modrm to 0.
+ (*vec_concat<mode>_avx): Override prefix_extra and length_immediate
+ to 1 for the first alternative.
+ * config/i386/mmx.md (*mov<mode>_internal_rex64): Override
+ prefix_rep, prefix_data16 and/or prefix_rex attributes in certain
+ cases.
+ (*mov<mode>_internal_avx, *movv2sf_internal_rex64,
+ *movv2sf_internal_avx, *movv2sf_internal): Override
+ prefix_rep attribute for certain alternatives.
+ (*mov<mode>_internal): Override prefix_rep or prefix_data16
+ attributes for certain alternatives.
+ (*movv2sf_internal_rex64_avx): Override prefix_rep and length_vex
+ attributes for certain alternatives.
+ (*mmx_addv2sf3, *mmx_subv2sf3, *mmx_mulv2sf3,
+ *mmx_<code>v2sf3_finite, *mmx_<code>v2sf3, mmx_rcpv2sf2,
+ mmx_rcpit1v2sf3, mmx_rcpit2v2sf3, mmx_rsqrtv2sf2, mmx_rsqit1v2sf3,
+ mmx_haddv2sf3, mmx_hsubv2sf3, mmx_addsubv2sf3,
+ *mmx_eqv2sf3, mmx_gtv2sf3, mmx_gev2sf3, mmx_pf2id, mmx_pf2iw,
+ mmx_pi2fw, mmx_floatv2si2, mmx_pswapdv2sf2, *mmx_pmulhrwv4hi3,
+ mmx_pswapdv2si2): Set prefix_extra attribute to 1.
+ (mmx_ashr<mode>3, mmx_lshr<mode>3, mmx_ashl<mode>3): Set
+ length_immediate to 1 if operand 2 is const_int_operand.
+ (*mmx_pinsrw, mmx_pextrw, mmx_pshufw_1, *vec_dupv4hi,
+ *vec_extractv2si_1): Set length_immediate attribute to 1.
+ (*mmx_uavgv8qi3): Override prefix_extra attribute to 1 if
+ using old 3DNOW insn rather than SSE/3DNOW_A.
+ (mmx_emms, mmx_femms): Clear modrm attribute.
+
+2009-05-29 Martin Jambor <mjambor@suse.cz>
+
+ * tree-sra.c: New implementation of SRA.
+
+ * params.def (PARAM_SRA_MAX_STRUCTURE_SIZE): Removed.
+ (PARAM_SRA_MAX_STRUCTURE_COUNT): Removed.
+ (PARAM_SRA_FIELD_STRUCTURE_RATIO): Removed.
+ * params.h (SRA_MAX_STRUCTURE_SIZE): Removed.
+ (SRA_MAX_STRUCTURE_COUNT): Removed.
+ (SRA_FIELD_STRUCTURE_RATIO): Removed.
+ * doc/invoke.texi (sra-max-structure-size): Removed.
+ (sra-field-structure-ratio): Removed.
+
+2009-05-29 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/40291
+ * builtins.c (expand_builtin_memcmp): Convert len to sizetype
+ before expansion.
+
+2009-05-29 Andrey Belevantsev <abel@ispras.ru>
+
+ PR rtl-optimization/40101
+ * sel-sched-ir.c (get_seqno_by_preds): Allow returning negative
+ seqno. Adjust comment.
+ * sel-sched.c (find_seqno_for_bookkeeping): Assert that when
+ inserting bookkeeping before a jump, the jump is not scheduled.
+ When no positive seqno found, provide a value. Add comment.
+
+2009-05-29 Richard Guenther <rguenther@suse.de>
+
+ * tree-ssa-alias.c (nonaliasing_component_refs_p): Remove
+ short-cutting on the first component.
+
+2009-05-29 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/39958
+ * omp-low.c (scan_omp_1_op): Call remap_type on TREE_TYPE
+ for trees other than decls/types.
+
+2009-05-29 Richard Guenther <rguenther@suse.de>
+
+ * tree-ssa-operands.c (get_expr_operands): Do not handle
+ INDIRECT_REFs in the handled-component case. Remove
+ unused get_ref_base_and_extent case.
+ * tree-dfa.c (get_ref_base_and_extent): Avoid calling
+ tree_low_cst and host_integerp where possible.
+ * tree-ssa-structalias.c (equiv_class_label_eq): Check hash
+ codes for equivalence.
+ * dce.c (find_call_stack_args): Avoid redundant bitmap queries.
+
+2009-05-29 David Billinghurst <billingd@gcc.gnu.org>
+
+ * config.gcc: Add i386/t-fprules-softfp and soft-fp/t-softfp
+ to tmake_file for i[34567]86-*-cygwin*.
+
+2009-05-29 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/40017
+ * config/rs6000/rs6000-c.c (_Bool_keyword): New variable.
+ (altivec_categorize_keyword, init_vector_keywords,
+ rs6000_cpu_cpp_builtins): Define _Bool as conditional macro
+ similar to bool.
+
+2009-05-29 Kai Tietz <kai.tietz@onevision.com>
+
+ * tree.c (handle_dll_attribute): Check if node is
+ of kind FUNCTION_DECL for DECL_DECLARED_INLINE_P check.
+
+2009-05-29 Richard Earnshaw <rearnsha@arm.com>
+
+ * config/arm/thumb2.md (thumb2_zero_extendsidi2): Add a split
+ component.
+ (thumb2_zero_extendqidi2): Likewise.
+
+2009-05-28 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ * config/sh/sh.c (sh_expand_t_scc): Use gen_xorsi3_movrt
+ instead of gen_movrt.
+ * config/sh/sh.md (movrt): Remove.
+
+2009-05-28 Steve Ellcey <sje@cup.hp.com>
+
+ * doc/invoke.texi (IA-64 Options):
+ Add -msdata, -mfused-madd, -mno-inline-float-divide,
+ -mno-inline-int-divide, -mno-inline-sqrt, -msched-spec-ldc,
+ -msched-spec-control-ldc, -msched-prefer-non-data-spec-insns,
+ -msched-prefer-non-control-spec-insns,
+ -msched-stop-bits-after-every-cycle,
+ -msched-count-spec-in-critical-path,
+ -msel-sched-dont-check-control-spec, -msched-fp-mem-deps-zero-cost
+ -msched-max-memory-insns-hard-limit, -msched-max-memory-insns.
+ Remove -mt, -pthread, -msched-ldc, -mno-sched-control-ldc,
+ and -msched-spec-verbose.
+
+2009-05-28 Joseph Myers <joseph@codesourcery.com>
+
+ * config/arm/lib1funcs.asm (__clear_cache): Define if L_clear_cache.
+ * config/arm/linux-eabi.h (CLEAR_INSN_CACHE): Define to give an
+ error if used.
+ * config/arm/t-linux-eabi (LIB1ASMFUNCS): Add _clear_cache.
+
+2009-05-28 Richard Guenther <rguenther@suse.de>
+
+ * tree-ssa-alias.c (ao_ref_init): New function.
+ (ao_ref_base): Likewise.
+ (ao_ref_base_alias_set): Likewise.
+ (ao_ref_alias_set): Likewise.
+ (refs_may_alias_p_1): Change signature.
+ (refs_may_alias_p): Adjust.
+ (refs_anti_dependent_p): Likewise.
+ (refs_output_dependent_p): Likewise.
+ (call_may_clobber_ref_p_1): Change signature.
+ (call_may_clobber_ref_p): Adjust.
+ (stmt_may_clobber_ref_p_1): New function split out from ...
+ (stmt_may_clobber_ref_p): ... here.
+ (maybe_skip_until): Adjust signature.
+ (get_continuation_for_phi): Likewise.
+ (walk_non_aliased_vuses): Likewise.
+ * tree-ssa-alias.h (struct ao_ref_s): New structure type.
+ (ao_ref_init): Declare.
+ (ao_ref_base): Likewise.
+ (ao_ref_alias_set): Likewise.
+ (stmt_may_clobber_ref_p_1): Likewise.
+ (walk_non_aliased_vuses): Adjust.
+ * tree-ssa-sccvn.c (ao_ref_init_from_vn_reference): New function.
+ (get_ref_from_reference_ops): remove.
+ (vn_reference_lookup_2): Adjust signature.
+ (vn_reference_lookup_3): Do not re-build trees. Handle unions.
+ (vn_reference_lookup_pieces): Adjust signature, do not re-build trees.
+ (vn_reference_lookup): Adjust.
+ (vn_reference_insert): Likewise.
+ (vn_reference_insert_pieces): Adjust signature.
+ (visit_reference_op_call): Adjust.
+ * tree-ssa-pre.c (get_expr_type): Simplify.
+ (phi_translate_1): Adjust.
+ (compute_avail): Likewise.
+ (translate_vuse_through_block): Do not re-build trees.
+ (value_dies_in_block_x): Likewise.
+ * tree-ssa-sccvn.h (struct vn_reference_s): Add type and alias-set
+ fields.
+ (vn_reference_lookup_pieces): Adjust declaration.
+ (vn_reference_insert_pieces): Likewise.
+
+2009-05-28 Benjamin Kosnik <bkoz@redhat.com>
+
+ * tree-ssa-copy.c (replace_exp_1): Move op for warning-free use
+ with checking disabled.
+
+2009-05-28 Dave Korn <dave.korn.cygwin@gmail.com>
+
+ PR target/37216
+
+ * configure.ac (HAVE_GAS_ALIGNED_COMM): Add autoconf test and
+ macro definition for support of three-operand format aligned
+ .comm directive in assembler on cygwin/pe/mingw target OS.
+ * configure: Regenerate.
+ * config.h: Regenerate.
+
+ * config/i386/winnt.c (i386_pe_asm_output_aligned_decl_common): Use
+ aligned form of .comm directive if -mpe-aligned-commons is in effect.
+ * config/i386/cygming.opt (-mpe-aligned-commons): Add new option.
+
+ * doc/invoke.texi (-mpe-aligned-commons): Document new target option.
+ * doc/tm.texi (ASM_OUTPUT_COMMON): Document zero size commons.
+
+2009-05-28 Ira Rosen <irar@il.ibm.com>
+
+ PR tree-optimization/40254
+ * tree-data-ref.c (dr_analyze_innermost): Take POFFSET into account
+ in analysis of basic blocks.
+
+2009-05-28 Adam Nemet <anemet@caviumnetworks.com>
+
+ PR middle-end/33699
+ * target.h (struct gcc_target): Fix indentation. Add const_anchor.
+ * target-def.h (TARGET_CONST_ANCHOR): New macro.
+ (TARGET_INITIALIZER): Use it.
+ * cse.c (CHEAPER): Move it up to the other macros.
+ (insert): Rename this ...
+ (insert_with_costs): ... to this. Add cost parameters. Update
+ function comment.
+ (insert): New function. Call insert_with_costs.
+ (compute_const_anchors, insert_const_anchor, insert_const_anchors,
+ find_reg_offset_for_const, try_const_anchors): New functions.
+ (cse_insn): Call try_const_anchors. Adjust cost of src_related
+ when using a const-anchor. Call insert_const_anchors.
+ * config/mips/mips.c (mips_set_mips16_mode): Set targetm.const_anchor.
+ * doc/tm.texi (Misc): Document TARGET_CONST_ANCHOR.
+
+2009-05-28 Alexandre Oliva <aoliva@redhat.com>
+
+ * tree-inline.c (remap_decls): Enable nonlocalized variables
+ when not optimizing.
+
+2009-05-28 Alexandre Oliva <aoliva@redhat.com>
+
+ * tree-ssa-live.c (remove_unused_locals): Skip when not optimizing.
+ Simplify other tests involving optimize.
+
+2009-05-27 Tom Tromey <tromey@redhat.com>
+
+ * unwind-dw2.c (_Unwind_DebugHook): New function.
+ (uw_install_context): Call _Unwind_DebugHook.
+
+2009-05-27 Tom Tromey <tromey@redhat.com>
+
+ * system.h (CONST_CAST2): Use C++ const_cast when compiled as C++
+
+2009-05-27 Ian Lance Taylor <iant@google.com>
+
+ * Makefile.in (LINKER, LINKER_FLAGS): Define.
+ (LINKER_FOR_BUILD, BUILD_LINKERFLAGS): Define.
+ (ALL_LINKERFLAGS): Define.
+ (xgcc$(exeext)): Change $(COMPILER) to $(LINKER).
+ (cpp$(exeext), cc1-dummy$(exeext), cc1$(exeext)): Likewise.
+ (collect2$(exeext), mips-tfile, mips-tdump): Likewise.
+ (gcov$(exeext), gcov-dump$(exeext)): Likewise.
+ (build/gen%$(build_exeext)): Change $(COMPILER_FOR_BUILD) to
+ $(LINKER_FOR_BUILD).
+ (build/gcov-iov$(build_exeext)): Likewise.
+
+2009-05-27 Julian Brown <julian@codesourcery.com>
+
+ * gcse.c (target.h): Include.
+ (can_assign_to_reg_without_clobbers_p): Check that the target allows
+ copy of argument to a pseudo register.
+
+2009-05-27 Diego Novillo <dnovillo@google.com>
+
+ * tree-ssa-live.c (dump_scope_block): Document arguments.
+ (dump_scope_blocks): Document.
+ (debug_scope_blocks): New.
+ * tree-flow.h (debug_scope_blocks): Declare.
+
+2009-05-21 Denis Chertykov <denisc@overta.ru>
+
+ * doc/contrib.texi (Contributors): Add myself to the list.
+
+2009-05-27 Olivier Hainque <hainque@adacore.com>
+
+ * expr.c (target_align): New function. Alignment the TARGET of an
+ assignment may be assume to have.
+ (highest_pow2_factor_for_target): Use it instead of relying on
+ immediate tree attributes of TARGET, not necessarily honored when
+ intermediate bitfields are involved.
+
+2009-05-27 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR target/40266
+ * config/i386/driver-i386.c (host_detect_local_cpu): Support
+ AVX, SSE4, AES, PCLMUL and POPCNT.
+
+2009-05-27 Diego Novillo <dnovillo@google.com>
+
+ * tree-pretty-print.c (dump_location): New.
+ (dump_generic_node): Call it.
+ Factor code to handle BLOCK nodes ...
+ (dump_block_node): ... here.
+
+2009-05-27 Rafael Avila de Espindola <espindola@google.com>
+
+ * Makefile.in (GCC_PLUGIN_H): New. Replace all uses of gcc-plugin.h
+ with it.
+ * doc/plugins.texi: Document that gcc-plugin.h must be the first to be
+ included.
+ * gcc-plugin.h: Include config.h and system.h.
+ (IN_GCC): Define if not defined.
+
+2009-05-27 Hans-Peter Nilsson <hp@axis.com>
+
+ PR middle-end/40249
+ * Makefile.in (CRTSTUFF_CFLAGS): Replace -fno-inline-functions
+ with -fno-inline.
+
+2009-05-27 Shujing Zhao <pearly.zhao@oracle.com>
+
+ * config/m32r/m32r.c: Use REG_P, MEM_P and CONST_INT_P where
+ applicable.
+ * config/m32r/m32r.h: Ditto.
+ * config/m32r/m32r.md: Ditto.
+ * config/m32r/predicates.md: Ditto.
+
+2009-05-27 Alexandre Oliva <aoliva@redhat.com>
+
+ * cgraph.c (dump_cgraph_node): Honor -fdump-noaddr.
+
+2009-05-26 Basile Starynkevitch <basile@starynkevitch.net>
+
+ * doc/plugins.texi
+ (Loading plugins): typo.
+ (Plugin callbacks): Documented PLUGIN_INFO, PLUGIN_GGC_START,
+ PLUGIN_GGC_MARKING, PLUGIN_GGC_END, PLUGIN_REGISTER_GGC_ROOTS.
+ (Interacting with the GCC Garbage Collector): Added new section.
+ (Giving information about a plugin): Added new section for
+ PLUGIN_INFO.
+ * ggc.h (ggc_register_root_tab): Added declaration.
+ * gcc-plugin.h (PLUGIN_GGC_START, PLUGIN_GGC_MARKING)
+ (PLUGIN_GGC_END, PLUGIN_REGISTER_GGC_ROOTS): Added new events.
+ (register_callback): Improved comment in declaration.
+ * ggc-common.c (const_ggc_root_tab_t) Added new typedef for vectors.
+ (extra_root_vec) Added static variable for dynamic roots registration.
+ (ggc_register_root_tab) Added new routine.
+ (ggc_mark_roots) Added iteration inside extra_root_vec, and invoke
+ PLUGIN_GGC_MARKING event.
+ * ggc-zone.c: Include plugin.h.
+ (ggc_collect): Invoke PLUGIN_GGC_START & PLUGIN_GGC_END events.
+ * ggc-page.c: Include plugin.h.
+ (ggc_collect): Invoke PLUGIN_GGC_START & PLUGIN_GGC_END events.
+ * plugin.c (plugin_event_name): added names of PLUGIN_GGC_START,
+ PLUGIN_GGC_MARKING, PLUGIN_GGC_END, PLUGIN_REGISTER_GGC_ROOTS
+ (register_callback): check lack of callbacks for
+ pseudo-events. Added handling of PLUGIN_REGISTER_GGC_ROOTS,
+ PLUGIN_GGC_START, PLUGIN_GGC_MARKING, PLUGIN_GGC_END.
+ (invoke_plugin_callbacks): Handle PLUGIN_GGC_START,
+ PLUGIN_GGC_MARKING, PLUGIN_GGC_END, PLUGIN_REGISTER_GGC_ROOTS.
+ * Makefile.in (ggc-common.o, ggc-zone.o, ggc-page.o): Added
+ dependency on plugin.h.
+ (plugin.o): Added dependency on ggc.h...
+
+2009-05-26 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/40248
+ Revert
+ * expr.c (expand_expr_real_1): Avoid calling do_store_flag
+ with mismatched comparison modes.
+
+ * expr.c (expand_expr_real_1): Expand the operand of a
+ VIEW_CONVERT_EXPR in its natural mode.
+
+2009-05-26 Ian Lance Taylor <iant@google.com>
+
+ * Makefile.in (COMPILER, COMPILER_FLAGS): Define.
+ (COMPILER_FOR_BUILD, BUILD_COMPILERFLAGS): Define.
+ (ALL_COMPILERFLAGS): Define.
+ (.c.o, xgcc$(exeext), cpp$(exeext)): Use $(COMPILER).
+ (cc1-dummy$(exeext), cc1$(exeext)): Likewise.
+ (collect2$(exeext), collect2.o): Likewise.
+ (c-opts.o, c-cppbuiltin.o, c-pch.o, gcc.o, gccspec.o): Likewise.
+ (gcc-options.o, version.o, prefix.o, toplev.o): Likewise.
+ ($(out_object_file), mips-tfile, mips-tdump): Likewise.
+ (libbackend.o, intl.o, cppdefault.o): Likewise.
+ (gcov$(exeext), gcov-dump$(exeext)): Likewise.
+ (build/%.o): Use $(COMPILER_FOR_BUILD).
+ (build/gen%$(build_exeext)): Likewise.
+ (build/gcov-iov$(build_exeext)): LIkewise.
+ * config/t-darwin (darwin.o): Use $(COMPILER).
+ (darwin-c.o, darwin-f.o, darwin-driver.o): Likewise.
+ * config/t-sol2 (sol2-c.o): Likewise.
+ (sol2.o): Likewise.
+ * config/t-vxworks (vxworks.o): Likewise.
+ * config/x-darwin (host-darwin.o): Likewise.
+ * config/x-hpux (host-hpux.o): Likewise.
+ * config/x-linux (host-linux.o): Likewise.
+ * config/x-solaris (host-solaris.o): Likewise.
+ * config/alpha/x-alpha (driver-alpha.o): Likewise.
+ * config/arm/t-arm (arm-c.o): Likewise.
+ * config/arm/t-pe (pe.o): Likewise.
+ * config/arm/t-wince-pe (pe.o): Likewise.
+ * config/i386/t-cygming (winnt.o): Likewise.
+ (winnt-cxx.o, winnt-stubs.o, msformat-c.o): Likewise.
+ * config/i386/t-cygwin (cygwin1.o): Likewise.
+ (cygwin2.o): Likewise.
+ * config/i386/t-i386 (i386-c.o): Likewise.
+ * config/i386/t-interix (winnt.o): Likewise.
+ * config/i386/t-netware (netware.o): Likewise.
+ * config/i386/t-nwld (nwld.o): Likewise.
+ * config/i386/x-darwin (host-i386-darwin.o): Likewise.
+ * config/i386/x-i386 (driver-i386.o): Likewise.
+ * config/i386/x-cygwin (host-cygwin.o): Likewise.
+ * config/i386/x-mingw32 (host-mingw32.o): Likewise.
+ * config/ia64/t-ia64 (ia64-c.o): Likewise.
+ * config/m32c/t-m32c (m32c-pragma.o): Likewise.
+ * config/mips/x-native (driver-native.o): Likewise.
+ * config/rs6000/t-rs6000 (rs6000-c.o): Likewise.
+ * config/rs6000/x-darwin (host-ppc-darwin.o): Likewise.
+ * config/rs6000/x-darwin64 (host-ppc64-darwin.o): Likewise.
+ * config/rs6000/x-rs6000 (driver-rs6000.o): Likewise.
+ * config/score/t-score-elf (score7.o): Likewise.
+ (score3.o): Likewise.
+ * config/sh/t-sh (sh-c.o): Likewise.
+ * config/sh/t-symbian (sh-c.o): Likewise.
+ (symbian.o): Likewise.
+ * config/spu/t-spu-elf (spu-c.o): Likewise.
+ * config/v850/t-v850 (v850-c.o): Likewise.
+ * config/v850/t-v850e (v850-c.o): Likewise.
+
+2009-05-26 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/40122
+ * tree-ssa-ccp.c (ccp_fold): Fold vector CONSTRUCTORs to
+ VECTOR_CSTs if possible.
+ (fold_gimple_assign): Likewise.
+
+2009-05-26 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/40252
+ * fold-const.c (fold_binary): Use the correct types for building
+ rotates.
+
+2009-05-26 Richard Guenther <rguenther@suse.de>
+
+ * tree-vect-data-refs.c (vect_create_data_ref_ptr): Remove
+ redundant calls to merge_alias_info.
+ (bump_vector_ptr): Likewise.
+ * tree-ssa-copy.c (merge_alias_info): Remove.
+ (replace_exp_1): Remove call to merge_alias_info.
+ (propagate_tree_value): Likewise.
+ (fini_copy_prop): Propagate points-to info.
+ * tree-flow.h (merge_alias_info): Remove.
+
+2009-05-07 Hariharan Sandanagobalane <hariharan@picochip.com>
+
+ * config/picochip/picochip.C (PARAM_INLINE_CALL_COST): Remove.
+
+2009-05-25 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.c (dump_cgraph_node): Dump size/time/benefit.
+ * cgraph.h (struct inline_summary): New filed self_wize,
+ size_inlining_benefit, self_time and time_inlining_benefit.
+ (struct cgraph_global_info): Replace insns by time ans size fields.
+ * ipa-cp (ipcp_cloning_candidate_p): Base estimate on size
+ (ipcp_estimate_growth, ipcp_insert_stage): Likewise.
+ (ipcp_update_callgraph): Do not touch function bodies.
+ * ipa-inline.c: Include except.h
+ (MAX_TIME): New constant.
+ (overall_insns): Remove.
+ (leaf_node_p): New.
+ (overall_size, max_benefit): New static variables.
+ (cgraph_estimate_time_after_inlining): New function.
+ (cgraph_estimate_size_after_inlining): Rewrite using benefits.
+ (cgraph_clone_inlined_nodes): Update size.
+ (cgraph_mark_inline_edge): Update size.
+ (cgraph_estimate_growth): Use size info.
+ (cgraph_check_inline_limits): Check size.
+ (cgraph_default_inline_p): Likewise.
+ (cgraph_edge_badness): Compute badness based on benefit and size cost.
+ (cgraph_decide_recursive_inlining): Check size.
+ (cgraph_decide_inlining_of_small_function): Update size; dump sizes
+ and times.
+ (cgraph_decide_inlining): Likewise.
+ (cgraph_decide_inlining_incrementally): Likewise; honor
+ PARAM_EARLY_INLINING_INSNS.
+ (likely_eliminated_by_inlining_p): New predicate.
+ (estimate_function_body_sizes): New function.
+ (compute_inline_parameters): Use it.
+ * except.c (must_not_throw_labels): New function.
+ * except.h (must_not_throw_labels): Declare.
+ * tree-inline.c (init_inline_once): Kill inlining_weigths
+ * tree-ssa-structalias.c: Avoid uninitialized warning.
+ * params.def (PARAM_MAX_INLINE_INSNS_SINGLE): Reduce to 300.
+ (PARAM_MAX_INLINE_INSNS_AUTO): Reduce to 60.
+ (PARAM_INLINE_CALL_COST): Remove.
+ (PARAM_EARLY_INLINING_INSNS): New.
+
+2009-05-25 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/36327
+ * tree-ssa-alias.c (walk_non_aliased_vuses): Add second walker
+ callback for reference translation or lookup at the point of may-defs.
+ * tree-ssa-alias.h (walk_non_aliased_vuses): Adjust prototype.
+ * tree-ssa-sccvn.c (get_ref_from_reference_ops): Bail out
+ for union COMPONENT_REFs.
+ (vn_reference_lookup_3): New callback. Lookup from memset
+ and CONSTRUCTOR assignment, translate through struct copies.
+ (vn_reference_lookup_pieces): Make sure to not free the
+ passed operands array. Adjust walk_non_aliased_vuses call.
+ (vn_reference_lookup): Adjust walk_non_aliased_vuses call,
+ make sure we do not leak memory.
+
+2009-05-25 Richard Guenther <rguenther@suse.de>
+
+ * tree-ssa-alias.h (dump_points_to_solution): Declare.
+ * tree-inline.c (expand_call_inline): Reset the escaped and
+ callused solutions.
+ * tree-ssa-structalias.c (pass_build_ealias): New.
+ * tree-pass.h (pass_build_ealias): Declare.
+ * passes.c (init_optimization_passes): Add PTA during
+ early optimizations.
+ * tree-ssa-alias.c (dump_alias_info): Dump the ESCAPED
+ and CALLUSED solutions.
+ (dump_points_to_solution): New function, split out from ...
+ (dump_points_to_info_for): ... here.
+ * tree-parloops.c (parallelize_loops): Reset the escaped and
+ callused solutions.
+
+2009-05-25 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ PR bootstrap/40027
+ * config/i386/i386.c (USE_HIDDEN_LINKONCE): Only define if missing.
+ * config/i386/sol2.h [!TARGET_GNU_LD] (USE_HIDDEN_LINKONCE): Define.
+
+2009-05-25 Ira Rosen <irar@il.ibm.com>
+
+ PR tree-optimization/40238
+ * tree-vect-stmts.c (vect_init_vector): Insert initialization
+ statements after basic block's labels.
+ * tree-vect-slp.c (vect_slp_transform_bb): Call destroy_bb_vec_info()
+ to free the allocated memory.
+
+2009-05-24 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ * gcc/config/sh/sh.c (sh_set_return_address): Mark store of
+ return address with a USE.
+
+2009-05-24 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/40233
+ * tree.c (make_vector_type): Build the TYPE_DEBUG_REPRESENTATION_TYPEs
+ array type from the main variant of the inner type.
+
+2009-05-24 Jan-Benedict Glaw <jbglaw@lug-owl.de>
+
+ * config/vax/vax-protos.h (legitimate_constant_address_p): Change
+ definition to bool (from int) to un-break build.
+ (legitimate_constant_p, vax_mode_dependent_address_p): Likewise.
+
+2009-05-24 Paolo Bonzini <bonzini@gnu.org>
+
+ * tree-ssa-operands.h (push_stmt_changes, pop_stmt_changes,
+ discard_stmt_changes): Delete.
+ * tree-ssa-operands.c (scb_stack): Delete.
+ (init_ssa_operands): Do not initialize it.
+ (fini_ssa_operands): Do not free it.
+ (push_stmt_changes, pop_stmt_changes, discard_stmt_changes): Delete.
+
+ * tree-cfg.c (replace_uses_by): Replace pop_stmt_changes with
+ update_stmt, remove the others. Fix comments.
+ * tree-dfa.c (optimize_stack_restore): Likewise.
+ * tree-ssa-forwprop.c (forward_propagate_addr_expr): Likewise.
+ * tree-ssa-loop-ivopts.c (rewrite_use): Likewise.
+ * tree-ssa-dce.c (eliminate_unnecessary_stmts): Likewise.
+ * tree-ssa-ccp.c (optimize_stack_restore, execute_fold_all_builtins):
+ Likewise.
+ * tree-ssa-propagate.c (substitute_and_fold): Likewise.
+ * tree-ssa-dom.c (propagate_rhs_into_lhs): Likewise.
+ (dom_opt_finalize_block): Likewise, adjusting access to
+ stmts_to_rescan.
+ (optimize_stmt): Likewise, adjusting access to stmts_to_rescan.
+ (stmts_to_rescan): Change item type to gimple.
+ (tree_ssa_dominator_optimize): Change type of stmts_to_rescan.
+
+2009-05-24 Ira Rosen <irar@il.ibm.com>
+
+ * doc/passes.texi (Tree-SSA passes): Document SLP pass.
+ * tree-pass.h (pass_slp_vectorize): New pass.
+ * params.h (SLP_MAX_INSNS_IN_BB): Define.
+ * timevar.def (TV_TREE_SLP_VECTORIZATION): Define.
+ * tree-vectorizer.c (timevar.h): Include.
+ (user_vect_verbosity_level): Declare.
+ (vect_location): Fix comment.
+ (vect_set_verbosity_level): Update user_vect_verbosity_level
+ instead of vect_verbosity_level.
+ (vect_set_dump_settings): Add an argument. Ignore user defined
+ verbosity if dump flags require higher level of verbosity. Print to
+ stderr only for loop vectorization.
+ (vectorize_loops): Update call to vect_set_dump_settings.
+ (execute_vect_slp): New function.
+ (gate_vect_slp): Likewise.
+ (struct gimple_opt_pass pass_slp_vectorize): New.
+ * tree-vectorizer.h (struct _bb_vec_info): Define along macros to
+ access its members.
+ (vec_info_for_bb): New function.
+ (struct _stmt_vec_info): Add bb_vinfo and a macro for its access.
+ (VECTORIZATION_ENABLED): New macro.
+ (SLP_ENABLED, SLP_DISABLED): Likewise.
+ (vect_is_simple_use): Add bb_vec_info argument.
+ (new_stmt_vec_info, vect_analyze_data_ref_dependences,
+ vect_analyze_data_refs_alignment, vect_verify_datarefs_alignment,
+ vect_analyze_data_ref_accesses, vect_analyze_data_refs,
+ vect_schedule_slp, vect_analyze_slp): Likewise.
+ (vect_analyze_stmt): Add slp_tree argument.
+ (find_bb_location): Declare.
+ (vect_slp_analyze_bb, vect_slp_transform_bb): Likewise.
+ * tree-vect-loop.c (new_loop_vec_info): Adjust function calls.
+ (vect_analyze_loop_operations, vect_analyze_loop,
+ get_initial_def_for_induction, vect_create_epilog_for_reduction,
+ vect_finalize_reduction, vectorizable_reduction,
+ vectorizable_live_operation, vect_transform_loop): Likewise.
+ * tree-data-ref.c (dr_analyze_innermost): Update comment,
+ skip evolution analysis if analyzing a basic block.
+ (dr_analyze_indices): Likewise.
+ (initialize_data_dependence_relation): Skip the test whether the
+ object is invariant for basic blocks.
+ (compute_all_dependences): Skip dependence analysis for data
+ references in basic blocks.
+ (find_data_references_in_stmt): Don't fail in case of invariant
+ access in basic block.
+ (find_data_references_in_bb): New function.
+ (find_data_references_in_loop): Move code to
+ find_data_references_in_bb and add a call to it.
+ (compute_data_dependences_for_bb): New function.
+ * tree-data-ref.h (compute_data_dependences_for_bb): Declare.
+ * tree-vect-data-refs.c (vect_check_interleaving): Adjust to the case
+ that STEP is 0.
+ (vect_analyze_data_ref_dependence): Check for interleaving in case of
+ unknown dependence in basic block and fail in case of dependence in
+ basic block.
+ (vect_analyze_data_ref_dependences): Add bb_vinfo argument, get data
+ dependence instances from either loop or basic block vectorization
+ info.
+ (vect_compute_data_ref_alignment): Check if it is loop vectorization
+ before calling nested_in_vect_loop_p.
+ (vect_compute_data_refs_alignment): Add bb_vinfo argument, get data
+ dependence instances from either loop or basic block vectorization
+ info.
+ (vect_verify_datarefs_alignment): Likewise.
+ (vect_enhance_data_refs_alignment): Adjust function calls.
+ (vect_analyze_data_refs_alignment): Likewise.
+ (vect_analyze_group_access): Fix printing. Skip different checks if
+ DR_STEP is 0. Keep strided stores either in loop or basic block
+ vectorization data structure. Fix indentation.
+ (vect_analyze_data_ref_access): Fix comments, allow zero step in
+ basic blocks.
+ (vect_analyze_data_ref_accesses): Add bb_vinfo argument, get data
+ dependence instances from either loop or basic block vectorization
+ info.
+ (vect_analyze_data_refs): Update comment. Call
+ compute_data_dependences_for_bb to analyze basic blocks.
+ (vect_create_addr_base_for_vector_ref): Check for outer loop only in
+ case of loop vectorization. In case of basic block vectorization use
+ data-ref itself as a base.
+ (vect_create_data_ref_ptr): In case of basic block vectorization:
+ don't advance the pointer, add new statements before the current
+ statement. Adjust function calls.
+ (vect_supportable_dr_alignment): Support only aligned accesses in
+ basic block vectorization.
+ * common.opt (ftree-slp-vectorize): New flag.
+ * tree-vect-patterns.c (widened_name_p): Adjust function calls.
+ (vect_pattern_recog_1): Likewise.
+ * tree-vect-stmts.c (process_use): Likewise.
+ (vect_init_vector): Add new statements in the beginning of the basic
+ block in case of basic block SLP.
+ (vect_get_vec_def_for_operand): Adjust function calls.
+ (vect_finish_stmt_generation): Likewise.
+ (vectorizable_call): Add assert that it is loop vectorization, adjust
+ function calls.
+ (vectorizable_conversion, vectorizable_assignment): Likewise.
+ (vectorizable_operation): In case of basic block SLP, take
+ vectorization factor from statement's type and skip the relevance
+ check. Adjust function calls.
+ (vectorizable_type_demotion): Add assert that it is loop
+ vectorization, adjust function calls.
+ (vectorizable_type_promotion): Likewise.
+ (vectorizable_store): Check for outer loop only in case of loop
+ vectorization. Adjust function calls. For basic blocks, skip the
+ relevance check and don't advance pointers.
+ (vectorizable_load): Likewise.
+ (vectorizable_condition): Add assert that it is loop vectorization,
+ adjust function calls.
+ (vect_analyze_stmt): Add argument. In case of basic block SLP, check
+ that it is not reduction, get vector type, call only supported
+ functions, skip loop specific parts.
+ (vect_transform_stmt): Check for outer loop only in case of loop
+ vectorization.
+ (new_stmt_vec_info): Add new argument and initialize bb_vinfo.
+ (vect_is_simple_use): Fix comment, add new argument, fix conditions
+ for external definition.
+ * passes.c (pass_slp_vectorize): New pass.
+ * tree-vect-slp.c (find_bb_location): New function.
+ (vect_get_and_check_slp_defs): Add argument, adjust function calls,
+ check for patterns only in loops.
+ (vect_build_slp_tree): Add argument, adjust function calls, fail in
+ case of multiple types in basic block SLP.
+ (vect_mark_slp_stmts_relevant): New function.
+ (vect_supported_load_permutation_p): Fix comment.
+ (vect_analyze_slp_instance): Add argument. In case of basic block
+ SLP, take vectorization factor from statement's type, check that
+ unrolling factor is 1. Adjust function call. Save SLP instance in
+ either loop or basic block vectorization structure. Return FALSE,
+ if SLP failed.
+ (vect_analyze_slp): Add argument. Get strided stores groups from
+ either loop or basic block vectorization structure. Return FALSE
+ if basic block SLP failed.
+ (new_bb_vec_info): New function.
+ (destroy_bb_vec_info, vect_slp_analyze_node_operations,
+ vect_slp_analyze_operations, vect_slp_analyze_bb): Likewise.
+ (vect_schedule_slp): Add argument. Get SLP instances from either
+ loop or basic block vectorization structure. Set vectorization factor
+ to be 1 for basic block SLP.
+ (vect_slp_transform_bb): New function.
+ * params.def (PARAM_SLP_MAX_INSNS_IN_BB): Define.
+
+2009-05-23 Mark Mitchell <mark@codesourcery.com>
+
+ * final.c (shorten_branches): Do not align labels for jump tables.
+ (final_scan_insn): Use JUMP_TABLE_DATA_P.
+
+2009-05-23 Eric Botcazou <ebotcazou@adacore.com>
+
+ * doc/passes.texi: Standardize spelling of RTL, Tree and Tree SSA.
+ Remove outdated reference to flow.c and fix nits.
+ * doc/gccint.texi: Tweak RTL description.
+ * doc/rtl.texi: Likewise.
+
+2009-05-23 Denis Chertykov <chertykov@gmail.com>
+
+ * config/avr/avr.c: Change my email address.
+ * config/avr/avr.h: Likewise.
+ * config/avr/avr.md: Likewise.
+ * config/avr/avr-protos.h: Likewise.
+ * config/avr/libgcc.S: Likewise.
+
+2009-05-22 Trevor Smigiel <Trevor_Smigiel@playstation.sony.com>
+
+ * config/spu/spu-protos.h (aligned_mem_p, spu_valid_mov): Remove.
+ (spu_split_load, spu_split_store): Change return type to int.
+ (spu_split_convert): Declare.
+ * config/spu/predicates.md (spu_mem_operand): Remove.
+ (spu_mov_operand): Update.
+ (spu_dest_operand, shiftrt_operator, extend_operator): Define.
+ * config/spu/spu.c (regno_aligned_for_load): Remove.
+ (reg_aligned_for_addr, spu_expand_load): Define.
+ (spu_expand_extv): Reimplement and handle MEM.
+ (spu_expand_insv): Handle MEM.
+ (spu_sched_reorder): Handle insn's with length 0.
+ (spu_legitimate_address_p): Reimplement.
+ (store_with_one_insn_p): Return TRUE for any mode with size
+ larger than 16 bytes.
+ (address_needs_split): Define.
+ (spu_expand_mov): Call spu_split_load and spu_split_store for MEM
+ operands.
+ (spu_convert_move): Define.
+ (spu_split_load): Use spu_expand_load and change all MEM's to TImode.
+ (spu_split_store): Change all MEM's to TImode.
+ (spu_init_expanders): Preallocate registers that correspond to
+ LAST_VIRTUAL_REG+1 and LAST_VIRTUAL_REG+2 and set them with
+ mark_reg_pointer.
+ (spu_split_convert): Define.
+ * config/spu/spu.md (QHSI, QHSDI): New mode iterators.
+ (_move<mode>, _movdi, _movti): Update predicate and condition.
+ (load, store): Change to define_split.
+ (extendqiti2, extendhiti2, extendsiti2, extendditi2): Simplify to
+ extend<mode>ti2.
+ (zero_extendqiti2, zero_extendhiti2, <v>lshr<mode>3_imm): Define.
+ (lshr<mode>3, lshr<mode>3_imm, lshr<mode>3_re): Simplify to one
+ define_insn_and_split of lshr<mode>3.
+ (shrqbybi_<mode>, shrqby_<mode>): Simplify to define_expand.
+ (<v>ashr<mode>3_imm): Define.
+ (extv, extzv, insv): Allow MEM operands.
+ (trunc_shr_ti<mode>, trunc_shr_tidi, shl_ext_<mode>ti,
+ shl_ext_diti, sext_trunc_lshr_tiqisi, zext_trunc_lshr_tiqisi,
+ sext_trunc_lshr_tihisi, zext_trunc_lshr_tihisi): Define for combine.
+ (_spu_convert2): Change to define_insn_and_split and remove the
+ corresponding define_peephole2.
+ (stack_protect_set, stack_protect_test, stack_protect_test_si):
+ Change predicates to memory_operand.
+
+2009-05-22 Mark Mitchell <mark@codesourcery.com>
+
+ * config/arm/thumb2.md: Add 16-bit multiply instructions.
+
+2009-05-21 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ PR tree-optimization/40219
+ * tree.c (iterative_hash_expr): Make sure the builtin function is
+ a normal builtin function and not a front end or back end builtin
+ before indexing into the built_in_decls array.
+
+2009-05-22 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/38964
+ * alias.c (write_dependence_p): Do not use TBAA for answering
+ anti-dependence or output-dependence.
+ * tree-ssa-structalias.c (set_uids_in_ptset): Remove TBAA pruning code.
+ (emit_pointer_definition): Remove.
+ (emit_alias_warning): Likewise.
+ (find_what_var_points_to): Remove TBAA pruning code.
+ (find_what_p_points_to): Likewise. Do not warn about strict-aliasing
+ violations.
+ (compute_points_to_sets): Remove code computing the set of
+ dereferenced pointers.
+ * tree-data-ref.c (dr_may_alias_p): Properly use the split
+ oracle for querying anti and output dependencies.
+ * tree-ssa-alias.c (refs_may_alias_p_1): Add argument specifying
+ if TBAA may be applied.
+ (refs_anti_dependent_p): New function.
+ (refs_output_dependent_p): Likewise.
+ * tree-ssa-alias.h (refs_anti_dependent_p): Declare.
+ (refs_output_dependent_p): Likewise.
+ * doc/tree-ssa.texi (Memory model): New section.
+ * doc/c-tree.texi (CHANGE_DYNAMIC_TYPE_EXPR): Remove.
+ * doc/gimple.texi (GIMPLE_CHANGE_DYNAMIC_TYPE): Remove.
+ * cfgexpand.c (expand_gimple_basic_block): Do not handle
+ GIMPLE_CHANGE_DYNAMIC_TYPE or CHANGE_DYNAMIC_TYPE_EXPR.
+ * expr.c (expand_expr_real_1): Likewise.
+ * gimple-low.c (lower_stmt): Likewise.
+ * gimple-pretty-print.c (dump_gimple_stmt): Likewise.
+ (dump_gimple_cdt): Remove.
+ * gimple.c (gss_for_code): Do not handle GIMPLE_CHANGE_DYNAMIC_TYPE.
+ (gimple_size): Likewise.
+ (walk_gimple_op): Likewise.
+ (is_gimple_stmt): Likewise.
+ (walk_stmt_load_store_addr_ops): Likewise.
+ (gimple_build_cdt): Remove.
+ * gimple.def (GIMPLE_CHANGE_DYNAMIC_TYPE): Remove.
+ * gimple.h (gimple_cdt_new_type): Remove.
+ (gimple_cdt_new_type_ptr): Likewise.
+ (gimple_cdt_set_new_type): Likewise.
+ (gimple_cdt_location): Likewise.
+ (gimple_cdt_location_ptr): Likewise.
+ (gimple_cdt_set_location): Likewise.
+ * gimplify.c (gimplify_expr): Do not handle CHANGE_DYNAMIC_TYPE_EXPR.
+ * tree-cfg.c (remove_useless_stmts_1): Do not handle
+ GIMPLE_CHANGE_DYNAMIC_TYPE.
+ (verify_types_in_gimple_stmt): Likewise.
+ * tree-inline.c (estimate_num_insns): Likewise.
+ (expand_call_inline): Do not copy DECL_NO_TBAA_P.
+ (copy_decl_to_var): Likewise.
+ (copy_result_decl_to_var): Likewise.
+ * tree-pretty-print.c (dump_generic_node): Do not handle
+ CHANGE_DYNAMIC_TYPE_EXPR.
+ * tree-ssa-dce.c (mark_stmt_if_obviously_necessary): Likewise.
+ * tree-ssa-operands.c (get_expr_operands): Likewise.
+ * tree-ssa-structalias.c (struct variable_info): Remove
+ no_tbaa_pruning member.
+ (new_var_info): Do not set it based on DECL_NO_TBAA_P.
+ (unify_nodes): Do not copy it.
+ (find_func_aliases): Do not handle GIMPLE_CHANGE_DYNAMIC_TYPE.
+ (dump_solution_for_var): Do not dump no_tbaa_pruning state.
+ (set_uids_in_ptset): Do not check it.
+ (find_what_var_points_to): Likewise.
+ (compute_tbaa_pruning): Remove.
+ (compute_points_to_sets): Do not call it.
+ * tree.c (walk_tree_1): Do not handle CHANGE_DYNAMIC_TYPE_EXPR.
+ * tree.def (CHANGE_DYNAMIC_TYPE_EXPR): Remove.
+ * tree.h (CHANGE_DYNAMIC_TYPE_NEW_TYPE): Remove.
+ (CHANGE_DYNAMIC_TYPE_LOCATION): Likewise.
+ (DECL_NO_TBAA_P): Likewise.
+ (struct tree_decl_common): Move no_tbaa_flag to unused flags section.
+ * omp-low.c (copy_var_decl): Do not copy DECL_NO_TBAA_P.
+ (expand_omp_atomic_pipeline): Do not set it.
+ * print-tree.c (print_node): Do not dump it.
+ * tree-ssa-copyrename.c (copy_rename_partition_coalesce): Remove
+ redundant check.
+
+2009-05-22 Vladimir Makarov <vmakarov@redhat.com>
+
+ PR target/39856
+ * reg-stack.c (subst_stack_regs_pat): Remove gcc_assert for note
+ for clobber.
+
+2009-05-22 Mark Mitchell <mark@codesourcery.com>
+
+ * tree.c (handle_dll_attribute): Mark dllexport'd inlines as
+ non-external.
+
+2009-05-22 Ben Elliston <bje@au.ibm.com>
+
+ * Makefile.in (bversion.h, s-bversion): New targets.
+ (TOPLEV_H): Add bversion.h.
+ * toplev.h: Include "bversion.h".
+ (ATTRIBUTE_GCC_DIAG): When building with checking disabled, use
+ the __format__ attribute only if compiling with the same version
+ of GCC as the sources (the "build version").
+
+2009-05-22 Ben Elliston <bje@au.ibm.com>
+
+ * c-format.c (handle_format_attribute): Fix comment typo.
+
+2009-05-21 Steve Ellcey <sje@cup.hp.com>
+
+ PR target/37846
+ * config/ia64/ia64.opt (mfused-madd): New.
+ * config/ia64/ia64.h (TARGET_DEFAULT): Set MASK_FUSED_MADD.
+ * config/ia64/hpux.h (TARGET_DEFAULT): Ditto.
+ * config/ia64/ia64.md (maddsf4, msubsf4, nmaddsf4,
+ madddf4, madddf4_trunc, msubdf4, msubdf4_trunc, nmadddf4,
+ nmadddf4_truncsf, maddxf4, maddxf4_truncsf, maddxf4_truncdf,
+ msubxf4, msubxf4_truncsf msubxf4_truncdf, nmaddxf4,
+ nmaddxf4_truncsf, nmaddxf4_truncdf): Check TARGET_FUSED_MADD.
+ * config/ia64/vect.md (addv2sf3, subv2sf3): Force fpma/fpms
+ instruction if !TARGET_FUSED_MADD.
+ (fpma, fpms): Remove colon from name.
+
+2009-05-22 Richard Guenther <rguenther@suse.de>
+
+ * tree-ssa-sccvn.c (copy_reference_ops_from_ref): Record
+ TMR_ORIGINAL. Always either record TMR_SYMBOL or TMR_BASE.
+ * tree-ssa-pre.c (create_component_ref_by_pieces_1): Handle
+ TARGET_MEM_REF.
+ (create_expression_by_pieces): Only convert if necessary.
+ * gimplify.c (gimplify_expr): Handle TARGET_MEM_REF.
+ * tree-ssa-loop-im.c (gen_lsm_tmp_name): Handle INTEGER_CST.
+
+2009-05-21 Adam Nemet <anemet@caviumnetworks.com>
+
+ * config/mips/mips.md (*extzv_trunc<mode>_exts): Turn into a
+ regular pattern from a template and rename it ...
+ (*extzv_truncsi_exts): ... to this.
+
+2009-05-21 Richard Guenther <rguenther@suse.de>
+
+ * cgraph.h (struct cgraph_node): Remove inline_decl member.
+ * ipa-inline.c (cgraph_mark_inline_edge): Do not check it.
+ (cgraph_default_inline_p): Likewise.
+ (cgraph_decide_inlining_incrementally): Likewise.
+
+2009-05-21 H.J. Lu <hongjiu.lu@intel.com>
+ Uros Bizjak <ubizjak@gmail.com>
+
+ * config/i386/cpuid.h (bit_MOVBE): New.
+
+ * config/i386/driver-i386.c (host_detect_local_cpu): Check movbe.
+
+ * config/i386/i386.c (OPTION_MASK_ISA_MOVBE_SET): New.
+ (OPTION_MASK_ISA_MOVBE_UNSET): Likewise.
+ (ix86_handle_option): Handle OPT_mmovbe.
+ (ix86_target_string): Add -mmovbe.
+ (pta_flags): Add PTA_MOVBE.
+ (processor_alias_table): Add PTA_MOVBE to "atom".
+ (override_options): Handle PTA_MOVBE.
+
+ * config/i386/i386.h (TARGET_MOVBE): New.
+
+ * config/i386/i386.md (bswapsi2): Check TARGET_MOVBE.
+ (*bswapsi_movbe): New.
+ (*bswapdi_movbe): Likewise.
+ (bswapdi2): Renamed to ...
+ (*bswapdi_1): This.
+ (bswapdi2): New expander.
+
+ * config/i386/i386.opt (mmovbe): New.
+
+ * doc/invoke.texi: Document -mmovbe.
+
+2009-05-21 Taras Glek <tglek@mozilla.com>
+
+ * plugin.c (try_init_one_plugin): Updated to new plugin_init API.
+ * gcc-plugin.h (plugin_init): Updated signature.
+ * gcc-plugin.h (plugin_name_args): Moved to this header.
+ * doc/plugins.texi (plugin_init): Updated documention to reflect
+ API change.
+ * doc/plugins.texi (plugin_name_args): Added to documention.
+
+2009-05-21 Mark Mitchell <mark@codesourcery.com>
+
+ * config/arm/neon.md (*mul<mode>3add<mode>_neon): New pattern.
+ (*mul<mode>3neg<mode>add<mode>_neon): Likewise.
+
+2009-05-21 Shujing Zhao <pearly.zhao@oracle.com>
+
+ * config/i386/i386.c: Use REG_P, MEM_P, CONST_INT_P, LABEL_P and
+ JUMP_TABLE_DATA_P predicates where applicable.
+ * config/i386/predicates.md: Ditto.
+ * config/i386/sse.md: Ditto.
+
+2009-05-21 Jakub Jelinek <jakub@redhat.com>
+
+ * config/i386/i386.md (adddi_4_rex64, addsi_4, addhi_4): For
+ operand2 -128 override length_immediate attribute to 1.
+ * config/i386/predicates.md (constm128_operand): New predicate.
+
+ * config/i386/i386.c (memory_address_length): Handle %r12
+ the same as %rsp and %r13 the same as %rbp. For %rsp and %rbp
+ also check REGNO.
+ (ix86_attr_length_address_default): For MODE_SI lea in 64-bit
+ mode look through optional ZERO_EXTEND and SUBREG.
+ * config/i386/i386.md (R12_REG): New define_constant.
+ (prefix_data16): For sse unit set also for MODE_TI insns.
+ (prefix_rex): For -m32 always return 0. For TYPE_IMOVX
+ insns set if operand 1 is ext_QIreg_operand.
+ (modrm): For TYPE_IMOV clear only if not MODE_DI. For
+ TYPE_{ALU{,1},ICMP,TEST} insn clear if there is non-shortened
+ immediate.
+ (*movdi_extzv_1, zero_extendhidi2, zero_extendqidi2): Change
+ mode from MODE_DI to MODE_SI.
+ (movdi_1_rex64): Override modrm and length_immediate attributes
+ only for movabs (TYPE_IMOV, alternative 2).
+ (zero_extendsidi2_rex64): Clear prefix_0f attribute if TYPE_IMOVX.
+ (*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit,
+ *float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit,
+ *float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit,
+ *float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit): Set
+ prefix_rex attribute if DImode.
+ (*adddi_1_rex64, *adddi_2_rex64, *adddi_3_rex64, *adddi_5_rex64,
+ *addsi_1, *addsi_1_zext, *addsi_2, *addsi_2_zext, *addsi_3,
+ *addsi_3_zext, *addsi_5, *addhi_1_lea, *addhi_1, *addhi_2, *addhi_3,
+ *addhi_5, *addqi_1_lea, *addqi_1): Override length_immediate
+ attribute to 1 if TYPE_ALU and operand 2 is const128_operand.
+ (pro_epilogue_adjust_stack_1, pro_epilogue_adjust_stack_rex64):
+ Likewise. For TYPE_IMOV clear length_immediate attribute.
+ (*ashldi3_1_rex64, *ashldi3_cmp_rex64, *ashldi3_cconly_rex64,
+ *ashlsi3_1, *ashlsi3_1_zext, *ashlsi3_cmp, **ashlsi3_cconly,
+ *ashlsi3_cmp_zext, *ashlhi3_1_lea, *ashlhi3_1, *ashlhi3_cmp,
+ *ashlhi3_cconly, *ashlqi3_1_lea, *ashlqi3_1, *ashlqi3_cmp,
+ *ashlqi3_cconly): Override length_immediate attribute to 0 if TYPE_ALU
+ or one operand TYPE_ISHIFT.
+ (*ashrdi3_1_one_bit_rex64, *ashrdi3_one_bit_cmp_rex64,
+ *ashrdi3_one_bit_cconly_rex64, *ashrsi3_1_one_bit,
+ *ashrsi3_1_one_bit_zext, *ashrsi3_one_bit_cmp,
+ *ashrsi3_one_bit_cconly, *ashrsi3_one_bit_cmp_zext,
+ *ashrhi3_1_one_bit, *ashrhi3_one_bit_cmp, *ashrhi3_one_bit_cconly,
+ *ashrqi3_1_one_bit, *ashrqi3_1_one_bit_slp, *ashrqi3_one_bit_cmp,
+ *ashrqi3_one_bit_cconly, *lshrdi3_1_one_bit_rex64,
+ *lshrdi3_cmp_one_bit_rex64, *lshrdi3_cconly_one_bit_rex64,
+ *lshrsi3_1_one_bit, *lshrsi3_1_one_bit_zext, *lshrsi3_one_bit_cmp,
+ *lshrsi3_one_bit_cconly, *lshrsi3_cmp_one_bit_zext,
+ *lshrhi3_1_one_bit, *lshrhi3_one_bit_cmp, *lshrhi3_one_bit_cconly,
+ *lshrqi3_1_one_bit, *lshrqi3_1_one_bit_slp, *lshrqi2_one_bit_cmp,
+ *lshrqi2_one_bit_cconly, *rotlsi3_1_one_bit_rex64, *rotlsi3_1_one_bit,
+ *rotlsi3_1_one_bit_zext, *rotlhi3_1_one_bit, *rotlqi3_1_one_bit_slp,
+ *rotlqi3_1_one_bit, *rotrdi3_1_one_bit_rex64, *rotrsi3_1_one_bit,
+ *rotrsi3_1_one_bit_zext, *rotrhi3_one_bit, *rotrqi3_1_one_bit,
+ *rotrqi3_1_one_bit_slp): Override length_immediate attribute to 0,
+ set mode attribute, don't override length attribute.
+ (*btsq, *btrq, *btcq, *btdi_rex64, *btsi): Set prefix_0f attribute
+ to 1.
+ (return_internal_long): Set length attribute to 2 instead of 1.
+ (*strmovqi_rex_1, *strsetqi_rex_1, *rep_stosqi_rex64,
+ *cmpstrnqi_nz_rex_1, *cmpstrnqi_rex_1, *strlenqi_rex_1): Clear
+ prefix_rex attribute.
+ * config/i386/predicates.md (ext_QIreg_operand, const128_operand):
+ New predicates.
+ (memory_displacement_only_operand): Always return 0 for TARGET_64BIT.
+
+2009-05-21 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
+
+ * config/arm/thumb2.md (orsi_notsi_si): Fix typo in pattern.
+
+2009-05-20 Ian Lance Taylor <iant@google.com>
+
+ * tree.c (build_tree_list_vec_stat): New function.
+ (ctor_to_vec): New function.
+ (build_nt_call_vec): New function.
+ (build_call_array): Change args to be a const pointer.
+ (build_call_vec): New function.
+ * tree.h (build_nt_call_vec): Declare.
+ (build_tree_list_vec_stat): Declare.
+ (build_tree_list_vec): Define.
+ (build_call_array): Update declaration.
+ (build_call_vec): Declare.
+ (ctor_to_vec): Declare.
+ * c-common.c (tree_vector_cache): New static variable.
+ (make_tree_vector): New function.
+ (release_tree_vector): New function.
+ (make_tree_vector_single): New function.
+ (make_tree_vector_copy): New function.
+ * c-common.h (tree_vector_cache, make_tree_vector): Declare.
+ (make_tree_vector_single, make_tree_vector_copy): Declare.
+ * c-parser.c (cached_expr_list_1, cached_expr_list_2): Remove.
+ (c_parser_expr_list): Don't manage cache here, instead call
+ make_tree_vector.
+ (c_parser_release_expr_list): Remove static function.
+ (c_parser_vec_to_tree_list): Remove static function.
+ (c_parser_attributes): Call build_tree_list_vec instead of
+ c_parser_vec_to_tree_list. Call release_tree_vector instead of
+ c_parser_release_expr_list.
+ (c_parser_postfix_expression_after_primary): Likewise.
+ (c_parser_objc_keywordexpr): Likewise.
+
+2009-05-20 Sandra Loosemore <sandra@codesourcery.com>
+
+ * doc/tm.texi (Misc): Document TARGET_INVALID_PARAMETER_TYPE,
+ TARGET_INVALID_RETURN_TYPE, TARGET_PROMOTED_TYPE, and
+ TARGET_CONVERT_TO_TYPE.
+ * hooks.c (hook_tree_const_tree_null): Define.
+ * hooks.h (hook_tree_const_tree_null): Declare.
+ * target.h (struct gcc_target): Add invalid_parameter_type,
+ invalid_return_type, promoted_type, and convert_to_type fields.
+ * target-def.h: (TARGET_INVALID_PARAMETER_TYPE): Define.
+ (TARGET_INVALID_RETURN_TYPE): Define.
+ (TARGET_PROMOTED_TYPE): Define.
+ (TARGET_CONVERT_TO_TYPE): Define.
+ (TARGET_INITIALIZER): Update for new fields.
+ * c-decl.c (grokdeclarator): Check targetm.invalid_return_type.
+ (grokparms): Check targetm.invalid_parameter_type.
+ * c-typeck.c (default_conversion): Check targetm.promoted_type.
+ * c-convert.c (convert): Check targetm.convert_to_type.
+
+2009-05-20 Adam Nemet <anemet@caviumnetworks.com>
+
+ * config/mips/mips.md (*extenddi_truncate<mode>,
+ *extendsi_truncate<mode>): Emit exts if supported. Add attribute
+ defintions.
+ (*extendhi_truncateqi): New define_insn_and_sptit.
+
+2009-05-20 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/40204
+ * fold-const.c (fold_binary) <case BIT_AND_EXPR>: Avoid infinite
+ recursion if build_int_cst_type returns the same INTEGER_CST as arg1.
+
+2009-05-20 Eric Botcazou <ebotcazou@adacore.com>
+
+ * fold-const.c (build_fold_addr_expr_with_type): Take the address of
+ the operand of VIEW_CONVERT_EXPR.
+
+2009-05-20 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config/i386/driver-i386.c (host_detect_local_cpu): Check
+ extended family and model for Intel processors. Support Intel Atom.
+
+2009-05-20 Olivier Hainque <hainque@adacore.com>
+
+ * gstab.h (stab_code_type): Define, to be used instead of the
+ __stab_debug_code enum, made anonymous. Add 2009 to the copyright
+ notice.
+ * dbxout.c (STAB_CODE_TYPE): Remove #define and replace use
+ occurrences by stab_code_type.
+ * mips-tfile.c (STAB_CODE_TYPE): Remove #define, unused.
+
+2009-05-20 Martin Jambor <mjambor@suse.cz>
+
+ * tree-flow.h (insert_edge_copies_seq): Undeclare.
+ (sra_insert_before): Likewise.
+ (sra_insert_after): Likewise.
+ (sra_init_cache): Likewise.
+ (sra_type_can_be_decomposed_p): Likewise.
+ * tree-mudflap.c (insert_edge_copies_seq): Copied here from tree-sra.c
+ * tree-sra.c (sra_type_can_be_decomposed_p): Made static.
+ (sra_insert_before): Likewise.
+ (sra_insert_after): Likewise.
+ (sra_init_cache): Likewise.
+ (insert_edge_copies_seq): Made static and moved upwards.
+
+ * tree-complex.c (extract_component): Added VIEW_CONVERT_EXPR switch
+ case.
+
+ * tree-flow-inline.h (contains_view_convert_expr_p): New function.
+
+ * ipa-prop.c (get_ssa_def_if_simple_copy): New function.
+ (determine_cst_member_ptr): Call get_ssa_def_if_simple_copy to skip
+ simple copies.
+
+2009-05-20 Richard Guenther <rguenther@suse.de>
+
+ * expr.c (expand_expr_real_1): Avoid calling do_store_flag
+ with mismatched comparison modes.
+
+2009-05-20 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
+
+ * config/arm/arm.md (*arm_iorsi3): Refactored for only ARM.
+ (peephole ior (reg, int) -> mov, ior): Refactored for only ARM.
+ * config/arm/thumb2.md (*thumb_andsi_not_shiftsi_si): Allow bic
+ with shifts for Thumb2.
+ (orsi_notsi): New for orn.
+ (*thumb_orsi_notshiftsi_si): Allow orn with shifts.
+ (*thumb2_iorsi3): Rewrite support for iorsi for Thumb2.
+ * config/arm/arm.c (const_ok_for_op): Split case for IOR for Thumb2.
+ (arm_gen_constant): Set can_invert for IOR and Thumb2, Add comments.
+ Don't invert remainder for IOR.
+
+2009-05-19 Zdenek Dvorak <ook@ucw.cz>
+
+ PR tree-optimization/40087
+ * tree-ssa-loop-niter.c (number_of_iterations_ne_max,
+ number_of_iterations_ne): Rename never_infinite argument.
+ (number_of_iterations_lt_to_ne, number_of_iterations_lt,
+ number_of_iterations_le): Handle pointer-type ivs when
+ exit_must_be_taken is false.
+ (number_of_iterations_cond): Do not always assume that
+ exit_must_be_taken if the control variable is a pointer.
+
+2009-05-19 Andrew Pinski <andrew_pinski@playstation.sony.com>
+
+ * c-typeck.c (build_binary_op): Allow % on integal vectors.
+ * doc/extend.texi (Vector Extension): Document that % is allowed too.
+
+2009-05-19 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config/i386/i386.c (ix86_avoid_jump_mispredicts): Check
+ ASM_OUTPUT_MAX_SKIP_PAD instead of ASM_OUTPUT_MAX_SKIP_ALIGN.
+
+2009-05-19 Manuel López-Ibáñez <manu@gcc.gnu.org>
+
+ PR c/40172
+ * c.opt (Wlogical-op): Disabled by default.
+ * c-opt (c_common_post_options): Do not enable Wlogical-op with
+ Wextra.
+ * doc/invoke.texi (Wlogical-op): Likewise.
+
+2009-05-19 Eric Botcazou <ebotcazou@adacore.com>
+
+ * tree-scalar-evolution.c (follow_ssa_edge_expr) <NOP_EXPR>: Turn
+ into CASE_CONVERT.
+ <PLUS_EXPR>: Strip useless type conversions instead of type nops.
+ Propagate the type of the first operand.
+ <ASSERT_EXPR>: Simplify.
+ (follow_ssa_edge_in_rhs): Use gimple_expr_type to get the type.
+ Rewrite using the RHS code as discriminant.
+ <NOP_EXPR>: Turn into CASE_CONVERT.
+ <PLUS_EXPR>: Propagate the type of the first operand.
+
+2009-05-19 Steve Ellcey <sje@cup.hp.com>
+
+ * config/ia64/ia64-protos.h (ia64_dconst_0_5): New.
+ (ia64_dconst_0_375): New.
+ * config/ia64/ia64.c (ia64_override_options): Remove
+ -minline-sqrt-min-latency warning.
+ (ia64_dconst_0_5_rtx, ia64_dconst_0_5): New.
+ (ia64_dconst_0_375_rtx, ia64_dconst_0_375): New
+ * config/ia64/ia64.md (*sqrt_approx): Remove.
+ (sqrtsf2): Remove #if 0.
+ (sqrtsf2_internal_thr): Rewrite and move to div.md.
+ (sqrtdf): Remove assert.
+ (sqrtdf2_internal_thr): Rewrite and move to div.md.
+ (sqrtxf2): Remove #if 0.
+ (sqrtxf2_internal_thr): Rewrite and move to div.md.
+ * div.md (sqrt_approx_rf): New.
+ (sqrtsf2_internal_thr): New implementation.
+ (sqrtsf2_internal_lat): New.
+ (sqrtdf2_internal_thr: New implementation.
+ (sqrtxf2_internal): New implementation.
+
+2009-05-19 Francois-Xavier Coudert <fxcoudert@gmail.com>
+ Hans-Peter Nilsson <hp@axis.com>
+
+ * defaults.h (UINT_FAST64_TYPE, INTPTR_TYPE, UINTPTR_TYPE)
+ (WCHAR_TYPE, MODIFIED_WCHAR_TYPE, PTRDIFF_TYPE, WINT_TYPE)
+ (INTMAX_TYPE, UINTMAX_TYPE, SIG_ATOMIC_TYPE, INT8_TYPE, INT16_TYPE)
+ (INT32_TYPE, INT64_TYPE, UINT8_TYPE, UINT16_TYPE, UINT32_TYPE)
+ (UINT64_TYPE, INT_LEAST8_TYPE, INT_LEAST16_TYPE, INT_LEAST32_TYPE)
+ (INT_LEAST64_TYPE, UINT_LEAST8_TYPE, UINT_LEAST16_TYPE)
+ (UINT_LEAST32_TYPE, UINT_LEAST64_TYPE, INT_FAST8_TYPE)
+ (INT_FAST16_TYPE, INT_FAST32_TYPE, INT_FAST64_TYPE)
+ (UINT_FAST8_TYPE, UINT_FAST16_TYPE, UINT_FAST32_TYPE)
+ (SIZE_TYPE, PID_TYPE, CHAR16_TYPE, CHAR32_TYPE): Move defaults here...
+ * c-common.c: ...from here.
+
+2009-05-19 Manuel López-Ibáñez <manu@gcc.gnu.org>
+
+ * c-common.c (warn_logical_operator): Remove unnecessary conditionals.
+
+2009-05-19 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtins.c (do_mpc_arg1): Separate MPFR/MPC C rounding types.
+
+2009-05-19 Ben Elliston <bje@au.ibm.com>
+
+ * unwind-dw2-fde.c (fde_unencoded_compare): Replace type punning
+ assignments with memcpy calls.
+ (add_fdes): Likewise.
+ (binary_search_unencoded_fdes): Likewise.
+ (linear_search_fdes): Eliminate type puns.
+
+2009-05-19 Richard Guenther <rguenther@suse.de>
+
+ * tree-ssa-forwprop.c (forward_propagate_addr_expr_1): Do
+ not falsely claim to have propagated into all uses.
+
+2009-05-19 Ben Elliston <bje@au.ibm.com>
+
+ * doc/invoke.texi (C Dialect Options): Update OpenMP specification
+ version to v3.0.
+
+2009-05-18 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ * config/sh/sh-protos.h (sh_legitimate_address_p): Remove.
+ * config/sh/sh.c (sh_legitimate_address_p): Make static.
+ (TARGET_LEGITIMATE_ADDRESS_P): New.
+ * config/sh/sh.h (GO_IF_LEGITIMATE_ADDRESS): Delete.
+ * config/sh/sh.md: Clean up references to GO_IF_LEGITIMATE_ADDRESS.
+
+2009-05-18 Dodji Seketeli <dodji@redhat.com>
+
+ PR debug/40109
+ * dwarf2out.c (gen_type_die_with_usage): Generate the DIE as a
+ child of the containing namespace's DIE.
+
+2009-05-18 Adam Nemet <anemet@caviumnetworks.com>
+
+ * config/mips/mips.md (*zero_extend<GPR:mode>_trunc<SHORT:mode>,
+ *zero_extendhi_truncqi): Move after the zero_extend patterns.
+ (*extenddi_truncate<mode>, *extendsi_truncate<mode>): Move after the
+ extend patterns.
+
+2009-05-18 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR target/39942
+ * config/i386/i386.c (ix86_avoid_jump_misspredicts): Replace
+ gen_align with gen_pad.
+ (ix86_reorg): Check ASM_OUTPUT_MAX_SKIP_PAD instead of
+ #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN.
+
+ * config/i386/i386.h (ASM_OUTPUT_MAX_SKIP_PAD): New.
+ * config/i386/x86-64.h (ASM_OUTPUT_MAX_SKIP_PAD): Likewise.
+
+ * config/i386/i386.md (align): Renamed to ...
+ (pad): This. Replace ASM_OUTPUT_MAX_SKIP_ALIGN with
+ ASM_OUTPUT_MAX_SKIP_PAD.
+
+2009-05-18 Andreas Schwab <schwab@linux-m68k.org>
+
+ * config.gcc: Fix variable syntax.
+
+ PR target/39531
+ * config/m68k/m68k.c (output_andsi3): Mask off sign bit copies
+ before calling exact_log2.
+ (output_iorsi3): Likewise.
+ (output_xorsi3): Likewise.
+
+2009-05-18 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ * config/sh/sh.c (expand_cbranchdi4): Use a scratch register
+ for the none zero constant operand except for EQ and NE
+ comprisons even when the first operand is R0.
+
+2009-05-18 Andreas Krebbel <krebbel1@de.ibm.com>
+
+ * config/s390/2064.md: Remove trailing whitespaces.
+ * config/s390/2084.md: Likewise.
+ * config/s390/constraints.md: Likewise.
+ * config/s390/fixdfdi.h: Likewise.
+ * config/s390/libgcc-glibc.ver: Likewise.
+ * config/s390/s390-modes.def: Likewise.
+ * config/s390/s390-protos.h: Likewise.
+ * config/s390/s390.c: Likewise.
+ * config/s390/s390.h: Likewise.
+ * config/s390/s390.md: Likewise.
+ * config/s390/tpf-unwind.h: Likewise.
+
+2009-05-18 Maxim Kuvyrkov <maxim@codesourcery.com>
+
+ * config/m68k/m68k.c (m68k_legitimize_address): Fix typo in signature.
+
+2009-05-18 Maxim Kuvyrkov <maxim@codesourcery.com>
+
+ M68K TLS support.
+ * configure.ac (m68k-*-*): Check if binutils support TLS.
+ * configure: Regenerate.
+ * config/m68k/predicates.md (symbolic_operand): Extend comment.
+ * config/m68k/constraints.md (Cu): New constraint.
+ * config/m68k/m68k.md (UNSPEC_GOTOFF): Remove.
+ (UNSPEC_RELOC16, UNSPEC_RELOC32): New constants.
+ (movsi): Handle TLS symbols.
+ (addsi3_5200): Handle XTLS symbols, indent.
+ * config/m68k/m68k-protos.h (m68k_legitimize_tls_address): Declare.
+ (m68k_tls_reference_p): Declare.
+ (m68k_legitimize_address): Declare.
+ (m68k_unwrap_symbol): Declare.
+ * config/m68k/m68k.opt (mxtls): New option.
+ * config/m68k/m68k.c (ggc.h): Include.
+ (m68k_output_dwarf_dtprel): Implement hook.
+ (TARGET_HAVE_TLS, TARGET_ASM_OUTPUT_DWARF_DTPREL): Define.
+ (m68k_expand_prologue): Load GOT pointer when function needs it.
+ (m68k_illegitimate_symbolic_constant_p): Handle TLS symbols.
+ (m68k_legitimate_constant_address_p): Same.
+ (m68k_decompose_address): Handle TLS references.
+ (m68k_get_gp): New static function.
+ (enum m68k_reloc): New contants.
+ (TLS_RELOC_P): New macro.
+ (m68k_wrap_symbol): New static function.
+ (m68k_unwrap_symbol): New function.
+ (m68k_final_prescan_insn_1): New static function.
+ (m68k_final_prescan_insn): New function.
+ (m68k_move_to_reg, m68k_wrap_symbol_into_got_ref): New static
+ functions.
+ (legitimize_pic_address): Handle TLS references..
+ (m68k_tls_get_addr, m68k_get_tls_get_addr)
+ (m68k_libcall_value_in_a0_p)
+ (m68k_call_tls_get_addr, m68k_read_tp, m68k_get_m68k_read_tp)
+ (m68k_call_m68k_read_tp): Helper variables and functions for ...
+ (m68k_legitimize_tls_address): Handle TLS references.
+ (m68k_tls_symbol_p, m68k_tls_reference_p_1, m68k_tls_reference_p):
+ New functions.
+ (m68k_legitimize_address): Handle TLS symbols.
+ (m68k_get_reloc_decoration): New static function.
+ (m68k_output_addr_const_extra): Handle UNSPEC_RELOC16 and
+ UNSPEC_RELOC32.
+ (m68k_output_dwarf_dtprel): Implement hook.
+ (print_operand_address): Handle UNSPEC_RELOC16 adn UNSPEC_RELOC32.
+ (m68k_libcall_value): Return result in A0 instead of D0 when asked by
+ m68k_call_* routines.
+ (sched_attr_op_type): Handle TLS symbols.
+ (gt-m68k.h): Include.
+ * config/m68k/m68k.h (FINAL_PRESCAN_INSN): Define.
+ (LEGITIMATE_PIC_OPERAND_P): Support TLS.
+
+2009-05-18 Martin Jambor <mjambor@suse.cz>
+
+ * ipa-prop.c (ipa_check_stmt_modifications): Removed.
+ (visit_store_addr_for_mod_analysis): New function.
+ (ipa_detect_param_modifications): Use walk_stmt_load_store_addr_ops.
+ (determine_cst_member_ptr): Use gimple_assign_single_p.
+ (ipa_get_stmt_member_ptr_load_param): Use gimple_assign_single_p.
+ (ipa_analyze_call_uses): Use !gimple_assign_rhs2 rather than number of
+ operands. Don't check number of operands of a NOP_EXPR.
+
+2009-05-18 Eric Fisher <joefoxreal@gmail.com>
+
+ * doc/tree-ssa.texi (SSA Operands): Fix a mistake.
+
+2009-05-17 Manuel López-Ibáñez <manu@gcc.gnu.org>
+
+ PR c/40172
+ * c-common.c (warn_logical_operator): Don't warn if one of
+ expression isn't always true or false.
+
+2009-05-17 Kai Tietz <kai.tietz@onevision.com>
+
+ * config/i386/biarch32.h: New file.
+ * config.gcc: Add for target i386-w64-* the biarch32.h to tm_file.
+
+2009-05-17 Adam Nemet <anemet@caviumnetworks.com>
+
+ * config/mips/mips.md (*zero_extend<mode>_trunchi,
+ *zero_extend<mode>_truncqi): Merge these into ...
+ (*zero_extend<GPR:mode>_trunc<SHORT:mode>): ... this new pattern.
+ Name the pattern following this as *zero_extendhi_truncqi.
+
+2009-05-16 Brad Lucier <lucier@math.purdue.edu>
+
+ PR middle-end/39301
+ * hwint.h: Add macro HOST_WIDEST_INT_PRINT.
+ * bitmap.c (bitmap_descriptor): Make fields HOST_WIDEST_INT.
+ (output_info): Make field HOST_WIDEST_INT.
+ (print_statistics): Use HOST_WIDEST_INT_PRINT.
+ (dump_bitmat_statistics): Same.
+
+2009-05-16 Francois-Xavier Coudert <fxcoudert@gmail.com>
+
+ * config.gcc (use_gcc_stdint): Set to wrap.
+ * config/darwin.h (SIG_ATOMIC_TYPE, INT8_TYPE, INT16_TYPE,
+ INT32_TYPE, INT64_TYPE, UINT8_TYPE, UINT16_TYPE, UINT32_TYPE,
+ UINT64_TYPE, INT_LEAST8_TYPE, INT_LEAST16_TYPE, INT_LEAST32_TYPE,
+ INT_LEAST64_TYPE, UINT_LEAST8_TYPE, UINT_LEAST16_TYPE,
+ UINT_LEAST32_TYPE, UINT_LEAST64_TYPE, INT_FAST8_TYPE,
+ INT_FAST16_TYPE, INT_FAST32_TYPE, INT_FAST64_TYPE,
+ UINT_FAST8_TYPE, UINT_FAST16_TYPE, UINT_FAST32_TYPE,
+ UINT_FAST64_TYPE, INTPTR_TYPE, UINTPTR_TYPE): Define.
+
+2009-05-16 Joseph Myers <joseph@codesourcery.com>
+
+ * config.gcc (mips*-*-*): Support arch_32, arch_64, tune_32 and
+ tune_64.
+ * config/mips/mips.h (MIPS_ABI_DEFAULT, MULTILIB_ABI_DEFAULT):
+ Move definitions earlier.
+ (OPT_ARCH64, OPT_ARCH32): Define.
+ (OPTION_DEFAULT_SPECS): Add entries for arch_32, arch_64, tune_32
+ and tune_64.
+
+2009-05-16 Richard Earnshaw <rearnsha@arm.com>
+
+ PR target/40153
+ * arm.md (cstoresi_nltu_thumb1): Use a neg of ltu as the pattern name
+ implies.
+
+2009-05-16 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.md (movdi2): Copy non-reg values to DImode registers.
+
+2009-05-16 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/39942
+ * final.c (label_to_max_skip): New function.
+ (label_to_alignment): Only use LABEL_TO_ALIGNMENT if
+ CODE_LABEL_NUMBER <= max_labelno.
+ * output.h (label_to_max_skip): New prototype.
+ * config/i386/i386.c (ix86_avoid_jump_misspredicts): Renamed to...
+ (ix86_avoid_jump_mispredicts): ... this. Don't define if
+ ASM_OUTPUT_MAX_SKIP_ALIGN isn't defined. Update comment.
+ Handle CODE_LABELs with >= 16 byte alignment or with
+ max_skip == (1 << align) - 1.
+ (ix86_reorg): Don't call ix86_avoid_jump_mispredicts if
+ ASM_OUTPUT_MAX_SKIP_ALIGN isn't defined.
+
+ PR target/39942
+ * config/i386/x86-64.h (ASM_OUTPUT_MAX_SKIP_ALIGN): Don't emit second
+ .p2align 3 if MAX_SKIP is smaller than 7.
+ * config/i386/linux.h (ASM_OUTPUT_MAX_SKIP_ALIGN): Likewise.
+
+2009-05-15 Ian Lance Taylor <iant@google.com>
+
+ * alias.c (struct alias_set_entry_d): Rename from struct
+ alias_set_entry. Change all uses.
+ * except.c (struct call_site_record_d): Rename from struct
+ call_site_record. Change all uses.
+ * except.h (struct eh_region_d): Rename from struct eh_region.
+ Change all uses.
+ * gcse.c (struct hash_table_d): Rename from struct hash_table.
+ Change all uses.
+ * graphite.c (struct ivtype_map_elt_d): Rename fromstruct
+ ivtype_map_elt. Change all uses.
+ (struct rename_map_elt_d): Rename fromstruct rename_map_elt.
+ Change all uses.
+ (struct ifsese_d): Rename fromstruct ifsese. Change all uses.
+ * graphite.h (struct name_tree_d): Rename from struct name_tree.
+ Change all uses.
+ (struct sese_d): Rename from struct sese. Change all uses.
+ * omega.h (struct eqn_d): Rename from struct eqn. Change all uses.
+ (struct omega_pb_d): Rename from struct omega_pb. Change all uses.
+ * optabs.h (struct optab_d): Rename from struct optab. Change all
+ uses.
+ (struct convert_optab_d): Rename from struct convert_optab.
+ Change all uses.
+ * tree-pass.h (struct ipa_opt_pass_d): Rename fromstruct
+ ipa_opt_pass. Change all uses.
+ * tree-predcom.c (struct dref_d): Rename from struct dref. Change
+ all uses.
+
+ * c-decl.c (pushtag): If -Wc++-compat, warn if the tag is already
+ defined as a typedef.
+ (grokdeclarator): If -Wc++-compat, warn if a typedef is already
+ defined as a tag.
+
+2009-05-15 Manuel López-Ibáñez <manu@gcc.gnu.org>
+
+ PR 16302
+ * fold-const.c (make_range,build_range_check,merge_ranges): Move
+ declaration to...
+ (merge_ranges): Returns bool.
+ * tree.h (make_range): .. to here.
+ (build_range_check): Likewise.
+ (merge_ranges): Likewise. Renamed from merge_ranges.
+ * c-typeck.c (parser_build_binary_op): Update calls to
+ warn_logical_operator.
+ * c-common.c (warn_logical_operator): Add new warning.
+ * c-common.h (warn_logical_operator): Update declaration.
+
+2009-05-15 Manuel López-Ibáñez <manu@gcc.gnu.org>
+
+ * ira-conflicts.c (add_insn_allocno_copies): Fix wrong conditional.
+
+2009-05-15 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * doc/install.texi: Document MPC requirements, flags etc.
+
+ * builtins.c (do_mpc_arg1, fold_builtin_ccos): New.
+ (fold_builtin_cexp): Ensure we get a complex REAL_TYPE.
+ Evaluate constant arguments.
+ (fold_builtin_carg): Ensure we get a complex REAL_TYPE.
+ (fold_builtin_1): Likewise, also evaluate constant arguments.
+ Remove superfluous break.
+ (do_mpc_ckconv): New.
+ * real.h: Include mpc.h.
+ * toplev.c (print_version): Output MPC version info if available.
+
+2009-05-15 Sandra Loosemore <sandra@codesourcery.com>
+
+ * fold-const.c (fold_convert_const_real_from_real): Check for overflow.
+
+2009-05-15 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config/i386/i386.c (ix86_reorg): Call optimize_function_for_speed_p
+ only once.
+
+2009-05-15 Jan Hubicka <jh@suse.cz>
+
+ * doc/invoke.texi (max-early-inliner-iterations): New flag.
+ * ipa-inline.c (enum inlining_mode): New INLINE_SIZE_NORECURSIVE.
+ (try_inline): Fix return value.
+ (cgraph_decide_inlining_incrementally): Honor new value.
+ (cgraph_early_inlining): Handle indirect inlining.
+ * params.def (PARAM_EARLY_INLINER_MAX_ITERATIONS): New.
+
+2009-05-15 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.h (struct cgraph_node): Add finalized_by_frotnend flag.
+ * cgraphunit.c (cgraph_finalize_function): Set it.
+ (cgraph_expand_function): Use it.
+
+2009-05-15 Sandra Loosemore <sandra@codesourcery.com>
+
+ * real.c (encode_ieee_half): Define.
+ (decode_ieee_half): Define.
+ (ieee_half_format): Define.
+ (arm_half_format): Define.
+ * real.h (ieee_half_format): Declare.
+ (arm_half_format): Declare.
+
+2009-05-15 Sandra Loosemore <sandra@codesourcery.com>
+
+ * optabs.c (prepare_float_lib_cmp): Test that the comparison,
+ swapped, and reversed optabs exist before trying to use them.
+
+2009-05-15 Paul Brook <paul@codesourcery.com>
+ Sandra Loosemore <sandra@codesourcery.com>
+
+ * config/arm/arm.c (neon_vector_mem_operand): Handle element/structure
+ loads. Allow PRE_DEC.
+ (output_move_neon): Handle PRE_DEC.
+ (arm_print_operand): Add 'A' for neon structure loads.
+ * config/arm/arm-protos.h (neon_vector_mem_operand): Update prototype.
+ * config/arm/neon.md (neon_mov): Update comment.
+ * config/arm/constraints.md (Un, Us): Update neon_vector_mem_operand
+ calls.
+ (Um): New constraint.
+
+2009-05-15 Jan Hubicka <jh@suse.cz>
+
+ Revert the following patch until testsuite fallout is fixed:
+ * cgraph.c (dump_cgraph_node): Dump size/time/benefit.
+ * cgraph.h (struct inline_summary): New filed self_wize,
+ size_inlining_benefit, self_time and time_inlining_benefit.
+ (struct cgraph_global_info): Replace insns by time ans size fields.
+ * ipa-cp (ipcp_cloning_candidate_p): Base estimate on size
+ (ipcp_estimate_growth, ipcp_insert_stage): Likewise.
+ (ipcp_update_callgraph): Do not touch function bodies.
+ * ipa-inline.c: Include except.h
+ (MAX_TIME): New constant.
+ (overall_insns): Remove
+ (overall_size, max_benefit): New static variables.
+ (cgraph_estimate_time_after_inlining): New function.
+ (cgraph_estimate_size_after_inlining): Rewrite using benefits.
+ (cgraph_clone_inlined_nodes): Update size.
+ (cgraph_mark_inline_edge): Update size.
+ (cgraph_estimate_growth): Use size info.
+ (cgraph_check_inline_limits): Check size.
+ (cgraph_default_inline_p): Likewise.
+ (cgraph_edge_badness): Compute badness based on benefit and size cost.
+ (cgraph_decide_recursive_inlining): Check size.
+ (cgraph_decide_inlining_of_small_function): Update size; dump sizes
+ and times.
+ (cgraph_decide_inlining): Likewise.
+ (cgraph_decide_inlining_incrementally): Likewise; honor
+ PARAM_EARLY_INLINING_INSNS.
+ (likely_eliminated_by_inlining_p): New predicate.
+ (estimate_function_body_sizes): New function.
+ (compute_inline_parameters): Use it.
+ * except.c (must_not_throw_labels): New function.
+ * except.h (must_not_throw_labels): Declare.
+ * tree-inline.c (init_inline_once): Kill inlining_weigths
+ * tree-ssa-structalias.c: Avoid uninitialized warning.
+ * params.def (PARAM_MAX_INLINE_INSNS_SINGLE): Reduce to 300.
+ (PARAM_MAX_INLINE_INSNS_AUTO): Reduce to 60.
+ (PARAM_INLINE_CALL_COST): Remove.
+ (PARAM_EARLY_INLINING_INSNS): New.
+
+2009-05-15 Richard Guenther <rguenther@suse.de>
+
+ * tree-ssa-pre.c (eliminate): Use TODO_update_ssa_only_virtuals,
+ not TODO_update_ssa.
+
+2009-05-15 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/39999
+ * gimple.h (gimple_expr_type): Use the expression type looking
+ through useless conversions.
+ * tree-ssa-sccvn.c (vn_nary_op_lookup_stmt): Use gimple_expr_type.
+ (vn_nary_op_insert_stmt): Likewise.
+ (simplify_binary_expression): Likewise.
+
+2009-05-15 Richard Guenther <rguenther@suse.de>
+
+ * common.opt (-ftree-forwprop, -ftree-phiprop, -ftree-pta):
+ New options, enabled by default.
+ * doc/invoke.texi (-ftree-forwprop, -ftree-phiprop, -ftree-pta):
+ Document.
+ * tree-ssa-forwprop.c (gate_forwprop): Use flag_tree_forwprop.
+ * tree-ssa-phiprop.c (gate_phiprop): Use flag_tree_phiprop.
+ * tree-ssa-structalias.c (gate_tree_pta): New function.
+ (pass_build_alias): Use it.
+
+2009-05-15 Joseph Myers <joseph@codesourcery.com>
+
+ * tree-ssa-forwprop.c (forward_propagate_addr_expr_1): Also
+ recurse on an invariant address if a conversion from a pointer
+ type to a wider integer type is involved.
+
+2009-05-15 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.c (dump_cgraph_node): Dump size/time/benefit.
+ * cgraph.h (struct inline_summary): New filed self_wize,
+ size_inlining_benefit, self_time and time_inlining_benefit.
+ (struct cgraph_global_info): Replace insns by time ans size fields.
+ * ipa-cp (ipcp_cloning_candidate_p): Base estimate on size
+ (ipcp_estimate_growth, ipcp_insert_stage): Likewise.
+ (ipcp_update_callgraph): Do not touch function bodies.
+ * ipa-inline.c: Include except.h
+ (MAX_TIME): New constant.
+ (overall_insns): Remove
+ (overall_size, max_benefit): New static variables.
+ (cgraph_estimate_time_after_inlining): New function.
+ (cgraph_estimate_size_after_inlining): Rewrite using benefits.
+ (cgraph_clone_inlined_nodes): Update size.
+ (cgraph_mark_inline_edge): Update size.
+ (cgraph_estimate_growth): Use size info.
+ (cgraph_check_inline_limits): Check size.
+ (cgraph_default_inline_p): Likewise.
+ (cgraph_edge_badness): Compute badness based on benefit and size cost.
+ (cgraph_decide_recursive_inlining): Check size.
+ (cgraph_decide_inlining_of_small_function): Update size; dump sizes
+ and times.
+ (cgraph_decide_inlining): Likewise.
+ (cgraph_decide_inlining_incrementally): Likewise; honor
+ PARAM_EARLY_INLINING_INSNS.
+ (likely_eliminated_by_inlining_p): New predicate.
+ (estimate_function_body_sizes): New function.
+ (compute_inline_parameters): Use it.
+ * except.c (must_not_throw_labels): New function.
+ * except.h (must_not_throw_labels): Declare.
+ * tree-inline.c (init_inline_once): Kill inlining_weigths
+ * tree-ssa-structalias.c: Avoid uninitialized warning.
+ * params.def (PARAM_MAX_INLINE_INSNS_SINGLE): Reduce to 300.
+ (PARAM_MAX_INLINE_INSNS_AUTO): Reduce to 60.
+ (PARAM_INLINE_CALL_COST): Remove.
+ (PARAM_EARLY_INLINING_INSNS): New.
+ doc/invoke.texi (max-inline-insns-auto, early-inlining-insns): Update.
+ (inline-call-cost): Remove.
+ (early-inlining-insns): New.
+
+2009-05-15 Eric Botcazou <ebotcazou@adacore.com>
+
+ * dbxout.c (dbxout_range_type): Add LOW and HIGH parameters. Use them
+ for bounds.
+ (print_int_cst_bounds_in_octal_p): Likewise.
+ (dbxout_type): Adjust calls to above functions. Be prepared to deal
+ with subtypes.
+ * dwarf2out.c (base_type_die): Likewise.
+ (is_subrange_type): Delete.
+ (subrange_type_die): Add LOW and HIGH parameters. Use them for bounds.
+ (modified_type_die): Call subrange_type_for_debug_p on subtypes.
+ * fold-const.c (fold_truth_not_expr) <CONVERT_EXPR>: Do not strip it
+ if the destination type is boolean.
+ (build_range_check): Do not special-case subtypes.
+ (fold_sign_changed_comparison): Likewise.
+ (fold_unary): Likewise.
+ * langhooks-def.h (LANG_HOOKS_GET_SUBRANGE_BOUNDS): Define.
+ (LANG_HOOKS_FOR_TYPES_INITIALIZER): Add LANG_HOOKS_GET_SUBRANGE_BOUNDS.
+ * langhooks.h (lang_hooks_for_types): Add get_subrange_bounds.
+ * tree.c (subrange_type_for_debug_p): New predicate based on the
+ former is_subrange_type.
+ * tree.h (subrange_type_for_debug_p): Declare.
+ * tree-chrec.c (avoid_arithmetics_in_type_p): Delete.
+ (convert_affine_scev): Remove call to above function.
+ (chrec_convert_aggressive): Likewise.
+ * tree-ssa.c (useless_type_conversion_p_1): Do not specifically return
+ false for conversions involving subtypes.
+ * tree-vrp.c (vrp_val_max): Do not special-case subtypes.
+ (vrp_val_min): Likewise.
+ (needs_overflow_infinity): Likewise.
+ (extract_range_from_unary_expr): Likewise.
+
+2009-05-15 Paolo Bonzini <bonzini@gnu.org>
+
+ * config/frv/frv.h: Clean up references to GO_IF_LEGITIMATE_ADDRESS.
+ * config/frv/frv.c: Likewise.
+ * config/s390/s390.c: Likewise.
+ * config/sparc/sparc.h: Likewise.
+ * config/i386/i386.h: Likewise.
+ * config/i386/i386.c: Likewise.
+ * config/crx/crx.c: Likewise.
+ * config/m68hc11/m68hc11.h: Likewise.
+ * config/iq2000/iq2000.c: Likewise.
+ * config/mn10300/mn10300.h: Likewise.
+ * config/mn10300/mn10300.c: Likewise.
+ * config/m68k/m68k.c: Likewise.
+ * config/rs6000/rs6000.c: Likewise.
+ * config/rs6000/xcoff.h: Likewise.
+ * config/rs6000/linux64.h: Likewise.
+ * config/rs6000/sysv4.h: Likewise.
+ * config/score/score3.c: Likewise.
+ * config/score/score7.c: Likewise.
+ * config/score/score.c: Likewise.
+ * config/arm/arm.md: Likewise.
+ * config/mips/mips.c: Likewise.
+ * config/mips/mips.md: Likewise.
+ * config/bfin/bfin.h: Likewise.
+ * config/pa/pa.c: Likewise.
+ * config/pa/constraints.md: Likewise.
+
+ * config/pdp11/pdp11-protos.h (legitimate_address_p): Delete.
+ * config/pdp11/pdp11.c (legitimate_address_p): Delete.
+ * config/pdp11/pdp11.h: Use memory_address_p instead.
+
+2009-05-14 Ian Lance Taylor <iant@google.com>
+
+ * passes.c (finish_optimization_passes): Change i to int.
+ * plugin.c (plugins_active_p): Change event to int.
+ (dump_active_plugins): Likewise.
+ * reginfo.c (invalid_mode_change_p): Change to to unsigned int.
+ Add cast.
+ * tree.c (tree_range_check_failed): Change c to unsigned int.
+ (omp_clause_range_check_failed): Likewise.
+ (build_common_builtin_nodes): Change mode to int. Add cast.
+ * config/ia64/ia64.c (is_emitted): Change r to unsigned int.
+ (ia64_hard_regno_rename_ok, ia64_eh_uses): Likewise.
+
+ * c-typeck.c (build_unary_op): If -Wc++-compat, warn about using
+ ++ or -- with a variable of enum type.
+
+2009-05-14 Steven Bosscher <steven@gcc.gnu.org>
+
+ PR driver/40144
+ * opts.c (common_handle_option): Add OPT_fcse_skip_blocks as a no-op.
+
+2009-05-14 Steven Bosscher <steven@gcc.gnu.org>
+
+ * store-motion.c: Do not include params.h
+ * Makefile.in: Fix dependencies for various files.
+
+2009-05-14 Steven Bosscher <steven@gcc.gnu.org>
+
+ * auto-inc-dec.c: Fix pass description, remove apparent
+ accidental duplication.
+
+2009-05-14 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR middle-end/40147
+ * ipa-utils.h (memory_identifier_string): Moved to ...
+ * tree.h (memory_identifier_string): Here. Add GTY(()).
+
+2009-05-14 Paolo Bonzini <bonzini@gnu.org>
+
+ * doc/tm.texi (TARGET_LEGITIMATE_ADDRESS_P): Refer mainly to this
+ in the former documentation of...
+ (GO_IF_LEGITIMATE_ADDRESS): ... this.
+ * ira-conflicts.c (get_dup_num): Use address_operand.
+ * targhooks.c (default_legitimate_address_p): New.
+ * targhooks.h (default_legitimate_address_p): New.
+ * reload.c (strict_memory_address_p) [!GO_IF_LEGITIMATE_ADDRESS]:
+ Call hook.
+ * recog.c (memory_address_p) [!GO_IF_LEGITIMATE_ADDRESS]: Call hook.
+ * target.h (struct target): Add legitimate_address_p.
+ * target-def.h (TARGET_LEGITIMATE_ADDRESS_P): New.
+ (TARGET_INITIALIZER): Include it.
+
+ * config/alpha/alpha.h (GO_IF_LEGITIMATE_ADDRESS): Delete.
+ * config/alpha/alpha-protos.h (alpha_legitimate_address_p): Remove.
+ * config/alpha/alpha.c (alpha_legitimate_address_p): Make static.
+ (TARGET_LEGITIMATE_ADDRESS_P): New.
+
+ * config/frv/frv.h (GO_IF_LEGITIMATE_ADDRESS): Delete.
+ (REG_OK_STRICT_P): Delete.
+ * config/frv/frv-protos.h (frv_legitimate_address_p): Rename to...
+ (frv_legitimate_address_p_1): ... this.
+ * config/frv/frv.c (frv_legitimate_address_p): Forward to...
+ (frv_legitimate_address_p_1): ... the renamed old
+ frv_legitimate_address_p.
+ * config/frv/predicates.md: Adjust calls to frv_legitimate_address_p.
+ (TARGET_LEGITIMATE_ADDRESS_P): New.
+
+ * config/s390/s390.h (GO_IF_LEGITIMATE_ADDRESS): Delete.
+ * config/s390/s390-protos.h (legitimate_address_p): Remove.
+ * config/s390/s390.c (legitimate_address_p): Rename to...
+ (s390_legitimate_address_p): ... this, make static.
+ (legitimize_address): Adjust call.
+ (TARGET_LEGITIMATE_ADDRESS_P): New.
+ * config/s390/constraints.md ("e"): Call strict_memory_address_p.
+
+ * config/m32c/m32c.h (GO_IF_LEGITIMATE_ADDRESS): Delete.
+ * config/m32c/m32c-protos.h (m32c_legitimate_address_p): Remove.
+ * config/m32c/m32c.c (m32c_legitimate_address_p): Make static.
+ (TARGET_LEGITIMATE_ADDRESS_P): New.
+
+ * config/spu/spu.h (GO_IF_LEGITIMATE_ADDRESS): Delete.
+ * config/spu/spu-protos.h (spu_legitimate_address): Remove.
+ * config/spu/spu.c (spu_legitimate_address): Rename to...
+ (spu_legitimate_address_p): ... this, make static.
+ (TARGET_LEGITIMATE_ADDRESS_P): New.
+
+ * config/sparc/sparc.h (GO_IF_LEGITIMATE_ADDRESS): Delete.
+ * config/sparc/sparc-protos.h (legitimate_address_p): Remove.
+ * config/sparc/sparc.c (legitimate_address_p): Rename to...
+ (sparc_legitimate_address_p): ... this, make static and return bool.
+ (legitimize_address): Adjust call.
+ (TARGET_LEGITIMATE_ADDRESS_P): New.
+
+ * config/i386/i386.h (GO_IF_LEGITIMATE_ADDRESS): Delete.
+ * config/i386/i386-protos.h (legitimate_address_p): Remove.
+ * config/i386/i386.c (legitimate_address_p): Rename to...
+ (ix86_legitimate_address_p): ... this, make static.
+ (constant_address_p): Move after it, adjust call.
+ (TARGET_LEGITIMATE_ADDRESS_P): New.
+
+ * config/avr/avr.h (GO_IF_LEGITIMATE_ADDRESS): Delete.
+ * config/avr/avr-protos.h (legitimate_address_p): Remove.
+ * config/avr/avr.c (legitimate_address_p): Rename to...
+ (avr_legitimate_address_p): ... this, make static.
+ (legitimize_address): Adjust call.
+ (TARGET_LEGITIMATE_ADDRESS_P): New.
+
+ * config/crx/crx.h (GO_IF_LEGITIMATE_ADDRESS): Delete.
+ * config/crx/crx-protos.h (crx_legitimate_address_p): Remove.
+ * config/crx/crx.c (crx_legitimate_address_p): Make static.
+ (TARGET_LEGITIMATE_ADDRESS_P): New.
+
+ * config/xtensa/xtensa.h (GO_IF_LEGITIMATE_ADDRESS): Delete.
+ * config/xtensa/xtensa-protos.h (xtensa_legitimate_address_p): Remove.
+ * config/xtensa/xtensa.c (xtensa_legitimate_address_p): Make static.
+ (TARGET_LEGITIMATE_ADDRESS_P): New.
+
+ * config/stormy16/stormy16.h (GO_IF_LEGITIMATE_ADDRESS): Delete.
+ * config/stormy16/stormy16-protos.h (xstormy16_legitimate_address_p):
+ Remove.
+ * config/stormy16/stormy16.c (xstormy16_legitimate_address_p):
+ Make static.
+ (TARGET_LEGITIMATE_ADDRESS_P): New.
+
+ * config/m68hc11/m68hc11.h (GO_IF_LEGITIMATE_ADDRESS): Delete.
+ * config/m68hc11/m68hc11-protos.h (m68hc11_go_if_legitimate_address):
+ Remove.
+ * config/m68hc11/m68hc11.c (m68hc11_go_if_legitimate_address):
+ Rename to...
+ (m68hc11_legitimate_address_p): ... this, make static.
+ (go_if_legitimate_address_internal): Rename to...
+ (m68hc11_legitimate_address_p_1): ... this.
+ (legitimize_address): Adjust call.
+ (TARGET_LEGITIMATE_ADDRESS_P): New.
+
+ * config/iq2000/iq2000.h (GO_IF_LEGITIMATE_ADDRESS): Delete.
+ * config/iq2000/iq2000-protos.h (iq2000_legitimate_address_p): Remove.
+ * config/iq2000/iq2000.c (iq2000_legitimate_address_p): Make static.
+ (TARGET_LEGITIMATE_ADDRESS_P): New.
+
+ * config/mn10300/mn10300.h (GO_IF_LEGITIMATE_ADDRESS): Delete.
+ * config/mn10300/mn10300-protos.h (legitimate_address_p): Remove.
+ * config/mn10300/mn10300.c (legitimate_address_p): Rename to...
+ (mn10300_legitimate_address_p): ... this, make static.
+ (TARGET_LEGITIMATE_ADDRESS_P): New.
+
+ * config/m68k/m68k.h (GO_IF_LEGITIMATE_ADDRESS): Delete.
+ * config/m68k/m68k-protos.h (m68k_legitimate_address_p): Remove.
+ * config/m68k/m68k.c (m68k_legitimate_address_p): Make static.
+ (TARGET_LEGITIMATE_ADDRESS_P): New.
+
+ * config/rs6000/rs6000.h (GO_IF_LEGITIMATE_ADDRESS): Delete.
+ (REG_OK_STRICT_FLAG, REG_OK_FOR_BASE_P, REG_OK_FOR_INDEX_P): Delete.
+ (INT_REG_OK_FOR_BASE_P, INT_REG_OK_FOR_INDEX_P): Move above.
+ * config/rs6000/rs6000.h (GO_IF_LEGITIMATE_ADDRESS): Delete.
+ * config/rs6000/rs6000-protos.h (rs6000_legitimate_address): Remove.
+ * config/rs6000/rs6000.c (rs6000_legitimate_address): Rename to...
+ (rs6000_legitimate_address_p): ... this, make static.
+ (TARGET_LEGITIMATE_ADDRESS_P): New.
+ (REG_MODE_OK_FOR_BASE_P): Delete.
+ (rs6000_legitimize_reload_address): Use INT_REG_OK_FOR_BASE_P.
+
+ * config/picochip/picochip.h (GO_IF_LEGITIMATE_ADDRESS): Delete.
+ * config/picochip/picochip-protos.h (picochip_legitimate_address_p):
+ Delete.
+ * config/picochip/picochip.c (picochip_legitimate_address_p): Make
+ static, adjust types.
+ (TARGET_LEGITIMATE_ADDRESS_P): New.
+
+ * config/score/score.h (GO_IF_LEGITIMATE_ADDRESS): Delete.
+ * config/score/score.c (score_address_p): Rename to...
+ (score_legitimate_address_p): ... this.
+ (TARGET_LEGITIMATE_ADDRESS_P): New.
+ * config/score/score3.c (score3_address_p): Rename to...
+ (score3_legitimate_address_p): ... this.
+ * config/score/score7.c (score7_address_p): Rename to...
+ (score7_legitimate_address_p): ... this.
+
+ * config/arm/arm.h (ARM_GO_IF_LEGITIMATE_ADDRESS,
+ THUMB2_GO_IF_LEGITIMATE_ADDRESS, THUMB1_GO_IF_LEGITIMATE_ADDRESS,
+ GO_IF_LEGITIMATE_ADDRESS): Delete.
+ * config/arm/arm-protos.h (thumb1_legitimate_address_p,
+ thumb2_legitimate_address_p): Delete.
+ (arm_legitimate_address_p): Rename to...
+ (arm_legitimate_address_outer_p): ... this.
+ * config/arm/constraints.md ("Uq"): Adjust call.
+ * config/arm/predicates.md (arm_extendqisi_mem_op): Likewise.
+ * config/arm/arm.c (arm_legitimate_address_p): New, rename old one
+ to...
+ (arm_legitimate_address_outer_p): ... this.
+ (thumb1_legitimate_address_p, thumb2_legitimate_address_p): Make
+ static.
+ (TARGET_LEGITIMATE_ADDRESS_P): New.
+
+ * config/mips/mips.h (GO_IF_LEGITIMATE_ADDRESS): Delete.
+ * config/mips/mips-protos.h (mips_legitimate_address_p): Remove.
+ * config/mips/mips.c (mips_legitimate_address_p): ... Make static.
+ (TARGET_LEGITIMATE_ADDRESS_P): New.
+
+ * config/vax/vax.h (GO_IF_LEGITIMATE_ADDRESS): Delete.
+ * config/vax/vax-protos.h (legitimate_address_p): Remove.
+ * config/vax/vax.c (legitimate_address_p): Rename to...
+ (vax_legitimate_address_p): ... this, make static.
+ (TARGET_LEGITIMATE_ADDRESS_P): New.
+
+ * config/h8300/h8300.h (GO_IF_LEGITIMATE_ADDRESS): Delete.
+ * config/h8300/h8300-protos.h (h8300_legitimate_address_p): Remove.
+ * config/h8300/h8300.c (h8300_legitimate_address_p): ... Make static.
+ (TARGET_LEGITIMATE_ADDRESS_P): New.
+
+ * config/mmix/mmix.h (GO_IF_LEGITIMATE_ADDRESS): Delete.
+ * config/mmix/mmix-protos.h (mmix_legitimize_address): Remove.
+ * config/mmix/mmix.c (mmix_legitimate_address): Rename to...
+ (mmix_legitimate_address_p): ... this, make static.
+ (TARGET_LEGITIMATE_ADDRESS_P): New.
+
+ * config/bfin/bfin.h (GO_IF_LEGITIMATE_ADDRESS): Delete.
+ * config/bfin/bfin-protos.h (bfin_legitimate_address_p): Remove.
+ * config/bfin/bfin.c (bfin_legitimate_address_p): ... Make static.
+ (TARGET_LEGITIMATE_ADDRESS_P): New.
+
+2009-05-14 Paolo Bonzini <bonzini@gnu.org>
+
+ * config/arm/arm.h (PROMOTE_FUNCTION_MODE): Remove handling
+ of MODE_COMPLEX_INT.
+
+2009-05-14 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * config/alpha/alpha.c (alpha_initialize_trampoline): Change 0 to
+ LCT_NORMAL in function call.
+ * mips-tdump.c (print_file_desc): Add cast to enum type.
+ * mips-tfile.c (add_ext_symbol): Add casts to enum types.
+ (mark_stabs): Add casts to enum types.
+ (parse_stabs_common): Add casts to enum types.
+
+2009-05-13 Adam Nemet <anemet@caviumnetworks.com>
+
+ * config/mips/mips.c (mips_print_operand) <REG, MEM, default>:
+ Check for invalid values of LETTER.
+
+2009-05-13 Taras Glek <tglek@mozilla.com>
+
+ * attribs.c (register_attribute): moved out attribute registration
+ into register_attribute.
+ * doc/plugins.texi: Documented register_attribute and
+ PLUGIN_ATTRIBUTES.
+ * gcc-plugin.h: Added forward decl for register_attribute.
+ * gcc-plugin.h (plugins_event): Added PLUGIN_ATTRIBUTES.
+ * plugin.c (register_callback, invoke_plugin_callbacks): Added
+ PLUGIN_ATTRIBUTES boilerplate.
+
+2009-05-14 Dave Korn <dave.korn.cygwin@gmail.com>
+
+ * config/i386/msformat-c.c (ms_printf_length_specs): Use enumeration
+ values even in sentinel and empty entries.
+ (ms_printf_flag_specs): Likewise.
+ (ms_scanf_flag_specs): Likewise.
+ (ms_strftime_flag_specs): Likewise.
+ (ms_print_char_table): Likewise.
+ (ms_scan_char_table): Likewise.
+ (ms_time_char_table): Likewise.
+
+2009-05-13 Doug Kwan <dougkwan@google.com>
+
+ * tree-ssa-sccvn.c (compare_ops): Stabilize qsort.
+
+2009-05-13 Adam Nemet <anemet@caviumnetworks.com>
+
+ * config/mips/mips.md (store): Add attributes for QI and HI.
+ Update comment.
+ (truncdisi2, truncdihi2, truncdiqi2): Merge these into ...
+ (truncdi<mode>2): ... this new pattern.
+
+2009-05-13 Brad Hards <bradh@kde.org>
+
+ * Makefile.in (TEXI_GCCINT_FILES): Add plugins.texi.
+
+2009-05-14 Jakub Jelinek <jakub@redhat.com>
+ Ben Elliston <bje@au.ibm.com>
+
+ PR middle-end/40035
+ * dse.c (check_mem_read_rtx): Guard against width == -1.
+
+2009-05-13 Michael Matz <matz@suse.de>
+
+ PR middle-end/39976
+ * tree-outof-ssa.c (maybe_renumber_stmts_bb): New function.
+ (trivially_conflicts_p): New function.
+ (insert_backedge_copies): Use it.
+
+2009-05-13 Janis Johnson <janis187@us.ibm.com>
+
+ * c-pragma.c (enum pragma_switch_t): Prefix constants with PRAGMA_.
+ (handle_stdc_pragma): Use new enum constant names.
+ (handle_pragma_float_const_decimal64): Ditto.
+
+2009-05-13 Ian Lance Taylor <iant@google.com>
+
+ * Makefile.in (build/gencheck.o): Depend upon all-tree.def, not
+ tree.def.
+
+2009-05-13 Nathan Sidwell <nathan@codesourcery.com>
+
+ * config/m68k/t-uclinux (M68K_MLIB_CPU): Check for FL_UCLINUX.
+ * config/m68k/m68k-devices.def: Add FL_UCLINUX to 68020 and 54455
+ multilibs.
+ * config/m68k/m68k.h (FL_UCLINUX): Define.
+
+2009-05-13 Jan Hubicka <jh@suse.cz>
+
+ * options.c (gfc_post_options): -fwhole-program imply -fwhole-file.
+
+2009-05-12 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ * config/sh/sh.h (OVERRIDE_OPTIONS): Clear flag_schedule_insns
+ unless -fschedule-insns is specified.
+
+2009-05-12 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ PR target/39561
+ * config/sh/sh.h (OPTIMIZATION_OPTIONS): Don't set
+ TARGET_EXPAND_CBRANCHDI4.
+ * config/sh/sh.md (cbranchdi4): Don't check TARGET_EXPAND_CBRANCHDI4.
+ * config/sh/sh.opt (mexpand-cbranchdi): Remove.
+ (cmpeqdi): Fix comment.
+
+2009-05-12 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ * config/sh/sh-protos.h (sh_legitimate_index_p): Declare.
+ (sh_legitimate_address_p): Likewise.
+ * config/sh/sh.c (sh_legitimate_index_p): New.
+ (sh_legitimate_address_p): Likewise.
+ * config/sh/sh.h (REG_OK_FOR_BASE_P): Add STRICT parameter.
+ (REG_OK_FOR_INDEX_P, SUBREG_OK_FOR_INDEX_P): Likewise.
+ (MODE_DISP_OK_4, MODE_DISP_OK_8): Remove.
+ (MAYBE_BASE_REGISTER_RTX_P): New macro.
+ (MAYBE_INDEX_REGISTER_RTX_P): Likewise.
+ (BASE_REGISTER_RTX_P): Use MAYBE_BASE_REGISTER_RTX_P.
+ (INDEX_REGISTER_RTX_P): Use MAYBE_INDEX_REGISTER_RTX_P.
+ (GO_IF_LEGITIMATE_INDEX): Use sh_legitimate_index_p.
+ (GO_IF_LEGITIMATE_ADDRESS): Use sh_legitimate_address_p.
+
+2009-05-12 Jan Hubicka <jh@suse.cz>
+
+ * tree-inline.c (estimate_operator_cost): Add operands;
+ when division happens by constant, it is cheap.
+ (estimate_num_insns): Loads and stores are not having cost of 0;
+ EH magic stuff is cheap; when computing runtime cost of switch,
+ use log2 base of amount of its cases; builtin_expect has cost of 0;
+ compute cost for moving return value of call.
+ (init_inline_once): Initialize time_based flags.
+ * tree-inline.h (eni_weights_d): Add time_based flag.
+
+2009-05-12 Paolo Bonzini <bonzini@gnu.org>
+
+ * df-core.c: Update head documentation.
+
+2009-05-12 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ PR bootstrap/40118
+ * rs6000.c (rs6000_generate_compare): Use op1b instead of
+ shadowing exisiting variable op1.
+
+2009-05-12 Uros Bizjak <ubizjak@gmail.com>
+
+ PR target/37179
+ * config/i386/driver-i386.c (processor_signatures): New enum.
+ (SIG_GEODE): Move from vendor_signatures to processor_signatures.
+ (host_detect_local_cpu): For SIG_AMD vendor, check for SIG_GEODE
+ processor signature to detect geode processor.
+
+2009-05-12 Paolo Bonzini <bonzini@gnu.org>
+
+ Revert:
+
+ 2009-05-12 Paolo Bonzini <bonzini@gnu.org>
+
+ * optabs.c (prepare_cmp_insn): Temporarily disable test that
+ causes spurious differences between trunk and cond-optab branch.
+
+2009-05-12 Paolo Bonzini <bonzini@gnu.org>
+
+ * dojump.c (compare_from_rtx): Delete.
+ * expmed.c (emit_store_flag): Only try cstore_optab. Canonicalize
+ any MODE_CC mode to the cstorecc4 pattern. Use prepare_operand, fail
+ if the comparison does not satisfy the predicate; test predicates for
+ operands 2 and 3 of a cstore pattern. Don't try cstore optab
+ further if one existing pattern fails.
+ * expr.h (compare_from_rtx): Delete.
+ (prepare_operand): Declare it.
+ * optabs.c: Change "lib call" to "libcall" throughout.
+ (bcc_gen_fctn, setcc_gen_code, trap_rtx,
+ HAVE_conditional_trap, emit_cmp_insn): Delete.
+ (can_compare_p): Delete cmp_optab case.
+ (prepare_float_lib_cmp): Return an rtx and a machine mode.
+ Accept other parameters by value.
+ (prepare_operand): Make non-static.
+ (prepare_cmp_insn): Return an rtx and a machine mode. Accept
+ other parameters by value. Try to widen operands here based on
+ an optab_methods argument and looking at cbranch_optab.
+ (emit_cmp_and_jump_insn_1): Accept test and mode, remove widening
+ loop. Use cbranch_optab directly.
+ (emit_cmp_and_jump_insns): Fix comment. Adjust call to
+ prepare_cmp_insn and emit_cmp_and_jump_insn_1, remove obsolete
+ assertion.
+ (emit_conditional_move, emit_conditional_add): Inline what's needed
+ of compare_from_rtx, using new prepare_cmp_insn for the rest.
+ (init_optabs): Init cmp_optab with UNKNOWN, cbranch_optab
+ with COMPARE. Move cmov_optab and cstore_optab above
+ with cbranch_optab, move cmp_optab down with ucmp_optab,
+ remove tst_otpab. Do not initialize trap_rtx.
+ (gen_cond_trap): Do it here. Use ctrap_optab. Test predicate
+ for trap code. Do not check HAVE_conditional_trap. Use
+ prepare_cmp_insn. Accept no predicate for operand 3.
+ * optabs.h (OTI_cmp): Mark as used only for libcalls.
+ (OTI_ctrap, ctrap_optab): New.
+ (tst_optab): Delete.
+ (bcc_gen_fctn, setcc_gen_code, emit_cmp_insn): Delete.
+ * ifcvt.c (find_if_header): Replace HAVE_conditional_trap
+ with lookup of ctrap_optab.
+ * genopinit.c (cmp_optab, tst_optab, bcc_gen_fctn, setcc_gen_code):
+ Delete.
+ (ctrap_optab): New.
+
+ * combine.c (combine_simplify_rtx, simplify_set): Do not
+ special case comparing against zero for cc0 machines.
+ * simplify-rtx.c (simplify_binary_operation_1): Never remove
+ COMPARE on cc0 machines.
+ (simplify_relational_operation): Return a new expression when
+ a COMPARE could be removed.
+ * final.c (final_scan_insn): Compare cc_status values
+ against LHS of a (compare FOO (const_int 0)) cc0 source.
+ Also check if cc_status.value is the full compare.
+
+ * doc/md.texi (bCC, sCC, tstMM, cmpMM): Delete.
+ (cstoreMM4): Document.
+ (conditional_trap): Document ctrapMM4 instead.
+ (sync_compare_and_swapMM): Refer to cbranchcc4.
+ (Dependent Patterns): Eliminate obsolete information referring to
+ the old jump optimization phase.
+ (Canonicalization): Include cbranchcc4 case, omit canonicalization
+ of compares with 0 on cc0 machines.
+ (Jump Patterns): Refer to MODE_CC jump patterns preferably,
+ avoiding references to cc0. Remove text about storing operands
+ in cmpMM.
+ * doc/tm.texi (Condition Codes): Include blurb on different
+ condition code representations, separate into subsections for
+ CC0, MODE_CC and conditional execution.
+
+ * config/alpha/alpha-protos.h (alpha_emit_conditional_branch,
+ alpha_emit_setcc): Accept operands and a machine mode.
+ * config/alpha/alpha.c (alpha_emit_conditional_branch):
+ Get code/op0/op1 from operands, use machine mode argument
+ instead of alpha_compare.fp_p. Emit the branch here.
+ (alpha_emit_setcc): Likewise, and return boolean.
+ (alpha_emit_conditional_move): Likewise. Assert that
+ cmp_op_mode == cmp_mode, and simplify accordingly.
+ * config/alpha/alpha.h (struct alpha_compare, alpha_compare): Delete.
+ * config/alpha/alpha.md (cmpdf, cmptf, cmpdi, bCC, sCC): Delete.
+ (cbranchdf4, cbranchtf4, cbranchdi4, cstoredf4, cstoretf4,cstoredi4):
+ Delete.
+ (stack probe test): Use cbranchdi4.
+ * config/alpha/predicates.md (alpha_cbranch_operator): New.
+
+ * config/arc/arc.c (gen_compare_reg): Do not emit cmp.
+ * config/arc/arc.h (movsicc, movsfcc): Use it.
+ (movdicc, *movdicc_insn, movdfcc, *movdfcc_insn): Remove.
+ (cbranchsi4, cstoresi4): New.
+ (cmpsi, bCC and sCC expanders): Remove.
+
+ * config/arm/arm.c (arm_compare_op0, arm_compare_op1): Delete.
+ * config/arm/arm.h (arm_compare_op0, arm_compare_op1): Delete.
+ * config/arm/predicates.md (arm_comparison_operator): Only include
+ floating-point operators if there is a hardware floating-point unit.
+ * config/arm/arm.md (cbranchsi4, cstoresi4): Enable for TARGET_32BIT,
+ deferring to cbranch_cc and cstore_cc respectively.
+ (cbranchsf4, cbranchdf4, cbranchdi4, cstoresf4, cstoredf4, cstoredi4,
+ cbranch_cc, cstore_cc): New.
+ (movsicc, movsfcc, movdfcc): Do not use arm_compare_op0 and
+ arm_compare_op1.
+ (bCC, sCC, cmpsi, cmpsf, cmpdf, cmpdi): Delete.
+
+ * config/avr/avr-protos.h (out_tstsi, out_tsthi): Adjust prototype.
+ * config/avr/avr.c (out_tstsi, out_tsthi): Get the tested operand
+ as an argument.
+ (adjust_insn_length): Adjust calls.
+ (avr_reorg): Handle (compare (foo) (const_int 0)).
+ * config/avr/avr.md (tstqi, tsthi, tstsi): Remove.
+ (*negated_tstqi, *negated_tsthi, *negated_tstsi): Unmacroize.
+ (*reversed_tsthi, *reversed_tstsi): Add a scratch for simplicity.
+ (cmpqi, cmphi, cmpsi): Prepend asterisk, fuse tst[qhs]i here.
+ (bCC): Remove.
+ (cbranchqi4, cbranchhi4, cbranchsi4): New.
+ (tst -> sbrc/sbrs peephole2, cpse peephole): Wrap RHS with COMPARE.
+
+ * config/bfin/bfin.md (cmpbi, cmpsi, bCC, sCC): Delete.
+ (cbranchsi4, cstorebi4, cstoresi4): New.
+ (movbisi): This insn is duplicate, split it to zero_extend.
+ * config/bfin/bfin.c (bfin_compare_op0, bfin_compare_op1): Delete
+ (bfin_gen_compare): Do not use them. Emit VOIDmode SET, not BImode.
+ (bfin_optimize_loop): Use cbranch expander.
+ * config/bfin/bfin.h (bfin_compare_op0, bfin_compare_op1): Delete.
+ * config/bfin/predicates.md (bfin_cbranch_operator): Rename to...
+ (bfin_bimode_comparison_operator): ... this.
+ (bfin_direct_comparison_operator): New.
+
+ * config/cris/cris.c (cris_normal_notice_update_cc): Look
+ inside (compare FOO (const_int 0)).
+ (cris_rtx_costs): Handle ZERO_EXTRACT.
+ * config/cris/cris.md (tstdi, tst<mode>, cmpdi): Delete.
+ (*tstdi_non_v32): Fold in *cmpdi_non_v32.
+ (*tstdi_v32): Delete.
+ (*cmpdi_non_v32): Add M alternative for operand 1.
+ (cmpsi, cmp<mode>): Make private.
+ (*tstsi, *tst<mode>_cmp, *tst<mode>_non_cmp, *btst): Wrap LHS
+ with COMPARE.
+ (cbranch<mode>4, cbranchdi4, cstore<mode>4): New.
+
+ * config/crx/crx.md (cstore<mode>4, cbranchcc4): New.
+ (cmp<mode>, bCOND_internal, b<code>, s<code>): Delete.
+ (cbranch<mode>4, sCOND_internal): Use ordered_comparison_operator.
+ (cc_reg_operand): New.
+ (any_cond): Delete.
+ * config/crx/crx.c (crx_compare_op0, crx_compare_op1,
+ crx_expand_compare, crx_expand_branch, crx_expand_scond): Delete.
+ * config/crx/crx.h (crx_compare_op0, crx_compare_op1): Delete.
+ * config/crx/crx-protos.h (crx_expand_compare, crx_expand_branch,
+ crx_expand_scond): Delete.
+
+ * config/fr30/fr30.md (cmp<mode>, bCC): Delete.
+ (cbranchsi4): New.
+ * config/fr30/fr30.c (fr30_compare_op0, fr30_compare_op1): Delete
+ * config/fr30/fr30.h (fr30_compare_op0, fr30_compare_op1): Delete.
+
+ * config/frv/frv.md (cbranchsi4, cbranchsf4, cbranchdf4,
+ cstoresi4, cstoresf4, cstoredf4): New.
+ (cmpdi, cmpsi, cmpsf, cmpdf, bCC, sCC): Remove.
+ * config/frv/frv-protos.h (frv_emit_cbranch, frv_emit_scc):
+ Receive the entire operands array.
+ * config/frv/frv.h (frv_compare_op0, frv_compare_op1): Delete.
+ * config/frv/frv.c (frv_compare_op0, frv_compare_op1): Delete.
+ * config/frv/frv-protos.h (frv_emit_cbranch, frv_emit_scc):
+ Get test/op0/op1 from the operands array.
+ (frv_emit_cond_move): Get test/op0/op1 from the test_rtx.
+
+ * config/h8300/h8300-protos.h (h8300_expand_branch): Accept operands.
+ (h8300_expand_store): New.
+ * config/h8300/h8300.c (h8300_rtx_costs): Handle (compare FOO
+ (const_int 0)).
+ (h8300_expand_branch): Emit compare here. Adjust for new arguments.
+ (h8300_expand_store): New.
+ * config/h8300/h8300.md (btst combine patterns): Wrap with COMPARE
+ or do not try to produce (set (cc0) REG).
+ (peepholes): Wrap arguments with COMPARE. Add a peephole to
+ change a compare into a move to a scratch register. Disable some
+ peepholes when comparing with zero.
+ (tstsi, tsthi, tstsi, cmpqi): Make private.
+ (cmphi): Delete.
+ (bCC, sCC): Delete.
+ (cbranchqi4, cbranchhi4, cbranchsi4, cstoreqi4, cstorehi4,
+ cstoresi4): New.
+
+ * config/i386/i386.c (ix86_expand_int_movcc, ix86_expand_int_addcc,
+ ix86_expand_fp_movcc): Set ix86_compare_op0 and ix86_compare_op1.
+ (ix86_emit_i387_log1p): Use gen_cbranchxf4.
+ (ix86_emit_i387_log1p): Use cbranchxf2.
+ (ix86_expand_setcc): Return void.
+ * config/i386/i386-protos.h (ix86_expand_setcc): Return void.
+ * config/i386/i386.md (cmpti, cmpdi, cmpsi, cmphi, cmpqi, cmpxf,
+ cmp<MODEF>, cmpcc): Remove.
+ (cbranchti4, cbranchdi4, cbranchsi4, cbranchhi4, cbranchqi4,
+ cbranchxf4, cbranch<MODEF>4, cbranchcc4, cstoredi4, cstoresi4,
+ cstorehi4, cstoreqi4, cstorexf4, cstore<MODEF>4, cstorecc): New.
+ (sCC and bCC expanders): Remove.
+ (stack_protect_test): Use cbranchcc4.
+
+ * config/ia64/ia64-protos.h (ia64_compare_op0, ia64_compare_op1):
+ Delete.
+ (ia64_expand_compare): Accept three rtx by reference and return void.
+ * config/ia64/ia64.c (ia64_compare_op0, ia64_compare_op1): Delete.
+ (ia64_expand_compare): Replace op0/op1 with *op0/*op1. Get code
+ from *expr. Update *expr with the BImode comparison to do.
+ * config/ia64/ia64.md (cmpbi, cmpsi, cmpdi, cmpsf, cmpdf, cmpxf,
+ cmptf, bCC, sCC, conditional_trap): Delete.
+ (cbranchbi4, cbranchsi4, cbranchdi4, cbranchsf4, cbranchdf4,
+ cbranchxf4, cbranchtf4, cstorebi4, cstoresi4, cstoredi4, cstoresf4,
+ cstoredf4, cstorexf4, cstoretf4, ctrapbi4, ctrapsi4, ctrapdi4,
+ ctrapsf4, ctrapdf4, ctrapxf4, ctraptf4): New.
+ * config/ia64/predicates.md (ia64_cbranch_operator): New.
+
+ * config/iq2000/iq2000-protos.h (gen_conditional_branch): Change
+ type of last argument.
+ * config/iq2000/iq2000.c (branch_cmp, branch_type): Remove.
+ (gen_conditional_branch): Get code/cmp0/cmp1 from operands,
+ use machine mode argument instead of branch_type. Remove dead
+ code for floating-point comparisons.
+ * config/iq2000/iq2000.h (branch_cmp, branch_type): Remove.
+ * config/iq2000/iq2000.md (cmpsi, cmpdi, cmpsf, cmpdf, tstsi, bCC):
+ Remove.
+ (cbranchsi4, cstoresi4): New.
+ * config/iq2000/predicates.md (reg_or_const_operand): New.
+
+ * config/m32c/m32c.md (cbranch splitter): Use match_op_dup.
+ * config/m32c/m32c.md (any_cond, gl_cond): Delete.
+ (b<code>_op): Rewrite to...
+ (bcc_op): ... this, using match_operator.
+ (s<code>_op): Rewrite to...
+ (scc_op): ... this, using match_operator.
+ (s<code>_24_op): Rewrite to...
+ (scc_op_24): ... this, using match_operator.
+ (s<code>_<mode>): Rewrite to...
+ (cstore<mode>4): ... this, using match_operator.
+ (s<code>_<mode>_24): Rewrite to...
+ (cstore<mode>4_24): ... this, using match_operator.
+ * config/m32c/m32c-protos.h (m32c_cmp_flg_0, m32c_pend_compare,
+ m32c_unpend_compare, m32c_expand_scc): Delete.
+ * config/m32c/m32c.c (compare_op0, compare_op1, m32c_cmp_flg_0,
+ m32c_pend_compare, m32c_unpend_compare, m32c_expand_scc): Delete.
+ (m32c_expand_movcc): Change NE to EQ if necessary.
+ (m32c_init_libfuncs): Modify cstore optab instead of setcc_gen_code.
+
+ * config/m32r/m32r-protos.h (gen_cond_store): New.
+ * config/m32r/m32r.c (m32r_compare_op0, m32r_compare_op1): Delete.
+ (gen_cond_store): New, from sCC patterns.
+ (m32r_expand_block_move): Use cbranchsi4.
+ * config/m32r/m32r.h (m32r_compare_op0, m32r_compare_op1): Delete.
+ * config/m32r/m32r.md (cmpsi, bCC, sCC): Delete.
+ (cbranchsi4, cstoresi4): New.
+
+ * config/m68hc11/m68hc11.c (m68hc11_compare_op0, m68hc11_compare_op1):
+ Delete.
+ (m68hc11_rtx_costs_1, m68hc11_rtx_costs): Handle ZERO_EXTRACT.
+ (m68hc11_notice_update_cc): Look into a compare with 0.
+ * config/m68hc11/m68hc11.h (m68hc11_compare_op0, m68hc11_compare_op1):
+ Delete.
+ * config/m68hc11/m68hc11.md (tstsi, tsthi, tstqi, cmpsi,
+ cmphi, cmpqi, bCC): Delete.
+ (cbranchsi4, cbranchhi4, cbranchqi4): New.
+ (tstqi_1, tstqi_z_used, tstqi_1, bitcmpqi, bitcmpqi_z_used,
+ bitcmpqi_12, bitcmphi, various splits and peephole2s): Wrap cc0<-reg
+ sets with COMPARE.
+
+ * config/m68k/predicates.md (m68k_cstore_comparison_operator,
+ const0_operand, const1_operand, m68k_subword_comparison_operand): New.
+ * config/m68k/constraints.md (H): New.
+ * config/m68k/m68k.md (tstdi): Remove define_expand, use name for
+ the define_insn below.
+ (tstsi, tsthi, tst<FP:mode>, cmphi, cmpqi, cmp<FP:mode>): Delete.
+ (*tstsi_internal_68020_cf, *tstsi_internal, *tsthi_internal,
+ *tstqi_internal, tst<mode>_6881, tst<mode>_cf, many unnamed
+ patterns): Wrap RHS with COMPARE.
+ (tst<FP>_68881, tst<FP>_cf): Use const0_operand.
+ (*cmpdi_internal): Name this pattern.
+ (cmpdi): Change to define_insn.
+ (cbranchdi4, cstoredi4, cbranchsi4, cstoresi4, cbranchhi4, cstorehi4,
+ cbranchqi4, cstoreqi4, cbranch<FP:mode>4, cstore<FP:mode>4): New.
+ (scc0_di, scc0_di_5200, scc_di): Use the ordered_comparison_operator
+ predicate.
+ (seq, sne, sgt, sgtu, slt, sltu, sge, sgeu, sle, sleu, sordered,
+ sunordered, suneq, sunge, sungt, sunle, sunlt, sltgt): Delete
+ (conditional_trap): Change to...
+ (ctrapdi4, ctrapsi4, ctraphi4, ctrapqi4): ... these.
+ (*conditional_trap): Use the ordered_comparison_operator and
+ const1_operand predicates.
+ * config/m68k/m68k.c (m68k_last_compare_had_fp_operands): Delete.
+ (m68k_expand_prologue): Use ctrapsi4 instead of cmpsi+conditional_trap.
+ (m68k_rtx_costs): Look for ZERO_EXTRACT in a COMPARE.
+ * config/m68k/m68k.h (m68k_last_compare_had_fp_operands): Delete.
+
+ * config/mcore/mcore-protos.h (arch_compare_op0, arch_compare_op1,
+ mcore_modify_comparison, mcore_gen_compare_reg): Remove.
+ (mcore_gen_compare): New.
+ * config/mcore/mcore.c (arch_compare_op0, arch_compare_op1): Delete.
+ (mcore_modify_comparison, mcore_gen_compare_reg): Fold into...
+ (mcore_gen_compare): ... this.
+ * config/mcore/mcore.md (cmpsi, bCC, sCC): Remove.
+ (cbranchsi4, cstoresi4): New, using mcore_gen_compare.
+ (stack probe pattern): Use cbranchsi4.
+
+ * config/mips/predicates.md (mips_cstore_operator): New.
+ * config/mips/mips-ps-3d.md (movv2sfcc): Do not use cmp_operands.
+ * config/mips/mips.md (any_cond): Delete.
+ (conditional_trap): Rename to ctrap<GPR:mode>4. Adjust predicates,
+ always succeed.
+ (fixuns_truncdfsi2, fixuns_truncdfdi2, fixuns_truncsfsi2,
+ fixuns_truncsfdi2): Use cbranch patterns.
+ (cmp<GPR:mode>, cmp<SCALARF:mode>): Delete.
+ (b<code>): Change to cbranch<GPR:mode>4 and cbranch<SCALARF:mode>4.
+ Adjust call to mips_expand_conditional_branch.
+ (seq, sne, slt<u>, sle<u>, sgt<u>, sge<u>): Change to
+ cstore<GPR:mode>4.
+ * config/mips/mips-protos.h (mips_expand_conditional_branch,
+ mips_expand_scc, mips_expand_conditional_trap): Adjust prototypes.
+ * config/mips/mips.c (cmp_operands): Delete.
+ (mips_emit_compare): Get comparison operands from *op0/*op1.
+ (mips_expand_scc): Get code/op0/op1/target from operands. Assert
+ that it succeeds. Use op0/op1 instead of cmp_operands.
+ (mips_expand_conditional_branch, mips_expand_conditional_move,
+ mips_expand_conditional_trap): Likewise.
+ (mips_block_move_loop): Use cbranch patterns.
+ * config/mips/mips.h (cmp_operands): Delete.
+
+ * config/mmix/mmix.c (mmix_valid_comparison): Delete.
+ (mmix_gen_compare_reg): Just return a register in the right CC mode.
+ * config/mmix/mmix.h (mmix_compare_op0, mmix_compare_op1): New.
+ * config/mmix/mmix.md (cmpdi, cmpdf): Remove.
+ (*cmpcc_folded): Rename to...
+ (*cmpdi_folded): this.
+ (*cmpcc): Rename to...
+ (*cmps): ... this.
+ (movdfcc, movdicc): Adjust for new semantics of mmix_gen_compare_reg.
+ (bCC): Remove.
+ (cbranchdi4): New.
+ (cbranchdf4): New. Handle invalid comparisons here.
+ * config/mmix/predicates.md (float_comparison_operator): New.
+
+ * config/mn10300/mn10300.c (mn10300_rtx_costs): Consider 0 and
+ zero_extract to be cheap in (compare (zero_extract) (const_int 0).
+ * config/mn10300/mn10300.md (tst): Delete.
+ (*tst_extqisi_am33, *tst_extqisi, *tst_exthisi_am33, *tst_exthisi):
+ Name these patterns and wrap RHS in a compare.
+ (*cmpsi): Make this pattern private. Include tst.
+ (*cmpsf): Make this pattern private.
+ (and and zero_extract cc0 set): Wrap RHS in a COMPARE.
+ (compare with zero peepholes): Likewise.
+ (bCC): Remove.
+ (cbranchsi4, cbranchsf4): New.
+ (casesi): Use cbranchsi4.
+
+ * config/pa/pa.c (hppa_compare_op0, hppa_compare_op1,
+ hppa_branch_type): Delete.
+ (return_addr_rtx): Use cbranchsi4.
+ (emit_bcond_fp): Accept all operands. Replace CODE with NE.
+ Emit CCFPmode comparison here.
+ (gen_cmp_fp): Delete, now part of emit_bcond_fp.
+ * config/pa/pa.h (enum cmp_type, hppa_compare_op0, hppa_compare_op1,
+ hppa_branch_type): Delete.
+ * config/pa/pa.md (cmpdi, cmpsi, cmpsf, cmpdf, sCC, bCC): Delete.
+ (movsicc, movdicc): Remove references to hppa_compare_op0,
+ hppa_compare_op1 and compare_from_rtx.
+ (cbranchdi4, cbranchsi4, cbranchsf4, cbranchdf4, cstoresi4): New.
+ (casesi): Use cbranchsi4.
+
+ * config/pdp11/pdp11-protos.h (output_jump): Change prototype.
+ * config/pdp11/pdp11.c (output_jump): Embed opcodes here.
+ * config/pdp11/pdp11.md (register_or_const0_operand): New.
+ (cmpdf, cmphi, cmpqi): Make private. Add tst alternatives.
+ (cmpsi, tstsi, tstdf, tsthi, tstqi): Delete.
+ (bCC): Delete.
+ (cbranchdf4, cbranchhi4, cbranchqi4): New.
+ (*branch, *branch_inverted): New.
+
+ * config/picochip/picochip.md (cbranchhi4): Use
+ ordered_comparison_operator.
+ (cmphi, bCC): Remove.
+
+ * config/rs6000/predicates.md (rs6000_cbranch_operator): New.
+ (trap_comparison_operator): Delete.
+ * config/rs6000/rs6000-protos.h (rs6000_emit_sCOND,
+ rs6000_emit_cbranch): Accept mode and operands.
+ * config/rs6000/rs6000.c (rs6000_compare_op0, rs6000_compare_op1,
+ rs6000_compare_fp_p): Delete.
+ (rs6000_generate_compare): Accept mode and comparison. Extract code
+ and op0/op1 from there. Replace references to rs6000_compare_op0
+ and rs6000_compare_op1.
+ (rs6000_emit_sCOND): Adjust call to rs6000_generate_compare and
+ extract result from passed operands.
+ (rs6000_emit_cbranch): Adjust call to rs6000_generate_compare and
+ extract loc from passed operands.
+ (rs6000_emit_cmove): Likewise.
+ * config/rs6000/rs6000.h (rs6000_compare_op0, rs6000_compare_op1,
+ rs6000_compare_fp_p): Delete.
+ * config/rs6000/rs6000.md (cmp<GPR>, cmp<FP>, bCC, sCC): Delete.
+ (cbranch<GPR>4, cbranch<FP>4): New.
+ (cstore<mode>4): New. Consolidate here all choices about when to use
+ portable or specialized sCC sequences.
+ (stack_protect_test): Use cbranchsi4.
+ (conditional_trap): Replace with ctrap<GPR>4.
+ (conditional trap insn): Replace trap_comparison_operator with
+ ordered_comparison_operator.
+
+ * config/s390/s390.c (s390_compare_op0, s390_compare_op1): Delete.
+ (s390_emit_prologue): Use ctrap.
+ * config/s390/s390.h (s390_compare_op0, s390_compare_op1): Delete.
+ * config/s390/predicates.md (s390_eqne_operator, s390_scond_operator):
+ New predicates replacing...
+ * config/s390/s390.md (COMPARE, SCOND): ... these iterators.
+ (cmp<GPR>, cmp<FP>, cmpcc): Delete.
+ (trunc patterns): Use emit_cmp_and_jump_insns instead of cmp/branch.
+ (add<mode>cc): Do not use s390_compare_op0/op1.
+ (s<code>): Change to...
+ (cstore<mode>4): ... this. Do not use s390_compare_op0/op1.
+ (seq): Change to...
+ (cstorecc4): ... this. Handle EQ or NE equally.
+ (*sne): Un-privatize for use in cstorecc4.
+ (b<code>): Change to...
+ (cbranch<GPR>4, cbranch<FP>4, cbranchcc4): ... these.
+ (conditional_trap): Replace with...
+ (ctrap<GPR>4, ctrap<FP>4): ... these.
+ (stack_protect): Use cbranchcc4.
+
+ * config/score/score-conv.h (cmp_op0, cmp_op1): Delete.
+ * config/score/score-protos.h (score_gen_cmp): Delete.
+ * config/score/score.c (cmp_op0, cmp_op1, score_gen_cmp): Delete.
+ (score_block_move-loop): Use cbranchsi4.
+ * config/score/score.md (cbranchsi4): New.
+ (cmpsi, bCC): Delete.
+ * config/score/score3.c (cmp_op0, cmp_op1, score3_gen_cmp): Delete.
+ (score3_movsicc): Use ops[1] operands instead of cmp_op0/cmp_op1.
+ * config/score/score7.c (cmp_op0, cmp_op1, score7_gen_cmp): Delete.
+ (score7_movsicc): Use ops[1] operands instead of cmp_op0/cmp_op1.
+ * config/score/score3.h (score3_gen_cmp): Delete.
+ * config/score/score7.h (score7_gen_cmp): Delete.
+
+ * config/sh/sh-protos.h (prepare_scc_operands): Rename to...
+ (sh_emit_scc_to_t): ... this. Return void.
+ (from_compare): Rename to...
+ (sh_emit_compare_and_branch): ... this.
+ (sh_emit_compare_and_set): New.
+ (sh_expand_t_scc): Accept operands.
+ * config/sh/predicates.md (sh_float_comparison_operator): New.
+ * config/sh/sh.c (sh_compare_op0, sh_compare_op1): Delete.
+ (prepare_scc_operands): Rename to...
+ (sh_emit_scc_to_t): ... this. Return void. Get op0/op1 from
+ arguments.
+ (sh_emit_cheap_store_flag): New.
+ (sh_emit_set_t_insn): New.
+ (from_compare): Rename to...
+ (sh_emit_compare_and_branch): ... this. Accept mode. Rewrite
+ handling of TARGET_SH2E floating point to avoid recursive call.
+ Generate branch here.
+ (sh_emit_compare_and_set): New.
+ (sh_expand_t_scc): Get op0/op1 from arguments.
+ (sh_emit_cheap_store_flag): New.
+ * config/sh/sh.md (cbranchdi4, cbranchsi4): Include -mno-cbranchdi
+ cases.
+ (cbranchdi4_i): Use an "I08" constraint instead of an "i" constraint.
+ (cmpsi, cmpdi, cmpsf, cmpdf): Delete.
+ (movsicc, movdicc): Do nothing when it recreated operands from
+ sh_compare_*. Use sh_emit_cheap_store_flag. Adjust call to
+ prepare_scc_operands (now sh_emit_scc_to_t).
+ (udivdi3): Use cstoresi4.
+ (beq_media, bne_media, bge_media, bgtu_media, bgeu_media, beq,
+ bne, bgt, blt, ble, bge, bgtu, bltu, bgeu, bleu, bunordered): Delete.
+ (cbranchint4_media, cbranchfp4_media): New.
+ (casesi): Use cbranchdi4.
+ (seq, slt, sle, sgt, sge, sgtu, sltu, sgeu, sne, sleu, sunordered):
+ Delete.
+ (cstore4_media, cstoresi4, cstoredi4, cstoresf4, cstoredf4): New.
+ (movnegt): Remove second operand.
+ (cbranchsf4, cbranchdf4): New.
+ (stack_protect): Use cbranchdi4/cbranchsi4.
+
+ * config/sparc/sparc.c (sparc_compare_op0, sparc_compare_op1): Delete.
+ (gen_compare_reg): Accept comparison, extract part of it to...
+ (gen_compare_reg_1): ... this.
+ (gen_compare_operator): Delete.
+ (gen_v9_scc): Accept separate destination, comparison code and arms.
+ Do not use sparc_compare_op0/sparc_compare_op1.
+ (emit_scc_insn, emit_conditional_branch_insn): New.
+ (emit_v9_brxx): Make static. Remove useless assertion.
+ (sparc_emit_float_lib_cmp): Return RTL instead of calling
+ emit_cmp_insn.
+ (sparc_expand_compare_and_swap_12): Use gen_compare_reg_1+cbranchcc4.
+ * config/sparc/sparc-protos.h (gen_compare_reg,
+ sparc_emit_float_lib_cmp): Adjust prototype.
+ (emit_scc_insn, emit_conditional_branch_insn): New.
+ (gen_v9_scc, emit_v9_brxx_insn, gen_compare_operator): Delete.
+ * config/sparc/sparc.h (sparc_compare_op0, sparc_compare_op1): Delete.
+ * config/sparc/sparc.md (P, I, F, V32, V32I, V64, V64I): Move all
+ iterators to the top.
+ (cmpsi, cmpdi, cmpsf, cmpdf, cmptf, seqsi_special_extend,
+ snesi_special_extend, sCC, bCC, seqdi_special_trunc,
+ snedi_special_trunc): Delete.
+ (seqdi_special, snedi_special): Use expansion of seqdi_special_trunc
+ and snedi_special_trunc.
+ (cstoresi4, cstoredi4, cstore<F:mode>4, cbranchcc4, cbranchsi4,
+ cbranchdi4, cbranch<F:mode>4): New.
+ (mov<I:mode>cc, mov<F:mode>cc): Handle sparc_emit_float_lib_cmp
+ here. Use gen_compare_reg instead of gen_compare_operator.
+ (conditional_trap): Replace with...
+ (ctrapsi4, ctrapdi4): ... this.
+ (stack_protect_test): Use cbranchcc4.
+
+ * config/spu/spu-protos.h (spu_emit_branch_or_set): Change second
+ argument to rtx.
+ * config/spu/spu.c (spu_compare_op0, spu_compare_op1): Remove.
+ (spu_emit_branch_or_set): Get code/op0/op1 from second argument.
+ Change spu_compare_op0/op1 to op0/op1 throughout. Get target
+ from operands[0] or operands[3] depending on is_set.
+ * config/spu/spu.h (spu_compare_op0, spu_compare_op1): Remove.
+ * config/spu/spu.md (cmp<mode:VQHSI>, cmp<mode:DTI>, cmp<mode:VSF>,
+ cmpdf, bCC), sCC: Remove.
+ (cbranch<mode:VQHSI>4, cbranch<mode:DTI>, cbranch<mode:VSF>4,
+ cbranchdf4, cstore<mode:VQHSI>4, cstore<mode:DTI>, cstore<mode:VSF>4,
+ cstoredf4): New.
+ (mov<mode>cc): Accept ordered_comparison_operator, adjust call to
+ spu_emit_branch_or_set.
+
+ * config/stormy16/stormy16-protos.h (xstormy16_emit_cbranch):
+ Add two arguments.
+ * config/stormy16/stormy16.h (xstormy16_compare_op0,
+ xstormy16_compare_op1): Delete.
+ * config/stormy16/stormy16.c (xstormy16_compare_op0,
+ xstormy16_compare_op1): Delete.
+ (xstormy16_emit_cbranch): Get op0/op1 from the new arguments.
+ Adjust calls.
+ * config/stormy16/stormy16.md (cbranchsi4, cbranchhi4): New.
+ (cmphi, cmpsi, bCC): Remove.
+
+ * config/v850/v850.md (tstsi, cmpsi): Fold into...
+ (*cmpsi): ... this one.
+ (cbranchsi4, cstoresi4): New.
+ (bCC expanders): Delete.
+ (sCC insns): Fold into...
+ (*setcc): ... this one.
+ (casesi): Do not use gen_cmpsi and gen_bgtu.
+ (various splits): Wrap "naked" RHS of a cc0 set with COMPARE.
+ (movsicc): Simplify.
+ * config/v850/v850.c (v850_rtx_costs): Handle ZERO_EXTRACT in COMPARE.
+
+ * config/vax/vax-protos.h (cond_name): New.
+ (vax_output_conditional_branch): Remove.
+ * config/vax/vax.c (cond_name): New.
+ (vax_output_conditional_branch): Remove.
+ * config/vax/vax.h (PRINT_OPERAND): Dispatch %c to cond_name.
+ * config/vax/vax.md (tst<VAXint>, tst<VAXfp>): Remove.
+ (cmp<VAXint>, cmp<VAXfp>): Privatize. Add constraints for tst.
+ (bit<VAXint>): Wrap source with (compare).
+ (b<code> and following unnamed pattern): Rename to *branch and
+ *branch_reversed. Change macroization to match_operator.
+ (cbranch<VAXint>4, cbranch<VAXfp>4): New.
+
+ * config/xtensa/predicates.md (xtensa_cstoresi_operator): New.
+ * config/xtensa/xtensa-protos.h (xtensa_expand_conditional_branch):
+ Change last argument to machine_mode.
+ (xtensa_expand_scc): Add machine_mode argument.
+ * config/xtensa/xtensa.c (branch_cmp, branch_type): Remove.
+ (gen_conditional_move, xtensa_expand_conditional_branch,
+ xtensa_expand_scc, xtensa_expand_conditional_move): Use mode
+ instead of branch_type, fetch cmp0/cmp1/test_code from operands[].
+ Adjust operand numbers.
+ * config/xtensa/xtensa.h (enum cmp_type, branch_cmp, branch_type):
+ Delete.
+ * config/xtensa/xtensa.md (any_cond, any_scc): Delete.
+ (cmpsi, cmpsf, b<code>, s<code>): Delete.
+ (cbranchsi4, cbranchsf4, cstoresi4, cstoresf4): New.
+
+2009-05-12 Paolo Bonzini <bonzini@gnu.org>
+
+ * optabs.c (prepare_cmp_insn): Temporarily disable test that
+ causes spurious differences between trunk and cond-optab branch.
+
2009-05-12 Alexandre Oliva <aoliva@redhat.com>
PR target/37137
@@ -159,20 +5029,16 @@
cgraph_local_info.
* cgraphunit.c (enum cgraph_order_sort_kind): New enum, broken out
of struct cgraph_order_sort.
- * combine.c (enum undo_kind): New enum, broken out of struct
- undo.
+ * combine.c (enum undo_kind): New enum, broken out of struct undo.
* cse.c (struct branch_path): Break out of struct
cse_basic_block_data.
* except.h (enum eh_region_type): Break out of struct eh_region.
* gcc.c (enum add_del): Break out of struct modify_target.
- * genrecog.c (enum decision_type): Break out of struct
- decision_test.
+ * genrecog.c (enum decision_type): Break out of struct decision_test.
* ggc-page.c (struct ggc_pch_ondisk): Break out of struct
ggc_pch_data.
- * matrix-reorg.c (struct free_info): Break out of struct
- matrix_info.
- * regmove.c (enum match_use): New enum, broken out of struct
- match.
+ * matrix-reorg.c (struct free_info): Break out of struct matrix_info.
+ * regmove.c (enum match_use): New enum, broken out of struct match.
* sched-int.h (enum post_call_group): New enum, broken out of
struct deps.
(struct deps_reg): Break out of struct deps.
@@ -194,8 +5060,7 @@
and loc parameters. Change all callers. Change error calls to
error_at, using loc. For a redefinition, if the location of the
original definition is known, report it. Set in_struct and
- struct_types. If -Wc++-compat warn if in sizeof, typeof, or
- alignof.
+ struct_types. If -Wc++-compat warn if in sizeof, typeof, or alignof.
(finish_struct): Add new parameters enclosing_in_struct and
enclosing_struct_types. Change all callers. Set
C_TYPE_DEFINED_IN_STRUCT for all struct/union/enum types defined
@@ -205,10 +5070,8 @@
location of the original definition is known, report it. If in a
struct, add this enum type to struct_types. If -Wc++-compat warn
if in sizeof, typeof, or alignof.
- * c-parser.c (disable_extension_diagnostics): Disable
- -Wc++-compat.
- (enable_extension_diagnostics): Reenable -Wc++-compat if
- appropriate.
+ * c-parser.c (disable_extension_diagnostics): Disable -Wc++-compat.
+ (enable_extension_diagnostics): Reenable -Wc++-compat if appropriate.
(c_parser_enum_specifier): Get enum location for start_enum.
(c_parser_struct_or_union_specifier): Get struct location for
start_struct. Save in_struct and struct_types status between
@@ -217,12 +5080,10 @@
(c_parser_alignof_expression): Get location of type.
(c_parser_postfix_expression): Likewise.
(c_parser_postfix_expression_after_paren_type): Add type_loc
- parameter. Change all callers. Call
- check_compound_literal_type. Use type_loc for error about
- variable size type.
- * c-typeck.c (build_external_ref): If -Wc++-compat, warn about a
- use of an enum constant from an enum type defined in a struct or
- union.
+ parameter. Change all callers. Call check_compound_literal_type.
+ Use type_loc for error about variable size type.
+ * c-typeck.c (build_external_ref): If -Wc++-compat, warn about a use
+ of an enum constant from an enum type defined in a struct or union.
(c_cast_expr): Add loc parameter. Change all callers. If
-Wc++-compat, warn about defining a type in a cast.
* c-tree.h (C_TYPE_DEFINED_IN_STRUCT): Define.
@@ -256,7 +5117,8 @@
2009-05-10 Jan Hubicka <jh@suse.cz>
* tree-inline.c (delete_unreachable_blocks_update_callgraph): Declare.
- (estimate_move_cost): Assert that it does not get called for VOID_TYPE_P.
+ (estimate_move_cost): Assert that it does not get called for
+ VOID_TYPE_P.
(estimate_num_insns): Skip VOID types in argument handling.
(optimize_inline_calls): Delete unreachable blocks and verify that
callgraph is valid.
@@ -294,8 +5156,7 @@
* config/arm/arm.c (arm_handle_fndecl_attribute,
arm_handle_isr_attribute): Likewise.
* config/avr/avr.c (avr_handle_progmem_attribute,
- avr_handle_fndecl_attribute, avr_handle_fntype_attribute):
- Likewise.
+ avr_handle_fndecl_attribute, avr_handle_fntype_attribute): Likewise.
* config/bfin/bfin.c (handle_int_attribute,
bfin_handle_longcall_attribute, bfin_handle_l1_text_attribute,
bfin_handle_l1_data_attribute, bfin_handle_longcall_attribute,
@@ -307,8 +5168,7 @@
h8300_handle_eightbit_data_attribute,
h8300_handle_tiny_data_attribute): Likewise.
* config/i386/i386.c (ix86_handle_cconv_attribute,
- ix86_handle_abi_attribute, ix86_handle_struct_attribute):
- Likewise.
+ ix86_handle_abi_attribute, ix86_handle_struct_attribute): Likewise.
* config/i386/winnt.c (ix86_handle_shared_attribute,
ix86_handle_selectany_attribute): Likewise.
* config/ia64/ia64.c (ia64_handle_model_attribute): Likewise.
@@ -337,8 +5197,7 @@
2009-05-10 Joseph Myers <joseph@codesourcery.com>
- * pretty-print.h (struct pretty_print_info): Add
- translate_identifiers.
+ * pretty-print.h (struct pretty_print_info): Add translate_identifiers.
(pp_translate_identifiers): New.
(pp_identifier): Only conditionally translate identifier to locale
character set.
@@ -1568,8 +6427,8 @@
(vectorize_loops): Fix comment. Use REPORT_VECTORIZED_LOCATIONS
and vect_location. Use REPORT_UNVECTORIZED_LOCATIONS
instead REPORT_UNVECTORIZED_LOOPS.
- * tree-vectorizer.h (enum vect_def_type): Rename vect_invariant_def and
- vect_loop_def to vect_external_def and vect_internal_def.
+ * tree-vectorizer.h (enum vect_def_type): Rename vect_invariant_def
+ and vect_loop_def to vect_external_def and vect_internal_def.
(enum verbosity_levels): Rename REPORT_VECTORIZED_LOOPS
and REPORT_UNVECTORIZED_LOOPS to REPORT_VECTORIZED_LOCATIONS and
REPORT_UNVECTORIZED_LOCATIONS.
@@ -1589,8 +6448,9 @@
vect_analyze_operations.
(vect_is_simple_reduction): Use new names.
(vectorizable_live_operation, vect_transform_loop): Likewise.
- * tree-vect-data-refs.c (vect_check_interleaving): Add a return value to
- specify whether the data references can be a part of interleaving chain.
+ * tree-vect-data-refs.c (vect_check_interleaving): Add a return value
+ to specify whether the data references can be a part of interleaving
+ chain.
(vect_analyze_data_ref_dependence): Use new names.
(vect_analyze_data_refs_alignment, vect_analyze_data_refs): Likewise.
(vect_create_addr_base_for_vector_ref): Remove redundant code.
diff --git a/gcc/ChangeLog.vta b/gcc/ChangeLog.vta
index cda9265738e..17037ed5ac6 100644
--- a/gcc/ChangeLog.vta
+++ b/gcc/ChangeLog.vta
@@ -1,5 +1,10 @@
2009-06-17 Alexandre Oliva <aoliva@redhat.com>
+ Merged with trunk@148582.
+ * rtl.def (VALUE): Move up.
+
+2009-06-17 Alexandre Oliva <aoliva@redhat.com>
+
* dwarf2out.c (mem_loc_descriptor): Handle DIV, MOD, AND, IOR,
XOR, NOT, ABS and NEG. Accept but discard EQ, GE, GT, LE, LT,
NE, COMPARE, IF_THEN_ELSE, SMIN, SMAX, ROTATE, ROTATERT,
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index 26b3d32290c..1d49b936678 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20090512
+20090617
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 2d6c6ed30ce..7c4331f31e8 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -197,6 +197,13 @@ NM = @NM@
RANLIB = @RANLIB@
RANLIB_FLAGS = @ranlib_flags@
+# The name of the compiler to use. Currently always $(CC). In the
+# future this may change to $(CXX).
+COMPILER = $(CC)
+COMPILER_FLAGS = $(CFLAGS)
+LINKER = $(CC)
+LINKER_FLAGS = $(CFLAGS)
+
# -------------------------------------------
# Programs which operate on the build machine
# -------------------------------------------
@@ -599,7 +606,7 @@ TARGET_LIBGCC2_CFLAGS =
# Options to use when compiling crtbegin/end.
CRTSTUFF_CFLAGS = -O2 $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -g0 \
- -finhibit-size-directive -fno-inline-functions -fno-exceptions \
+ -finhibit-size-directive -fno-inline -fno-exceptions \
-fno-zero-initialized-in-bss -fno-toplevel-reorder -fno-tree-vectorize \
$(INHIBIT_LIBC_CFLAGS)
@@ -698,6 +705,14 @@ DIR = ../gcc
CC_FOR_BUILD = @CC_FOR_BUILD@
BUILD_CFLAGS= @BUILD_CFLAGS@ -DGENERATOR_FILE
+# Native compiler that we use. This may be C++ some day.
+COMPILER_FOR_BUILD = $(CC_FOR_BUILD)
+BUILD_COMPILERFLAGS = $(BUILD_CFLAGS)
+
+# Native linker that we use.
+LINKER_FOR_BUILD = $(CC_FOR_BUILD)
+BUILD_LINKERFLAGS = $(BUILD_CFLAGS)
+
# Native linker and preprocessor flags. For x-fragment overrides.
BUILD_LDFLAGS=@BUILD_LDFLAGS@
BUILD_CPPFLAGS=$(ALL_CPPFLAGS)
@@ -792,7 +807,7 @@ endif
# Shorthand variables for dependency lists.
EXCEPT_H = except.h sbitmap.h vecprim.h
-TOPLEV_H = toplev.h input.h
+TOPLEV_H = toplev.h input.h bversion.h
TARGET_H = $(TM_H) target.h insn-modes.h
MACHMODE_H = machmode.h mode-classes.def insn-modes.h
HOOKS_H = hooks.h $(MACHMODE_H)
@@ -884,7 +899,8 @@ EBIMAP_H = ebitmap.h sbitmap.h
IPA_PROP_H = ipa-prop.h $(TREE_H) vec.h $(CGRAPH_H)
GSTAB_H = gstab.h stab.def
BITMAP_H = bitmap.h $(HASHTAB_H) statistics.h
-PLUGIN_H = plugin.h gcc-plugin.h
+GCC_PLUGIN_H = gcc-plugin.h $(CONFIG_H) $(SYSTEM_H)
+PLUGIN_H = plugin.h $(GCC_PLUGIN_H)
PLUGIN_VERSION_H = plugin-version.h configargs.h
#
@@ -906,6 +922,12 @@ ALL_CFLAGS = $(T_CFLAGS) \
# win against random include files in /usr/include.
ALL_CPPFLAGS = $(INCLUDES) $(CPPFLAGS)
+# This is the variable to use when using $(COMPILER).
+ALL_COMPILERFLAGS = $(ALL_CFLAGS)
+
+# This is the variable to use when using $(LINKER).
+ALL_LINKERFLAGS = $(ALL_CFLAGS)
+
# Build and host support libraries.
LIBIBERTY = ../libiberty/libiberty.a
BUILD_LIBIBERTY = $(build_libobjdir)/libiberty/libiberty.a
@@ -952,7 +974,7 @@ INCLUDES = -I. -I$(@D) -I$(srcdir) -I$(srcdir)/$(@D) \
$(PPLINC) $(CLOOGINC)
.c.o:
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $< $(OUTPUT_OPTION)
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $< $(OUTPUT_OPTION)
#
# Support for additional languages (other than C).
@@ -1627,16 +1649,16 @@ libbackend.a: $(OBJS@onestep@)
# and CC is `gcc'. It is renamed to `gcc' when it is installed.
xgcc$(exeext): $(GCC_OBJS) gccspec.o version.o intl.o prefix.o \
version.o $(LIBDEPS) $(EXTRA_GCC_OBJS)
- $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(GCC_OBJS) gccspec.o \
- intl.o prefix.o version.o $(EXTRA_GCC_OBJS) $(LIBS)
+ $(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ $(GCC_OBJS) \
+ gccspec.o intl.o prefix.o version.o $(EXTRA_GCC_OBJS) $(LIBS)
# cpp is to cpp0 as gcc is to cc1.
# The only difference from xgcc is that it's linked with cppspec.o
# instead of gccspec.o.
cpp$(exeext): $(GCC_OBJS) cppspec.o version.o intl.o prefix.o \
version.o $(LIBDEPS) $(EXTRA_GCC_OBJS)
- $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(GCC_OBJS) cppspec.o \
- intl.o prefix.o version.o $(EXTRA_GCC_OBJS) $(LIBS)
+ $(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ $(GCC_OBJS) \
+ cppspec.o intl.o prefix.o version.o $(EXTRA_GCC_OBJS) $(LIBS)
# Dump a specs file to make -B./ read these specs over installed ones.
$(SPECS): xgcc$(exeext)
@@ -1649,20 +1671,20 @@ $(SPECS): xgcc$(exeext)
gcc-cross$(exeext): xgcc$(exeext)
cp xgcc$(exeext) gcc-cross$(exeext)
-dummy-checksum.o : dummy-checksum.c
+dummy-checksum.o : dummy-checksum.c $(CONFIG_H) $(SYSTEM_H)
cc1-dummy$(exeext): $(C_OBJS) dummy-checksum.o $(BACKEND) $(LIBDEPS)
- $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(C_OBJS) dummy-checksum.o \
- $(BACKEND) $(LIBS) $(BACKENDLIBS)
+ $(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ $(C_OBJS) \
+ dummy-checksum.o $(BACKEND) $(LIBS) $(BACKENDLIBS)
cc1-checksum.c : cc1-dummy$(exeext) build/genchecksum$(build_exeext)
build/genchecksum$(build_exeext) cc1-dummy$(exeext) > $@
-cc1-checksum.o : cc1-checksum.c
+cc1-checksum.o : cc1-checksum.c $(CONFIG_H) $(SYSTEM_H)
cc1$(exeext): $(C_OBJS) cc1-checksum.o $(BACKEND) $(LIBDEPS)
- $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(C_OBJS) cc1-checksum.o \
- $(BACKEND) $(LIBS) $(BACKENDLIBS)
+ $(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ $(C_OBJS) \
+ cc1-checksum.o $(BACKEND) $(LIBS) $(BACKENDLIBS)
#
# Build libgcc.a.
@@ -1731,6 +1753,7 @@ libgcc.mvars: config.status Makefile $(LIB2ADD) $(LIB2ADD_ST) specs \
echo CRTSTUFF_CFLAGS = '$(CRTSTUFF_CFLAGS)' >> tmp-libgcc.mvars
echo CRTSTUFF_T_CFLAGS = '$(CRTSTUFF_T_CFLAGS)' >> tmp-libgcc.mvars
echo CRTSTUFF_T_CFLAGS_S = '$(CRTSTUFF_T_CFLAGS_S)' >> tmp-libgcc.mvars
+ echo TARGET_SYSTEM_ROOT = '$(TARGET_SYSTEM_ROOT)' >> tmp-libgcc.mvars
mv tmp-libgcc.mvars libgcc.mvars
@@ -1874,19 +1897,22 @@ ebitmap.o: ebitmap.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(EBITMAP_H) $(RTL_H) $(FLAGS_H) $(OBSTACK_H)
sparseset.o: sparseset.c $(SYSTEM_H) sparseset.h $(CONFIG_H)
-COLLECT2_OBJS = collect2.o tlink.o intl.o version.o
+COLLECT2_OBJS = collect2.o collect2-aix.o tlink.o intl.o version.o
COLLECT2_LIBS = @COLLECT2_LIBS@
collect2$(exeext): $(COLLECT2_OBJS) $(LIBDEPS)
# Don't try modifying collect2 (aka ld) in place--it might be linking this.
- $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o T$@ \
+ $(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o T$@ \
$(COLLECT2_OBJS) $(LIBS) $(COLLECT2_LIBS)
mv -f T$@ $@
collect2.o : collect2.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) intl.h \
- $(OBSTACK_H) $(DEMANGLE_H) collect2.h version.h
- $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) \
+ $(OBSTACK_H) $(DEMANGLE_H) collect2.h collect2-aix.h version.h
+ $(COMPILER) $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) \
-DTARGET_MACHINE=\"$(target_noncanonical)\" \
- -c $(srcdir)/collect2.c $(OUTPUT_OPTION)
+ -c $(srcdir)/collect2.c $(OUTPUT_OPTION) @TARGET_SYSTEM_ROOT_DEFINE@
+
+collect2-aix.o : collect2-aix.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
+ collect2-aix.h
tlink.o: tlink.c $(DEMANGLE_H) $(HASHTAB_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(OBSTACK_H) collect2.h intl.h
@@ -1911,15 +1937,15 @@ c-opts.o : c-opts.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_INLINE_H) $(DIAGNOSTIC_H) intl.h debug.h $(C_COMMON_H) \
opts.h options.h $(MKDEPS_H) incpath.h cppdefault.h $(TARGET_H) \
$(TM_P_H) $(VARRAY_H) $(C_TREE_H)
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) \
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) \
$< $(OUTPUT_OPTION) @TARGET_SYSTEM_ROOT_DEFINE@
c-cppbuiltin.o : c-cppbuiltin.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) version.h $(C_COMMON_H) $(C_PRAGMA_H) $(FLAGS_H) \
$(TOPLEV_H) output.h $(EXCEPT_H) $(REAL_H) $(TARGET_H) $(TM_P_H) \
$(BASEVER) debug.h
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) -DBASEVER=$(BASEVER_s) \
- $< $(OUTPUT_OPTION)
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) \
+ -DBASEVER=$(BASEVER_s) $< $(OUTPUT_OPTION)
# A file used by all variants of C and some other languages.
@@ -1943,7 +1969,7 @@ c-dump.o : c-dump.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
c-pch.o : c-pch.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(CPPLIB_H) $(TREE_H) \
$(C_COMMON_H) output.h $(TOPLEV_H) $(C_PRAGMA_H) $(GGC_H) debug.h \
langhooks.h $(FLAGS_H) hosthooks.h version.h $(TARGET_H) opts.h
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) \
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) \
-DHOST_MACHINE=\"$(host)\" -DTARGET_MACHINE=\"$(target)\" \
$< $(OUTPUT_OPTION)
@@ -1969,13 +1995,13 @@ gcc.o: gcc.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) intl.h multilib.h \
Makefile $(lang_specs_files) specs.h prefix.h $(GCC_H) $(FLAGS_H) \
configargs.h $(OBSTACK_H) opts.h
(SHLIB_LINK='$(SHLIB_LINK)'; \
- $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) \
+ $(COMPILER) $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) \
$(DRIVER_DEFINES) \
-c $(srcdir)/gcc.c $(OUTPUT_OPTION))
gccspec.o: gccspec.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(GCC_H)
(SHLIB_LINK='$(SHLIB_LINK)'; \
- $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) \
+ $(COMPILER) $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) \
$(DRIVER_DEFINES) \
-c $(srcdir)/gccspec.c $(OUTPUT_OPTION))
@@ -2010,7 +2036,8 @@ options.o: options.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TARGET_H) $(FLAGS_H)
$(TM_H) opts.h intl.h
gcc-options.o: options.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) opts.h intl.h
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(OUTPUT_OPTION) -DGCC_DRIVER options.c
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(OUTPUT_OPTION) \
+ -DGCC_DRIVER options.c
dumpvers: dumpvers.c
@@ -2019,7 +2046,7 @@ version.o: version.c version.h $(REVISION) $(DATESTAMP) $(BASEVER) $(DEVPHASE)
else
version.o: version.c version.h $(DATESTAMP) $(BASEVER) $(DEVPHASE)
endif
- $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) \
+ $(COMPILER) $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) \
-DBASEVER=$(BASEVER_s) -DDATESTAMP=$(DATESTAMP_s) \
-DREVISION=$(REVISION_s) \
-DDEVPHASE=$(DEVPHASE_s) -DPKGVERSION=$(PKGVERSION_s) \
@@ -2033,15 +2060,16 @@ gtype-desc.o: gtype-desc.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(CPP_ID_DATA_H) tree-chrec.h $(CFGLAYOUT_H) $(EXCEPT_H) output.h \
$(CFGLOOP_H)
-ggc-common.o: ggc-common.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(GGC_H) \
- $(HASHTAB_H) $(TOPLEV_H) $(PARAMS_H) hosthooks.h $(HOSTHOOKS_DEF_H)
+ggc-common.o: ggc-common.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
+ $(GGC_H) $(HASHTAB_H) $(TOPLEV_H) $(PARAMS_H) hosthooks.h \
+ $(HOSTHOOKS_DEF_H) vec.h plugin.h
ggc-page.o: ggc-page.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
- $(FLAGS_H) $(TOPLEV_H) $(GGC_H) $(TIMEVAR_H) $(TM_P_H) $(PARAMS_H) $(TREE_FLOW_H)
+ $(FLAGS_H) $(TOPLEV_H) $(GGC_H) $(TIMEVAR_H) $(TM_P_H) $(PARAMS_H) $(TREE_FLOW_H) plugin.h
ggc-zone.o: ggc-zone.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(TREE_H) $(FLAGS_H) $(TOPLEV_H) $(GGC_H) $(TIMEVAR_H) $(TM_P_H) \
- $(PARAMS_H) $(BITMAP_H) $(VARRAY_H)
+ $(PARAMS_H) $(BITMAP_H) $(VARRAY_H) plugin.h
ggc-none.o: ggc-none.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(GGC_H) \
$(BCONFIG_H)
@@ -2051,7 +2079,7 @@ stringpool.o: stringpool.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
prefix.o: prefix.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) prefix.h \
Makefile $(BASEVER)
- $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) \
+ $(COMPILER) $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) \
-DPREFIX=\"$(prefix)\" -DBASEVER=$(BASEVER_s) \
-c $(srcdir)/prefix.c $(OUTPUT_OPTION)
@@ -2088,8 +2116,8 @@ stor-layout.o : stor-layout.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
tree-ssa-structalias.o: tree-ssa-structalias.c \
$(SYSTEM_H) $(CONFIG_H) coretypes.h $(TM_H) $(GGC_H) $(OBSTACK_H) $(BITMAP_H) \
$(FLAGS_H) $(RTL_H) $(TM_P_H) hard-reg-set.h $(BASIC_BLOCK_H) output.h \
- $(DIAGNOSTIC_H) $(TREE_H) $(C_COMMON_H) $(TREE_FLOW_H) $(TREE_INLINE_H) varray.h \
- $(C_TREE_H) $(GIMPLE_H) $(HASHTAB_H) $(FUNCTION_H) $(CGRAPH_H) \
+ $(DIAGNOSTIC_H) $(TREE_H) $(TREE_FLOW_H) $(TREE_INLINE_H) varray.h \
+ $(GIMPLE_H) $(HASHTAB_H) $(FUNCTION_H) $(CGRAPH_H) \
$(TREE_PASS_H) $(TIMEVAR_H) alloc-pool.h $(SPLAY_TREE_H) $(PARAMS_H) \
gt-tree-ssa-structalias.h $(CGRAPH_H) $(ALIAS_H) pointer-set.h
tree-ssa.o : tree-ssa.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
@@ -2226,7 +2254,7 @@ tree-nested.o: tree-nested.c $(CONFIG_H) $(SYSTEM_H) $(TM_H) $(TREE_H) \
$(GGC_H) gt-tree-nested.h coretypes.h $(TREE_FLOW_H) pointer-set.h
tree-if-conv.o: tree-if-conv.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) $(FLAGS_H) $(TIMEVAR_H) $(BASIC_BLOCK_H) $(TREE_FLOW_H) \
- $(CFGLOOP_H) $(RTL_H) $(C_COMMON_H) tree-chrec.h $(TREE_DATA_REF_H) \
+ $(CFGLOOP_H) $(RTL_H) tree-chrec.h $(TREE_DATA_REF_H) \
$(SCEV_H) $(TREE_PASS_H) $(DIAGNOSTIC_H) $(TARGET_H) $(TREE_DUMP_H) \
$(VARRAY_H)
tree-iterator.o : tree-iterator.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) \
@@ -2388,7 +2416,7 @@ tree-vect-slp.o: tree-vect-slp.c $(CONFIG_H) $(SYSTEM_H) \
tree-vect-stmts.o: tree-vect-stmts.c $(CONFIG_H) $(SYSTEM_H) \
coretypes.h $(TM_H) $(GGC_H) $(TREE_H) $(TARGET_H) $(BASIC_BLOCK_H) \
$(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TREE_DUMP_H) $(CFGLOOP_H) \
- $(EXPR_H) $(RECOG_H) $(OPTABS_H) tree-vectorizer.h langhooks.h
+ $(EXPR_H) $(RECOG_H) $(OPTABS_H) $(TOPLEV_H) tree-vectorizer.h langhooks.h
tree-vect-data-refs.o: tree-vect-data-refs.c $(CONFIG_H) $(SYSTEM_H) \
coretypes.h $(TM_H) $(GGC_H) $(TREE_H) $(TARGET_H) $(BASIC_BLOCK_H) \
$(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TREE_DUMP_H) $(CFGLOOP_H) \
@@ -2455,6 +2483,14 @@ targhooks.o : targhooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \
$(MACHMODE_H) $(TARGET_DEF_H) $(TARGET_H) $(GGC_H) gt-targhooks.h \
$(OPTABS_H) $(RECOG_H) reload.h
+bversion.h: s-bversion; @true
+s-bversion: BASE-VER
+ echo "#define BUILDING_GCC_MAJOR `echo $(BASEVER_c) | sed -e 's/^\([0-9]*\).*$$/\1/'`" > bversion.h
+ echo "#define BUILDING_GCC_MINOR `echo $(BASEVER_c) | sed -e 's/^[0-9]*\.\([0-9]*\).*$$/\1/'`" >> bversion.h
+ echo "#define BUILDING_GCC_PATCHLEVEL `echo $(BASEVER_c) | sed -e 's/^[0-9]*\.[0-9]*\.\([0-9]*\)$$/\1/'`" >> bversion.h
+ echo "#define BUILDING_GCC_VERSION (BUILDING_GCC_MAJOR * 1000 + BUILDING_GCC_MINOR)" >> bversion.h
+ $(STAMP) s-bversion
+
toplev.o : toplev.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
version.h $(RTL_H) $(FUNCTION_H) $(FLAGS_H) xcoffout.h $(INPUT_H) \
$(INSN_ATTR_H) output.h $(DIAGNOSTIC_H) debug.h insn-config.h intl.h \
@@ -2465,7 +2501,7 @@ toplev.o : toplev.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
$(CGRAPH_H) $(COVERAGE_H) alloc-pool.h $(GGC_H) $(INTEGRATE_H) \
opts.h params.def tree-mudflap.h $(REAL_H) $(TREE_PASS_H) $(GIMPLE_H) \
tree-ssa-alias.h $(PLUGIN_H)
- $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) \
+ $(COMPILER) $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) \
-DTARGET_NAME=\"$(target_noncanonical)\" \
-c $(srcdir)/toplev.c $(OUTPUT_OPTION)
@@ -2481,7 +2517,7 @@ passes.o : passes.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
gt-passes.h $(DF_H) $(PREDICT_H)
plugin.o : plugin.c $(PLUGIN_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h \
- $(TOPLEV_H) $(TREE_H) $(TREE_PASS_H) intl.h $(PLUGIN_VERSION_H)
+ $(TOPLEV_H) $(TREE_H) $(TREE_PASS_H) intl.h $(PLUGIN_VERSION_H) $(GGC_H)
main.o : main.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TOPLEV_H)
@@ -2505,7 +2541,7 @@ rtlanal.o : rtlanal.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TOPLEV_H) \
varasm.o : varasm.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
$(RTL_H) $(FLAGS_H) $(FUNCTION_H) $(EXPR_H) hard-reg-set.h $(REGS_H) \
- output.h $(C_PRAGMA_H) $(TOPLEV_H) xcoffout.h debug.h $(GGC_H) $(TM_P_H) \
+ output.h $(TOPLEV_H) xcoffout.h debug.h $(GGC_H) $(TM_P_H) \
$(HASHTAB_H) $(TARGET_H) langhooks.h gt-varasm.h $(BASIC_BLOCK_H) \
$(CFGLAYOUT_H) $(CGRAPH_H) targhooks.h tree-mudflap.h $(REAL_H) tree-iterator.h
function.o : function.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
@@ -2525,7 +2561,7 @@ except.o : except.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(TREE_H) $(FLAGS_H) $(EXCEPT_H) $(FUNCTION_H) $(EXPR_H) libfuncs.h \
langhooks.h insn-config.h hard-reg-set.h $(BASIC_BLOCK_H) output.h \
dwarf2asm.h dwarf2out.h $(TOPLEV_H) $(HASHTAB_H) intl.h $(GGC_H) \
- gt-$(EXCEPT_H) $(CGRAPH_H) $(INTEGRATE_H) $(DIAGNOSTIC_H) dwarf2.h \
+ gt-except.h $(CGRAPH_H) $(INTEGRATE_H) $(DIAGNOSTIC_H) dwarf2.h \
$(TARGET_H) $(TM_P_H) $(TREE_PASS_H) $(TIMEVAR_H) $(TREE_FLOW_H)
expr.o : expr.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(TREE_H) $(FLAGS_H) $(FUNCTION_H) $(REGS_H) $(EXPR_H) $(OPTABS_H) \
@@ -2613,7 +2649,7 @@ cgraph.o : cgraph.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
cgraphunit.o : cgraphunit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) langhooks.h $(TREE_INLINE_H) $(TOPLEV_H) $(FLAGS_H) $(GGC_H) \
$(TARGET_H) $(CGRAPH_H) intl.h pointer-set.h $(FUNCTION_H) $(GIMPLE_H) \
- $(TREE_FLOW_H) $(TREE_PASS_H) $(C_COMMON_H) debug.h $(DIAGNOSTIC_H) \
+ $(TREE_FLOW_H) $(TREE_PASS_H) debug.h $(DIAGNOSTIC_H) \
$(FIBHEAP_H) output.h $(PARAMS_H) $(RTL_H) $(TIMEVAR_H) $(IPA_PROP_H) \
gt-cgraphunit.h tree-iterator.h $(COVERAGE_H)
cgraphbuild.o : cgraphbuild.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
@@ -2632,12 +2668,12 @@ ipa-prop.o : ipa-prop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
ipa-cp.o : ipa-cp.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TREE_H) $(TARGET_H) $(CGRAPH_H) $(IPA_PROP_H) $(TREE_FLOW_H) \
$(TREE_PASS_H) $(FLAGS_H) $(TIMEVAR_H) $(DIAGNOSTIC_H) $(TREE_DUMP_H) \
- $(TREE_INLINE_H)
+ $(TREE_INLINE_H) $(FIBHEAP_H) $(PARAMS_H)
matrix-reorg.o : matrix-reorg.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
- $(TM_H) $(TREE_H) $(RTL_H) $(C_TREE_H) $(TREE_INLINE_H) $(TREE_FLOW_H) \
+ $(TM_H) $(TREE_H) $(RTL_H) $(TREE_INLINE_H) $(TREE_FLOW_H) \
tree-flow-inline.h langhooks.h $(HASHTAB_H) $(TOPLEV_H) $(FLAGS_H) $(GGC_H) \
debug.h $(TARGET_H) $(CGRAPH_H) $(DIAGNOSTIC_H) $(TIMEVAR_H) $(PARAMS_H) \
- $(FIBHEAP_H) $(C_COMMON_H) intl.h $(FUNCTION_H) $(BASIC_BLOCK_H) $(CFGLOOP_H) \
+ $(FIBHEAP_H) intl.h $(FUNCTION_H) $(BASIC_BLOCK_H) $(CFGLOOP_H) \
tree-iterator.h $(TREE_PASS_H) opts.h $(TREE_DATA_REF_H) tree-chrec.h \
tree-scalar-evolution.h
ipa-inline.o : ipa-inline.c gt-ipa-inline.h $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
@@ -2646,30 +2682,29 @@ ipa-inline.o : ipa-inline.c gt-ipa-inline.h $(CONFIG_H) $(SYSTEM_H) coretypes.h
$(HASHTAB_H) $(COVERAGE_H) $(GGC_H) $(TREE_FLOW_H) $(RTL_H) $(IPA_PROP_H)
ipa-utils.o : ipa-utils.c $(IPA_UTILS_H) $(CONFIG_H) $(SYSTEM_H) \
coretypes.h $(TM_H) $(TREE_H) $(TREE_FLOW_H) $(TREE_INLINE_H) langhooks.h \
- pointer-set.h $(GGC_H) $(C_COMMON_H) $(GIMPLE_H) \
+ pointer-set.h $(GGC_H) $(GIMPLE_H) $(SPLAY_TREE_H) \
$(CGRAPH_H) output.h $(FLAGS_H) $(TREE_PASS_H) $(TIMEVAR_H) $(DIAGNOSTIC_H)
ipa-reference.o : ipa-reference.c $(CONFIG_H) $(SYSTEM_H) \
coretypes.h $(TM_H) $(TREE_H) $(TREE_FLOW_H) $(TREE_INLINE_H) langhooks.h \
- pointer-set.h $(GGC_H) $(IPA_REFERENCE_H) $(IPA_UTILS_H) $(C_COMMON_H) \
+ pointer-set.h $(GGC_H) $(IPA_REFERENCE_H) $(IPA_UTILS_H) $(SPLAY_TREE_H) \
$(GIMPLE_H) $(CGRAPH_H) output.h $(FLAGS_H) $(TREE_PASS_H) \
- $(TIMEVAR_H) $(DIAGNOSTIC_H) $(FUNCTION_H)
-
+ $(TIMEVAR_H) $(DIAGNOSTIC_H) $(FUNCTION_H) gt-ipa-reference.h
ipa-pure-const.o : ipa-pure-const.c $(CONFIG_H) $(SYSTEM_H) \
coretypes.h $(TM_H) $(TREE_H) $(TREE_FLOW_H) $(TREE_INLINE_H) langhooks.h \
- pointer-set.h $(GGC_H) $(IPA_UTILS_H) $(C_COMMON_H) $(TARGET_H) \
+ pointer-set.h $(GGC_H) $(IPA_UTILS_H) $(TARGET_H) \
$(GIMPLE_H) $(CGRAPH_H) output.h $(FLAGS_H) $(TREE_PASS_H) $(TIMEVAR_H) \
$(DIAGNOSTIC_H)
ipa-type-escape.o : ipa-type-escape.c $(CONFIG_H) $(SYSTEM_H) \
coretypes.h $(TM_H) $(TREE_H) $(TREE_FLOW_H) $(TREE_INLINE_H) langhooks.h \
- pointer-set.h $(GGC_H) $(IPA_TYPE_ESCAPE_H) $(IPA_UTILS_H) $(C_COMMON_H) \
+ pointer-set.h $(GGC_H) $(IPA_TYPE_ESCAPE_H) $(IPA_UTILS_H) $(SPLAY_TREE_H) \
$(GIMPLE_H) $(CGRAPH_H) output.h $(FLAGS_H) $(TREE_PASS_H) \
$(TIMEVAR_H) $(DIAGNOSTIC_H) $(FUNCTION_H)
ipa-struct-reorg.o: ipa-struct-reorg.c ipa-struct-reorg.h $(CONFIG_H) $(SYSTEM_H) \
coretypes.h $(TM_H) $(GGC_H) $(TREE_H) $(RTL_H) $(GIMPLE_H) tree-inline.h \
- $(TREE_FLOW_H) langhooks.h pointer-set.h $(HASHTAB_H) $(C_TREE_H) $(TOPLEV_H) \
+ $(TREE_FLOW_H) langhooks.h pointer-set.h $(HASHTAB_H) $(TOPLEV_H) \
$(FLAGS_H) debug.h $(TARGET_H) $(CGRAPH_H) $(DIAGNOSTIC_H) $(TIMEVAR_H) \
$(PARAMS_H) $(FIBHEAP_H) intl.h $(FUNCTION_H) $(BASIC_BLOCK_H) tree-iterator.h \
- $(TREE_PASS_H) opts.h $(IPA_TYPE_ESCAPE_H) $(TREE_DUMP_H) $(C_COMMON_H) \
+ $(TREE_PASS_H) opts.h $(IPA_TYPE_ESCAPE_H) $(TREE_DUMP_H) \
$(GIMPLE_H)
coverage.o : coverage.c $(GCOV_IO_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h \
@@ -2707,12 +2742,12 @@ see.o : see.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
gcse.o : gcse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(REGS_H) hard-reg-set.h $(FLAGS_H) $(REAL_H) insn-config.h $(GGC_H) \
$(RECOG_H) $(EXPR_H) $(BASIC_BLOCK_H) $(FUNCTION_H) output.h $(TOPLEV_H) \
- $(TM_P_H) $(PARAMS_H) $(EXCEPT_H) $(TREE_H) $(TIMEVAR_H) \
+ $(TM_P_H) $(PARAMS_H) $(EXCEPT_H) gt-gcse.h $(TREE_H) $(TIMEVAR_H) \
intl.h $(OBSTACK_H) $(TREE_PASS_H) $(DF_H) $(DBGCNT_H)
store-motion.o : store-motion.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(REGS_H) hard-reg-set.h $(FLAGS_H) $(REAL_H) insn-config.h $(GGC_H) \
$(RECOG_H) $(EXPR_H) $(BASIC_BLOCK_H) $(FUNCTION_H) output.h $(TOPLEV_H) \
- $(TM_P_H) $(PARAMS_H) $(EXCEPT_H) gt-gcse.h $(TREE_H) cselib.h $(TIMEVAR_H) \
+ $(TM_P_H) $(EXCEPT_H) $(TREE_H) $(TIMEVAR_H) \
intl.h $(OBSTACK_H) $(TREE_PASS_H) $(DF_H) $(DBGCNT_H)
resource.o : resource.c $(CONFIG_H) $(RTL_H) hard-reg-set.h $(SYSTEM_H) \
coretypes.h $(TM_H) $(REGS_H) $(FLAGS_H) output.h $(RESOURCE_H) $(DF_H) \
@@ -2738,11 +2773,9 @@ tree-ssa-ccp.o : tree-ssa-ccp.c $(TREE_FLOW_H) $(CONFIG_H) \
$(DIAGNOSTIC_H) $(FUNCTION_H) $(TIMEVAR_H) $(TM_H) coretypes.h \
$(TREE_DUMP_H) $(BASIC_BLOCK_H) $(TREE_PASS_H) langhooks.h \
tree-ssa-propagate.h value-prof.h $(FLAGS_H) $(TARGET_H) $(TOPLEV_H)
-tree-sra.o : tree-sra.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) \
- $(TM_P_H) $(TREE_FLOW_H) $(DIAGNOSTIC_H) $(TREE_INLINE_H) \
- $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) $(GIMPLE_H) \
- langhooks.h $(TREE_PASS_H) $(FLAGS_H) $(EXPR_H) $(BASIC_BLOCK_H) \
- $(BITMAP_H) $(GGC_H) hard-reg-set.h $(OBSTACK_H) $(PARAMS_H) $(TARGET_H)
+tree-sra.o : tree-sra.c $(CONFIG_H) $(SYSTEM_H) coretypes.h alloc-pool.h \
+ $(TM_H) $(TREE_H) $(GIMPLE_H) $(TREE_FLOW_H) $(DIAGNOSTIC_H) $(TREE_DUMP_H) \
+ $(TIMEVAR_H) $(PARAMS_H) $(TARGET_H) $(FLAGS_H)
tree-switch-conversion.o : tree-switch-conversion.c $(CONFIG_H) $(SYSTEM_H) \
$(TREE_H) $(TM_P_H) $(TREE_FLOW_H) $(DIAGNOSTIC_H) $(TREE_INLINE_H) \
$(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) $(GIMPLE_H) \
@@ -3092,18 +3125,20 @@ $(out_object_file): $(out_file) $(CONFIG_H) coretypes.h $(TM_H) $(TREE_H) \
output.h $(INSN_ATTR_H) $(SYSTEM_H) $(TOPLEV_H) $(TARGET_H) libfuncs.h \
$(TARGET_DEF_H) $(FUNCTION_H) $(SCHED_INT_H) $(TM_P_H) $(EXPR_H) \
langhooks.h $(GGC_H) $(OPTABS_H) $(REAL_H) tm-constrs.h $(GIMPLE_H)
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) \
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) \
$(out_file) $(OUTPUT_OPTION)
# Build auxiliary files that support ecoff format.
mips-tfile: mips-tfile.o version.o $(LIBDEPS)
- $(CC) $(CFLAGS) $(LDFLAGS) -o $@ mips-tfile.o version.o $(LIBS)
+ $(LINKER) $(LINKERFLAGS) $(LDFLAGS) -o $@ \
+ mips-tfile.o version.o $(LIBS)
mips-tfile.o : mips-tfile.c $(CONFIG_H) $(RTL_H) $(SYSTEM_H) coretypes.h \
$(TM_H) version.h $(srcdir)/../include/getopt.h $(GSTAB_H) intl.h
mips-tdump: mips-tdump.o version.o $(LIBDEPS)
- $(CC) $(CFLAGS) $(LDFLAGS) -o $@ mips-tdump.o version.o $(LIBS)
+ $(LINKER) $(LINKERFLAGS) $(LDFLAGS) -o $@ \
+ mips-tdump.o version.o $(LIBS)
mips-tdump.o : mips-tdump.c $(CONFIG_H) $(RTL_H) $(SYSTEM_H) coretypes.h \
$(TM_H) version.h $(srcdir)/../include/getopt.h stab.def
@@ -3112,7 +3147,7 @@ mips-tdump.o : mips-tdump.c $(CONFIG_H) $(RTL_H) $(SYSTEM_H) coretypes.h \
libbackend.o : $(OBJS-common:.o=.c) $(out_file) \
insn-config.h insn-flags.h insn-codes.h insn-constants.h \
insn-attr.h $(DATESTAMP) $(BASEVER) $(DEVPHASE) gcov-iov.h
- $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) \
+ $(COMPILER) $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) \
-DTARGET_NAME=\"$(target_noncanonical)\" \
-DLOCALEDIR=\"$(localedir)\" \
-c $(filter %.c,$^) -o $@ \
@@ -3383,7 +3418,8 @@ s-gtype: build/gengtype$(build_exeext) $(filter-out [%], $(GTFILES)) \
# How to compile object files to run on the build machine.
build/%.o : # dependencies provided by explicit rule later
- $(CC_FOR_BUILD) -c $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) -o $@ $<
+ $(COMPILER_FOR_BUILD) -c $(BUILD_COMPILERFLAGS) $(BUILD_CPPFLAGS) \
+ -o $@ $<
# Header dependencies for the programs that generate source code.
# These are library modules...
@@ -3422,7 +3458,7 @@ build/genattrtab.o : genattrtab.c $(RTL_BASE_H) $(OBSTACK_H) \
build/genautomata.o : genautomata.c $(RTL_BASE_H) $(OBSTACK_H) \
$(BCONFIG_H) $(SYSTEM_H) coretypes.h $(GTM_H) errors.h vec.h \
$(HASHTAB_H) gensupport.h
-build/gencheck.o : gencheck.c tree.def $(BCONFIG_H) $(GTM_H) \
+build/gencheck.o : gencheck.c all-tree.def $(BCONFIG_H) $(GTM_H) \
$(SYSTEM_H) coretypes.h $(lang_tree_files) gimple.def
build/genchecksum.o : genchecksum.c $(BCONFIG_H) $(SYSTEM_H) $(MD5_H)
build/gencodes.o : gencodes.c $(RTL_BASE_H) $(BCONFIG_H) $(SYSTEM_H) \
@@ -3461,13 +3497,13 @@ build/genrecog.o : genrecog.c $(RTL_BASE_H) $(BCONFIG_H) $(SYSTEM_H) \
coretypes.h $(GTM_H) errors.h gensupport.h
# Compile the programs that generate insn-* from the machine description.
-# They are compiled with $(CC_FOR_BUILD), and associated libraries,
+# They are compiled with $(COMPILER_FOR_BUILD), and associated libraries,
# since they need to run on this machine
# even if GCC is being compiled to run on some other machine.
# As a general rule...
build/gen%$(build_exeext): build/gen%.o $(BUILD_LIBDEPS)
- $(CC_FOR_BUILD) $(BUILD_CFLAGS) $(BUILD_LDFLAGS) -o $@ \
+ $(LINKER_FOR_BUILD) $(BUILD_LINKERFLAGS) $(BUILD_LDFLAGS) -o $@ \
$(filter-out $(BUILD_LIBDEPS), $^) $(BUILD_LIBS)
# All these programs use the MD reader ($(BUILD_RTL)).
@@ -3491,7 +3527,7 @@ gengtype-lex.c : gengtype-lex.l
#
# Remake internationalization support.
intl.o: intl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) intl.h Makefile
- $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) \
+ $(COMPILER) $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) \
-DLOCALEDIR=\"$(localedir)\" \
-c $(srcdir)/intl.c $(OUTPUT_OPTION)
@@ -3513,7 +3549,7 @@ PREPROCESSOR_DEFINES = \
cppdefault.o: cppdefault.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
cppdefault.h Makefile
- $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) \
+ $(COMPILER) $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) \
$(PREPROCESSOR_DEFINES) \
-c $(srcdir)/cppdefault.c $(OUTPUT_OPTION)
@@ -3525,7 +3561,8 @@ build/gcov-iov.o: gcov-iov.c $(BCONFIG_H) coretypes.h $(GTM_H) \
$(SYSTEM_H) coretypes.h $(TM_H)
build/gcov-iov$(build_exeext): build/gcov-iov.o
- $(CC_FOR_BUILD) $(BUILD_CFLAGS) $(BUILD_LDFLAGS) build/gcov-iov.o -o $@
+ $(LINKER_FOR_BUILD) $(BUILD_LINKERFLAGS) $(BUILD_LDFLAGS) \
+ build/gcov-iov.o -o $@
gcov-iov.h: s-iov
s-iov: build/gcov-iov$(build_exeext) $(BASEVER) $(DEVPHASE)
@@ -3541,10 +3578,11 @@ gcov-dump.o: gcov-dump.c gcov-io.c $(GCOV_IO_H) $(SYSTEM_H) coretypes.h \
GCOV_OBJS = gcov.o intl.o version.o errors.o
gcov$(exeext): $(GCOV_OBJS) $(LIBDEPS)
- $(CC) $(ALL_CFLAGS) $(LDFLAGS) $(GCOV_OBJS) $(LIBS) -o $@
+ $(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) $(GCOV_OBJS) $(LIBS) -o $@
GCOV_DUMP_OBJS = gcov-dump.o version.o errors.o
gcov-dump$(exeext): $(GCOV_DUMP_OBJS) $(LIBDEPS)
- $(CC) $(ALL_CFLAGS) $(LDFLAGS) $(GCOV_DUMP_OBJS) $(LIBS) -o $@
+ $(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) $(GCOV_DUMP_OBJS) \
+ $(LIBS) -o $@
#
# Build the include directories. The stamp files are stmp-* rather than
# s-* so that mostlyclean does not force the include directory to
@@ -3720,7 +3758,7 @@ TEXI_GCCINT_FILES = gccint.texi gcc-common.texi gcc-vers.texi \
configfiles.texi collect2.texi headerdirs.texi funding.texi \
gnu.texi gpl_v3.texi fdl.texi contrib.texi languages.texi \
sourcebuild.texi gty.texi libgcc.texi cfg.texi tree-ssa.texi \
- loop.texi generic.texi gimple.texi
+ loop.texi generic.texi gimple.texi plugins.texi
TEXI_GCCINSTALL_FILES = install.texi install-old.texi fdl.texi \
gcc-common.texi gcc-vers.texi
@@ -4009,8 +4047,8 @@ installdirs:
$(mkinstalldirs) $(DESTDIR)$(man7dir)
PLUGIN_HEADERS = $(TREE_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
- $(TOPLEV_H) $(BASIC_BLOCK_H) $(GIMPLE_H) $(TREE_PASS_H) gcc-plugin.h intl.h \
- $(PLUGIN_VERSION_H)
+ $(TOPLEV_H) $(BASIC_BLOCK_H) $(GIMPLE_H) $(TREE_PASS_H) $(GCC_PLUGIN_H) \
+ intl.h $(PLUGIN_VERSION_H)
# Install the headers needed to build a plugin.
install-plugin: installdirs
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 473d8f37bbe..c22d2a76ca9 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,17 +1,263 @@
-2009-05-07 Arnaud Charlet <charlet@adacore.com>
+2009-06-13 Aldy Hernandez <aldyh@redhat.com>
+
+ * gcc-interface/utils.c (record_builtin_type): Pass location
+ argument to build_decl.
+ (create_type_stub_decl): Same.
+ (create_type_decl): Same.
+ (create_var_decl_1): Same.
+ (create_field_decl): Same.
+ (create_param_decl): Same.
+ (create_label_decl): Same.
+ (create_subprog_decl): Same.
+ * gcc-interface/decl.c (gnat_to_gnu_entity): Same.
+ * gcc-interface/trans.c (Case_Statement_to_gnu): Pass location
+ argument to create_artificial_label.
+ (Loop_Statement_to_gnu): Same.
+ (Subprogram_Body_to_gnu): Same.
+ (gnat_gimplify_stmt): Same.
+
+2009-06-11 Richard Henderson <rth@redhat.com>
+
+ * gcc-interface/misc.c (gnat_handle_option): Rename OPT_gdwarf_ to
+ OPT_gdwarfplus.
+
+2009-06-11 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_attr.adb (Resolve_Attribute, case 'access): Add missing
+ accessibiliy check on access_to_subprogram in the context of an
+ anonymous access that is not an access parameter.
+
+2009-06-11 Eric Botcazou <ebotcazou@adacore.com>
+
+ * tracebak.c (i386 section): Define IS_BAD_PTR on Solaris.
+
+2009-06-11 Quentin Ochem <ochem@adacore.com>
- * gcc-interface/Make-lang.in: Update dependencies
+ * sem_warn.adb, scng.adb, sfn_scan.adb, freeze.adb: Add CODEFIX
+ comments for message handled by GPS.
+
+2009-06-11 Matthew Gingell <gingell@adacore.com>
+
+ * adaint.c: Use fopen64 instead of fopen on platforms where we know
+ it's supported.
+
+2009-06-11 Pascal Obry <obry@adacore.com>
-2009-05-06 Laurent GUERBY <laurent@guerby.net>
+ * g-cgi.ads: Fix comment typo.
- * s-linux.ads, s-linux-alpha.ads, s-linux-hppa.ads,
- osinte-linux.ads: Define sa_handler_pos.
- * s-osinte-linux.ads: Use it.
- * s-linux-mipsel.ads: New.
- * system-linux-mips64el.ads: New.
- * gcc-interface/Makefile.in: Multilib handling for
- mipsel-linux and mips64el-linux.
+ * g-cgi.adb: Properly decode "+" in CGI parameters as spaces.
+
+2009-06-10 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Record_Subtype>: Use
+ a reference to the original type for the type of the field of the
+ XVS type.
+ (maybe_pad_type): Likewise.
+
+ * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Record_Type>: Factor
+ common predicate and remove redundant setting of TYPE_BY_REFERENCE_P.
+ Pass correctly typed arguments to create_field_decl.
+ <E_Record_Subtype>: Set BLKmode for tagged and limited types in the
+ case of contrained discriminants as well. Use the padded base type
+ in the other case as well. Rename temporary variable. Tweak test.
+ Factor common access pattern. Set GNU_SIZE only once.
+
+2009-06-09 Olivier Hainque <hainque@adacore.com>
+
+ * gcc-interface/utils2.c (build_call_alloc_dealloc_proc): New
+ helper for build_call_alloc_dealloc with arguments to be interpreted
+ identically. Process the case where a GNAT_PROC to call is provided.
+ (maybe_wrap_malloc): New helper for build_call_alloc_dealloc, to build
+ and return an allocator for DATA_SIZE bytes aimed at containing a
+ DATA_TYPE object, using the default __gnat_malloc allocator. Honor
+ DATA_TYPE alignments greater than what the latter offers.
+ (maybe_wrap_free): New helper for build_call_alloc_dealloc, to
+ release a DATA_TYPE object designated by DATA_PTR using the
+ __gnat_free entry point.
+ (build_call_alloc_dealloc): Expect object data type instead of naked
+ alignment constraint. Use the new helpers.
+ (build_allocator): Remove special processing for the super-aligned
+ case, now handled by build_call_alloc_dealloc. Pass data
+ type instead of the former alignment argument, as expected by the new
+ interface.
+ * gcc-interface/gigi.h (build_call_alloc_dealloc): Adjust prototype
+ and comment.
+ * gcc-interface/trans.c (gnat_to_gnu) <case N_Free_Statement>:
+ Remove special processing for the super-aligned case, now handled
+ by build_call_alloc_dealloc. Pass data type instead of the former
+ alignment argument, as expected by the new interface.
+2009-06-08 Alexandre Oliva <aoliva@redhat.com>
+
+ * lib-writ.adb (flag_compare_debug): Import.
+ (Write_ALI): Skip during -fcompare-debug-second.
+
+2009-06-03 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Record_Type>: When
+ adjusting the discriminant nodes in an extension, use the full view
+ of the parent subtype if it is of a private kind.
+
+2009-06-03 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Record_Type>: Add the
+ _Parent field, if any, to the record before adding the other fields.
+ <E_Record_Subtype>: Put the _Controller field before the other fields
+ except for the _Tag or _Parent fields.
+ (components_to_record): Likewise. Retrieve the _Parent field from the
+ record type.
+
+2009-06-03 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/decl.c (substitution_list): Rename to build_subst_list,
+ remove unused parameter and simplify.
+ (gnat_to_gnu_entity) <E_Record_Type>: Do not set TYPE_FIELDS. Factor
+ common predicate. Rewrite loop for clarity. Use GNU_TYPE directly
+ as context for all discriminants. Fix formatting nits.
+ <E_Record_Subtype>: Add cosmetic 'break'. Test Has_Discriminants
+ before Discriminant_Constraint. Adjust for above renaming. Do not
+ set GNU_TYPE more than once.
+ (elaborate_entity): Test Has_Discriminants on the entity and use
+ Implementation_Base_Type.
+ (components_to_record): Rename component_list to gnat_component_list.
+ Retrieve the _Parent field from the list. Fix nits in comments.
+ Clarify logic in loop. Pass correct arguments to create_field_decl.
+
+2009-06-02 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/Make-lang.in: Fix formatting.
+
+2009-06-01 Olivier Hainque <hainque@adacore.com>
+ Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/utils.c (convert) <CONSTRUCTOR case>: When converting
+ to the packable version of the type, clear TREE_STATIC/TREE_CONSTANT
+ on the result if at least one of the input fields couldn't be output
+ as a static constant any more.
+
+2009-06-01 Olivier Hainque <hainque@adacore.com>
+ Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/utils2.c (gnat_build_constructor): Factor
+ out code. Use initializer_constant_valid_for_bitfield_p and
+ CONSTRUCTOR_BITFIELD_P for bit-fields.
+
+2009-05-26 Ian Lance Taylor <iant@google.com>
+
+ * gcc-interface/Makefile.in (COMPILER): Define.
+ (COMPILER_FLAGS, ALL_COMPILERFLAGS): Define.
+ (.c.o, cio.o, init.o, initialize.o, targext.o): Use $(COMPILER).
+ (seh_init.o, tracebak.o): Likewise.
+ * gcc-interface/Make-lang.in (ada/targext.o): Likewise.
+ (ada/cio.o, ada/init.o, ada/initialize.o, ada/raise.o): Likewise.
+ (ada/tracebak.o, ada/cuintp.o, ada/decl.o, ada/misc.o): Likewise.
+ (ada/targtyps.o, ada/trans.o, ada/utils.o): Likewise.
+ (ada/utils2.o): Likewise.
+
+2009-05-24 Olivier Hainque <hainque@adacore.com>
+
+ * switch.adb (Is_Internal_GCC_Switch, Switch_Last): Bodies of ...
+ * switch.ads (Is_Internal_GCC_Switch, Switch_Last): New functions.
+ Add -auxbase variants to the list of recognized internal switches.
+ * back_end.adb (Scan_Back_End_Switches): Use the new functions and
+ adjust comments.
+ * lib.ads: Make comment on internal GCC switches more general.
+ * gcc-interface/lang-specs.h (specs for Ada): Pass -auxbase variants
+ as for C.
+
+2009-05-23 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/misc.c (gnat_get_subrange_bounds): Fix thinko.
+
+2009-05-23 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/decl.c (set_rm_size): Bypass the check for packed array
+ types.
+
+2009-05-23 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/decl.c (gnat_to_gnu_entity) <object>: Do not modify the
+ original type because of the alignment when there is an address clause.
+
+2009-05-20 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Record_Subtype>: When
+ discriminants affect the shape of the subtype, retrieve the GCC type
+ directly from the original field if the GNAT types for the field and
+ the original field are the same.
+
+2009-05-15 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/ada-tree.h (TYPE_GCC_MIN_VALUE, TYPE_GCC_MAX_VALUE):
+ New macros.
+ (TYPE_RM_VALUES): Likewise.
+ (TYPE_RM_SIZE): Rewrite in terms of TYPE_RM_VALUES.
+ (SET_TYPE_RM_SIZE): New macro.
+ (TYPE_RM_MIN_VALUE, TYPE_RM_MAX_VALUE): Likewise.
+ (SET_TYPE_RM_SIZE, SET_TYPE_RM_MAX_VALUE): Likewise.
+ (TYPE_MIN_VALUE, TYPE_MAX_VALUE): Redefine.
+ * gcc-interface/gigi.h (create_range_type): Declare.
+ * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Modular_Integer_Type>
+ Use SET_TYPE_RM_MAX_VALUE to set the upper bound on the UMT type.
+ <E_Signed_Integer_Subtype>: Build a regular integer type first and
+ then set the RM bounds. Use SET_TYPE_RM_SIZE to set the RM size.
+ <E_Floating_Point_Subtype>: Build a regular floating-point type first
+ and then set the RM bounds.
+ <E_Array_Type>: Use create_range_type instead of build_range_type.
+ <E_Array_Subtype>: Build a regular integer type first and then set
+ the RM bounds for the extra subtype.
+ <E_String_Literal_Subtype>: Use create_range_type instead of
+ build_range_type.
+ <all>: Set the RM bounds for enumeration types and the GCC bounds for
+ floating-point types.
+ (set_rm_size): Use SET_TYPE_RM_SIZE to set the RM size.
+ (make_type_from_size) <INTEGER_TYPE>: Use SET_TYPE_RM_{MIN,MAX}_VALUE
+ to set the bounds. Use SET_TYPE_RM_SIZE to set the RM size.
+ (substitute_in_type) <INTEGER_TYPE>: Deal with GCC bounds for domain
+ types and with RM bounds for subtypes.
+ * gcc-interface/misc.c (LANG_HOOKS_GET_SUBRANGE_BOUNDS): Define.
+ (gnat_print_type) <REAL_TYPE>: New case.
+ <ENUMERAL_TYPE>: Fall through to above case.
+ (gnat_get_subrange_bounds): New function.
+ * gcc-interface/trans.c (add_decl_expr): Mark the trees rooted as
+ TYPE_RM_MIN_VALUE and TYPE_RM_MAX_VALUE, if any.
+ * gcc-interface/utils.c (gnat_init_decl_processing): Use precision 8
+ for booleans. Adjust and use SET_TYPE_RM_SIZE to set the RM size.
+ (create_range_type): New function.
+ (create_param_decl): Build a regular integer type first and then set
+ the RM bounds for the extra subtype.
+ (unchecked_convert): Remove kludge for 'Valid.
+ * gcc-interface/utils2.c (build_binary_op) <ARRAY_RANGE_REF>: Convert
+ the index to sizetype instead of TYPE_DOMAIN.
+
+2009-05-14 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/decl.c (elaborate_expression_1): Remove GNAT_EXPR
+ parameter and move check for static expression to...
+ (elaborate_expression): ...here. Adjust call to above function.
+ (gnat_to_gnu_entity): Likewise for all calls. Use correct arguments
+ in calls to elaborate_expression.
+ (elaborate_entity): Likewise.
+ (substitution_list): Likewise.
+ (maybe_variable): Fix formatting.
+ (substitute_in_type) <REAL_TYPE>: Merge with INTEGER_TYPE case and add
+ missing guard.
+ * gcc-interface/trans.c (protect_multiple_eval): Minor cleanup.
+
+2009-05-07 Arnaud Charlet <charlet@adacore.com>
+
+ * gcc-interface/Make-lang.in: Update dependencies.
+
+2009-05-06 Laurent GUERBY <laurent@guerby.net>
+
+ * s-linux.ads, s-linux-alpha.ads, s-linux-hppa.ads, osinte-linux.ads:
+ Define sa_handler_pos.
+ * s-osinte-linux.ads: Use it.
+ * s-linux-mipsel.ads: New.
+ * system-linux-mips64el.ads: New.
+ * gcc-interface/Makefile.in: Multilib handling for mipsel-linux and
+ mips64el-linux.
+
2009-05-06 Arnaud Charlet <charlet@adacore.com>
* exp_ch5.adb, exp_util.adb, exp_attr.adb, sem_util.adb, sem_res.adb,
@@ -70,7 +316,7 @@
GPS.
* sinput.ads, sinput.adb (Expr_First_Char): New function
- (Expr_Last_Char): New function
+ (Expr_Last_Char): New function
2009-05-06 Sergey Rybin <rybin@adacore.com>
@@ -1090,9 +1336,9 @@
* prj-proc.adb, prj.adb, prj.ads, prj-nmsc.adb, prj-env.adb
(Source_Iterator): new type.
- This removes the need for having the sources on three different
- lists at the project tree, project and language level. They are now
- on a single list.
+ This removes the need for having the sources on three different
+ lists at the project tree, project and language level. They are now
+ on a single list.
2009-04-24 Emmanuel Briot <briot@adacore.com>
@@ -1121,7 +1367,7 @@
efficient.
2009-04-24 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
- Thomas Quinot <quinot@adacore.com>
+ Thomas Quinot <quinot@adacore.com>
* fe.h (Set_Identifier_Casing): Add const to second parameter.
* gcc-interface/misc.c (internal_error_function): Make copy of return
@@ -5299,17 +5545,17 @@
2009-04-09 Robert Dewar <dewar@adacore.com>
- * checks.adb:
- (Insert_Valid_Check): Avoid unnecessary generation of junk declaration
- when no invalid values exist, Avoid duplicate read of atomic variable.
+ * checks.adb:
+ (Insert_Valid_Check): Avoid unnecessary generation of junk declaration
+ when no invalid values exist, Avoid duplicate read of atomic variable.
- * cstand.adb (Build_Signed_Integer_Type): Set Is_Known_Valid
- (Standard_Unsigned): Set Is_Known_Valid
+ * cstand.adb (Build_Signed_Integer_Type): Set Is_Known_Valid
+ (Standard_Unsigned): Set Is_Known_Valid
- * sem_ch3.adb (Analyze_Subtype_Declaration): Copy Is_Known_Valid on
+ * sem_ch3.adb (Analyze_Subtype_Declaration): Copy Is_Known_Valid on
subtype declaration if no constraint.
- (Set_Modular_Size): Set Is_Known_Valid if appropriate
- (Build_Derived_Numeric_Type): Copy Is_Known_Valid if no constraint
+ (Set_Modular_Size): Set Is_Known_Valid if appropriate
+ (Build_Derived_Numeric_Type): Copy Is_Known_Valid if no constraint
2009-04-09 Robert Dewar <dewar@adacore.com>
@@ -6279,7 +6525,7 @@
PR ada/39221
* a-teioed.adb (Expand): Fix Result overflow.
-2009-02-25 Laurent GUERBY <laurent@guerby.net>
+2009-02-25 Laurent GUERBY <laurent@guerby.net>
* gcc-interface/Makefile.in: Fix multilib handling for
sparc64-linux.
diff --git a/gcc/ada/adaint.c b/gcc/ada/adaint.c
index 1f5e1546796..dd36bac4cb6 100644
--- a/gcc/ada/adaint.c
+++ b/gcc/ada/adaint.c
@@ -775,8 +775,16 @@ __gnat_fopen (char *path, char *mode, int encoding ATTRIBUTE_UNUSED)
#elif defined (VMS)
return decc$fopen (path, mode);
#else
+
+#if defined (__GLIBC__) || defined (sun)
+ /* GLIBC and Solaris provides fopen64, which allows IO on files
+ larger than 2GB on systems that support it. */
+ return fopen64 (path, mode);
+#else
return fopen (path, mode);
#endif
+
+#endif
}
FILE *
diff --git a/gcc/ada/back_end.adb b/gcc/ada/back_end.adb
index baf3ffda37f..a15d9ecfc16 100644
--- a/gcc/ada/back_end.adb
+++ b/gcc/ada/back_end.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2008, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2009, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -158,12 +158,10 @@ package body Back_End is
-- entire string should consist of valid switch characters, except that
-- an optional terminating NUL character is allowed.
--
- -- Back end switches have already been checked and processed by GCC
- -- in toplev.c, so no errors can occur and control will always return.
- -- The switches must still be scanned to skip the arguments of the
- -- "-o" or the (undocumented) "-dumpbase" switch, by incrementing
- -- the Next_Arg variable. The "-dumpbase" switch is used to set the
- -- basename for GCC dumpfiles.
+ -- Back end switches have already been checked and processed by GCC in
+ -- toplev.c, so no errors can occur and control will always return. The
+ -- switches must still be scanned to skip "-o" or internal GCC switches
+ -- with their argument.
-------------
-- Len_Arg --
@@ -186,21 +184,13 @@ package body Back_End is
procedure Scan_Back_End_Switches (Switch_Chars : String) is
First : constant Positive := Switch_Chars'First + 1;
- Last : Natural := Switch_Chars'Last;
+ Last : constant Natural := Switch_Last (Switch_Chars);
begin
- if Last >= First
- and then Switch_Chars (Last) = ASCII.NUL
- then
- Last := Last - 1;
- end if;
-
- -- For switches -o, -dumpbase, --param, skip following argument and
- -- do not store either the switch or the following argument.
+ -- Skip -o or internal GCC switches together with their argument
- if Switch_Chars (First .. Last) = "o" or else
- Switch_Chars (First .. Last) = "dumpbase" or else
- Switch_Chars (First .. Last) = "-param"
+ if Switch_Chars (First .. Last) = "o"
+ or else Is_Internal_GCC_Switch (Switch_Chars)
then
Next_Arg := Next_Arg + 1;
diff --git a/gcc/ada/freeze.adb b/gcc/ada/freeze.adb
index 1f91db98388..079b39cd0ec 100644
--- a/gcc/ada/freeze.adb
+++ b/gcc/ada/freeze.adb
@@ -2205,9 +2205,9 @@ package body Freeze is
declare
Sz : constant Node_Id := Size_Clause (Rec);
begin
- Error_Msg_NE
+ Error_Msg_NE -- CODEFIX
("size given for& too small", Sz, Rec);
- Error_Msg_N
+ Error_Msg_N -- CODEFIX
("\use explicit pragma Pack "
& "or use pragma Implicit_Packing", Sz);
end;
diff --git a/gcc/ada/g-cgi.adb b/gcc/ada/g-cgi.adb
index 34f3e4f3266..b1b6789e4fb 100644
--- a/gcc/ada/g-cgi.adb
+++ b/gcc/ada/g-cgi.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2001-2006, AdaCore --
+-- Copyright (C) 2001-2009, AdaCore --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -123,6 +123,11 @@ package body GNAT.CGI is
(Natural'Value ("16#" & S (K + 1 .. K + 2) & '#'));
K := K + 3;
+ elsif S (K) = '+' then
+ -- + sign is decoded as a space
+ Result (J) := ' ';
+ K := K + 1;
+
else
Result (J) := S (K);
K := K + 1;
diff --git a/gcc/ada/g-cgi.ads b/gcc/ada/g-cgi.ads
index eb7d70cbb29..b444b586edd 100644
--- a/gcc/ada/g-cgi.ads
+++ b/gcc/ada/g-cgi.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 2000-2006, AdaCore --
+-- Copyright (C) 2000-2009, AdaCore --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -78,7 +78,7 @@
-- -- the HTML form) and that one of them is called "client_name".
-- if CGI.Argument_Count = 2
--- and the CGI.Key_Exists ("client_name")
+-- and then CGI.Key_Exists ("client_name")
-- then
-- Add_Client_To_Database (CGI.Value ("client_name"));
-- end if;
diff --git a/gcc/ada/gcc-interface/Make-lang.in b/gcc/ada/gcc-interface/Make-lang.in
index 564919d793e..83b74fa4ff2 100644
--- a/gcc/ada/gcc-interface/Make-lang.in
+++ b/gcc/ada/gcc-interface/Make-lang.in
@@ -1124,35 +1124,35 @@ ada/link.o : ada/link.c
ada/targext.o : ada/targext.c $(SYSTEM_H) coretypes.h $(TM_H)
- $(CC) -c $(ALL_CFLAGS) $(ADA_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
- $< $(OUTPUT_OPTION)
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ADA_CFLAGS) \
+ $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
-ada/cio.o : ada/cio.c $(CONFIG_H) $(SYSTEM_H) ada/adaint.h
- $(CC) -c $(ALL_CFLAGS) $(ADA_CFLAGS) \
- $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
+ada/cio.o : ada/cio.c $(CONFIG_H) $(SYSTEM_H) ada/adaint.h
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ADA_CFLAGS) \
+ $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
-ada/init.o : ada/init.c $(CONFIG_H) $(SYSTEM_H) ada/adaint.h ada/raise.h
- $(CC) -c $(ALL_CFLAGS) $(ADA_CFLAGS) \
- $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
+ada/init.o : ada/init.c $(CONFIG_H) $(SYSTEM_H) ada/adaint.h ada/raise.h
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ADA_CFLAGS) \
+ $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
ada/initialize.o : ada/initialize.c
- $(CC) -c $(ALL_CFLAGS) $(ADA_CFLAGS) \
- $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ADA_CFLAGS) \
+ $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
-ada/raise.o : ada/raise.c $(CONFIG_H) $(SYSTEM_H) ada/adaint.h ada/raise.h
- $(CC) -c $(ALL_CFLAGS) $(ADA_CFLAGS) \
+ada/raise.o : ada/raise.c $(CONFIG_H) $(SYSTEM_H) ada/adaint.h ada/raise.h
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ADA_CFLAGS) \
$(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
# Need to keep the frame pointer to unwind the stack properly for some targets.
ada/tracebak.o : ada/tracebak.c $(CONFIG_H) $(SYSTEM_H)
- $(CC) -c $(ALL_CFLAGS) $(ADA_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
- -fno-omit-frame-pointer $< $(OUTPUT_OPTION)
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ADA_CFLAGS) $(ALL_CPPFLAGS) \
+ $(INCLUDES) -fno-omit-frame-pointer $< $(OUTPUT_OPTION)
ada/cuintp.o : ada/gcc-interface/cuintp.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(TREE_H) ada/gcc-interface/ada.h ada/types.h ada/uintp.h \
ada/atree.h ada/elists.h ada/nlists.h ada/stringt.h ada/fe.h $(ADA_TREE_H) \
ada/gcc-interface/gigi.h
- $(CC) -c $(ALL_CFLAGS) -I.. $(ALL_CPPFLAGS) $< -o $@
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) -I.. $(ALL_CPPFLAGS) $< -o $@
ada/decl.o : ada/gcc-interface/decl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(TREE_H) $(FLAGS_H) toplev.h $(TARGET_H) $(EXPR_H) \
@@ -1160,7 +1160,7 @@ ada/decl.o : ada/gcc-interface/decl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
ada/elists.h ada/namet.h ada/nlists.h ada/repinfo.h ada/snames.h \
ada/stringt.h ada/uintp.h ada/fe.h ada/sinfo.h ada/einfo.h $(ADA_TREE_H) \
ada/gcc-interface/gigi.h gt-ada-decl.h
- $(CC) -c $(ALL_CFLAGS) -I.. $(ALL_CPPFLAGS) $< -o $@
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) -I.. $(ALL_CPPFLAGS) $< -o $@
ada/misc.o : ada/gcc-interface/misc.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(TREE_H) $(DIAGNOSTIC_H) $(TARGET_H) $(EXPR_H) libfuncs.h \
@@ -1169,14 +1169,14 @@ ada/misc.o : ada/gcc-interface/misc.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
ada/gcc-interface/ada.h ada/adadecode.h ada/types.h ada/atree.h \
ada/elists.h ada/namet.h ada/nlists.h ada/stringt.h ada/uintp.h ada/fe.h \
ada/sinfo.h ada/einfo.h $(ADA_TREE_H) ada/gcc-interface/gigi.h
- $(CC) -c $(ALL_CFLAGS) -I.. $(ALL_CPPFLAGS) $< -o $@
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) -I.. $(ALL_CPPFLAGS) $< -o $@
ada/targtyps.o : ada/gcc-interface/targtyps.c $(CONFIG_H) $(SYSTEM_H) \
coretypes.h $(TM_H) $(TREE_H) ada/gcc-interface/ada.h ada/types.h \
ada/atree.h ada/elists.h ada/namet.h ada/nlists.h ada/snames.h \
ada/stringt.h ada/uintp.h ada/urealp.h ada/fe.h ada/sinfo.h ada/einfo.h \
$(ADA_TREE_H) ada/gcc-interface/gigi.h
- $(CC) -c $(ALL_CFLAGS) -I.. $(ALL_CPPFLAGS) $< -o $@
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) -I.. $(ALL_CPPFLAGS) $< -o $@
ada/trans.o : ada/gcc-interface/trans.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(TREE_H) $(FLAGS_H) $(EXPR_H) output.h tree-iterator.h \
@@ -1184,7 +1184,7 @@ ada/trans.o : ada/gcc-interface/trans.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
ada/atree.h ada/elists.h ada/namet.h ada/nlists.h ada/snames.h \
ada/stringt.h ada/uintp.h ada/urealp.h ada/fe.h ada/sinfo.h ada/einfo.h \
$(ADA_TREE_H) ada/gcc-interface/gigi.h gt-ada-trans.h
- $(CC) -c $(ALL_CFLAGS) -I.. $(ALL_CPPFLAGS) $< -o $@
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) -I.. $(ALL_CPPFLAGS) $< -o $@
ada/utils.o : ada/gcc-interface/utils.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(TREE_H) $(FLAGS_H) toplev.h $(RTL_H) output.h debug.h convert.h \
@@ -1193,14 +1193,14 @@ ada/utils.o : ada/gcc-interface/utils.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
ada/gcc-interface/ada.h ada/types.h ada/atree.h ada/elists.h ada/namet.h \
ada/nlists.h ada/stringt.h ada/uintp.h ada/fe.h ada/sinfo.h ada/einfo.h \
$(ADA_TREE_H) ada/gcc-interface/gigi.h gt-ada-utils.h gtype-ada.h
- $(CC) -c $(ALL_CFLAGS) -I.. $(ALL_CPPFLAGS) $< -o $@
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) -I.. $(ALL_CPPFLAGS) $< -o $@
ada/utils2.o : ada/gcc-interface/utils2.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(TREE_H) $(FLAGS_H) output.h $(TREE_INLINE_H) \
ada/gcc-interface/ada.h ada/types.h ada/atree.h ada/elists.h ada/namet.h \
ada/nlists.h ada/snames.h ada/stringt.h ada/uintp.h ada/fe.h ada/sinfo.h \
ada/einfo.h $(ADA_TREE_H) ada/gcc-interface/gigi.h
- $(CC) -c $(ALL_CFLAGS) -I.. $(ALL_CPPFLAGS) $< -o $@
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) -I.. $(ALL_CPPFLAGS) $< -o $@
#
# DO NOT PUT SPECIAL RULES BELOW, THIS SECTION IS UPDATED AUTOMATICALLY
diff --git a/gcc/ada/gcc-interface/Makefile.in b/gcc/ada/gcc-interface/Makefile.in
index 04553d4b2ce..ef42fa3bea9 100644
--- a/gcc/ada/gcc-interface/Makefile.in
+++ b/gcc/ada/gcc-interface/Makefile.in
@@ -92,6 +92,9 @@ RANLIB = @RANLIB@
RANLIB_FLAGS = @ranlib_flags@
AWK = @AWK@
+COMPILER = $(CC)
+COMPILER_FLAGS = $(CFLAGS)
+
SHELL = @SHELL@
PWD_COMMAND = $${PWDCMD-pwd}
# How to copy preserving the date
@@ -218,6 +221,9 @@ ALL_CFLAGS = $(INTERNAL_CFLAGS) $(T_CFLAGS) $(LOOSE_CFLAGS)
# Likewise.
ALL_CPPFLAGS = $(CPPFLAGS)
+# Used with $(COMPILER).
+ALL_COMPILERFLAGS = $(ALL_CFLAGS)
+
# This is where we get libiberty.a from.
LIBIBERTY = ../../libiberty/libiberty.a
@@ -253,8 +259,8 @@ ADA_INCLUDES_FOR_SUBDIR = -I. -I$(fsrcdir)/ada
$(CC) -c -x assembler $< $(OUTPUT_OPTION)
.c.o:
- $(CC) -c $(ALL_CFLAGS) $(ADA_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< \
- $(OUTPUT_OPTION)
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ADA_CFLAGS) $(ALL_CPPFLAGS) \
+ $(INCLUDES) $< $(OUTPUT_OPTION)
.adb.o:
$(CC) -c $(ALL_ADAFLAGS) $(ADA_INCLUDES) $< $(OUTPUT_OPTION)
@@ -2529,33 +2535,33 @@ raise.o : raise.c raise.h
vx_stack_info.o : vx_stack_info.c
cio.o : cio.c
- $(CC) -c $(ALL_CFLAGS) $(ADA_CFLAGS) \
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ADA_CFLAGS) \
$(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
init.o : init.c adaint.h raise.h
- $(CC) -c $(ALL_CFLAGS) $(ADA_CFLAGS) \
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ADA_CFLAGS) \
$(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
initialize.o : initialize.c raise.h
- $(CC) -c $(ALL_CFLAGS) $(ADA_CFLAGS) \
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ADA_CFLAGS) \
$(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
targext.o : targext.c
- $(CC) -c $(ALL_CFLAGS) $(ADA_CFLAGS) \
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ADA_CFLAGS) \
$(ALL_CPPFLAGS) $(INCLUDES_FOR_SUBDIR) \
$< $(OUTPUT_OPTION)
# No optimization to compile this file as optimizations (-O1 or above) breaks
# the SEH handling on Windows. The reasons are not clear.
seh_init.o : seh_init.c raise.h
- $(CC) -c $(ALL_CFLAGS) $(ADA_CFLAGS) -O0 \
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ADA_CFLAGS) -O0 \
$(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
# Need to keep the frame pointer in this file to pop the stack properly on
# some targets.
tracebak.o : tracebak.c tb-alvms.c tb-alvxw.c tb-gcc.c
- $(CC) -c $(ALL_CFLAGS) $(ADA_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
- -fno-omit-frame-pointer $< $(OUTPUT_OPTION)
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ADA_CFLAGS) $(ALL_CPPFLAGS) \
+ $(INCLUDES) -fno-omit-frame-pointer $< $(OUTPUT_OPTION)
# In GNU Make, ignore whether `stage*' exists.
.PHONY: stage1 stage2 stage3 stage4 clean realclean TAGS bootstrap
diff --git a/gcc/ada/gcc-interface/ada-tree.h b/gcc/ada/gcc-interface/ada-tree.h
index 19c9fa51f2b..38bc8620815 100644
--- a/gcc/ada/gcc-interface/ada-tree.h
+++ b/gcc/ada/gcc-interface/ada-tree.h
@@ -167,9 +167,87 @@ struct GTY(()) lang_decl { tree t; };
mechanism refer to the routine gnat_to_gnu_entity. */
#define TYPE_CI_CO_LIST(NODE) TYPE_LANG_SLOT_1 (FUNCTION_TYPE_CHECK (NODE))
-/* For integral types, this is the RM size of the type. */
+/* For numerical types, this is the GCC lower bound of the type. The GCC
+ type system is based on the invariant that an object X of a given type
+ cannot hold at run time a value smaller than its lower bound; otherwise
+ the behavior is undefined. The optimizer takes advantage of this and
+ considers that the assertion X >= LB is always true. */
+#define TYPE_GCC_MIN_VALUE(NODE) (NUMERICAL_TYPE_CHECK (NODE)->type.minval)
+
+/* For numerical types, this is the GCC upper bound of the type. The GCC
+ type system is based on the invariant that an object X of a given type
+ cannot hold at run time a value larger than its upper bound; otherwise
+ the behavior is undefined. The optimizer takes advantage of this and
+ considers that the assertion X <= UB is always true. */
+#define TYPE_GCC_MAX_VALUE(NODE) (NUMERICAL_TYPE_CHECK (NODE)->type.maxval)
+
+/* For numerical types, this holds various RM-defined values. */
+#define TYPE_RM_VALUES(NODE) TYPE_LANG_SLOT_1 (NUMERICAL_TYPE_CHECK (NODE))
+
+/* For numerical types, this is the RM size of the type, aka its precision.
+ There is a discrepancy between what is called precision here (and more
+ generally throughout gigi) and what is called precision in the GCC type
+ system: in the former case it's TYPE_RM_SIZE whereas it's TYPE_PRECISION
+ in the latter case. They are not identical because of the need to support
+ invalid values.
+
+ These values can be outside the range of values allowed by the RM size
+ but they must nevertheless be valid in the GCC type system, otherwise
+ the optimizer can pretend that they simply don't exist. Therefore they
+ must be within the range of values allowed by the precision in the GCC
+ sense, hence TYPE_PRECISION be set to the Esize, not the RM size. */
#define TYPE_RM_SIZE(NODE) \
- TYPE_LANG_SLOT_1 (TREE_CHECK3 (NODE, ENUMERAL_TYPE, BOOLEAN_TYPE, INTEGER_TYPE))
+ (TYPE_RM_VALUES (NODE) ? TREE_VEC_ELT (TYPE_RM_VALUES (NODE), 0) : NULL_TREE)
+#define SET_TYPE_RM_SIZE(NODE, X) \
+ TREE_VEC_ELT ((TYPE_RM_VALUES (NODE) \
+ = (TYPE_RM_VALUES (NODE) \
+ ? TYPE_RM_VALUES (NODE) : make_tree_vec (3))), 0) = (X)
+
+/* For numerical types, this is the RM lower bound of the type. There is
+ again a discrepancy between this lower bound and the GCC lower bound,
+ again because of the need to support invalid values.
+
+ These values can be outside the range of values allowed by the RM lower
+ bound but they must nevertheless be valid in the GCC type system, otherwise
+ the optimizer can pretend that they simply don't exist. Therefore they
+ must be within the range of values allowed by the lower bound in the GCC
+ sense, hence the GCC lower bound be set to that of the base type. */
+#define TYPE_RM_MIN_VALUE(NODE) \
+ (TYPE_RM_VALUES (NODE) ? TREE_VEC_ELT (TYPE_RM_VALUES (NODE), 1) : NULL_TREE)
+#define SET_TYPE_RM_MIN_VALUE(NODE, X) \
+ TREE_VEC_ELT ((TYPE_RM_VALUES (NODE) \
+ = (TYPE_RM_VALUES (NODE) \
+ ? TYPE_RM_VALUES (NODE) : make_tree_vec (3))), 1) = (X)
+
+/* For numerical types, this is the RM upper bound of the type. There is
+ again a discrepancy between this upper bound and the GCC upper bound,
+ again because of the need to support invalid values.
+
+ These values can be outside the range of values allowed by the RM upper
+ bound but they must nevertheless be valid in the GCC type system, otherwise
+ the optimizer can pretend that they simply don't exist. Therefore they
+ must be within the range of values allowed by the upper bound in the GCC
+ sense, hence the GCC upper bound be set to that of the base type. */
+#define TYPE_RM_MAX_VALUE(NODE) \
+ (TYPE_RM_VALUES (NODE) ? TREE_VEC_ELT (TYPE_RM_VALUES (NODE), 2) : NULL_TREE)
+#define SET_TYPE_RM_MAX_VALUE(NODE, X) \
+ TREE_VEC_ELT ((TYPE_RM_VALUES (NODE) \
+ = (TYPE_RM_VALUES (NODE) \
+ ? TYPE_RM_VALUES (NODE) : make_tree_vec (3))), 2) = (X)
+
+/* For numerical types, this is the lower bound of the type, i.e. the RM lower
+ bound for language-defined types and the GCC lower bound for others. */
+#undef TYPE_MIN_VALUE
+#define TYPE_MIN_VALUE(NODE) \
+ (TYPE_RM_MIN_VALUE (NODE) \
+ ? TYPE_RM_MIN_VALUE (NODE) : TYPE_GCC_MIN_VALUE (NODE))
+
+/* For numerical types, this is the upper bound of the type, i.e. the RM upper
+ bound for language-defined types and the GCC upper bound for others. */
+#undef TYPE_MAX_VALUE
+#define TYPE_MAX_VALUE(NODE) \
+ (TYPE_RM_MAX_VALUE (NODE) \
+ ? TYPE_RM_MAX_VALUE (NODE) : TYPE_GCC_MAX_VALUE (NODE))
/* In an UNCONSTRAINED_ARRAY_TYPE, points to the record containing both
the template and object.
diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c
index d55d56b61f6..63ade27c5e9 100644
--- a/gcc/ada/gcc-interface/decl.c
+++ b/gcc/ada/gcc-interface/decl.c
@@ -121,15 +121,14 @@ enum alias_set_op
static void relate_alias_sets (tree, tree, enum alias_set_op);
-static tree substitution_list (Entity_Id, Entity_Id, tree, bool);
+static tree build_subst_list (Entity_Id, Entity_Id, bool);
static bool allocatable_size_p (tree, bool);
static void prepend_one_attribute_to (struct attrib **,
enum attr_type, tree, tree, Node_Id);
static void prepend_attributes (Entity_Id, struct attrib **);
static tree elaborate_expression (Node_Id, Entity_Id, tree, bool, bool, bool);
static bool is_variable_size (tree);
-static tree elaborate_expression_1 (Node_Id, Entity_Id, tree, tree,
- bool, bool);
+static tree elaborate_expression_1 (tree, Entity_Id, tree, bool, bool);
static tree make_packable_type (tree, bool);
static tree gnat_to_gnu_field (Entity_Id, tree, int, bool);
static tree gnat_to_gnu_param (Entity_Id, Mechanism_Type, Entity_Id, bool,
@@ -575,7 +574,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
if (Present (Debug_Renaming_Link (gnat_entity)))
{
rtx addr;
- gnu_decl = build_decl (VAR_DECL, gnu_entity_name, gnu_type);
+ gnu_decl = build_decl (input_location,
+ VAR_DECL, gnu_entity_name, gnu_type);
/* The (MEM (CONST (0))) pattern is prescribed by STABS. */
if (global_bindings_p ())
addr = gen_rtx_CONST (VOIDmode, const0_rtx);
@@ -609,17 +609,22 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
return error_mark_node;
}
- /* If an alignment is specified, use it if valid. Note that
- exceptions are objects but don't have alignments. We must do this
- before we validate the size, since the alignment can affect the
- size. */
+ /* If an alignment is specified, use it if valid. Note that exceptions
+ are objects but don't have an alignment. We must do this before we
+ validate the size, since the alignment can affect the size. */
if (kind != E_Exception && Known_Alignment (gnat_entity))
{
gcc_assert (Present (Alignment (gnat_entity)));
align = validate_alignment (Alignment (gnat_entity), gnat_entity,
TYPE_ALIGN (gnu_type));
- gnu_type = maybe_pad_type (gnu_type, NULL_TREE, align, gnat_entity,
- "PAD", false, definition, true);
+ /* No point in changing the type if there is an address clause
+ as the final type of the object will be a reference type. */
+ if (Present (Address_Clause (gnat_entity)))
+ align = 0;
+ else
+ gnu_type
+ = maybe_pad_type (gnu_type, NULL_TREE, align, gnat_entity,
+ "PAD", false, definition, true);
}
/* If we are defining the object, see if it has a Size value and
@@ -1504,7 +1509,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
&& !tree_int_cst_equal (gnu_high, TYPE_MAX_VALUE (gnu_type)))
{
tree gnu_subtype = make_unsigned_type (esize);
- TYPE_MAX_VALUE (gnu_subtype) = gnu_high;
+ SET_TYPE_RM_MAX_VALUE (gnu_subtype, gnu_high);
TREE_TYPE (gnu_subtype) = gnu_type;
TYPE_EXTRA_SUBTYPE_P (gnu_subtype) = 1;
TYPE_NAME (gnu_type) = create_concat_name (gnat_entity, "UMT");
@@ -1520,7 +1525,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
case E_Decimal_Fixed_Point_Subtype:
/* For integral subtypes, we make a new INTEGER_TYPE. Note that we do
- not want to call build_range_type since we would like each subtype
+ not want to call create_range_type since we would like each subtype
node to be distinct. ??? Historically this was in preparation for
when memory aliasing is implemented, but that's obsolete now given
the call to relate_alias_sets below.
@@ -1540,39 +1545,37 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
|| !Compile_Time_Known_Value (Type_High_Bound (gnat_entity))))
gnat_to_gnu_entity (Ancestor_Subtype (gnat_entity), gnu_expr, 0);
- gnu_type = make_node (INTEGER_TYPE);
- TREE_TYPE (gnu_type) = get_unpadded_type (Etype (gnat_entity));
-
- /* This should be an unsigned type if the base type is unsigned or
- if the lower bound is constant and non-negative or if the type
- is biased. */
- TYPE_UNSIGNED (gnu_type) = (Is_Unsigned_Type (Etype (gnat_entity))
- || Is_Unsigned_Type (gnat_entity)
- || Has_Biased_Representation (gnat_entity));
-
- /* Set the precision to the Esize except for bit-packed arrays and
- subtypes of Standard.Boolean. */
+ /* Set the precision to the Esize except for bit-packed arrays. */
if (Is_Packed_Array_Type (gnat_entity)
&& Is_Bit_Packed_Array (Original_Array_Type (gnat_entity)))
esize = UI_To_Int (RM_Size (gnat_entity));
- else if (Is_Boolean_Type (gnat_entity))
- esize = 1;
-
- TYPE_PRECISION (gnu_type) = esize;
- TYPE_MIN_VALUE (gnu_type)
- = convert (TREE_TYPE (gnu_type),
- elaborate_expression (Type_Low_Bound (gnat_entity),
- gnat_entity,
- get_identifier ("L"), definition, 1,
- Needs_Debug_Info (gnat_entity)));
+ /* This should be an unsigned type if the base type is unsigned or
+ if the lower bound is constant and non-negative or if the type
+ is biased. */
+ if (Is_Unsigned_Type (Etype (gnat_entity))
+ || Is_Unsigned_Type (gnat_entity)
+ || Has_Biased_Representation (gnat_entity))
+ gnu_type = make_unsigned_type (esize);
+ else
+ gnu_type = make_signed_type (esize);
+ TREE_TYPE (gnu_type) = get_unpadded_type (Etype (gnat_entity));
- TYPE_MAX_VALUE (gnu_type)
- = convert (TREE_TYPE (gnu_type),
- elaborate_expression (Type_High_Bound (gnat_entity),
- gnat_entity,
- get_identifier ("U"), definition, 1,
- Needs_Debug_Info (gnat_entity)));
+ SET_TYPE_RM_MIN_VALUE
+ (gnu_type,
+ convert (TREE_TYPE (gnu_type),
+ elaborate_expression (Type_Low_Bound (gnat_entity),
+ gnat_entity, get_identifier ("L"),
+ definition, true,
+ Needs_Debug_Info (gnat_entity))));
+
+ SET_TYPE_RM_MAX_VALUE
+ (gnu_type,
+ convert (TREE_TYPE (gnu_type),
+ elaborate_expression (Type_High_Bound (gnat_entity),
+ gnat_entity, get_identifier ("U"),
+ definition, true,
+ Needs_Debug_Info (gnat_entity))));
/* One of the above calls might have caused us to be elaborated,
so don't blow up if so. */
@@ -1585,8 +1588,6 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
TYPE_BIASED_REPRESENTATION_P (gnu_type)
= Has_Biased_Representation (gnat_entity);
- layout_type (gnu_type);
-
/* Attach the TYPE_STUB_DECL in case we have a parallel type. */
TYPE_STUB_DECL (gnu_type)
= create_type_stub_decl (gnu_entity_name, gnu_type);
@@ -1617,8 +1618,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
tree gnu_field_type, gnu_field;
/* Set the RM size before wrapping up the type. */
- TYPE_RM_SIZE (gnu_type)
- = UI_To_gnu (RM_Size (gnat_entity), bitsizetype);
+ SET_TYPE_RM_SIZE (gnu_type,
+ UI_To_gnu (RM_Size (gnat_entity), bitsizetype));
TYPE_PACKED_ARRAY_TYPE_P (gnu_type) = 1;
gnu_field_type = gnu_type;
@@ -1670,8 +1671,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
tree gnu_field_type, gnu_field;
/* Set the RM size before wrapping up the type. */
- TYPE_RM_SIZE (gnu_type)
- = UI_To_gnu (RM_Size (gnat_entity), bitsizetype);
+ SET_TYPE_RM_SIZE (gnu_type,
+ UI_To_gnu (RM_Size (gnat_entity), bitsizetype));
gnu_field_type = gnu_type;
gnu_type = make_node (RECORD_TYPE);
@@ -1742,20 +1743,27 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
gnu_type = make_node (REAL_TYPE);
TREE_TYPE (gnu_type) = get_unpadded_type (Etype (gnat_entity));
TYPE_PRECISION (gnu_type) = fp_size_to_prec (esize);
+ TYPE_GCC_MIN_VALUE (gnu_type)
+ = TYPE_GCC_MIN_VALUE (TREE_TYPE (gnu_type));
+ TYPE_GCC_MAX_VALUE (gnu_type)
+ = TYPE_GCC_MAX_VALUE (TREE_TYPE (gnu_type));
+ layout_type (gnu_type);
- TYPE_MIN_VALUE (gnu_type)
- = convert (TREE_TYPE (gnu_type),
- elaborate_expression (Type_Low_Bound (gnat_entity),
- gnat_entity, get_identifier ("L"),
- definition, 1,
- Needs_Debug_Info (gnat_entity)));
-
- TYPE_MAX_VALUE (gnu_type)
- = convert (TREE_TYPE (gnu_type),
- elaborate_expression (Type_High_Bound (gnat_entity),
- gnat_entity, get_identifier ("U"),
- definition, 1,
- Needs_Debug_Info (gnat_entity)));
+ SET_TYPE_RM_MIN_VALUE
+ (gnu_type,
+ convert (TREE_TYPE (gnu_type),
+ elaborate_expression (Type_Low_Bound (gnat_entity),
+ gnat_entity, get_identifier ("L"),
+ definition, true,
+ Needs_Debug_Info (gnat_entity))));
+
+ SET_TYPE_RM_MAX_VALUE
+ (gnu_type,
+ convert (TREE_TYPE (gnu_type),
+ elaborate_expression (Type_High_Bound (gnat_entity),
+ gnat_entity, get_identifier ("U"),
+ definition, true,
+ Needs_Debug_Info (gnat_entity))));
/* One of the above calls might have caused us to be elaborated,
so don't blow up if so. */
@@ -1765,8 +1773,6 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
break;
}
- layout_type (gnu_type);
-
/* Inherit our alias set from what we're a subtype of, as for
integer subtypes. */
relate_alias_sets (gnu_type, TREE_TYPE (gnu_type), ALIAS_SET_COPY);
@@ -1815,7 +1821,10 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
gnu_type = make_node (UNCONSTRAINED_ARRAY_TYPE);
if (!definition)
- defer_incomplete_level++, this_deferred = true;
+ {
+ defer_incomplete_level++;
+ this_deferred = true;
+ }
/* Build the fat pointer type. Use a "void *" object instead of
a pointer to the array type since we don't have the array type
@@ -1900,8 +1909,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
gnu_index_types[index]
= create_index_type (convert (sizetype, gnu_min),
convert (sizetype, gnu_max),
- build_range_type (gnu_ind_subtype,
- gnu_min, gnu_max),
+ create_range_type (gnu_ind_subtype,
+ gnu_min, gnu_max),
gnat_entity);
/* Update the maximum size of the array, in elements. */
gnu_max_size
@@ -2434,9 +2443,9 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
tree eltype = TREE_TYPE (gnu_arr_type);
TYPE_SIZE (gnu_arr_type)
- = elaborate_expression_1 (gnat_entity, gnat_entity,
- TYPE_SIZE (gnu_arr_type),
- gnu_str_name, definition, 0);
+ = elaborate_expression_1 (TYPE_SIZE (gnu_arr_type),
+ gnat_entity, gnu_str_name,
+ definition, false);
/* ??? For now, store the size as a multiple of the
alignment of the element type in bytes so that we
@@ -2445,12 +2454,12 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
= build_binary_op
(MULT_EXPR, sizetype,
elaborate_expression_1
- (gnat_entity, gnat_entity,
- build_binary_op (EXACT_DIV_EXPR, sizetype,
+ (build_binary_op (EXACT_DIV_EXPR, sizetype,
TYPE_SIZE_UNIT (gnu_arr_type),
size_int (TYPE_ALIGN (eltype)
/ BITS_PER_UNIT)),
- concat_name (gnu_str_name, "A_U"), definition, 0),
+ gnat_entity, concat_name (gnu_str_name, "A_U"),
+ definition, false),
size_int (TYPE_ALIGN (eltype) / BITS_PER_UNIT));
/* ??? create_type_decl is not invoked on the inner types so
@@ -2586,19 +2595,14 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
subtype if necessary. */
if (TYPE_MODULAR_P (gnu_inner_type))
{
- tree gnu_subtype = make_node (INTEGER_TYPE);
+ tree gnu_subtype
+ = make_unsigned_type (TYPE_PRECISION (gnu_inner_type));
TREE_TYPE (gnu_subtype) = gnu_inner_type;
TYPE_EXTRA_SUBTYPE_P (gnu_subtype) = 1;
-
- TYPE_UNSIGNED (gnu_subtype) = 1;
- TYPE_PRECISION (gnu_subtype)
- = TYPE_PRECISION (gnu_inner_type);
- TYPE_MIN_VALUE (gnu_subtype)
- = TYPE_MIN_VALUE (gnu_inner_type);
- TYPE_MAX_VALUE (gnu_subtype)
- = TYPE_MAX_VALUE (gnu_inner_type);
- layout_type (gnu_subtype);
-
+ SET_TYPE_RM_MIN_VALUE (gnu_subtype,
+ TYPE_MIN_VALUE (gnu_inner_type));
+ SET_TYPE_RM_MAX_VALUE (gnu_subtype,
+ TYPE_MAX_VALUE (gnu_inner_type));
gnu_inner_type = gnu_subtype;
}
@@ -2666,9 +2670,9 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
tree gnu_index_type
= create_index_type (convert (sizetype, gnu_lower_bound),
convert (sizetype, gnu_upper_bound),
- build_range_type (gnu_string_index_type,
- gnu_lower_bound,
- gnu_upper_bound),
+ create_range_type (gnu_string_index_type,
+ gnu_lower_bound,
+ gnu_upper_bound),
gnat_entity);
gnu_type
@@ -2724,9 +2728,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
Node_Id full_definition = Declaration_Node (gnat_entity);
Node_Id record_definition = Type_Definition (full_definition);
Entity_Id gnat_field;
- tree gnu_field;
- tree gnu_field_list = NULL_TREE;
- tree gnu_get_parent;
+ tree gnu_field, gnu_field_list = NULL_TREE, gnu_get_parent;
/* Set PACKED in keeping with gnat_to_gnu_field. */
int packed
= Is_Packed (gnat_entity)
@@ -2738,21 +2740,27 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
&& Known_Static_Esize (gnat_entity)))
? -2
: 0;
+ bool has_discr = Has_Discriminants (gnat_entity);
bool has_rep = Has_Specified_Layout (gnat_entity);
bool all_rep = has_rep;
bool is_extension
= (Is_Tagged_Type (gnat_entity)
&& Nkind (record_definition) == N_Derived_Type_Definition);
+ bool is_unchecked_union = Is_Unchecked_Union (gnat_entity);
/* See if all fields have a rep clause. Stop when we find one
that doesn't. */
- for (gnat_field = First_Entity (gnat_entity);
- Present (gnat_field) && all_rep;
- gnat_field = Next_Entity (gnat_field))
- if ((Ekind (gnat_field) == E_Component
- || Ekind (gnat_field) == E_Discriminant)
- && No (Component_Clause (gnat_field)))
- all_rep = false;
+ if (all_rep)
+ for (gnat_field = First_Entity (gnat_entity);
+ Present (gnat_field);
+ gnat_field = Next_Entity (gnat_field))
+ if ((Ekind (gnat_field) == E_Component
+ || Ekind (gnat_field) == E_Discriminant)
+ && No (Component_Clause (gnat_field)))
+ {
+ all_rep = false;
+ break;
+ }
/* If this is a record extension, go a level further to find the
record definition. Also, verify we have a Parent_Subtype. */
@@ -2773,7 +2781,10 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
TYPE_PACKED (gnu_type) = (packed != 0) || has_rep;
if (!definition)
- defer_incomplete_level++, this_deferred = true;
+ {
+ defer_incomplete_level++;
+ this_deferred = true;
+ }
/* If both a size and rep clause was specified, put the size in
the record type now so that it can get the proper mode. */
@@ -2823,11 +2834,12 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
base type of the parent subtype. */
gnu_get_parent = build3 (COMPONENT_REF, void_type_node,
build0 (PLACEHOLDER_EXPR, gnu_type),
- build_decl (FIELD_DECL, NULL_TREE,
+ build_decl (input_location,
+ FIELD_DECL, NULL_TREE,
void_type_node),
NULL_TREE);
- if (Has_Discriminants (gnat_entity))
+ if (has_discr)
for (gnat_field = First_Stored_Discriminant (gnat_entity);
Present (gnat_field);
gnat_field = Next_Stored_Discriminant (gnat_field))
@@ -2872,7 +2884,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
gnat_field = Next_Stored_Discriminant (gnat_field))
if (Present (Corresponding_Discriminant (gnat_field)))
{
- tree gnu_field = gnat_to_gnu_field_decl (gnat_field);
+ gnu_field = gnat_to_gnu_field_decl (gnat_field);
tree gnu_ref
= build3 (COMPONENT_REF, TREE_TYPE (gnu_field),
gnu_get_parent, gnu_field, NULL_TREE);
@@ -2887,48 +2899,61 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
initially built. The discriminants must reference the fields
of the parent subtype and not those of its base type for the
placeholder machinery to properly work. */
- if (Has_Discriminants (gnat_entity))
- for (gnat_field = First_Stored_Discriminant (gnat_entity);
- Present (gnat_field);
- gnat_field = Next_Stored_Discriminant (gnat_field))
- if (Present (Corresponding_Discriminant (gnat_field)))
+ if (has_discr)
+ {
+ /* The actual parent subtype is the full view. */
+ if (IN (Ekind (gnat_parent), Private_Kind))
{
- Entity_Id field = Empty;
- for (field = First_Stored_Discriminant (gnat_parent);
- Present (field);
- field = Next_Stored_Discriminant (field))
- if (same_discriminant_p (gnat_field, field))
- break;
- gcc_assert (Present (field));
- TREE_OPERAND (get_gnu_tree (gnat_field), 1)
- = gnat_to_gnu_field_decl (field);
+ if (Present (Full_View (gnat_parent)))
+ gnat_parent = Full_View (gnat_parent);
+ else
+ gnat_parent = Underlying_Full_View (gnat_parent);
}
+ for (gnat_field = First_Stored_Discriminant (gnat_entity);
+ Present (gnat_field);
+ gnat_field = Next_Stored_Discriminant (gnat_field))
+ if (Present (Corresponding_Discriminant (gnat_field)))
+ {
+ Entity_Id field = Empty;
+ for (field = First_Stored_Discriminant (gnat_parent);
+ Present (field);
+ field = Next_Stored_Discriminant (field))
+ if (same_discriminant_p (gnat_field, field))
+ break;
+ gcc_assert (Present (field));
+ TREE_OPERAND (get_gnu_tree (gnat_field), 1)
+ = gnat_to_gnu_field_decl (field);
+ }
+ }
+
/* The "get to the parent" COMPONENT_REF must be given its
proper type... */
TREE_TYPE (gnu_get_parent) = gnu_parent;
- /* ...and reference the _parent field of this record. */
- gnu_field_list
+ /* ...and reference the _Parent field of this record. */
+ gnu_field
= create_field_decl (get_identifier
(Get_Name_String (Name_uParent)),
gnu_parent, gnu_type, 0,
- has_rep ? TYPE_SIZE (gnu_parent) : 0,
- has_rep ? bitsize_zero_node : 0, 1);
- DECL_INTERNAL_P (gnu_field_list) = 1;
- TREE_OPERAND (gnu_get_parent, 1) = gnu_field_list;
+ has_rep
+ ? TYPE_SIZE (gnu_parent) : NULL_TREE,
+ has_rep
+ ? bitsize_zero_node : NULL_TREE, 1);
+ DECL_INTERNAL_P (gnu_field) = 1;
+ TREE_OPERAND (gnu_get_parent, 1) = gnu_field;
+ TYPE_FIELDS (gnu_type) = gnu_field;
}
/* Make the fields for the discriminants and put them into the record
unless it's an Unchecked_Union. */
- if (Has_Discriminants (gnat_entity))
+ if (has_discr)
for (gnat_field = First_Stored_Discriminant (gnat_entity);
Present (gnat_field);
gnat_field = Next_Stored_Discriminant (gnat_field))
{
- /* If this is a record extension and this discriminant
- is the renaming of another discriminant, we've already
- handled the discriminant above. */
+ /* If this is a record extension and this discriminant is the
+ renaming of another discriminant, we've handled it above. */
if (Present (Parent_Subtype (gnat_entity))
&& Present (Corresponding_Discriminant (gnat_field)))
continue;
@@ -2938,53 +2963,45 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
/* Make an expression using a PLACEHOLDER_EXPR from the
FIELD_DECL node just created and link that with the
- corresponding GNAT defining identifier. Then add to the
- list of fields. */
+ corresponding GNAT defining identifier. */
save_gnu_tree (gnat_field,
build3 (COMPONENT_REF, TREE_TYPE (gnu_field),
- build0 (PLACEHOLDER_EXPR,
- DECL_CONTEXT (gnu_field)),
+ build0 (PLACEHOLDER_EXPR, gnu_type),
gnu_field, NULL_TREE),
true);
- if (!Is_Unchecked_Union (gnat_entity))
+ if (!is_unchecked_union)
{
TREE_CHAIN (gnu_field) = gnu_field_list;
gnu_field_list = gnu_field;
}
}
- /* Put the discriminants into the record (backwards), so we can
- know the appropriate discriminant to use for the names of the
- variants. */
- TYPE_FIELDS (gnu_type) = gnu_field_list;
-
- /* Add the listed fields into the record and finish it up. */
+ /* Add the fields into the record type and finish it up. */
components_to_record (gnu_type, Component_List (record_definition),
gnu_field_list, packed, definition, NULL,
- false, all_rep, false,
- Is_Unchecked_Union (gnat_entity));
-
- /* We used to remove the associations of the discriminants and
- _Parent for validity checking, but we may need them if there's
- Freeze_Node for a subtype used in this record. */
- TYPE_VOLATILE (gnu_type) = Treat_As_Volatile (gnat_entity);
- TYPE_BY_REFERENCE_P (gnu_type) = Is_By_Reference_Type (gnat_entity);
+ false, all_rep, false, is_unchecked_union);
- /* If it is a tagged record force the type to BLKmode to insure
- that these objects will always be placed in memory. Do the
- same thing for limited record types. */
+ /* If it is a tagged record force the type to BLKmode to insure that
+ these objects will always be put in memory. Likewise for limited
+ record types. */
if (Is_Tagged_Type (gnat_entity) || Is_Limited_Record (gnat_entity))
SET_TYPE_MODE (gnu_type, BLKmode);
+ /* We used to remove the associations of the discriminants and _Parent
+ for validity checking but we may need them if there's a Freeze_Node
+ for a subtype used in this record. */
+ TYPE_VOLATILE (gnu_type) = Treat_As_Volatile (gnat_entity);
+
/* Fill in locations of fields. */
annotate_rep (gnat_entity, gnu_type);
- /* If there are any entities in the chain corresponding to
- components that we did not elaborate, ensure we elaborate their
- types if they are Itypes. */
+ /* If there are any entities in the chain corresponding to components
+ that we did not elaborate, ensure we elaborate their types if they
+ are Itypes. */
for (gnat_temp = First_Entity (gnat_entity);
- Present (gnat_temp); gnat_temp = Next_Entity (gnat_temp))
+ Present (gnat_temp);
+ gnat_temp = Next_Entity (gnat_temp))
if ((Ekind (gnat_temp) == E_Component
|| Ekind (gnat_temp) == E_Discriminant)
&& Is_Itype (Etype (gnat_temp))
@@ -3007,7 +3024,6 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
/* ... fall through ... */
case E_Record_Subtype:
-
/* If Cloned_Subtype is Present it means this record subtype has
identical layout to that type or subtype and we should use
that GCC type for this one. The front end guarantees that
@@ -3017,72 +3033,58 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
gnu_decl = gnat_to_gnu_entity (Cloned_Subtype (gnat_entity),
NULL_TREE, 0);
maybe_present = true;
+ break;
}
/* Otherwise, first ensure the base type is elaborated. Then, if we are
- changing the type, make a new type with each field having the
- type of the field in the new subtype but having the position
- computed by transforming every discriminant reference according
- to the constraints. We don't see any difference between
- private and nonprivate type here since derivations from types should
- have been deferred until the completion of the private type. */
+ changing the type, make a new type with each field having the type of
+ the field in the new subtype but the position computed by transforming
+ every discriminant reference according to the constraints. We don't
+ see any difference between private and non-private type here since
+ derivations from types should have been deferred until the completion
+ of the private type. */
else
{
Entity_Id gnat_base_type = Implementation_Base_Type (gnat_entity);
tree gnu_base_type;
- tree gnu_orig_type;
if (!definition)
- defer_incomplete_level++, this_deferred = true;
+ {
+ defer_incomplete_level++;
+ this_deferred = true;
+ }
- /* Get the base type initially for its alignment and sizes. But
- if it is a padded type, we do all the other work with the
- unpadded type. */
gnu_base_type = gnat_to_gnu_type (gnat_base_type);
- if (TREE_CODE (gnu_base_type) == RECORD_TYPE
- && TYPE_IS_PADDING_P (gnu_base_type))
- gnu_type = gnu_orig_type = TREE_TYPE (TYPE_FIELDS (gnu_base_type));
- else
- gnu_type = gnu_orig_type = gnu_base_type;
-
if (present_gnu_tree (gnat_entity))
{
maybe_present = true;
break;
}
- /* When the type has discriminants, and these discriminants
- affect the shape of what it built, factor them in.
-
- If we are making a subtype of an Unchecked_Union (must be an
- Itype), just return the type.
-
- We can't just use Is_Constrained because private subtypes without
- discriminants of full types with discriminants with default
- expressions are Is_Constrained but aren't constrained! */
+ /* When the subtype has discriminants and these discriminants affect
+ the initial shape it has inherited, factor them in. But for the
+ of an Unchecked_Union (it must be an Itype), just return the type.
+ We can't just test Is_Constrained because private subtypes without
+ discriminants of types with discriminants with default expressions
+ are Is_Constrained but aren't constrained! */
if (IN (Ekind (gnat_base_type), Record_Kind)
- && !Is_For_Access_Subtype (gnat_entity)
&& !Is_Unchecked_Union (gnat_base_type)
+ && !Is_For_Access_Subtype (gnat_entity)
&& Is_Constrained (gnat_entity)
- && Stored_Constraint (gnat_entity) != No_Elist
- && Present (Discriminant_Constraint (gnat_entity)))
+ && Has_Discriminants (gnat_entity)
+ && Present (Discriminant_Constraint (gnat_entity))
+ && Stored_Constraint (gnat_entity) != No_Elist)
{
- Entity_Id gnat_field;
- tree gnu_field_list = 0;
- tree gnu_pos_list
- = compute_field_positions (gnu_orig_type, NULL_TREE,
- size_zero_node, bitsize_zero_node,
- BIGGEST_ALIGNMENT);
tree gnu_subst_list
- = substitution_list (gnat_entity, gnat_base_type, NULL_TREE,
- definition);
- tree gnu_temp;
+ = build_subst_list (gnat_entity, gnat_base_type, definition);
+ tree gnu_pos_list, gnu_field_list = NULL_TREE;
+ tree gnu_unpad_base_type, t;
+ Entity_Id gnat_field;
gnu_type = make_node (RECORD_TYPE);
TYPE_NAME (gnu_type) = gnu_entity_name;
- TYPE_VOLATILE (gnu_type) = Treat_As_Volatile (gnat_entity);
/* Set the size, alignment and alias set of the new type to
match that of the old one, doing required substitutions.
@@ -3095,63 +3097,77 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
relate_alias_sets (gnu_type, gnu_base_type, ALIAS_SET_COPY);
if (CONTAINS_PLACEHOLDER_P (TYPE_SIZE (gnu_type)))
- for (gnu_temp = gnu_subst_list;
- gnu_temp; gnu_temp = TREE_CHAIN (gnu_temp))
+ for (t = gnu_subst_list; t; t = TREE_CHAIN (t))
TYPE_SIZE (gnu_type)
= substitute_in_expr (TYPE_SIZE (gnu_type),
- TREE_PURPOSE (gnu_temp),
- TREE_VALUE (gnu_temp));
+ TREE_PURPOSE (t),
+ TREE_VALUE (t));
if (CONTAINS_PLACEHOLDER_P (TYPE_SIZE_UNIT (gnu_type)))
- for (gnu_temp = gnu_subst_list;
- gnu_temp; gnu_temp = TREE_CHAIN (gnu_temp))
+ for (t = gnu_subst_list; t; t = TREE_CHAIN (t))
TYPE_SIZE_UNIT (gnu_type)
= substitute_in_expr (TYPE_SIZE_UNIT (gnu_type),
- TREE_PURPOSE (gnu_temp),
- TREE_VALUE (gnu_temp));
+ TREE_PURPOSE (t),
+ TREE_VALUE (t));
if (CONTAINS_PLACEHOLDER_P (TYPE_ADA_SIZE (gnu_type)))
- for (gnu_temp = gnu_subst_list;
- gnu_temp; gnu_temp = TREE_CHAIN (gnu_temp))
+ for (t = gnu_subst_list; t; t = TREE_CHAIN (t))
SET_TYPE_ADA_SIZE
(gnu_type, substitute_in_expr (TYPE_ADA_SIZE (gnu_type),
- TREE_PURPOSE (gnu_temp),
- TREE_VALUE (gnu_temp)));
+ TREE_PURPOSE (t),
+ TREE_VALUE (t)));
+
+ if (TREE_CODE (gnu_base_type) == RECORD_TYPE
+ && TYPE_IS_PADDING_P (gnu_base_type))
+ gnu_unpad_base_type = TREE_TYPE (TYPE_FIELDS (gnu_base_type));
+ else
+ gnu_unpad_base_type = gnu_base_type;
+
+ gnu_pos_list
+ = compute_field_positions (gnu_unpad_base_type, NULL_TREE,
+ size_zero_node, bitsize_zero_node,
+ BIGGEST_ALIGNMENT);
for (gnat_field = First_Entity (gnat_entity);
- Present (gnat_field); gnat_field = Next_Entity (gnat_field))
+ Present (gnat_field);
+ gnat_field = Next_Entity (gnat_field))
if ((Ekind (gnat_field) == E_Component
|| Ekind (gnat_field) == E_Discriminant)
- && (Underlying_Type (Scope (Original_Record_Component
- (gnat_field)))
- == gnat_base_type)
- && (No (Corresponding_Discriminant (gnat_field))
- || !Is_Tagged_Type (gnat_base_type)))
+ && !(Present (Corresponding_Discriminant (gnat_field))
+ && Is_Tagged_Type (gnat_base_type))
+ && Underlying_Type (Scope (Original_Record_Component
+ (gnat_field)))
+ == gnat_base_type)
{
+ Name_Id gnat_name = Chars (gnat_field);
+ Entity_Id gnat_old_field
+ = Original_Record_Component (gnat_field);
tree gnu_old_field
- = gnat_to_gnu_field_decl (Original_Record_Component
- (gnat_field));
+ = gnat_to_gnu_field_decl (gnat_old_field);
tree gnu_offset
- = TREE_VALUE (purpose_member (gnu_old_field,
- gnu_pos_list));
+ = TREE_VALUE
+ (purpose_member (gnu_old_field, gnu_pos_list));
tree gnu_pos = TREE_PURPOSE (gnu_offset);
tree gnu_bitpos = TREE_VALUE (TREE_VALUE (gnu_offset));
- tree gnu_field_type
- = gnat_to_gnu_type (Etype (gnat_field));
- tree gnu_size = TYPE_SIZE (gnu_field_type);
- tree gnu_new_pos = NULL_TREE;
+ tree gnu_field, gnu_field_type, gnu_size, gnu_new_pos;
+ tree gnu_last = NULL_TREE;
unsigned int offset_align
- = tree_low_cst (TREE_PURPOSE (TREE_VALUE (gnu_offset)),
- 1);
- tree gnu_field;
+ = tree_low_cst
+ (TREE_PURPOSE (TREE_VALUE (gnu_offset)), 1);
+
+ /* If the type is the same, retrieve the GCC type from the
+ old field to take into account possible adjustments. */
+ if (Etype (gnat_field) == Etype (gnat_old_field))
+ gnu_field_type = TREE_TYPE (gnu_old_field);
+ else
+ gnu_field_type = gnat_to_gnu_type (Etype (gnat_field));
/* If there was a component clause, the field types must be
the same for the type and subtype, so copy the data from
the old field to avoid recomputation here. Also if the
field is justified modular and the optimization in
gnat_to_gnu_field was applied. */
- if (Present (Component_Clause
- (Original_Record_Component (gnat_field)))
+ if (Present (Component_Clause (gnat_old_field))
|| (TREE_CODE (gnu_field_type) == RECORD_TYPE
&& TYPE_JUSTIFIED_MODULAR_P (gnu_field_type)
&& TREE_TYPE (TYPE_FIELDS (gnu_field_type))
@@ -3178,16 +3194,18 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
= make_packable_type (gnu_field_type, true);
}
+ else
+ gnu_size = TYPE_SIZE (gnu_field_type);
+
if (CONTAINS_PLACEHOLDER_P (gnu_pos))
- for (gnu_temp = gnu_subst_list;
- gnu_temp; gnu_temp = TREE_CHAIN (gnu_temp))
+ for (t = gnu_subst_list; t; t = TREE_CHAIN (t))
gnu_pos = substitute_in_expr (gnu_pos,
- TREE_PURPOSE (gnu_temp),
- TREE_VALUE (gnu_temp));
+ TREE_PURPOSE (t),
+ TREE_VALUE (t));
/* If the position is now a constant, we can set it as the
- position of the field when we make it. Otherwise, we need
- to deal with it specially below. */
+ position of the field when we make it. Otherwise, we
+ need to deal with it specially below. */
if (TREE_CONSTANT (gnu_pos))
{
gnu_new_pos = bit_from_pos (gnu_pos, gnu_bitpos);
@@ -3202,6 +3220,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
TYPE_SIZE (gnu_type)))
continue;
}
+ else
+ gnu_new_pos = NULL_TREE;
gnu_field
= create_field_decl
@@ -3234,15 +3254,29 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
TREE_THIS_VOLATILE (gnu_field)
= TREE_THIS_VOLATILE (gnu_old_field);
- /* To match the layout crafted in components_to_record, if
- this is the _Tag field, put it before any discriminants
- instead of after them as for all other fields. */
- if (Chars (gnat_field) == Name_uTag)
+ /* To match the layout crafted in components_to_record,
+ if this is the _Tag or _Parent field, put it before
+ any other fields. */
+ if (gnat_name == Name_uTag || gnat_name == Name_uParent)
gnu_field_list = chainon (gnu_field_list, gnu_field);
+
+ /* Similarly, if this is the _Controller field, put
+ it before the other fields except for the _Tag or
+ _Parent field. */
+ else if (gnat_name == Name_uController && gnu_last)
+ {
+ TREE_CHAIN (gnu_field) = TREE_CHAIN (gnu_last);
+ TREE_CHAIN (gnu_last) = gnu_field;
+ }
+
+ /* Otherwise, if this is a regular field, put it after
+ the other fields. */
else
{
TREE_CHAIN (gnu_field) = gnu_field_list;
gnu_field_list = gnu_field;
+ if (!gnu_last)
+ gnu_last = gnu_field;
}
save_gnu_tree (gnat_field, gnu_field, false);
@@ -3267,7 +3301,14 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
TYPE_SIZE_UNIT (gnu_type)
= variable_size (TYPE_SIZE_UNIT (gnu_type));
- compute_record_mode (gnu_type);
+ /* See the E_Record_Type case for the rationale. */
+ if (Is_Tagged_Type (gnat_entity)
+ || Is_Limited_Record (gnat_entity))
+ SET_TYPE_MODE (gnu_type, BLKmode);
+ else
+ compute_record_mode (gnu_type);
+
+ TYPE_VOLATILE (gnu_type) = Treat_As_Volatile (gnat_entity);
/* Fill in locations of fields. */
annotate_rep (gnat_entity, gnu_type);
@@ -3278,16 +3319,17 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
if (debug_info_p)
{
tree gnu_subtype_marker = make_node (RECORD_TYPE);
- tree gnu_orig_name = TYPE_NAME (gnu_orig_type);
+ tree gnu_unpad_base_name = TYPE_NAME (gnu_unpad_base_type);
- if (TREE_CODE (gnu_orig_name) == TYPE_DECL)
- gnu_orig_name = DECL_NAME (gnu_orig_name);
+ if (TREE_CODE (gnu_unpad_base_name) == TYPE_DECL)
+ gnu_unpad_base_name = DECL_NAME (gnu_unpad_base_name);
TYPE_NAME (gnu_subtype_marker)
= create_concat_name (gnat_entity, "XVS");
finish_record_type (gnu_subtype_marker,
- create_field_decl (gnu_orig_name,
- integer_type_node,
+ create_field_decl (gnu_unpad_base_name,
+ build_reference_type
+ (gnu_unpad_base_type),
gnu_subtype_marker,
0, NULL_TREE,
NULL_TREE, 0),
@@ -3301,17 +3343,23 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
rest_of_record_type_compilation (gnu_type);
}
- /* Otherwise, go down all the components in the new type and
- make them equivalent to those in the base type. */
+ /* Otherwise, go down all the components in the new type and make
+ them equivalent to those in the base type. */
else
- for (gnat_temp = First_Entity (gnat_entity); Present (gnat_temp);
- gnat_temp = Next_Entity (gnat_temp))
- if ((Ekind (gnat_temp) == E_Discriminant
- && !Is_Unchecked_Union (gnat_base_type))
- || Ekind (gnat_temp) == E_Component)
- save_gnu_tree (gnat_temp,
- gnat_to_gnu_field_decl
- (Original_Record_Component (gnat_temp)), false);
+ {
+ gnu_type = gnu_base_type;
+
+ for (gnat_temp = First_Entity (gnat_entity);
+ Present (gnat_temp);
+ gnat_temp = Next_Entity (gnat_temp))
+ if ((Ekind (gnat_temp) == E_Discriminant
+ && !Is_Unchecked_Union (gnat_base_type))
+ || Ekind (gnat_temp) == E_Component)
+ save_gnu_tree (gnat_temp,
+ gnat_to_gnu_field_decl
+ (Original_Record_Component (gnat_temp)),
+ false);
+ }
}
break;
@@ -3868,10 +3916,13 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
bool has_stub = false;
int parmnum;
+ /* A parameter may refer to this type, so defer completion of any
+ incomplete types. */
if (kind == E_Subprogram_Type && !definition)
- /* A parameter may refer to this type, so defer completion
- of any incomplete types. */
- defer_incomplete_level++, this_deferred = true;
+ {
+ defer_incomplete_level++;
+ this_deferred = true;
+ }
/* If the subprogram has an alias, it is probably inherited, so
we can use the original one. If the original "subprogram"
@@ -4515,19 +4566,17 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
TYPE_SIZE (gnu_type), 0))
{
TYPE_SIZE (gnu_type)
- = elaborate_expression_1 (gnat_entity, gnat_entity,
- TYPE_SIZE (gnu_type),
- get_identifier ("SIZE"),
- definition, 0);
+ = elaborate_expression_1 (TYPE_SIZE (gnu_type),
+ gnat_entity, get_identifier ("SIZE"),
+ definition, false);
SET_TYPE_ADA_SIZE (gnu_type, TYPE_SIZE (gnu_type));
}
else
{
TYPE_SIZE (gnu_type)
- = elaborate_expression_1 (gnat_entity, gnat_entity,
- TYPE_SIZE (gnu_type),
- get_identifier ("SIZE"),
- definition, 0);
+ = elaborate_expression_1 (TYPE_SIZE (gnu_type),
+ gnat_entity, get_identifier ("SIZE"),
+ definition, false);
/* ??? For now, store the size as a multiple of the alignment
in bytes so that we can see the alignment from the tree. */
@@ -4535,23 +4584,21 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
= build_binary_op
(MULT_EXPR, sizetype,
elaborate_expression_1
- (gnat_entity, gnat_entity,
- build_binary_op (EXACT_DIV_EXPR, sizetype,
+ (build_binary_op (EXACT_DIV_EXPR, sizetype,
TYPE_SIZE_UNIT (gnu_type),
size_int (TYPE_ALIGN (gnu_type)
/ BITS_PER_UNIT)),
- get_identifier ("SIZE_A_UNIT"),
- definition, 0),
+ gnat_entity, get_identifier ("SIZE_A_UNIT"),
+ definition, false),
size_int (TYPE_ALIGN (gnu_type) / BITS_PER_UNIT));
if (TREE_CODE (gnu_type) == RECORD_TYPE)
SET_TYPE_ADA_SIZE
(gnu_type,
- elaborate_expression_1 (gnat_entity,
+ elaborate_expression_1 (TYPE_ADA_SIZE (gnu_type),
gnat_entity,
- TYPE_ADA_SIZE (gnu_type),
get_identifier ("RM_SIZE"),
- definition, 0));
+ definition, false));
}
}
@@ -4577,13 +4624,12 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
= build_binary_op
(MULT_EXPR, sizetype,
elaborate_expression_1
- (gnat_temp, gnat_temp,
- build_binary_op (EXACT_DIV_EXPR, sizetype,
+ (build_binary_op (EXACT_DIV_EXPR, sizetype,
DECL_FIELD_OFFSET (gnu_field),
size_int (DECL_OFFSET_ALIGN (gnu_field)
/ BITS_PER_UNIT)),
- get_identifier ("OFFSET"),
- definition, 0),
+ gnat_temp, get_identifier ("OFFSET"),
+ definition, false),
size_int (DECL_OFFSET_ALIGN (gnu_field) / BITS_PER_UNIT));
/* ??? The context of gnu_field is not necessarily gnu_type so
@@ -4749,6 +4795,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
|| (kind == E_Floating_Point_Type && !Vax_Float (gnat_entity)))
{
tree gnu_scalar_type = gnu_type;
+ tree gnu_low_bound, gnu_high_bound;
/* If this is a padded type, we need to use the underlying type. */
if (TREE_CODE (gnu_scalar_type) == RECORD_TYPE
@@ -4760,19 +4807,27 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
if (!longest_float_type_node && kind == E_Floating_Point_Type)
longest_float_type_node = gnu_scalar_type;
- TYPE_MIN_VALUE (gnu_scalar_type)
- = gnat_to_gnu (Type_Low_Bound (gnat_entity));
- TYPE_MAX_VALUE (gnu_scalar_type)
- = gnat_to_gnu (Type_High_Bound (gnat_entity));
+ gnu_low_bound = gnat_to_gnu (Type_Low_Bound (gnat_entity));
+ gnu_high_bound = gnat_to_gnu (Type_High_Bound (gnat_entity));
- /* For enumeration types, write full debugging information. */
if (kind == E_Enumeration_Type)
{
- /* Since this has both a typedef and a tag, avoid outputting
- the name twice. */
+ /* Enumeration types have specific RM bounds. */
+ SET_TYPE_RM_MIN_VALUE (gnu_scalar_type, gnu_low_bound);
+ SET_TYPE_RM_MAX_VALUE (gnu_scalar_type, gnu_high_bound);
+
+ /* Write full debugging information. Since this has both a
+ typedef and a tag, avoid outputting the name twice. */
DECL_ARTIFICIAL (gnu_decl) = 1;
rest_of_type_decl_compilation (gnu_decl);
}
+
+ else
+ {
+ /* Floating-point types don't have specific RM bounds. */
+ TYPE_GCC_MIN_VALUE (gnu_scalar_type) = gnu_low_bound;
+ TYPE_GCC_MAX_VALUE (gnu_scalar_type) = gnu_high_bound;
+ }
}
/* If we deferred processing of incomplete types, re-enable it. If there
@@ -5265,10 +5320,10 @@ elaborate_entity (Entity_Id gnat_entity)
conversions on bounds of real types. */
if (!Raises_Constraint_Error (gnat_lb))
elaborate_expression (gnat_lb, gnat_entity, get_identifier ("L"),
- 1, 0, Needs_Debug_Info (gnat_entity));
+ true, false, Needs_Debug_Info (gnat_entity));
if (!Raises_Constraint_Error (gnat_hb))
elaborate_expression (gnat_hb, gnat_entity, get_identifier ("U"),
- 1, 0, Needs_Debug_Info (gnat_entity));
+ true, false, Needs_Debug_Info (gnat_entity));
break;
}
@@ -5289,13 +5344,14 @@ elaborate_entity (Entity_Id gnat_entity)
case E_Limited_Private_Subtype:
case E_Record_Subtype_With_Private:
if (Is_Constrained (gnat_entity)
- && Has_Discriminants (Base_Type (gnat_entity))
+ && Has_Discriminants (gnat_entity)
&& Present (Discriminant_Constraint (gnat_entity)))
{
Node_Id gnat_discriminant_expr;
Entity_Id gnat_field;
- for (gnat_field = First_Discriminant (Base_Type (gnat_entity)),
+ for (gnat_field
+ = First_Discriminant (Implementation_Base_Type (gnat_entity)),
gnat_discriminant_expr
= First_Elmt (Discriminant_Constraint (gnat_entity));
Present (gnat_field);
@@ -5304,8 +5360,8 @@ elaborate_entity (Entity_Id gnat_entity)
/* ??? For now, ignore access discriminants. */
if (!Is_Access_Type (Etype (Node (gnat_discriminant_expr))))
elaborate_expression (Node (gnat_discriminant_expr),
- gnat_entity,
- get_entity_name (gnat_field), 1, 0, 0);
+ gnat_entity, get_entity_name (gnat_field),
+ true, false, false);
}
break;
@@ -5427,38 +5483,33 @@ relate_alias_sets (tree gnu_new_type, tree gnu_old_type, enum alias_set_op op)
record_component_aliases (gnu_new_type);
}
-/* Return a TREE_LIST describing the substitutions needed to reflect
- discriminant substitutions from GNAT_SUBTYPE to GNAT_TYPE and add
- them to GNU_LIST. If GNAT_TYPE is not specified, use the base type
- of GNAT_SUBTYPE. The substitutions can be in any order. TREE_PURPOSE
- gives the tree for the discriminant and TREE_VALUES is the replacement
- value. They are in the form of operands to substitute_in_expr.
- DEFINITION is as in gnat_to_gnu_entity. */
+/* Return a TREE_LIST describing the substitutions needed to reflect the
+ discriminant substitutions from GNAT_TYPE to GNAT_SUBTYPE. They can
+ be in any order. TREE_PURPOSE gives the tree for the discriminant and
+ TREE_VALUE is the replacement value. They are in the form of operands
+ to substitute_in_expr. DEFINITION is true if this is for a definition
+ of GNAT_SUBTYPE. */
static tree
-substitution_list (Entity_Id gnat_subtype, Entity_Id gnat_type,
- tree gnu_list, bool definition)
+build_subst_list (Entity_Id gnat_subtype, Entity_Id gnat_type, bool definition)
{
+ tree gnu_list = NULL_TREE;
Entity_Id gnat_discrim;
Node_Id gnat_value;
- if (No (gnat_type))
- gnat_type = Implementation_Base_Type (gnat_subtype);
-
- if (Has_Discriminants (gnat_type))
- for (gnat_discrim = First_Stored_Discriminant (gnat_type),
- gnat_value = First_Elmt (Stored_Constraint (gnat_subtype));
- Present (gnat_discrim);
- gnat_discrim = Next_Stored_Discriminant (gnat_discrim),
- gnat_value = Next_Elmt (gnat_value))
- /* Ignore access discriminants. */
- if (!Is_Access_Type (Etype (Node (gnat_value))))
- gnu_list = tree_cons (gnat_to_gnu_field_decl (gnat_discrim),
- elaborate_expression
- (Node (gnat_value), gnat_subtype,
- get_entity_name (gnat_discrim), definition,
- 1, 0),
- gnu_list);
+ for (gnat_discrim = First_Stored_Discriminant (gnat_type),
+ gnat_value = First_Elmt (Stored_Constraint (gnat_subtype));
+ Present (gnat_discrim);
+ gnat_discrim = Next_Stored_Discriminant (gnat_discrim),
+ gnat_value = Next_Elmt (gnat_value))
+ /* Ignore access discriminants. */
+ if (!Is_Access_Type (Etype (Node (gnat_value))))
+ gnu_list = tree_cons (gnat_to_gnu_field_decl (gnat_discrim),
+ elaborate_expression
+ (Node (gnat_value), gnat_subtype,
+ get_entity_name (gnat_discrim), definition,
+ true, false),
+ gnu_list);
return gnu_list;
}
@@ -5591,63 +5642,66 @@ prepend_attributes (Entity_Id gnat_entity, struct attrib ** attr_list)
}
}
-/* Called when we need to protect a variable object using a save_expr. */
+/* Called when we need to protect a variable object using a SAVE_EXPR. */
tree
maybe_variable (tree gnu_operand)
{
- if (TREE_CONSTANT (gnu_operand) || TREE_READONLY (gnu_operand)
+ if (TREE_CONSTANT (gnu_operand)
+ || TREE_READONLY (gnu_operand)
|| TREE_CODE (gnu_operand) == SAVE_EXPR
|| TREE_CODE (gnu_operand) == NULL_EXPR)
return gnu_operand;
if (TREE_CODE (gnu_operand) == UNCONSTRAINED_ARRAY_REF)
{
- tree gnu_result = build1 (UNCONSTRAINED_ARRAY_REF,
- TREE_TYPE (gnu_operand),
- variable_size (TREE_OPERAND (gnu_operand, 0)));
+ tree gnu_result
+ = build1 (UNCONSTRAINED_ARRAY_REF, TREE_TYPE (gnu_operand),
+ variable_size (TREE_OPERAND (gnu_operand, 0)));
TREE_READONLY (gnu_result) = TREE_STATIC (gnu_result)
= TYPE_READONLY (TREE_TYPE (TREE_TYPE (gnu_operand)));
return gnu_result;
}
- else
- return variable_size (gnu_operand);
+
+ return variable_size (gnu_operand);
}
/* Given a GNAT tree GNAT_EXPR, for an expression which is a value within a
type definition (either a bound or a discriminant value) for GNAT_ENTITY,
- return the GCC tree to use for that expression. GNU_NAME is the
- qualification to use if an external name is appropriate and DEFINITION is
- true if this is a definition of GNAT_ENTITY. If NEED_VALUE is true, we
- need a result. Otherwise, we are just elaborating this for side-effects.
- If NEED_DEBUG is true we need the symbol for debugging purposes even if it
+ return the GCC tree to use for that expression. GNU_NAME is the suffix
+ to use if a variable needs to be created and DEFINITION is true if this
+ is a definition of GNAT_ENTITY. If NEED_VALUE is true, we need a result;
+ otherwise, we are just elaborating the expression for side-effects. If
+ NEED_DEBUG is true, we need a variable for debugging purposes even if it
isn't needed for code generation. */
static tree
-elaborate_expression (Node_Id gnat_expr, Entity_Id gnat_entity,
- tree gnu_name, bool definition, bool need_value,
- bool need_debug)
+elaborate_expression (Node_Id gnat_expr, Entity_Id gnat_entity, tree gnu_name,
+ bool definition, bool need_value, bool need_debug)
{
tree gnu_expr;
- /* If we already elaborated this expression (e.g., it was involved
+ /* If we already elaborated this expression (e.g. it was involved
in the definition of a private type), use the old value. */
if (present_gnu_tree (gnat_expr))
return get_gnu_tree (gnat_expr);
- /* If we don't need a value and this is static or a discriminant, we
- don't need to do anything. */
- else if (!need_value
- && (Is_OK_Static_Expression (gnat_expr)
- || (Nkind (gnat_expr) == N_Identifier
- && Ekind (Entity (gnat_expr)) == E_Discriminant)))
- return 0;
+ /* If we don't need a value and this is static or a discriminant,
+ we don't need to do anything. */
+ if (!need_value
+ && (Is_OK_Static_Expression (gnat_expr)
+ || (Nkind (gnat_expr) == N_Identifier
+ && Ekind (Entity (gnat_expr)) == E_Discriminant)))
+ return NULL_TREE;
- /* Otherwise, convert this tree to its GCC equivalent. */
- gnu_expr
- = elaborate_expression_1 (gnat_expr, gnat_entity, gnat_to_gnu (gnat_expr),
- gnu_name, definition, need_debug);
+ /* If it's a static expression, we don't need a variable for debugging. */
+ if (need_debug && Is_OK_Static_Expression (gnat_expr))
+ need_debug = false;
+
+ /* Otherwise, convert this tree to its GCC equivalent and elaborate it. */
+ gnu_expr = elaborate_expression_1 (gnat_to_gnu (gnat_expr), gnat_entity,
+ gnu_name, definition, need_debug);
/* Save the expression in case we try to elaborate this entity again. Since
it's not a DECL, don't check it. Don't save if it's a discriminant. */
@@ -5657,29 +5711,27 @@ elaborate_expression (Node_Id gnat_expr, Entity_Id gnat_entity,
return need_value ? gnu_expr : error_mark_node;
}
-/* Similar, but take a GNU expression. */
+/* Similar, but take a GNU expression and always return a result. */
static tree
-elaborate_expression_1 (Node_Id gnat_expr, Entity_Id gnat_entity,
- tree gnu_expr, tree gnu_name, bool definition,
- bool need_debug)
+elaborate_expression_1 (tree gnu_expr, Entity_Id gnat_entity, tree gnu_name,
+ bool definition, bool need_debug)
{
- tree gnu_decl = NULL_TREE;
/* Skip any conversions and simple arithmetics to see if the expression
is a read-only variable.
??? This really should remain read-only, but we have to think about
the typing of the tree here. */
tree gnu_inner_expr
= skip_simple_arithmetic (remove_conversions (gnu_expr, true));
+ tree gnu_decl = NULL_TREE;
bool expr_global = Is_Public (gnat_entity) || global_bindings_p ();
bool expr_variable;
- /* In most cases, we won't see a naked FIELD_DECL here because a
- discriminant reference will have been replaced with a COMPONENT_REF
- when the type is being elaborated. However, there are some cases
- involving child types where we will. So convert it to a COMPONENT_REF
- here. We have to hope it will be at the highest level of the
- expression in these cases. */
+ /* In most cases, we won't see a naked FIELD_DECL because a discriminant
+ reference will have been replaced with a COMPONENT_REF when the type
+ is being elaborated. However, there are some cases involving child
+ types where we will. So convert it to a COMPONENT_REF. We hope it
+ will be at the highest level of the expression in these cases. */
if (TREE_CODE (gnu_expr) == FIELD_DECL)
gnu_expr = build3 (COMPONENT_REF, TREE_TYPE (gnu_expr),
build0 (PLACEHOLDER_EXPR, DECL_CONTEXT (gnu_expr)),
@@ -5693,19 +5745,14 @@ elaborate_expression_1 (Node_Id gnat_expr, Entity_Id gnat_entity,
by the variable; otherwise use a SAVE_EXPR if needed. Note that we
rely here on the fact that an expression cannot contain both the
discriminant and some other variable. */
-
expr_variable = (!CONSTANT_CLASS_P (gnu_expr)
&& !(TREE_CODE (gnu_inner_expr) == VAR_DECL
&& (TREE_READONLY (gnu_inner_expr)
|| DECL_READONLY_ONCE_ELAB (gnu_inner_expr)))
&& !CONTAINS_PLACEHOLDER_P (gnu_expr));
- /* If this is a static expression or contains a discriminant, we don't
- need the variable for debugging (and can't elaborate anyway if a
- discriminant). */
- if (need_debug
- && (Is_OK_Static_Expression (gnat_expr)
- || CONTAINS_PLACEHOLDER_P (gnu_expr)))
+ /* If GNU_EXPR contains a discriminant, we can't elaborate a variable. */
+ if (need_debug && CONTAINS_PLACEHOLDER_P (gnu_expr))
need_debug = false;
/* Now create the variable if we need it. */
@@ -5721,10 +5768,8 @@ elaborate_expression_1 (Node_Id gnat_expr, Entity_Id gnat_entity,
can do the right thing in the local case. */
if (expr_global && expr_variable)
return gnu_decl;
- else if (!expr_variable)
- return gnu_expr;
- else
- return maybe_variable (gnu_expr);
+
+ return expr_variable ? maybe_variable (gnu_expr) : gnu_expr;
}
/* Create a record type that contains a SIZE bytes long field of TYPE with a
@@ -6132,7 +6177,8 @@ maybe_pad_type (tree type, tree size, unsigned int align,
TYPE_NAME (marker) = concat_name (name, "XVS");
finish_record_type (marker,
- create_field_decl (orig_name, integer_type_node,
+ create_field_decl (orig_name,
+ build_reference_type (type),
marker, 0, NULL_TREE, NULL_TREE,
0),
0, false);
@@ -6614,12 +6660,13 @@ compare_field_bitpos (const PTR rt1, const PTR rt2)
return ret ? ret : (int) (DECL_UID (field1) - DECL_UID (field2));
}
-/* Return a GCC tree for a record type given a GNAT Component_List and a chain
- of GCC trees for fields that are in the record and have already been
- processed. When called from gnat_to_gnu_entity during the processing of a
- record type definition, the GCC nodes for the discriminants will be on
- the chain. The other calls to this function are recursive calls from
- itself for the Component_List of a variant and the chain is empty.
+/* Translate and chain the GNAT_COMPONENT_LIST to the GNU_FIELD_LIST, set
+ the result as the field list of GNU_RECORD_TYPE and finish it up. When
+ called from gnat_to_gnu_entity during the processing of a record type
+ definition, the GCC node for the parent, if any, will be the single field
+ of GNU_RECORD_TYPE and the GCC nodes for the discriminants will be on the
+ GNU_FIELD_LIST. The other calls to this function are recursive calls for
+ the component list of a variant and, in this case, GNU_FIELD_LIST is empty.
PACKED is 1 if this is for a packed record, -1 if this is for a record
with Component_Alignment of Storage_Unit, -2 if this is for a record
@@ -6628,64 +6675,77 @@ compare_field_bitpos (const PTR rt1, const PTR rt2)
DEFINITION is true if we are defining this record.
P_GNU_REP_LIST, if nonzero, is a pointer to a list to which each field
- with a rep clause is to be added. If it is nonzero, that is all that
- should be done with such fields.
+ with a rep clause is to be added; in this case, that is all that should
+ be done with such fields.
CANCEL_ALIGNMENT, if true, means the alignment should be zeroed before
- laying out the record. This means the alignment only serves to force fields
- to be bitfields, but not require the record to be that aligned. This is
- used for variants.
+ laying out the record. This means the alignment only serves to force
+ fields to be bitfields, but not require the record to be that aligned.
+ This is used for variants.
ALL_REP, if true, means a rep clause was found for all the fields. This
simplifies the logic since we know we're not in the mixed case.
DO_NOT_FINALIZE, if true, means that the record type is expected to be
- modified afterwards so it will not be sent to the back-end for finalization.
+ modified afterwards so it will not be finalized here.
UNCHECKED_UNION, if true, means that we are building a type for a record
- with a Pragma Unchecked_Union.
-
- The processing of the component list fills in the chain with all of the
- fields of the record and then the record type is finished. */
+ with a Pragma Unchecked_Union. */
static void
-components_to_record (tree gnu_record_type, Node_Id component_list,
+components_to_record (tree gnu_record_type, Node_Id gnat_component_list,
tree gnu_field_list, int packed, bool definition,
tree *p_gnu_rep_list, bool cancel_alignment,
bool all_rep, bool do_not_finalize, bool unchecked_union)
{
- Node_Id component_decl;
- Entity_Id gnat_field;
- Node_Id variant_part;
- tree gnu_our_rep_list = NULL_TREE;
- tree gnu_field, gnu_last;
- bool layout_with_rep = false;
bool all_rep_and_size = all_rep && TYPE_SIZE (gnu_record_type);
+ bool layout_with_rep = false;
+ Node_Id component_decl, variant_part;
+ tree gnu_our_rep_list = NULL_TREE;
+ tree gnu_field, gnu_next, gnu_last = tree_last (gnu_field_list);
- /* For each variable within each component declaration create a GCC field
- and add it to the list, skipping any pragmas in the list. */
- if (Present (Component_Items (component_list)))
- for (component_decl = First_Non_Pragma (Component_Items (component_list));
+ /* For each component referenced in a component declaration create a GCC
+ field and add it to the list, skipping pragmas in the GNAT list. */
+ if (Present (Component_Items (gnat_component_list)))
+ for (component_decl
+ = First_Non_Pragma (Component_Items (gnat_component_list));
Present (component_decl);
component_decl = Next_Non_Pragma (component_decl))
{
- gnat_field = Defining_Entity (component_decl);
+ Entity_Id gnat_field = Defining_Entity (component_decl);
+ Name_Id gnat_name = Chars (gnat_field);
- if (Chars (gnat_field) == Name_uParent)
- gnu_field = tree_last (TYPE_FIELDS (gnu_record_type));
+ /* If present, the _Parent field must have been created as the single
+ field of the record type. Put it before any other fields. */
+ if (gnat_name == Name_uParent)
+ {
+ gnu_field = TYPE_FIELDS (gnu_record_type);
+ gnu_field_list = chainon (gnu_field_list, gnu_field);
+ }
else
{
gnu_field = gnat_to_gnu_field (gnat_field, gnu_record_type,
packed, definition);
- /* If this is the _Tag field, put it before any discriminants,
- instead of after them as is the case for all other fields. */
- if (Chars (gnat_field) == Name_uTag)
+ /* If this is the _Tag field, put it before any other fields. */
+ if (gnat_name == Name_uTag)
gnu_field_list = chainon (gnu_field_list, gnu_field);
+
+ /* If this is the _Controller field, put it before the other
+ fields except for the _Tag or _Parent field. */
+ else if (gnat_name == Name_uController && gnu_last)
+ {
+ TREE_CHAIN (gnu_field) = TREE_CHAIN (gnu_last);
+ TREE_CHAIN (gnu_last) = gnu_field;
+ }
+
+ /* If this is a regular field, put it after the other fields. */
else
{
TREE_CHAIN (gnu_field) = gnu_field_list;
gnu_field_list = gnu_field;
+ if (!gnu_last)
+ gnu_last = gnu_field;
}
}
@@ -6693,7 +6753,7 @@ components_to_record (tree gnu_record_type, Node_Id component_list,
}
/* At the end of the component list there may be a variant part. */
- variant_part = Variant_Part (component_list);
+ variant_part = Variant_Part (gnat_component_list);
/* We create a QUAL_UNION_TYPE for the variant part since the variants are
mutually exclusive and should go in the same memory. To do this we need
@@ -6751,14 +6811,14 @@ components_to_record (tree gnu_record_type, Node_Id component_list,
IDENTIFIER_POINTER (gnu_inner_name));
/* Set the alignment of the inner type in case we need to make
- inner objects into bitfields, but then clear it out
- so the record actually gets only the alignment required. */
+ inner objects into bitfields, but then clear it out so the
+ record actually gets only the alignment required. */
TYPE_ALIGN (gnu_variant_type) = TYPE_ALIGN (gnu_record_type);
TYPE_PACKED (gnu_variant_type) = TYPE_PACKED (gnu_record_type);
- /* Similarly, if the outer record has a size specified and all fields
- have record rep clauses, we can propagate the size into the
- variant part. */
+ /* Similarly, if the outer record has a size specified and all
+ fields have record rep clauses, we can propagate the size
+ into the variant part. */
if (all_rep_and_size)
{
TYPE_SIZE (gnu_variant_type) = TYPE_SIZE (gnu_record_type);
@@ -6766,8 +6826,8 @@ components_to_record (tree gnu_record_type, Node_Id component_list,
= TYPE_SIZE_UNIT (gnu_record_type);
}
- /* Create the record type for the variant. Note that we defer
- finalizing it until after we are sure to actually use it. */
+ /* Add the fields into the record type for the variant. Note that we
+ defer finalizing it until after we are sure to really use it. */
components_to_record (gnu_variant_type, Component_List (variant),
NULL_TREE, packed, definition,
&gnu_our_rep_list, !all_rep_and_size, all_rep,
@@ -6815,7 +6875,7 @@ components_to_record (tree gnu_record_type, Node_Id component_list,
gnu_variant_list = gnu_field;
}
- /* Only make the QUAL_UNION_TYPE if there are any non-empty variants. */
+ /* Only make the QUAL_UNION_TYPE if there are non-empty variants. */
if (gnu_variant_list)
{
int union_field_packed;
@@ -6858,18 +6918,19 @@ components_to_record (tree gnu_record_type, Node_Id component_list,
}
/* Scan GNU_FIELD_LIST and see if any fields have rep clauses. If they
- do, pull them out and put them into GNU_OUR_REP_LIST. We have to do this
- in a separate pass since we want to handle the discriminants but can't
- play with them until we've used them in debugging data above.
-
- ??? Note: if we then reorder them, debugging information will be wrong,
- but there's nothing that can be done about this at the moment. */
- for (gnu_field = gnu_field_list, gnu_last = NULL_TREE; gnu_field; )
+ do, pull them out and put them into GNU_OUR_REP_LIST. We have to do
+ this in a separate pass since we want to handle the discriminants but
+ can't play with them until we've used them in debugging data above.
+
+ ??? If we then reorder them, debugging information will be wrong but
+ there's nothing that can be done about this at the moment. */
+ gnu_last = NULL_TREE;
+ for (gnu_field = gnu_field_list; gnu_field; gnu_field = gnu_next)
{
+ gnu_next = TREE_CHAIN (gnu_field);
+
if (DECL_FIELD_OFFSET (gnu_field))
{
- tree gnu_next = TREE_CHAIN (gnu_field);
-
if (!gnu_last)
gnu_field_list = gnu_next;
else
@@ -6877,31 +6938,28 @@ components_to_record (tree gnu_record_type, Node_Id component_list,
TREE_CHAIN (gnu_field) = gnu_our_rep_list;
gnu_our_rep_list = gnu_field;
- gnu_field = gnu_next;
}
else
- {
- gnu_last = gnu_field;
- gnu_field = TREE_CHAIN (gnu_field);
- }
+ gnu_last = gnu_field;
}
- /* If we have any items in our rep'ed field list, it is not the case that all
- the fields in the record have rep clauses, and P_REP_LIST is nonzero,
- set it and ignore the items. */
+ /* If we have any fields in our rep'ed field list and it is not the case that
+ all the fields in the record have rep clauses and P_REP_LIST is nonzero,
+ set it and ignore these fields. */
if (gnu_our_rep_list && p_gnu_rep_list && !all_rep)
*p_gnu_rep_list = chainon (*p_gnu_rep_list, gnu_our_rep_list);
+
+ /* Otherwise, sort the fields by bit position and put them into their own
+ record, before the others, if we also have fields without rep clauses. */
else if (gnu_our_rep_list)
{
- /* Otherwise, sort the fields by bit position and put them into their
- own record if we have any fields without rep clauses. */
tree gnu_rep_type
= (gnu_field_list ? make_node (RECORD_TYPE) : gnu_record_type);
- int len = list_length (gnu_our_rep_list);
+ int i, len = list_length (gnu_our_rep_list);
tree *gnu_arr = (tree *) alloca (sizeof (tree) * len);
- int i;
- for (i = 0, gnu_field = gnu_our_rep_list; gnu_field;
+ for (gnu_field = gnu_our_rep_list, i = 0;
+ gnu_field;
gnu_field = TREE_CHAIN (gnu_field), i++)
gnu_arr[i] = gnu_field;
@@ -6920,8 +6978,9 @@ components_to_record (tree gnu_record_type, Node_Id component_list,
if (gnu_field_list)
{
finish_record_type (gnu_rep_type, gnu_our_rep_list, 1, false);
- gnu_field = create_field_decl (get_identifier ("REP"), gnu_rep_type,
- gnu_record_type, 0, 0, 0, 1);
+ gnu_field
+ = create_field_decl (get_identifier ("REP"), gnu_rep_type,
+ gnu_record_type, 0, NULL_TREE, NULL_TREE, 1);
DECL_INTERNAL_P (gnu_field) = 1;
gnu_field_list = chainon (gnu_field_list, gnu_field);
}
@@ -7385,11 +7444,18 @@ set_rm_size (Uint uint_size, tree gnu_type, Entity_Id gnat_entity)
if (CONTAINS_PLACEHOLDER_P (old_size))
old_size = max_size (old_size, true);
- /* If the size of the object is a constant, the new size must not be
- smaller (the front-end checks this for scalar types). */
+ /* If the size of the object is a constant, the new size must not be smaller
+ (the front-end has verified this for scalar and packed array types). */
if (TREE_CODE (old_size) != INTEGER_CST
|| TREE_OVERFLOW (old_size)
- || (AGGREGATE_TYPE_P (gnu_type) && tree_int_cst_lt (size, old_size)))
+ || (AGGREGATE_TYPE_P (gnu_type)
+ && !(TREE_CODE (gnu_type) == ARRAY_TYPE
+ && TYPE_PACKED_ARRAY_TYPE_P (gnu_type))
+ && !(TREE_CODE (gnu_type) == RECORD_TYPE
+ && TYPE_IS_PADDING_P (gnu_type)
+ && TREE_CODE (TREE_TYPE (TYPE_FIELDS (gnu_type))) == ARRAY_TYPE
+ && TYPE_PACKED_ARRAY_TYPE_P (TREE_TYPE (TYPE_FIELDS (gnu_type))))
+ && tree_int_cst_lt (size, old_size)))
{
if (Present (gnat_attr_node))
post_error_ne_tree
@@ -7403,7 +7469,7 @@ set_rm_size (Uint uint_size, tree gnu_type, Entity_Id gnat_entity)
&& Is_Discrete_Or_Fixed_Point_Type (gnat_entity))
|| (TREE_CODE (gnu_type) == ENUMERAL_TYPE
|| TREE_CODE (gnu_type) == BOOLEAN_TYPE))
- TYPE_RM_SIZE (gnu_type) = size;
+ SET_TYPE_RM_SIZE (gnu_type, size);
/* ...or the Ada size for record and union types. */
else if ((TREE_CODE (gnu_type) == RECORD_TYPE
@@ -7455,10 +7521,12 @@ make_type_from_size (tree type, tree size_tree, bool for_biased)
else
new_type = make_signed_type (size);
TREE_TYPE (new_type) = TREE_TYPE (type) ? TREE_TYPE (type) : type;
- TYPE_MIN_VALUE (new_type)
- = convert (TREE_TYPE (new_type), TYPE_MIN_VALUE (type));
- TYPE_MAX_VALUE (new_type)
- = convert (TREE_TYPE (new_type), TYPE_MAX_VALUE (type));
+ SET_TYPE_RM_MIN_VALUE (new_type,
+ convert (TREE_TYPE (new_type),
+ TYPE_MIN_VALUE (type)));
+ SET_TYPE_RM_MAX_VALUE (new_type,
+ convert (TREE_TYPE (new_type),
+ TYPE_MAX_VALUE (type)));
/* Propagate the name to avoid creating a fake subrange type. */
if (TYPE_NAME (type))
{
@@ -7468,7 +7536,7 @@ make_type_from_size (tree type, tree size_tree, bool for_biased)
TYPE_NAME (new_type) = TYPE_NAME (type);
}
TYPE_BIASED_REPRESENTATION_P (new_type) = biased_p;
- TYPE_RM_SIZE (new_type) = bitsize_int (size);
+ SET_TYPE_RM_SIZE (new_type, bitsize_int (size));
return new_type;
case RECORD_TYPE:
@@ -7714,39 +7782,43 @@ substitute_in_type (tree t, tree f, tree r)
case INTEGER_TYPE:
case ENUMERAL_TYPE:
case BOOLEAN_TYPE:
- if (CONTAINS_PLACEHOLDER_P (TYPE_MIN_VALUE (t))
- || CONTAINS_PLACEHOLDER_P (TYPE_MAX_VALUE (t)))
+ case REAL_TYPE:
+
+ /* First the domain types of arrays. */
+ if (CONTAINS_PLACEHOLDER_P (TYPE_GCC_MIN_VALUE (t))
+ || CONTAINS_PLACEHOLDER_P (TYPE_GCC_MAX_VALUE (t)))
{
- tree low = SUBSTITUTE_IN_EXPR (TYPE_MIN_VALUE (t), f, r);
- tree high = SUBSTITUTE_IN_EXPR (TYPE_MAX_VALUE (t), f, r);
+ tree low = SUBSTITUTE_IN_EXPR (TYPE_GCC_MIN_VALUE (t), f, r);
+ tree high = SUBSTITUTE_IN_EXPR (TYPE_GCC_MAX_VALUE (t), f, r);
- if (low == TYPE_MIN_VALUE (t) && high == TYPE_MAX_VALUE (t))
+ if (low == TYPE_GCC_MIN_VALUE (t) && high == TYPE_GCC_MAX_VALUE (t))
return t;
new = copy_type (t);
- TYPE_MIN_VALUE (new) = low;
- TYPE_MAX_VALUE (new) = high;
- if (TYPE_INDEX_TYPE (t))
+ TYPE_GCC_MIN_VALUE (new) = low;
+ TYPE_GCC_MAX_VALUE (new) = high;
+
+ if (TREE_CODE (t) == INTEGER_TYPE && TYPE_INDEX_TYPE (t))
SET_TYPE_INDEX_TYPE
(new, substitute_in_type (TYPE_INDEX_TYPE (t), f, r));
+
return new;
}
- return t;
-
- case REAL_TYPE:
- if (CONTAINS_PLACEHOLDER_P (TYPE_MIN_VALUE (t))
- || CONTAINS_PLACEHOLDER_P (TYPE_MAX_VALUE (t)))
+ /* Then the subtypes. */
+ if (CONTAINS_PLACEHOLDER_P (TYPE_RM_MIN_VALUE (t))
+ || CONTAINS_PLACEHOLDER_P (TYPE_RM_MAX_VALUE (t)))
{
- tree low = SUBSTITUTE_IN_EXPR (TYPE_MIN_VALUE (t), f, r);
- tree high = SUBSTITUTE_IN_EXPR (TYPE_MAX_VALUE (t), f, r);
+ tree low = SUBSTITUTE_IN_EXPR (TYPE_RM_MIN_VALUE (t), f, r);
+ tree high = SUBSTITUTE_IN_EXPR (TYPE_RM_MAX_VALUE (t), f, r);
- if (low == TYPE_MIN_VALUE (t) && high == TYPE_MAX_VALUE (t))
+ if (low == TYPE_RM_MIN_VALUE (t) && high == TYPE_RM_MAX_VALUE (t))
return t;
new = copy_type (t);
- TYPE_MIN_VALUE (new) = low;
- TYPE_MAX_VALUE (new) = high;
+ SET_TYPE_RM_MIN_VALUE (new, low);
+ SET_TYPE_RM_MAX_VALUE (new, high);
+
return new;
}
diff --git a/gcc/ada/gcc-interface/gigi.h b/gcc/ada/gcc-interface/gigi.h
index 8ccb39c4b0a..7bc89eef6fd 100644
--- a/gcc/ada/gcc-interface/gigi.h
+++ b/gcc/ada/gcc-interface/gigi.h
@@ -558,6 +558,10 @@ extern tree copy_type (tree type);
extern tree create_index_type (tree min, tree max, tree index,
Node_Id gnat_node);
+/* Return a subtype of TYPE with range MIN to MAX. If TYPE is NULL,
+ sizetype is used. */
+extern tree create_range_type (tree type, tree min, tree max);
+
/* Return a TYPE_DECL node suitable for the TYPE_STUB_DECL field of a type.
TYPE_NAME gives the name of the type and TYPE is a ..._TYPE node giving
its data type. */
@@ -839,13 +843,13 @@ extern tree build_component_ref (tree record_variable, tree component,
If GNU_OBJ is nonzero, it is an object to deallocate. Otherwise,
generate an allocator.
- GNU_SIZE is the size of the object in bytes and ALIGN is the alignment
- in bits. GNAT_PROC, if present, is a procedure to call and GNAT_POOL
- is the storage pool to use. If not present, malloc and free are used.
- GNAT_NODE is used to provide an error location for restriction violation
- messages. */
+ GNU_SIZE is the number of bytes to allocate and GNU_TYPE is the contained
+ object type, used to determine the to-be-honored address alignment.
+ GNAT_PROC, if present, is a procedure to call and GNAT_POOL is the storage
+ pool to use. If not present, malloc and free are used. GNAT_NODE is used
+ to provide an error location for restriction violation messages. */
extern tree build_call_alloc_dealloc (tree gnu_obj, tree gnu_size,
- unsigned align, Entity_Id gnat_proc,
+ tree gnu_type, Entity_Id gnat_proc,
Entity_Id gnat_pool, Node_Id gnat_node);
/* Build a GCC tree to correspond to allocating an object of TYPE whose
diff --git a/gcc/ada/gcc-interface/lang-specs.h b/gcc/ada/gcc-interface/lang-specs.h
index c07547fbdf6..1afba3706b4 100644
--- a/gcc/ada/gcc-interface/lang-specs.h
+++ b/gcc/ada/gcc-interface/lang-specs.h
@@ -35,6 +35,7 @@
gnat1 %{I*} %{k8:-gnatk8} %{Wall:-gnatwa} %{w:-gnatws} %{!Q:-quiet}\
%{nostdinc*} %{nostdlib*}\
-dumpbase %{.adb:%b.adb}%{.ads:%b.ads}%{!.adb:%{!.ads:%b.ada}}\
+ %{c|S:%{o*:-auxbase-strip %*}%{!o*:-auxbase %b}}%{!c:%{!S:-auxbase %b}} \
%{O*} %{W*} %{w} %{p} %{pg:-p} %{a} %{d*} %{f*}\
%{coverage:-fprofile-arcs -ftest-coverage} "
#if CONFIG_DUAL_EXCEPTIONS
diff --git a/gcc/ada/gcc-interface/misc.c b/gcc/ada/gcc-interface/misc.c
index 5ccf13469b1..63d7805796f 100644
--- a/gcc/ada/gcc-interface/misc.c
+++ b/gcc/ada/gcc-interface/misc.c
@@ -78,6 +78,7 @@ static int gnat_eh_type_covers (tree, tree);
static void gnat_parse_file (int);
static void internal_error_function (const char *, va_list *);
static tree gnat_type_max_size (const_tree);
+static void gnat_get_subrange_bounds (const_tree, tree *, tree *);
/* Definitions for our language-specific hooks. */
@@ -125,6 +126,8 @@ static tree gnat_type_max_size (const_tree);
#define LANG_HOOKS_TYPE_FOR_SIZE gnat_type_for_size
#undef LANG_HOOKS_TYPES_COMPATIBLE_P
#define LANG_HOOKS_TYPES_COMPATIBLE_P gnat_types_compatible_p
+#undef LANG_HOOKS_GET_SUBRANGE_BOUNDS
+#define LANG_HOOKS_GET_SUBRANGE_BOUNDS gnat_get_subrange_bounds
#undef LANG_HOOKS_ATTRIBUTE_TABLE
#define LANG_HOOKS_ATTRIBUTE_TABLE gnat_internal_attribute_table
#undef LANG_HOOKS_BUILTIN_FUNCTION
@@ -269,8 +272,8 @@ gnat_handle_option (size_t scode, const char *arg, int value)
gnat_argc++;
break;
- case OPT_gdwarf_:
- gnat_dwarf_extensions ++;
+ case OPT_gdwarfplus:
+ gnat_dwarf_extensions = 1;
break;
default:
@@ -513,6 +516,12 @@ gnat_print_type (FILE *file, tree node, int indent)
case ENUMERAL_TYPE:
case BOOLEAN_TYPE:
print_node_brief (file, "RM size", TYPE_RM_SIZE (node), indent + 4);
+
+ /* ... fall through ... */
+
+ case REAL_TYPE:
+ print_node_brief (file, "RM min", TYPE_RM_MIN_VALUE (node), indent + 4);
+ print_node_brief (file, "RM max", TYPE_RM_MAX_VALUE (node), indent + 4);
break;
case ARRAY_TYPE:
@@ -644,6 +653,22 @@ gnat_type_max_size (const_tree gnu_type)
return max_unitsize;
}
+/* GNU_TYPE is a subtype of an integral type. Set LOWVAL to the low bound
+ and HIGHVAL to the high bound, respectively. */
+
+static void
+gnat_get_subrange_bounds (const_tree gnu_type, tree *lowval, tree *highval)
+{
+ tree min = TYPE_MIN_VALUE (gnu_type);
+ tree max = TYPE_MAX_VALUE (gnu_type);
+ /* If the bounds aren't constant, use non-representable constant values
+ to get the same effect on debug info without tree sharing issues. */
+ *lowval
+ = TREE_CONSTANT (min) ? min : build_int_cstu (integer_type_node, -1);
+ *highval
+ = TREE_CONSTANT (max) ? max : build_int_cstu (integer_type_node, -1);
+}
+
/* GNU_TYPE is a type. Determine if it should be passed by reference by
default. */
diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c
index d6aa7dfa123..b59af8cdb19 100644
--- a/gcc/ada/gcc-interface/trans.c
+++ b/gcc/ada/gcc-interface/trans.c
@@ -1843,7 +1843,8 @@ Case_Statement_to_gnu (Node_Id gnat_node)
/* We build a SWITCH_EXPR that contains the code with interspersed
CASE_LABEL_EXPRs for each label. */
- push_stack (&gnu_switch_label_stack, NULL_TREE, create_artificial_label ());
+ push_stack (&gnu_switch_label_stack, NULL_TREE,
+ create_artificial_label (input_location));
start_stmt_group ();
for (gnat_when = First_Non_Pragma (Alternatives (gnat_node));
Present (gnat_when);
@@ -1908,9 +1909,10 @@ Case_Statement_to_gnu (Node_Id gnat_node)
if ((!gnu_low || TREE_CODE (gnu_low) == INTEGER_CST)
&& (!gnu_high || TREE_CODE (gnu_high) == INTEGER_CST))
{
- add_stmt_with_node (build3 (CASE_LABEL_EXPR, void_type_node,
- gnu_low, gnu_high,
- create_artificial_label ()),
+ add_stmt_with_node (build3
+ (CASE_LABEL_EXPR, void_type_node,
+ gnu_low, gnu_high,
+ create_artificial_label (input_location)),
gnat_choice);
choices_added++;
}
@@ -1953,7 +1955,7 @@ Loop_Statement_to_gnu (Node_Id gnat_node)
TREE_TYPE (gnu_loop_stmt) = void_type_node;
TREE_SIDE_EFFECTS (gnu_loop_stmt) = 1;
- LOOP_STMT_LABEL (gnu_loop_stmt) = create_artificial_label ();
+ LOOP_STMT_LABEL (gnu_loop_stmt) = create_artificial_label (input_location);
set_expr_location_from_node (gnu_loop_stmt, gnat_node);
Sloc_to_locus (Sloc (End_Label (gnat_node)),
&DECL_SOURCE_LOCATION (LOOP_STMT_LABEL (gnu_loop_stmt)));
@@ -2213,7 +2215,8 @@ Subprogram_Body_to_gnu (Node_Id gnat_node)
properly copies them out. We do this by making a new block and converting
any inner return into a goto to a label at the end of the block. */
push_stack (&gnu_return_label_stack, NULL_TREE,
- gnu_cico_list ? create_artificial_label () : NULL_TREE);
+ gnu_cico_list ? create_artificial_label (input_location)
+ : NULL_TREE);
/* Get a tree corresponding to the code for the subprogram. */
start_stmt_group ();
@@ -5101,9 +5104,6 @@ gnat_to_gnu (Node_Id gnat_node)
tree gnu_obj_type;
tree gnu_actual_obj_type = 0;
tree gnu_obj_size;
- unsigned int align;
- unsigned int default_allocator_alignment
- = get_target_default_allocator_alignment () * BITS_PER_UNIT;
/* If this is a thin pointer, we must dereference it to create
a fat pointer, then go back below to a thin pointer. The
@@ -5142,7 +5142,6 @@ gnat_to_gnu (Node_Id gnat_node)
gnu_actual_obj_type = gnu_obj_type;
gnu_obj_size = TYPE_SIZE_UNIT (gnu_actual_obj_type);
- align = TYPE_ALIGN (gnu_obj_type);
if (TREE_CODE (gnu_obj_type) == RECORD_TYPE
&& TYPE_CONTAINS_TEMPLATE_P (gnu_obj_type))
@@ -5159,42 +5158,11 @@ gnat_to_gnu (Node_Id gnat_node)
gnu_ptr, gnu_byte_offset);
}
- /* If the object was allocated from the default storage pool, the
- alignment was greater than what the allocator provides, and this
- is not a fat or thin pointer, what we have in gnu_ptr here is an
- address dynamically adjusted to match the alignment requirement
- (see build_allocator). What we need to pass to free is the
- initial allocator's return value, which has been stored just in
- front of the block we have. */
-
- if (No (Procedure_To_Call (gnat_node))
- && align > default_allocator_alignment
- && ! TYPE_FAT_OR_THIN_POINTER_P (gnu_ptr_type))
- {
- /* We set GNU_PTR
- as * (void **)((void *)GNU_PTR - (void *)sizeof(void *))
- in two steps: */
-
- /* GNU_PTR (void *)
- = (void *)GNU_PTR - (void *)sizeof (void *)) */
- gnu_ptr
- = build_binary_op
- (POINTER_PLUS_EXPR, ptr_void_type_node,
- convert (ptr_void_type_node, gnu_ptr),
- size_int (-POINTER_SIZE/BITS_PER_UNIT));
-
- /* GNU_PTR (void *) = *(void **)GNU_PTR */
- gnu_ptr
- = build_unary_op
- (INDIRECT_REF, NULL_TREE,
- convert (build_pointer_type (ptr_void_type_node),
- gnu_ptr));
- }
-
- gnu_result = build_call_alloc_dealloc (gnu_ptr, gnu_obj_size, align,
- Procedure_To_Call (gnat_node),
- Storage_Pool (gnat_node),
- gnat_node);
+ gnu_result
+ = build_call_alloc_dealloc (gnu_ptr, gnu_obj_size, gnu_obj_type,
+ Procedure_To_Call (gnat_node),
+ Storage_Pool (gnat_node),
+ gnat_node);
}
break;
@@ -5562,6 +5530,7 @@ add_decl_expr (tree gnu_decl, Entity_Id gnat_entity)
Note that walk_tree knows how to deal with TYPE_DECL, but neither
VAR_DECL nor CONST_DECL. This appears to be somewhat arbitrary. */
mark_visited (&gnu_stmt);
+
if (TREE_CODE (gnu_decl) == VAR_DECL
|| TREE_CODE (gnu_decl) == CONST_DECL)
{
@@ -5569,13 +5538,31 @@ add_decl_expr (tree gnu_decl, Entity_Id gnat_entity)
mark_visited (&DECL_SIZE_UNIT (gnu_decl));
mark_visited (&DECL_INITIAL (gnu_decl));
}
- /* In any case, we have to deal with our own TYPE_ADA_SIZE field. */
- if (TREE_CODE (gnu_decl) == TYPE_DECL
- && (TREE_CODE (type) == RECORD_TYPE
- || TREE_CODE (type) == UNION_TYPE
- || TREE_CODE (type) == QUAL_UNION_TYPE)
- && (t = TYPE_ADA_SIZE (type)))
- mark_visited (&t);
+
+ /* In any case, we have to deal with our own fields. */
+ else if (TREE_CODE (gnu_decl) == TYPE_DECL)
+ switch (TREE_CODE (type))
+ {
+ case RECORD_TYPE:
+ case UNION_TYPE:
+ case QUAL_UNION_TYPE:
+ if ((t = TYPE_ADA_SIZE (type)))
+ mark_visited (&t);
+ break;
+
+ case INTEGER_TYPE:
+ case ENUMERAL_TYPE:
+ case BOOLEAN_TYPE:
+ case REAL_TYPE:
+ if ((t = TYPE_RM_MIN_VALUE (type)))
+ mark_visited (&t);
+ if ((t = TYPE_RM_MAX_VALUE (type)))
+ mark_visited (&t);
+ break;
+
+ default:
+ break;
+ }
}
else
add_stmt_with_node (gnu_stmt, gnat_entity);
@@ -5891,7 +5878,7 @@ gnat_gimplify_stmt (tree *stmt_p)
case LOOP_STMT:
{
- tree gnu_start_label = create_artificial_label ();
+ tree gnu_start_label = create_artificial_label (input_location);
tree gnu_end_label = LOOP_STMT_LABEL (stmt);
tree t;
@@ -7246,30 +7233,29 @@ protect_multiple_eval (tree exp)
if (!TREE_SIDE_EFFECTS (exp))
return exp;
- /* If it is a conversion, protect what's inside the conversion.
+ /* If this is a conversion, protect what's inside the conversion.
Similarly, if we're indirectly referencing something, we only
- actually need to protect the address since the data itself can't
- change in these situations. */
- else if (TREE_CODE (exp) == NON_LVALUE_EXPR
- || CONVERT_EXPR_P (exp)
- || TREE_CODE (exp) == VIEW_CONVERT_EXPR
- || TREE_CODE (exp) == INDIRECT_REF
- || TREE_CODE (exp) == UNCONSTRAINED_ARRAY_REF)
- return build1 (TREE_CODE (exp), type,
- protect_multiple_eval (TREE_OPERAND (exp, 0)));
-
- /* If EXP is a fat pointer or something that can be placed into a register,
- just make a SAVE_EXPR. */
+ need to protect the address since the data itself can't change
+ in these situations. */
+ if (TREE_CODE (exp) == NON_LVALUE_EXPR
+ || CONVERT_EXPR_P (exp)
+ || TREE_CODE (exp) == VIEW_CONVERT_EXPR
+ || TREE_CODE (exp) == INDIRECT_REF
+ || TREE_CODE (exp) == UNCONSTRAINED_ARRAY_REF)
+ return build1 (TREE_CODE (exp), type,
+ protect_multiple_eval (TREE_OPERAND (exp, 0)));
+
+ /* If this is a fat pointer or something that can be placed into a
+ register, just make a SAVE_EXPR. */
if (TYPE_FAT_POINTER_P (type) || TYPE_MODE (type) != BLKmode)
return save_expr (exp);
- /* Otherwise, dereference, protect the address, and re-reference. */
- else
- return
- build_unary_op (INDIRECT_REF, type,
- save_expr (build_unary_op (ADDR_EXPR,
- build_reference_type (type),
- exp)));
+ /* Otherwise, reference, protect the address and dereference. */
+ return
+ build_unary_op (INDIRECT_REF, type,
+ save_expr (build_unary_op (ADDR_EXPR,
+ build_reference_type (type),
+ exp)));
}
/* This is equivalent to stabilize_reference in tree.c, but we know how to
diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c
index e3cf9756ea3..922e2941506 100644
--- a/gcc/ada/gcc-interface/utils.c
+++ b/gcc/ada/gcc-interface/utils.c
@@ -530,12 +530,14 @@ gnat_init_decl_processing (void)
set_sizetype (size_type_node);
/* In Ada, we use an unsigned 8-bit type for the default boolean type. */
- boolean_type_node = make_node (BOOLEAN_TYPE);
- TYPE_PRECISION (boolean_type_node) = 1;
- fixup_unsigned_type (boolean_type_node);
- TYPE_RM_SIZE (boolean_type_node) = bitsize_int (1);
+ boolean_type_node = make_unsigned_type (8);
+ TREE_SET_CODE (boolean_type_node, BOOLEAN_TYPE);
+ SET_TYPE_RM_MAX_VALUE (boolean_type_node,
+ build_int_cst (boolean_type_node, 1));
+ SET_TYPE_RM_SIZE (boolean_type_node, bitsize_int (1));
build_common_tree_nodes_2 (0);
+ boolean_true_node = TYPE_MAX_VALUE (boolean_type_node);
ptr_void_type_node = build_pointer_type (void_type_node);
}
@@ -545,7 +547,8 @@ gnat_init_decl_processing (void)
void
record_builtin_type (const char *name, tree type)
{
- tree type_decl = build_decl (TYPE_DECL, get_identifier (name), type);
+ tree type_decl = build_decl (input_location,
+ TYPE_DECL, get_identifier (name), type);
gnat_pushdecl (type_decl, Empty);
@@ -1195,6 +1198,42 @@ create_index_type (tree min, tree max, tree index, Node_Id gnat_node)
return type;
}
+
+/* Return a subtype of TYPE with range MIN to MAX. If TYPE is NULL,
+ sizetype is used. */
+
+tree
+create_range_type (tree type, tree min, tree max)
+{
+ tree range_type;
+
+ if (type == NULL_TREE)
+ type = sizetype;
+
+ /* First build a type with the base range. */
+ range_type
+ = build_range_type (type, TYPE_MIN_VALUE (type), TYPE_MAX_VALUE (type));
+
+ min = convert (type, min);
+ max = convert (type, max);
+
+ /* If this type has the TYPE_RM_{MIN,MAX}_VALUE we want, return it. */
+ if (TYPE_RM_MIN_VALUE (range_type)
+ && TYPE_RM_MAX_VALUE (range_type)
+ && operand_equal_p (TYPE_RM_MIN_VALUE (range_type), min, 0)
+ && operand_equal_p (TYPE_RM_MAX_VALUE (range_type), max, 0))
+ return range_type;
+
+ /* Otherwise, if TYPE_RM_{MIN,MAX}_VALUE is set, make a copy. */
+ if (TYPE_RM_MIN_VALUE (range_type) || TYPE_RM_MAX_VALUE (range_type))
+ range_type = copy_type (range_type);
+
+ /* Then set the actual range. */
+ SET_TYPE_RM_MIN_VALUE (range_type, min);
+ SET_TYPE_RM_MAX_VALUE (range_type, max);
+
+ return range_type;
+}
/* Return a TYPE_DECL node suitable for the TYPE_STUB_DECL field of a type.
TYPE_NAME gives the name of the type and TYPE is a ..._TYPE node giving
@@ -1206,7 +1245,8 @@ create_type_stub_decl (tree type_name, tree type)
/* Using a named TYPE_DECL ensures that a type name marker is emitted in
STABS while setting DECL_ARTIFICIAL ensures that no DW_TAG_typedef is
emitted in DWARF. */
- tree type_decl = build_decl (TYPE_DECL, type_name, type);
+ tree type_decl = build_decl (input_location,
+ TYPE_DECL, type_name, type);
DECL_ARTIFICIAL (type_decl) = 1;
return type_decl;
}
@@ -1236,7 +1276,8 @@ create_type_decl (tree type_name, tree type, struct attrib *attr_list,
DECL_NAME (type_decl) = type_name;
}
else
- type_decl = build_decl (TYPE_DECL, type_name, type);
+ type_decl = build_decl (input_location,
+ TYPE_DECL, type_name, type);
DECL_ARTIFICIAL (type_decl) = artificial_p;
gnat_pushdecl (type_decl, gnat_node);
@@ -1314,7 +1355,8 @@ create_var_decl_1 (tree var_name, tree asm_name, tree type, tree var_init,
/* The actual DECL node. CONST_DECL was initially intended for enumerals
and may be used for scalars in general but not for aggregates. */
tree var_decl
- = build_decl ((constant_p && const_decl_allowed_p
+ = build_decl (input_location,
+ (constant_p && const_decl_allowed_p
&& !AGGREGATE_TYPE_P (type)) ? CONST_DECL : VAR_DECL,
var_name, type);
@@ -1427,7 +1469,8 @@ tree
create_field_decl (tree field_name, tree field_type, tree record_type,
int packed, tree size, tree pos, int addressable)
{
- tree field_decl = build_decl (FIELD_DECL, field_name, field_type);
+ tree field_decl = build_decl (input_location,
+ FIELD_DECL, field_name, field_type);
DECL_CONTEXT (field_decl) = record_type;
TREE_READONLY (field_decl) = TYPE_READONLY (field_type);
@@ -1568,7 +1611,8 @@ create_field_decl (tree field_name, tree field_type, tree record_type,
tree
create_param_decl (tree param_name, tree param_type, bool readonly)
{
- tree param_decl = build_decl (PARM_DECL, param_name, param_type);
+ tree param_decl = build_decl (input_location,
+ PARM_DECL, param_name, param_type);
/* Honor TARGET_PROMOTE_PROTOTYPES like the C compiler, as not doing so
can lead to various ABI violations. */
@@ -1581,16 +1625,12 @@ create_param_decl (tree param_name, tree param_type, bool readonly)
if (TREE_CODE (param_type) == INTEGER_TYPE
&& TYPE_BIASED_REPRESENTATION_P (param_type))
{
- tree subtype = make_node (INTEGER_TYPE);
+ tree subtype
+ = make_unsigned_type (TYPE_PRECISION (integer_type_node));
TREE_TYPE (subtype) = integer_type_node;
TYPE_BIASED_REPRESENTATION_P (subtype) = 1;
-
- TYPE_UNSIGNED (subtype) = 1;
- TYPE_PRECISION (subtype) = TYPE_PRECISION (integer_type_node);
- TYPE_MIN_VALUE (subtype) = TYPE_MIN_VALUE (param_type);
- TYPE_MAX_VALUE (subtype) = TYPE_MAX_VALUE (param_type);
- layout_type (subtype);
-
+ SET_TYPE_RM_MIN_VALUE (subtype, TYPE_MIN_VALUE (param_type));
+ SET_TYPE_RM_MAX_VALUE (subtype, TYPE_MAX_VALUE (param_type));
param_type = subtype;
}
else
@@ -1752,7 +1792,8 @@ potential_alignment_gap (tree prev_field, tree curr_field, tree offset)
tree
create_label_decl (tree label_name)
{
- tree label_decl = build_decl (LABEL_DECL, label_name, void_type_node);
+ tree label_decl = build_decl (input_location,
+ LABEL_DECL, label_name, void_type_node);
DECL_CONTEXT (label_decl) = current_function_decl;
DECL_MODE (label_decl) = VOIDmode;
@@ -1776,7 +1817,8 @@ create_subprog_decl (tree subprog_name, tree asm_name,
struct attrib *attr_list, Node_Id gnat_node)
{
tree return_type = TREE_TYPE (subprog_type);
- tree subprog_decl = build_decl (FUNCTION_DECL, subprog_name, subprog_type);
+ tree subprog_decl = build_decl (input_location,
+ FUNCTION_DECL, subprog_name, subprog_type);
/* If this is a non-inline function nested inside an inlined external
function, we cannot honor both requests without cloning the nested
@@ -1797,7 +1839,8 @@ create_subprog_decl (tree subprog_name, tree asm_name,
TREE_SIDE_EFFECTS (subprog_decl) = TYPE_VOLATILE (subprog_type);
DECL_DECLARED_INLINE_P (subprog_decl) = inline_flag;
DECL_ARGUMENTS (subprog_decl) = param_decl_list;
- DECL_RESULT (subprog_decl) = build_decl (RESULT_DECL, 0, return_type);
+ DECL_RESULT (subprog_decl) = build_decl (input_location,
+ RESULT_DECL, 0, return_type);
DECL_ARTIFICIAL (DECL_RESULT (subprog_decl)) = 1;
DECL_IGNORED_P (DECL_RESULT (subprog_decl)) = 1;
@@ -3945,6 +3988,10 @@ convert (tree type, tree expr)
unsigned HOST_WIDE_INT idx;
tree index, value;
+ /* Whether we need to clear TREE_CONSTANT et al. on the output
+ constructor when we convert in place. */
+ bool clear_constant = false;
+
FOR_EACH_CONSTRUCTOR_ELT(e, idx, index, value)
{
constructor_elt *elt = VEC_quick_push (constructor_elt, v, NULL);
@@ -3953,15 +4000,30 @@ convert (tree type, tree expr)
break;
elt->index = field;
elt->value = convert (TREE_TYPE (field), value);
+
+ /* If packing has made this field a bitfield and the input
+ value couldn't be emitted statically any more, we need to
+ clear TREE_CONSTANT on our output. */
+ if (!clear_constant && TREE_CONSTANT (expr)
+ && !CONSTRUCTOR_BITFIELD_P (efield)
+ && CONSTRUCTOR_BITFIELD_P (field)
+ && !initializer_constant_valid_for_bitfield_p (value))
+ clear_constant = true;
+
efield = TREE_CHAIN (efield);
field = TREE_CHAIN (field);
}
+ /* If we have been able to match and convert all the input fields
+ to their output type, convert in place now. We'll fallback to a
+ view conversion downstream otherwise. */
if (idx == len)
{
expr = copy_node (expr);
TREE_TYPE (expr) = type;
CONSTRUCTOR_ELTS (expr) = v;
+ if (clear_constant)
+ TREE_CONSTANT (expr) = TREE_STATIC (expr) = false;
return expr;
}
}
@@ -4288,8 +4350,7 @@ maybe_unconstrained_array (tree exp)
}
/* Return true if EXPR is an expression that can be folded as an operand
- of a VIEW_CONVERT_EXPR. See the head comment of unchecked_convert for
- the rationale. */
+ of a VIEW_CONVERT_EXPR. See ada-tree.h for a complete rationale. */
static bool
can_fold_for_view_convert_p (tree expr)
@@ -4337,22 +4398,7 @@ can_fold_for_view_convert_p (tree expr)
we expect the 8 bits at Vbits'Address to always contain Value, while
their original location depends on the endianness, at Value'Address
- on a little-endian architecture but not on a big-endian one.
-
- ??? There is a problematic discrepancy between what is called precision
- here (and more generally throughout gigi) for integral types and what is
- called precision in the middle-end. In the former case it's the RM size
- as given by TYPE_RM_SIZE (or rm_size) whereas it's TYPE_PRECISION in the
- latter case, the hitch being that they are not equal when they matter,
- that is when the number of value bits is not equal to the type's size:
- TYPE_RM_SIZE does give the number of value bits but TYPE_PRECISION is set
- to the size. The sole exception are BOOLEAN_TYPEs for which both are 1.
-
- The consequence is that gigi must duplicate code bridging the gap between
- the type's size and its precision that exists for TYPE_PRECISION in the
- middle-end, because the latter knows nothing about TYPE_RM_SIZE, and be
- wary of transformations applied in the middle-end based on TYPE_PRECISION
- because this value doesn't reflect the actual precision for Ada. */
+ on a little-endian architecture but not on a big-endian one. */
tree
unchecked_convert (tree type, tree expr, bool notrunc_p)
@@ -4397,43 +4443,6 @@ unchecked_convert (tree type, tree expr, bool notrunc_p)
expr = convert (rtype, expr);
expr = build1 (NOP_EXPR, type, expr);
}
-
- /* We have another special case: if we are unchecked converting either
- a subtype or a type with limited range into a base type, we need to
- ensure that VRP doesn't propagate range information because this
- conversion may be done precisely to validate that the object is
- within the range it is supposed to have. */
- else if (TREE_CODE (expr) != INTEGER_CST
- && TREE_CODE (type) == INTEGER_TYPE && !TREE_TYPE (type)
- && ((TREE_CODE (etype) == INTEGER_TYPE && TREE_TYPE (etype))
- || TREE_CODE (etype) == ENUMERAL_TYPE
- || TREE_CODE (etype) == BOOLEAN_TYPE))
- {
- /* The optimization barrier is a VIEW_CONVERT_EXPR node; moreover,
- in order not to be deemed an useless type conversion, it must
- be from subtype to base type.
-
- Therefore we first do the bulk of the conversion to a subtype of
- the final type. And this conversion must itself not be deemed
- useless if the source type is not a subtype because, otherwise,
- the final VIEW_CONVERT_EXPR will be deemed so as well. That's
- why we toggle the unsigned flag in this conversion, which is
- harmless since the final conversion is only a reinterpretation
- of the bit pattern.
-
- ??? This may raise addressability and/or aliasing issues because
- VIEW_CONVERT_EXPR gets gimplified as an lvalue, thus causing the
- address of its operand to be taken if it is deemed addressable
- and not already in GIMPLE form. */
- tree rtype
- = gnat_type_for_mode (TYPE_MODE (type), !TYPE_UNSIGNED (etype));
- rtype = copy_type (rtype);
- TYPE_MAIN_VARIANT (rtype) = rtype;
- TREE_TYPE (rtype) = type;
- expr = convert (rtype, expr);
- expr = build1 (VIEW_CONVERT_EXPR, type, expr);
- }
-
else
expr = convert (type, expr);
}
diff --git a/gcc/ada/gcc-interface/utils2.c b/gcc/ada/gcc-interface/utils2.c
index e5001ab7d42..aab01f9b5d7 100644
--- a/gcc/ada/gcc-interface/utils2.c
+++ b/gcc/ada/gcc-interface/utils2.c
@@ -802,11 +802,10 @@ build_binary_op (enum tree_code op_code, tree result_type,
left_type = TREE_TYPE (left_operand);
}
- /* Then convert the right operand to its base type. This will
- prevent unneeded signedness conversions when sizetype is wider than
- integer. */
+ /* Then convert the right operand to its base type. This will prevent
+ unneeded sign conversions when sizetype is wider than integer. */
right_operand = convert (right_base_type, right_operand);
- right_operand = convert (TYPE_DOMAIN (left_type), right_operand);
+ right_operand = convert (sizetype, right_operand);
if (!TREE_CONSTANT (right_operand)
|| !TREE_CONSTANT (TYPE_MIN_VALUE (right_type)))
@@ -1624,34 +1623,35 @@ compare_elmt_bitpos (const PTR rt1, const PTR rt2)
tree
gnat_build_constructor (tree type, tree list)
{
- tree elmt;
- int n_elmts;
bool allconstant = (TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST);
bool side_effects = false;
- tree result;
+ tree elmt, result;
+ int n_elmts;
/* Scan the elements to see if they are all constant or if any has side
effects, to let us set global flags on the resulting constructor. Count
the elements along the way for possible sorting purposes below. */
for (n_elmts = 0, elmt = list; elmt; elmt = TREE_CHAIN (elmt), n_elmts ++)
{
- if (!TREE_CONSTANT (TREE_VALUE (elmt))
+ tree obj = TREE_PURPOSE (elmt);
+ tree val = TREE_VALUE (elmt);
+
+ /* The predicate must be in keeping with output_constructor. */
+ if (!TREE_CONSTANT (val)
|| (TREE_CODE (type) == RECORD_TYPE
- && DECL_BIT_FIELD (TREE_PURPOSE (elmt))
- && TREE_CODE (TREE_VALUE (elmt)) != INTEGER_CST)
- || !initializer_constant_valid_p (TREE_VALUE (elmt),
- TREE_TYPE (TREE_VALUE (elmt))))
+ && CONSTRUCTOR_BITFIELD_P (obj)
+ && !initializer_constant_valid_for_bitfield_p (val))
+ || !initializer_constant_valid_p (val, TREE_TYPE (val)))
allconstant = false;
- if (TREE_SIDE_EFFECTS (TREE_VALUE (elmt)))
+ if (TREE_SIDE_EFFECTS (val))
side_effects = true;
/* Propagate an NULL_EXPR from the size of the type. We won't ever
be executing the code we generate here in that case, but handle it
specially to avoid the compiler blowing up. */
if (TREE_CODE (type) == RECORD_TYPE
- && (0 != (result
- = contains_null_expr (DECL_SIZE (TREE_PURPOSE (elmt))))))
+ && (result = contains_null_expr (DECL_SIZE (obj))) != NULL_TREE)
return build1 (NULL_EXPR, type, TREE_OPERAND (result, 0));
}
@@ -1830,95 +1830,99 @@ build_component_ref (tree record_variable, tree component,
N_Raise_Constraint_Error));
}
-/* Build a GCC tree to call an allocation or deallocation function.
- If GNU_OBJ is nonzero, it is an object to deallocate. Otherwise,
- generate an allocator.
-
- GNU_SIZE is the size of the object in bytes and ALIGN is the alignment
- in bits. GNAT_PROC, if present, is a procedure to call and GNAT_POOL
- is the storage pool to use. If not present, malloc and free are used.
- GNAT_NODE is used to provide an error location for restriction violation
- messages. */
+/* Helper for build_call_alloc_dealloc, with arguments to be interpreted
+ identically. Process the case where a GNAT_PROC to call is provided. */
-tree
-build_call_alloc_dealloc (tree gnu_obj, tree gnu_size, unsigned align,
- Entity_Id gnat_proc, Entity_Id gnat_pool,
- Node_Id gnat_node)
+static inline tree
+build_call_alloc_dealloc_proc (tree gnu_obj, tree gnu_size, tree gnu_type,
+ Entity_Id gnat_proc, Entity_Id gnat_pool)
{
- tree gnu_align = size_int (align / BITS_PER_UNIT);
-
- gnu_size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (gnu_size, gnu_obj);
+ tree gnu_proc = gnat_to_gnu (gnat_proc);
+ tree gnu_proc_addr = build_unary_op (ADDR_EXPR, NULL_TREE, gnu_proc);
+ tree gnu_call;
- if (Present (gnat_proc))
+ /* The storage pools are obviously always tagged types, but the
+ secondary stack uses the same mechanism and is not tagged. */
+ if (Is_Tagged_Type (Etype (gnat_pool)))
{
- /* The storage pools are obviously always tagged types, but the
- secondary stack uses the same mechanism and is not tagged. */
- if (Is_Tagged_Type (Etype (gnat_pool)))
- {
- /* The size is the third parameter; the alignment is the
- same type. */
- Entity_Id gnat_size_type
- = Etype (Next_Formal (Next_Formal (First_Formal (gnat_proc))));
- tree gnu_size_type = gnat_to_gnu_type (gnat_size_type);
- tree gnu_proc = gnat_to_gnu (gnat_proc);
- tree gnu_proc_addr = build_unary_op (ADDR_EXPR, NULL_TREE, gnu_proc);
- tree gnu_pool = gnat_to_gnu (gnat_pool);
- tree gnu_pool_addr = build_unary_op (ADDR_EXPR, NULL_TREE, gnu_pool);
- tree gnu_call;
-
- gnu_size = convert (gnu_size_type, gnu_size);
- gnu_align = convert (gnu_size_type, gnu_align);
-
- /* The first arg is always the address of the storage pool; next
- comes the address of the object, for a deallocator, then the
- size and alignment. */
- if (gnu_obj)
- gnu_call = build_call_nary (TREE_TYPE (TREE_TYPE (gnu_proc)),
- gnu_proc_addr, 4, gnu_pool_addr,
- gnu_obj, gnu_size, gnu_align);
- else
- gnu_call = build_call_nary (TREE_TYPE (TREE_TYPE (gnu_proc)),
- gnu_proc_addr, 3, gnu_pool_addr,
- gnu_size, gnu_align);
- TREE_SIDE_EFFECTS (gnu_call) = 1;
- return gnu_call;
- }
+ /* The size is the third parameter; the alignment is the
+ same type. */
+ Entity_Id gnat_size_type
+ = Etype (Next_Formal (Next_Formal (First_Formal (gnat_proc))));
+ tree gnu_size_type = gnat_to_gnu_type (gnat_size_type);
+
+ tree gnu_pool = gnat_to_gnu (gnat_pool);
+ tree gnu_pool_addr = build_unary_op (ADDR_EXPR, NULL_TREE, gnu_pool);
+ tree gnu_align = size_int (TYPE_ALIGN (gnu_type) / BITS_PER_UNIT);
+
+ gnu_size = convert (gnu_size_type, gnu_size);
+ gnu_align = convert (gnu_size_type, gnu_align);
+
+ /* The first arg is always the address of the storage pool; next
+ comes the address of the object, for a deallocator, then the
+ size and alignment. */
+ if (gnu_obj)
+ gnu_call = build_call_nary (TREE_TYPE (TREE_TYPE (gnu_proc)),
+ gnu_proc_addr, 4, gnu_pool_addr,
+ gnu_obj, gnu_size, gnu_align);
+ else
+ gnu_call = build_call_nary (TREE_TYPE (TREE_TYPE (gnu_proc)),
+ gnu_proc_addr, 3, gnu_pool_addr,
+ gnu_size, gnu_align);
+ }
- /* Secondary stack case. */
+ /* Secondary stack case. */
+ else
+ {
+ /* The size is the second parameter. */
+ Entity_Id gnat_size_type
+ = Etype (Next_Formal (First_Formal (gnat_proc)));
+ tree gnu_size_type = gnat_to_gnu_type (gnat_size_type);
+
+ gnu_size = convert (gnu_size_type, gnu_size);
+
+ /* The first arg is the address of the object, for a deallocator,
+ then the size. */
+ if (gnu_obj)
+ gnu_call = build_call_nary (TREE_TYPE (TREE_TYPE (gnu_proc)),
+ gnu_proc_addr, 2, gnu_obj, gnu_size);
else
- {
- /* The size is the second parameter. */
- Entity_Id gnat_size_type
- = Etype (Next_Formal (First_Formal (gnat_proc)));
- tree gnu_size_type = gnat_to_gnu_type (gnat_size_type);
- tree gnu_proc = gnat_to_gnu (gnat_proc);
- tree gnu_proc_addr = build_unary_op (ADDR_EXPR, NULL_TREE, gnu_proc);
- tree gnu_call;
-
- gnu_size = convert (gnu_size_type, gnu_size);
-
- /* The first arg is the address of the object, for a deallocator,
- then the size. */
- if (gnu_obj)
- gnu_call = build_call_nary (TREE_TYPE (TREE_TYPE (gnu_proc)),
- gnu_proc_addr, 2, gnu_obj, gnu_size);
- else
- gnu_call = build_call_nary (TREE_TYPE (TREE_TYPE (gnu_proc)),
- gnu_proc_addr, 1, gnu_size);
- TREE_SIDE_EFFECTS (gnu_call) = 1;
- return gnu_call;
- }
+ gnu_call = build_call_nary (TREE_TYPE (TREE_TYPE (gnu_proc)),
+ gnu_proc_addr, 1, gnu_size);
}
- if (gnu_obj)
- return build_call_1_expr (free_decl, gnu_obj);
+ TREE_SIDE_EFFECTS (gnu_call) = 1;
+ return gnu_call;
+}
+
+/* Helper for build_call_alloc_dealloc, to build and return an allocator for
+ DATA_SIZE bytes aimed at containing a DATA_TYPE object, using the default
+ __gnat_malloc allocator. Honor DATA_TYPE alignments greater than what the
+ latter offers. */
+
+static inline tree
+maybe_wrap_malloc (tree data_size, tree data_type, Node_Id gnat_node)
+{
+ /* When the DATA_TYPE alignment is stricter than what malloc offers
+ (super-aligned case), we allocate an "aligning" wrapper type and return
+ the address of its single data field with the malloc's return value
+ stored just in front. */
+
+ unsigned int data_align = TYPE_ALIGN (data_type);
+ unsigned int default_allocator_alignment
+ = get_target_default_allocator_alignment () * BITS_PER_UNIT;
+
+ tree aligning_type
+ = ((data_align > default_allocator_alignment)
+ ? make_aligning_type (data_type, data_align, data_size,
+ default_allocator_alignment,
+ POINTER_SIZE / BITS_PER_UNIT)
+ : NULL_TREE);
- /* Assert that we no longer can be called with this special pool. */
- gcc_assert (gnat_pool != -1);
+ tree size_to_malloc
+ = aligning_type ? TYPE_SIZE_UNIT (aligning_type) : data_size;
- /* Check that we aren't violating the associated restriction. */
- if (!(Nkind (gnat_node) == N_Allocator && Comes_From_Source (gnat_node)))
- Check_No_Implicit_Heap_Alloc (gnat_node);
+ tree malloc_ptr;
/* On VMS, if 64-bit memory is disabled or pointers are 64-bit and the
allocator size is 32-bit or Convention C, allocate 32-bit memory. */
@@ -1927,9 +1931,127 @@ build_call_alloc_dealloc (tree gnu_obj, tree gnu_size, unsigned align,
|| (POINTER_SIZE == 64
&& (UI_To_Int (Esize (Etype (gnat_node))) == 32
|| Convention (Etype (gnat_node)) == Convention_C))))
- return build_call_1_expr (malloc32_decl, gnu_size);
+ malloc_ptr = build_call_1_expr (malloc32_decl, size_to_malloc);
+ else
+ malloc_ptr = build_call_1_expr (malloc_decl, size_to_malloc);
+
+ if (aligning_type)
+ {
+ /* Latch malloc's return value and get a pointer to the aligning field
+ first. */
+ tree storage_ptr = save_expr (malloc_ptr);
+
+ tree aligning_record_addr
+ = convert (build_pointer_type (aligning_type), storage_ptr);
+
+ tree aligning_record
+ = build_unary_op (INDIRECT_REF, NULL_TREE, aligning_record_addr);
+
+ tree aligning_field
+ = build_component_ref (aligning_record, NULL_TREE,
+ TYPE_FIELDS (aligning_type), 0);
+
+ tree aligning_field_addr
+ = build_unary_op (ADDR_EXPR, NULL_TREE, aligning_field);
+
+ /* Then arrange to store the allocator's return value ahead
+ and return. */
+ tree storage_ptr_slot_addr
+ = build_binary_op (POINTER_PLUS_EXPR, ptr_void_type_node,
+ convert (ptr_void_type_node, aligning_field_addr),
+ size_int (-POINTER_SIZE/BITS_PER_UNIT));
+
+ tree storage_ptr_slot
+ = build_unary_op (INDIRECT_REF, NULL_TREE,
+ convert (build_pointer_type (ptr_void_type_node),
+ storage_ptr_slot_addr));
+
+ return
+ build2 (COMPOUND_EXPR, TREE_TYPE (aligning_field_addr),
+ build_binary_op (MODIFY_EXPR, NULL_TREE,
+ storage_ptr_slot, storage_ptr),
+ aligning_field_addr);
+ }
+ else
+ return malloc_ptr;
+}
+
+/* Helper for build_call_alloc_dealloc, to release a DATA_TYPE object
+ designated by DATA_PTR using the __gnat_free entry point. */
+
+static inline tree
+maybe_wrap_free (tree data_ptr, tree data_type)
+{
+ /* In the regular alignment case, we pass the data pointer straight to free.
+ In the superaligned case, we need to retrieve the initial allocator
+ return value, stored in front of the data block at allocation time. */
- return build_call_1_expr (malloc_decl, gnu_size);
+ unsigned int data_align = TYPE_ALIGN (data_type);
+ unsigned int default_allocator_alignment
+ = get_target_default_allocator_alignment () * BITS_PER_UNIT;
+
+ tree free_ptr;
+
+ if (data_align > default_allocator_alignment)
+ {
+ /* DATA_FRONT_PTR (void *)
+ = (void *)DATA_PTR - (void *)sizeof (void *)) */
+ tree data_front_ptr
+ = build_binary_op
+ (POINTER_PLUS_EXPR, ptr_void_type_node,
+ convert (ptr_void_type_node, data_ptr),
+ size_int (-POINTER_SIZE/BITS_PER_UNIT));
+
+ /* FREE_PTR (void *) = *(void **)DATA_FRONT_PTR */
+ free_ptr
+ = build_unary_op
+ (INDIRECT_REF, NULL_TREE,
+ convert (build_pointer_type (ptr_void_type_node), data_front_ptr));
+ }
+ else
+ free_ptr = data_ptr;
+
+ return build_call_1_expr (free_decl, free_ptr);
+}
+
+/* Build a GCC tree to call an allocation or deallocation function.
+ If GNU_OBJ is nonzero, it is an object to deallocate. Otherwise,
+ generate an allocator.
+
+ GNU_SIZE is the number of bytes to allocate and GNU_TYPE is the contained
+ object type, used to determine the to-be-honored address alignment.
+ GNAT_PROC, if present, is a procedure to call and GNAT_POOL is the storage
+ pool to use. If not present, malloc and free are used. GNAT_NODE is used
+ to provide an error location for restriction violation messages. */
+
+tree
+build_call_alloc_dealloc (tree gnu_obj, tree gnu_size, tree gnu_type,
+ Entity_Id gnat_proc, Entity_Id gnat_pool,
+ Node_Id gnat_node)
+{
+ gnu_size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (gnu_size, gnu_obj);
+
+ /* Explicit proc to call ? This one is assumed to deal with the type
+ alignment constraints. */
+ if (Present (gnat_proc))
+ return build_call_alloc_dealloc_proc (gnu_obj, gnu_size, gnu_type,
+ gnat_proc, gnat_pool);
+
+ /* Otherwise, object to "free" or "malloc" with possible special processing
+ for alignments stricter than what the default allocator honors. */
+ else if (gnu_obj)
+ return maybe_wrap_free (gnu_obj, gnu_type);
+ else
+ {
+ /* Assert that we no longer can be called with this special pool. */
+ gcc_assert (gnat_pool != -1);
+
+ /* Check that we aren't violating the associated restriction. */
+ if (!(Nkind (gnat_node) == N_Allocator && Comes_From_Source (gnat_node)))
+ Check_No_Implicit_Heap_Alloc (gnat_node);
+
+ return maybe_wrap_malloc (gnu_size, gnu_type, gnat_node);
+ }
}
/* Build a GCC tree to correspond to allocating an object of TYPE whose
@@ -1949,8 +2071,6 @@ build_allocator (tree type, tree init, tree result_type, Entity_Id gnat_proc,
{
tree size = TYPE_SIZE_UNIT (type);
tree result;
- unsigned int default_allocator_alignment
- = get_target_default_allocator_alignment () * BITS_PER_UNIT;
/* If the initializer, if present, is a NULL_EXPR, just return a new one. */
if (init && TREE_CODE (init) == NULL_EXPR)
@@ -1977,8 +2097,7 @@ build_allocator (tree type, tree init, tree result_type, Entity_Id gnat_proc,
if (TREE_CODE (size) == INTEGER_CST && TREE_OVERFLOW (size))
size = ssize_int (-1);
- storage = build_call_alloc_dealloc (NULL_TREE, size,
- TYPE_ALIGN (storage_type),
+ storage = build_call_alloc_dealloc (NULL_TREE, size, storage_type,
gnat_proc, gnat_pool, gnat_node);
storage = convert (storage_ptr_type, protect_multiple_eval (storage));
@@ -2050,70 +2169,10 @@ build_allocator (tree type, tree init, tree result_type, Entity_Id gnat_proc,
if (TREE_CODE (size) == INTEGER_CST && TREE_OVERFLOW (size))
size = ssize_int (-1);
- /* If this is in the default storage pool and the type alignment is larger
- than what the default allocator supports, make an "aligning" record type
- with room to store a pointer before the field, allocate an object of that
- type, store the system's allocator return value just in front of the
- field and return the field's address. */
-
- if (No (gnat_proc) && TYPE_ALIGN (type) > default_allocator_alignment)
- {
- /* Construct the aligning type with enough room for a pointer ahead
- of the field, then allocate. */
- tree record_type
- = make_aligning_type (type, TYPE_ALIGN (type), size,
- default_allocator_alignment,
- POINTER_SIZE / BITS_PER_UNIT);
-
- tree record, record_addr;
-
- record_addr
- = build_call_alloc_dealloc (NULL_TREE, TYPE_SIZE_UNIT (record_type),
- default_allocator_alignment, Empty, Empty,
- gnat_node);
-
- record_addr
- = convert (build_pointer_type (record_type),
- save_expr (record_addr));
-
- record = build_unary_op (INDIRECT_REF, NULL_TREE, record_addr);
-
- /* Our RESULT (the Ada allocator's value) is the super-aligned address
- of the internal record field ... */
- result
- = build_unary_op (ADDR_EXPR, NULL_TREE,
- build_component_ref
- (record, NULL_TREE, TYPE_FIELDS (record_type), 0));
- result = convert (result_type, result);
-
- /* ... with the system allocator's return value stored just in
- front. */
- {
- tree ptr_addr
- = build_binary_op (POINTER_PLUS_EXPR, ptr_void_type_node,
- convert (ptr_void_type_node, result),
- size_int (-POINTER_SIZE/BITS_PER_UNIT));
-
- tree ptr_ref
- = convert (build_pointer_type (ptr_void_type_node), ptr_addr);
-
- result
- = build2 (COMPOUND_EXPR, TREE_TYPE (result),
- build_binary_op (MODIFY_EXPR, NULL_TREE,
- build_unary_op (INDIRECT_REF, NULL_TREE,
- ptr_ref),
- convert (ptr_void_type_node,
- record_addr)),
- result);
- }
- }
- else
- result = convert (result_type,
- build_call_alloc_dealloc (NULL_TREE, size,
- TYPE_ALIGN (type),
- gnat_proc,
- gnat_pool,
- gnat_node));
+ result = convert (result_type,
+ build_call_alloc_dealloc (NULL_TREE, size, type,
+ gnat_proc, gnat_pool,
+ gnat_node));
/* If we have an initial value, put the new address into a SAVE_EXPR, assign
the value, and return the address. Do this with a COMPOUND_EXPR. */
diff --git a/gcc/ada/lib.ads b/gcc/ada/lib.ads
index 50be722e1f6..145d16dff08 100644
--- a/gcc/ada/lib.ads
+++ b/gcc/ada/lib.ads
@@ -734,9 +734,9 @@ private
Table_Name => "Linker_Option_Lines");
-- The following table records the compilation switches used to compile
- -- the main unit. The table includes only switches and excludes -quiet,
- -- -dumpbase, and -o switches, since the latter are typically artifacts
- -- of the gcc/gnat1 interface.
+ -- the main unit. The table includes only switches. It excludes -o
+ -- switches as well as artifacts of the gcc/gnat1 interface such as
+ -- -quiet, -dumpbase, or -auxbase.
-- This table is set as part of the compiler argument scanning in
-- Back_End. It can also be reset in -gnatc mode from the data in an
diff --git a/gcc/ada/scng.adb b/gcc/ada/scng.adb
index 56b1e4cc404..e7d9edc336e 100644
--- a/gcc/ada/scng.adb
+++ b/gcc/ada/scng.adb
@@ -875,7 +875,8 @@ package body Scng is
end if;
end if;
- Error_Msg_S ("missing string quote");
+ Error_Msg_S -- CODEFIX
+ ("missing string quote");
end Error_Unterminated_String;
----------------
diff --git a/gcc/ada/sem_attr.adb b/gcc/ada/sem_attr.adb
index 028d8b54ac3..51536ae5bd1 100644
--- a/gcc/ada/sem_attr.adb
+++ b/gcc/ada/sem_attr.adb
@@ -7834,16 +7834,16 @@ package body Sem_Attr is
-- Check the static accessibility rule of 3.10.2(32).
-- This rule also applies within the private part of an
-- instantiation. This rule does not apply to anonymous
- -- access-to-subprogram types (Ada 2005).
+ -- access-to-subprogram types in access parameters.
elsif Attr_Id = Attribute_Access
and then not In_Instance_Body
+ and then
+ (Ekind (Btyp) = E_Access_Subprogram_Type
+ or else Is_Local_Anonymous_Access (Btyp))
+
and then Subprogram_Access_Level (Entity (P)) >
Type_Access_Level (Btyp)
- and then Ekind (Btyp) /=
- E_Anonymous_Access_Subprogram_Type
- and then Ekind (Btyp) /=
- E_Anonymous_Access_Protected_Subprogram_Type
then
Error_Msg_F
("subprogram must not be deeper than access type", P);
diff --git a/gcc/ada/sem_warn.adb b/gcc/ada/sem_warn.adb
index 8132531cc0c..0ba87cccc4c 100644
--- a/gcc/ada/sem_warn.adb
+++ b/gcc/ada/sem_warn.adb
@@ -3523,11 +3523,11 @@ package body Sem_Warn is
if Nkind (Original_Node (X)) = N_Integer_Literal then
if Intval (X) = Low_Bound then
- Error_Msg_FE
+ Error_Msg_FE -- CODEFIX
("\suggested replacement: `&''First`", X, Ent);
else
Error_Msg_Uint_1 := Intval (X) - Low_Bound;
- Error_Msg_FE
+ Error_Msg_FE -- CODEFIX
("\suggested replacement: `&''First + ^`", X, Ent);
end if;
@@ -3633,7 +3633,7 @@ package body Sem_Warn is
-- Replacement subscript is now in string buffer
- Error_Msg_FE
+ Error_Msg_FE -- CODEFIX
("\suggested replacement: `&~`", Original_Node (X), Ent);
end if;
diff --git a/gcc/ada/sfn_scan.adb b/gcc/ada/sfn_scan.adb
index 226ef8b58d1..dc6ab38d448 100644
--- a/gcc/ada/sfn_scan.adb
+++ b/gcc/ada/sfn_scan.adb
@@ -637,7 +637,8 @@ package body SFN_Scan is
loop
if At_EOF or else S (P) = LF or else S (P) = CR then
- Error ("missing string quote");
+ Error -- CODEFIX
+ ("missing string quote");
elsif S (P) = HT then
Error ("tab character in string");
diff --git a/gcc/ada/switch.adb b/gcc/ada/switch.adb
index f318de7f191..cb5c4d11f49 100644
--- a/gcc/ada/switch.adb
+++ b/gcc/ada/switch.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2008, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2009, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -138,6 +138,22 @@ package body Switch is
and then Switch_Chars (Ptr + 2 .. Ptr + 4) = "RTS"));
end Is_Front_End_Switch;
+ ----------------------------
+ -- Is_Internal_GCC_Switch --
+ ----------------------------
+
+ function Is_Internal_GCC_Switch (Switch_Chars : String) return Boolean is
+ First : constant Natural := Switch_Chars'First + 1;
+ Last : constant Natural := Switch_Last (Switch_Chars);
+ begin
+ return Is_Switch (Switch_Chars)
+ and then
+ (Switch_Chars (First .. Last) = "-param" or else
+ Switch_Chars (First .. Last) = "dumpbase" or else
+ Switch_Chars (First .. Last) = "auxbase-strip" or else
+ Switch_Chars (First .. Last) = "auxbase");
+ end Is_Internal_GCC_Switch;
+
---------------
-- Is_Switch --
---------------
@@ -149,6 +165,22 @@ package body Switch is
end Is_Switch;
-----------------
+ -- Switch_last --
+ -----------------
+
+ function Switch_Last (Switch_Chars : String) return Natural is
+ Last : constant Natural := Switch_Chars'Last;
+ begin
+ if Last >= Switch_Chars'First
+ and then Switch_Chars (Last) = ASCII.NUL
+ then
+ return Last - 1;
+ else
+ return Last;
+ end if;
+ end Switch_Last;
+
+ -----------------
-- Nat_Present --
-----------------
diff --git a/gcc/ada/switch.ads b/gcc/ada/switch.ads
index 9b6c7ea4552..027bf835487 100644
--- a/gcc/ada/switch.ads
+++ b/gcc/ada/switch.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 1992-2008, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2009, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -72,11 +72,21 @@ package Switch is
-- Returns True iff Switch_Chars represents a front-end switch, i.e. it
-- starts with -I, -gnat or -?RTS.
-private
+ function Is_Internal_GCC_Switch (Switch_Chars : String) return Boolean;
+ -- Returns True iff Switch_Chars represents an internal GCC switch to be
+ -- followed by a single argument, such as -dumpbase, --param or -auxbase.
+ -- Eventhough passed by the "gcc" driver, these need not be stored in ALI
+ -- files and may safely be ignored by non GCC back-ends.
+
+ function Switch_Last (Switch_Chars : String) return Natural;
+ -- Index in Switch_Chars of the last relevant character for later string
+ -- comparison purposes. This is typically 'Last, minus one if there is a
+ -- terminating ASCII.NUL.
+private
-- This section contains some common routines used by the tool dependent
- -- child packages (there is one such child package for each tool that
- -- uses Switches to scan switches - Compiler/gnatbind/gnatmake/.
+ -- child packages (there is one such child package for each tool that uses
+ -- Switches to scan switches - Compiler/gnatbind/gnatmake/.
Switch_Max_Value : constant := 999_999;
-- Maximum value permitted in switches that take a value
diff --git a/gcc/ada/tracebak.c b/gcc/ada/tracebak.c
index 8f3c4cc389d..63f93b37eb7 100644
--- a/gcc/ada/tracebak.c
+++ b/gcc/ada/tracebak.c
@@ -6,7 +6,7 @@
* *
* C Implementation File *
* *
- * Copyright (C) 2000-2008, AdaCore *
+ * Copyright (C) 2000-2009, AdaCore *
* *
* GNAT is free software; you can redistribute it and/or modify it under *
* terms of the GNU General Public License as published by the Free Soft- *
@@ -294,9 +294,11 @@ struct layout
#elif defined (i386)
-#ifdef __WIN32
+#if defined (__WIN32)
#include <windows.h>
#define IS_BAD_PTR(ptr) (IsBadCodePtr((void *)ptr))
+#elif defined (sun)
+#define IS_BAD_PTR(ptr) ((unsigned long)ptr == -1)
#else
#define IS_BAD_PTR(ptr) 0
#endif
diff --git a/gcc/alias.c b/gcc/alias.c
index 794df755040..3488382df6c 100644
--- a/gcc/alias.c
+++ b/gcc/alias.c
@@ -128,7 +128,7 @@ along with GCC; see the file COPYING3. If not see
However, this is no actual entry for alias set zero. It is an
error to attempt to explicitly construct a subset of zero. */
-struct GTY(()) alias_set_entry {
+struct GTY(()) alias_set_entry_d {
/* The alias set number, as stored in MEM_ALIAS_SET. */
alias_set_type alias_set;
@@ -145,7 +145,7 @@ struct GTY(()) alias_set_entry {
`int', `double', `float', and `struct S'. */
splay_tree GTY((param1_is (int), param2_is (int))) children;
};
-typedef struct alias_set_entry *alias_set_entry;
+typedef struct alias_set_entry_d *alias_set_entry;
static int rtx_equal_for_memref_p (const_rtx, const_rtx);
static int memrefs_conflict_p (int, rtx, int, rtx, HOST_WIDE_INT);
@@ -791,7 +791,7 @@ record_alias_subset (alias_set_type superset, alias_set_type subset)
{
/* Create an entry for the SUPERSET, so that we have a place to
attach the SUBSET. */
- superset_entry = GGC_NEW (struct alias_set_entry);
+ superset_entry = GGC_NEW (struct alias_set_entry_d);
superset_entry->alias_set = superset;
superset_entry->children
= splay_tree_new_ggc (splay_tree_compare_ints);
@@ -1511,10 +1511,18 @@ find_base_term (rtx x)
/* If either operand is known to be a pointer, then use it
to determine the base term. */
if (REG_P (tmp1) && REG_POINTER (tmp1))
- return find_base_term (tmp1);
+ {
+ rtx base = find_base_term (tmp1);
+ if (base)
+ return base;
+ }
if (REG_P (tmp2) && REG_POINTER (tmp2))
- return find_base_term (tmp2);
+ {
+ rtx base = find_base_term (tmp2);
+ if (base)
+ return base;
+ }
/* Neither operand was known to be a pointer. Go ahead and find the
base term for both operands. */
@@ -2373,9 +2381,6 @@ write_dependence_p (const_rtx mem, const_rtx x, int writep)
|| MEM_ALIAS_SET (mem) == ALIAS_SET_MEMORY_BARRIER)
return 1;
- if (DIFFERENT_ALIAS_SETS_P (x, mem))
- return 0;
-
/* A read from read-only memory can't conflict with read-write memory. */
if (!writep && MEM_READONLY_P (mem))
return 0;
diff --git a/gcc/attribs.c b/gcc/attribs.c
index df4ca73124d..5ae462e7287 100644
--- a/gcc/attribs.c
+++ b/gcc/attribs.c
@@ -1,6 +1,6 @@
/* Functions dealing with attribute handling, used by most front ends.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
- 2002, 2003, 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
+ 2002, 2003, 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
This file is part of GCC.
@@ -33,6 +33,7 @@ along with GCC; see the file COPYING3. If not see
#include "target.h"
#include "langhooks.h"
#include "hashtab.h"
+#include "plugin.h"
static void init_attributes (void);
@@ -182,20 +183,29 @@ init_attributes (void)
for (i = 0; i < ARRAY_SIZE (attribute_tables); i++)
for (k = 0; attribute_tables[i][k].name != NULL; k++)
{
- struct substring str;
- const void **slot;
-
- str.str = attribute_tables[i][k].name;
- str.length = strlen (attribute_tables[i][k].name);
- slot = (const void **)htab_find_slot_with_hash (attribute_hash, &str,
- substring_hash (str.str, str.length),
- INSERT);
- gcc_assert (!*slot);
- *slot = &attribute_tables[i][k];
+ register_attribute (&attribute_tables[i][k]);
}
+ invoke_plugin_callbacks (PLUGIN_ATTRIBUTES, NULL);
attributes_initialized = true;
}
+/* Insert a single ATTR into the attribute table. */
+
+void
+register_attribute (const struct attribute_spec *attr)
+{
+ struct substring str;
+ void **slot;
+
+ str.str = attr->name;
+ str.length = strlen (str.str);
+ slot = htab_find_slot_with_hash (attribute_hash, &str,
+ substring_hash (str.str, str.length),
+ INSERT);
+ gcc_assert (!*slot);
+ *slot = (void *) CONST_CAST (struct attribute_spec *, attr);
+}
+
/* Return the spec for the attribute named NAME. */
const struct attribute_spec *
diff --git a/gcc/auto-inc-dec.c b/gcc/auto-inc-dec.c
index 55227ab38b2..5bcd3e63e7b 100644
--- a/gcc/auto-inc-dec.c
+++ b/gcc/auto-inc-dec.c
@@ -46,6 +46,7 @@ along with GCC; see the file COPYING3. If not see
There are (4) basic forms that are matched:
+ (1) FORM_PRE_ADD
a <- b + c
...
*a
@@ -55,6 +56,9 @@ along with GCC; see the file COPYING3. If not see
a <- b
...
*(a += c) pre
+
+
+ (2) FORM_PRE_INC
a += c
...
*a
@@ -62,18 +66,24 @@ along with GCC; see the file COPYING3. If not see
becomes
*(a += c) pre
+
+
+ (3) FORM_POST_ADD
*a
...
b <- a + c
- for this case to be true, b must not be assigned or used between
- the *a and the assignment to b. B must also be a Pmode reg.
+ (For this case to be true, b must not be assigned or used between
+ the *a and the assignment to b. B must also be a Pmode reg.)
becomes
b <- a
...
*(b += c) post
+
+
+ (4) FORM_POST_INC
*a
...
a <- a + c
@@ -99,56 +109,8 @@ along with GCC; see the file COPYING3. If not see
The is one special case: if a already had an offset equal to it +-
its width and that offset is equal to -c when the increment was
before the ref or +c if the increment was after the ref, then if we
- can do the combination but switch the pre/post bit.
-
- (1) FORM_PRE_ADD
-
- a <- b + c
- ...
- *(a - c)
-
- becomes
-
- a <- b
- ...
- *(a += c) post
-
- (2) FORM_PRE_INC
-
- a += c
- ...
- *(a - c)
-
- becomes
-
- *(a += c) post
+ can do the combination but switch the pre/post bit. */
- (3) FORM_POST_ADD
-
- *(a + c)
- ...
- b <- a + c
-
- for this case to be true, b must not be assigned or used between
- the *a and the assignment to b. B must also be a Pmode reg.
-
- becomes
-
- b <- a
- ...
- *(b += c) pre
-
-
- (4) FORM_POST_INC
-
- *(a + c)
- ...
- a <- a + c
-
- becomes
-
- *(a += c) pre
-*/
#ifdef AUTO_INC_DEC
enum form
diff --git a/gcc/basic-block.h b/gcc/basic-block.h
index 41d9f9514cb..72bdf5c6504 100644
--- a/gcc/basic-block.h
+++ b/gcc/basic-block.h
@@ -249,6 +249,9 @@ struct GTY((chain_next ("%h.next_bb"), chain_prev ("%h.prev_bb"))) basic_block_d
/* Expected frequency. Normalized to be in range 0 to BB_FREQ_MAX. */
int frequency;
+ /* The discriminator for this block. */
+ int discriminator;
+
/* Various flags. See BB_* below. */
int flags;
};
@@ -488,7 +491,8 @@ extern bitmap_obstack reg_obstack;
#define BB_HEAD(B) (B)->il.rtl->head_
#define BB_END(B) (B)->il.rtl->end_
-/* Special block numbers [markers] for entry and exit. */
+/* Special block numbers [markers] for entry and exit.
+ Neither of them is supposed to hold actual statements. */
#define ENTRY_BLOCK (0)
#define EXIT_BLOCK (1)
diff --git a/gcc/bitmap.c b/gcc/bitmap.c
index c9a226a5a2c..61a40ee352d 100644
--- a/gcc/bitmap.c
+++ b/gcc/bitmap.c
@@ -37,10 +37,10 @@ struct bitmap_descriptor
const char *function;
const char *file;
int line;
- int allocated;
int created;
- int peak;
- int current;
+ HOST_WIDEST_INT allocated;
+ HOST_WIDEST_INT peak;
+ HOST_WIDEST_INT current;
int nsearches;
};
@@ -291,7 +291,7 @@ bitmap_elt_clear_from (bitmap head, bitmap_element *elt)
/* Clear a bitmap by freeing the linked list. */
-inline void
+void
bitmap_clear (bitmap head)
{
if (head->first)
@@ -2013,8 +2013,8 @@ bitmap_print (FILE *file, const_bitmap head, const char *prefix, const char *suf
/* Used to accumulate statistics about bitmap sizes. */
struct output_info
{
+ HOST_WIDEST_INT size;
int count;
- int size;
};
/* Called via htab_traverse. Output bitmap descriptor pointed out by SLOT
@@ -2034,8 +2034,9 @@ print_statistics (void **slot, void *b)
s1 = s2 + 4;
sprintf (s, "%s:%i (%s)", s1, d->line, d->function);
s[41] = 0;
- fprintf (stderr, "%-41s %6d %10d %10d %10d %10d\n", s,
- d->created, d->allocated, d->peak, d->current, d->nsearches);
+ fprintf (stderr, "%-41s %8d %15"HOST_WIDEST_INT_PRINT"d %15"
+ HOST_WIDEST_INT_PRINT"d %15"HOST_WIDEST_INT_PRINT"d %10d\n",
+ s, d->created, d->allocated, d->peak, d->current, d->nsearches);
i->size += d->allocated;
i->count += d->created;
}
@@ -2053,14 +2054,14 @@ dump_bitmap_statistics (void)
return;
fprintf (stderr, "\nBitmap Overall "
- "Allocated Peak Leak searched "
+ " Allocated Peak Leak searched "
" per search\n");
fprintf (stderr, "---------------------------------------------------------------------------------\n");
info.count = 0;
info.size = 0;
htab_traverse (bitmap_desc_hash, print_statistics, &info);
fprintf (stderr, "---------------------------------------------------------------------------------\n");
- fprintf (stderr, "%-40s %7d %10d\n",
+ fprintf (stderr, "%-40s %9d %15"HOST_WIDEST_INT_PRINT"d\n",
"Total", info.count, info.size);
fprintf (stderr, "---------------------------------------------------------------------------------\n");
#endif
diff --git a/gcc/builtins.c b/gcc/builtins.c
index e12418983bf..a6d26efa776 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -58,6 +58,9 @@ along with GCC; see the file COPYING3. If not see
#ifndef PAD_VARARGS_DOWN
#define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
#endif
+#ifdef HAVE_mpc
+static tree do_mpc_arg1 (tree, tree, int (*)(mpc_ptr, mpc_srcptr, mpc_rnd_t));
+#endif
/* Define the names of the builtin function types and codes. */
const char *const built_in_class_names[4]
@@ -4186,7 +4189,7 @@ expand_builtin_memcmp (tree exp, rtx target, enum machine_mode mode)
arg1_rtx = get_memory_rtx (arg1, len);
arg2_rtx = get_memory_rtx (arg2, len);
- arg3_rtx = expand_normal (len);
+ arg3_rtx = expand_normal (fold_convert (sizetype, len));
/* Set MEM_SIZE as appropriate. */
if (GET_CODE (arg3_rtx) == CONST_INT)
@@ -4972,6 +4975,8 @@ gimplify_va_arg_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
tree valist = TREE_OPERAND (*expr_p, 0);
tree type = TREE_TYPE (*expr_p);
tree t;
+ location_t loc = EXPR_HAS_LOCATION (*expr_p) ? EXPR_LOCATION (*expr_p) :
+ UNKNOWN_LOCATION;
/* Verify that valist is of the proper type. */
have_va_type = TREE_TYPE (valist);
@@ -4981,7 +4986,7 @@ gimplify_va_arg_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
if (have_va_type == NULL_TREE)
{
- error ("first argument to %<va_arg%> not of type %<va_list%>");
+ error_at (loc, "first argument to %<va_arg%> not of type %<va_list%>");
return GS_ERROR;
}
@@ -4996,19 +5001,20 @@ gimplify_va_arg_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
/* Unfortunately, this is merely undefined, rather than a constraint
violation, so we cannot make this an error. If this call is never
executed, the program is still strictly conforming. */
- warned = warning (0, "%qT is promoted to %qT when passed through %<...%>",
- type, promoted_type);
+ warned = warning_at (loc, 0,
+ "%qT is promoted to %qT when passed through %<...%>",
+ type, promoted_type);
if (!gave_help && warned)
{
gave_help = true;
- inform (input_location, "(so you should pass %qT not %qT to %<va_arg%>)",
- promoted_type, type);
+ inform (loc, "(so you should pass %qT not %qT to %<va_arg%>)",
+ promoted_type, type);
}
/* We can, however, treat "undefined" any way we please.
Call abort to encourage the user to fix the program. */
if (warned)
- inform (input_location, "if this code is reached, the program will abort");
+ inform (loc, "if this code is reached, the program will abort");
/* Before the abort, allow the evaluation of the va_list
expression to exit or longjmp. */
gimplify_and_add (valist, pre_p);
@@ -5295,6 +5301,17 @@ expand_builtin_trap (void)
emit_barrier ();
}
+/* Expand a call to __builtin_unreachable. We do nothing except emit
+ a barrier saying that control flow will not pass here.
+
+ It is the responsibility of the program being compiled to ensure
+ that control flow does never reach __builtin_unreachable. */
+static void
+expand_builtin_unreachable (void)
+{
+ emit_barrier ();
+}
+
/* Expand EXP, a call to fabs, fabsf or fabsl.
Return NULL_RTX if a normal call should be emitted rather than expanding
the function inline. If convenient, the result should be placed
@@ -5970,7 +5987,8 @@ expand_builtin_fork_or_exec (tree fn, tree exp, rtx target, int ignore)
gcc_unreachable ();
}
- decl = build_decl (FUNCTION_DECL, id, TREE_TYPE (fn));
+ decl = build_decl (DECL_SOURCE_LOCATION (fn),
+ FUNCTION_DECL, id, TREE_TYPE (fn));
DECL_EXTERNAL (decl) = 1;
TREE_PUBLIC (decl) = 1;
DECL_ARTIFICIAL (decl) = 1;
@@ -6036,6 +6054,7 @@ expand_builtin_sync_operation (enum machine_mode mode, tree exp,
{
rtx val, mem;
enum machine_mode old_mode;
+ location_t loc = EXPR_LOCATION (exp);
if (code == NOT && warn_sync_nand)
{
@@ -6056,8 +6075,7 @@ expand_builtin_sync_operation (enum machine_mode mode, tree exp,
break;
fndecl = implicit_built_in_decls[BUILT_IN_FETCH_AND_NAND_N];
- inform (input_location,
- "%qD changed semantics in GCC 4.4", fndecl);
+ inform (loc, "%qD changed semantics in GCC 4.4", fndecl);
warned_f_a_n = true;
break;
@@ -6071,8 +6089,7 @@ expand_builtin_sync_operation (enum machine_mode mode, tree exp,
break;
fndecl = implicit_built_in_decls[BUILT_IN_NAND_AND_FETCH_N];
- inform (input_location,
- "%qD changed semantics in GCC 4.4", fndecl);
+ inform (loc, "%qD changed semantics in GCC 4.4", fndecl);
warned_n_a_f = true;
break;
@@ -6792,6 +6809,10 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
expand_builtin_trap ();
return const0_rtx;
+ case BUILT_IN_UNREACHABLE:
+ expand_builtin_unreachable ();
+ return const0_rtx;
+
case BUILT_IN_PRINTF:
target = expand_builtin_printf (exp, target, mode, false);
if (target)
@@ -7886,6 +7907,33 @@ fold_builtin_cosh (tree arg, tree type, tree fndecl)
return NULL_TREE;
}
+/* Fold function call to builtin ccos (or ccosh if HYPER is TRUE) with
+ argument ARG. TYPE is the type of the return value. Return
+ NULL_TREE if no simplification can be made. */
+
+static tree
+fold_builtin_ccos (tree arg, tree type ATTRIBUTE_UNUSED, tree fndecl,
+ bool hyper ATTRIBUTE_UNUSED)
+{
+ if (validate_arg (arg, COMPLEX_TYPE)
+ && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == REAL_TYPE)
+ {
+ tree tmp;
+
+#ifdef HAVE_mpc
+ /* Calculate the result when the argument is a constant. */
+ if ((tmp = do_mpc_arg1 (arg, type, (hyper ? mpc_cosh : mpc_cos))))
+ return tmp;
+#endif
+
+ /* Optimize fn(-x) into fn(x). */
+ if ((tmp = fold_strip_sign_ops (arg)))
+ return build_call_expr (fndecl, 1, tmp);
+ }
+
+ return NULL_TREE;
+}
+
/* Fold function call to builtin tan, tanf, or tanl with argument ARG.
Return NULL_TREE if no simplification can be made. */
@@ -7960,10 +8008,20 @@ fold_builtin_cexp (tree arg0, tree type)
{
tree rtype;
tree realp, imagp, ifn;
+#ifdef HAVE_mpc
+ tree res;
+#endif
- if (!validate_arg (arg0, COMPLEX_TYPE))
+ if (!validate_arg (arg0, COMPLEX_TYPE)
+ && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
return NULL_TREE;
+#ifdef HAVE_mpc
+ /* Calculate the result when the argument is a constant. */
+ if ((res = do_mpc_arg1 (arg0, type, mpc_exp)))
+ return res;
+#endif
+
rtype = TREE_TYPE (TREE_TYPE (arg0));
/* In case we can figure out the real part of arg0 and it is constant zero
@@ -9670,7 +9728,8 @@ fold_builtin_fmin_fmax (tree arg0, tree arg1, tree type, bool max)
static tree
fold_builtin_carg (tree arg, tree type)
{
- if (validate_arg (arg, COMPLEX_TYPE))
+ if (validate_arg (arg, COMPLEX_TYPE)
+ && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == REAL_TYPE)
{
tree atan2_fn = mathfn_built_in (type, BUILT_IN_ATAN2);
@@ -10215,12 +10274,14 @@ fold_builtin_1 (tree fndecl, tree arg0, bool ignore)
return fold_builtin_abs (arg0, type);
CASE_FLT_FN (BUILT_IN_CONJ):
- if (validate_arg (arg0, COMPLEX_TYPE))
+ if (validate_arg (arg0, COMPLEX_TYPE)
+ && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
return fold_build1 (CONJ_EXPR, type, arg0);
break;
CASE_FLT_FN (BUILT_IN_CREAL):
- if (validate_arg (arg0, COMPLEX_TYPE))
+ if (validate_arg (arg0, COMPLEX_TYPE)
+ && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
return non_lvalue (fold_build1 (REALPART_EXPR, type, arg0));;
break;
@@ -10230,16 +10291,49 @@ fold_builtin_1 (tree fndecl, tree arg0, bool ignore)
break;
CASE_FLT_FN (BUILT_IN_CCOS):
+ return fold_builtin_ccos(arg0, type, fndecl, /*hyper=*/ false);
+
CASE_FLT_FN (BUILT_IN_CCOSH):
- /* These functions are "even", i.e. f(x) == f(-x). */
- if (validate_arg (arg0, COMPLEX_TYPE))
- {
- tree narg = fold_strip_sign_ops (arg0);
- if (narg)
- return build_call_expr (fndecl, 1, narg);
- }
+ return fold_builtin_ccos(arg0, type, fndecl, /*hyper=*/ true);
+
+#ifdef HAVE_mpc
+ CASE_FLT_FN (BUILT_IN_CSIN):
+ if (validate_arg (arg0, COMPLEX_TYPE)
+ && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
+ return do_mpc_arg1 (arg0, type, mpc_sin);
break;
-
+
+ CASE_FLT_FN (BUILT_IN_CSINH):
+ if (validate_arg (arg0, COMPLEX_TYPE)
+ && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
+ return do_mpc_arg1 (arg0, type, mpc_sinh);
+ break;
+
+ CASE_FLT_FN (BUILT_IN_CTAN):
+ if (validate_arg (arg0, COMPLEX_TYPE)
+ && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
+ return do_mpc_arg1 (arg0, type, mpc_tan);
+ break;
+
+ CASE_FLT_FN (BUILT_IN_CTANH):
+ if (validate_arg (arg0, COMPLEX_TYPE)
+ && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
+ return do_mpc_arg1 (arg0, type, mpc_tanh);
+ break;
+
+ CASE_FLT_FN (BUILT_IN_CLOG):
+ if (validate_arg (arg0, COMPLEX_TYPE)
+ && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
+ return do_mpc_arg1 (arg0, type, mpc_log);
+ break;
+
+ CASE_FLT_FN (BUILT_IN_CSQRT):
+ if (validate_arg (arg0, COMPLEX_TYPE)
+ && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
+ return do_mpc_arg1 (arg0, type, mpc_sqrt);
+ break;
+#endif
+
CASE_FLT_FN (BUILT_IN_CABS):
return fold_builtin_cabs (arg0, type, fndecl);
@@ -10293,7 +10387,6 @@ fold_builtin_1 (tree fndecl, tree arg0, bool ignore)
CASE_FLT_FN (BUILT_IN_COS):
return fold_builtin_cos (arg0, type, fndecl);
- break;
CASE_FLT_FN (BUILT_IN_TAN):
return fold_builtin_tan (arg0, type);
@@ -11156,7 +11249,7 @@ validate_gimple_arglist (const_gimple call, ...)
do
{
- code = va_arg (ap, enum tree_code);
+ code = (enum tree_code) va_arg (ap, int);
switch (code)
{
case 0:
@@ -11207,7 +11300,7 @@ validate_arglist (const_tree callexpr, ...)
do
{
- code = va_arg (ap, enum tree_code);
+ code = (enum tree_code) va_arg (ap, int);
switch (code)
{
case 0:
@@ -13127,6 +13220,50 @@ do_mpfr_ckconv (mpfr_srcptr m, tree type, int inexact)
return NULL_TREE;
}
+#ifdef HAVE_mpc
+/* Helper function for do_mpc_arg*(). Ensure M is a normal complex
+ number and no overflow/underflow occurred. INEXACT is true if M
+ was not exactly calculated. TYPE is the tree type for the result.
+ This function assumes that you cleared the MPFR flags and then
+ calculated M to see if anything subsequently set a flag prior to
+ entering this function. Return NULL_TREE if any checks fail. */
+
+static tree
+do_mpc_ckconv (mpc_srcptr m, tree type, int inexact)
+{
+ /* Proceed iff we get a normal number, i.e. not NaN or Inf and no
+ overflow/underflow occurred. If -frounding-math, proceed iff the
+ result of calling FUNC was exact. */
+ if (mpfr_number_p (mpc_realref (m)) && mpfr_number_p (mpc_imagref (m))
+ && !mpfr_overflow_p () && !mpfr_underflow_p ()
+ && (!flag_rounding_math || !inexact))
+ {
+ REAL_VALUE_TYPE re, im;
+
+ real_from_mpfr (&re, mpc_realref (m), type, GMP_RNDN);
+ real_from_mpfr (&im, mpc_imagref (m), type, GMP_RNDN);
+ /* Proceed iff GCC's REAL_VALUE_TYPE can hold the MPFR values,
+ check for overflow/underflow. If the REAL_VALUE_TYPE is zero
+ but the mpft_t is not, then we underflowed in the
+ conversion. */
+ if (real_isfinite (&re) && real_isfinite (&im)
+ && (re.cl == rvc_zero) == (mpfr_zero_p (mpc_realref (m)) != 0)
+ && (im.cl == rvc_zero) == (mpfr_zero_p (mpc_imagref (m)) != 0))
+ {
+ REAL_VALUE_TYPE re_mode, im_mode;
+
+ real_convert (&re_mode, TYPE_MODE (TREE_TYPE (type)), &re);
+ real_convert (&im_mode, TYPE_MODE (TREE_TYPE (type)), &im);
+ /* Proceed iff the specified mode can hold the value. */
+ if (real_identical (&re_mode, &re) && real_identical (&im_mode, &im))
+ return build_complex (type, build_real (TREE_TYPE (type), re_mode),
+ build_real (TREE_TYPE (type), im_mode));
+ }
+ }
+ return NULL_TREE;
+}
+#endif /* HAVE_mpc */
+
/* If argument ARG is a REAL_CST, call the one-argument mpfr function
FUNC on it and return the resulting value as a tree with type TYPE.
If MIN and/or MAX are not NULL, then the supplied ARG must be
@@ -13523,6 +13660,53 @@ do_mpfr_lgamma_r (tree arg, tree arg_sg, tree type)
return result;
}
+#ifdef HAVE_mpc
+/* If argument ARG is a COMPLEX_CST, call the one-argument mpc
+ function FUNC on it and return the resulting value as a tree with
+ type TYPE. The mpfr precision is set to the precision of TYPE. We
+ assume that function FUNC returns zero if the result could be
+ calculated exactly within the requested precision. */
+
+static tree
+do_mpc_arg1 (tree arg, tree type, int (*func)(mpc_ptr, mpc_srcptr, mpc_rnd_t))
+{
+ tree result = NULL_TREE;
+
+ STRIP_NOPS (arg);
+
+ /* To proceed, MPFR must exactly represent the target floating point
+ format, which only happens when the target base equals two. */
+ if (TREE_CODE (arg) == COMPLEX_CST && !TREE_OVERFLOW (arg)
+ && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == REAL_TYPE
+ && REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (TREE_TYPE (arg))))->b == 2)
+ {
+ const REAL_VALUE_TYPE *const re = TREE_REAL_CST_PTR (TREE_REALPART (arg));
+ const REAL_VALUE_TYPE *const im = TREE_REAL_CST_PTR (TREE_IMAGPART (arg));
+
+ if (real_isfinite (re) && real_isfinite (im))
+ {
+ const struct real_format *const fmt =
+ REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (type)));
+ const int prec = fmt->p;
+ const mp_rnd_t rnd = fmt->round_towards_zero ? GMP_RNDZ : GMP_RNDN;
+ const mpc_rnd_t crnd = fmt->round_towards_zero ? MPC_RNDZZ : MPC_RNDNN;
+ int inexact;
+ mpc_t m;
+
+ mpc_init2 (m, prec);
+ mpfr_from_real (mpc_realref(m), re, rnd);
+ mpfr_from_real (mpc_imagref(m), im, rnd);
+ mpfr_clear_flags ();
+ inexact = func (m, m, crnd);
+ result = do_mpc_ckconv (m, type, inexact);
+ mpc_clear (m);
+ }
+ }
+
+ return result;
+}
+#endif /* HAVE_mpc */
+
/* FIXME tuples.
The functions below provide an alternate interface for folding
builtin function calls presented as GIMPLE_CALL statements rather
diff --git a/gcc/builtins.def b/gcc/builtins.def
index 3f4e251c3fd..8d1693605a6 100644
--- a/gcc/builtins.def
+++ b/gcc/builtins.def
@@ -698,6 +698,7 @@ DEF_GCC_BUILTIN (BUILT_IN_SETJMP, "setjmp", BT_FN_INT_PTR, ATTR_NULL)
DEF_EXT_LIB_BUILTIN (BUILT_IN_STRFMON, "strfmon", BT_FN_SSIZE_STRING_SIZE_CONST_STRING_VAR, ATTR_FORMAT_STRFMON_NOTHROW_3_4)
DEF_LIB_BUILTIN (BUILT_IN_STRFTIME, "strftime", BT_FN_SIZE_STRING_SIZE_CONST_STRING_CONST_PTR, ATTR_FORMAT_STRFTIME_NOTHROW_3_0)
DEF_GCC_BUILTIN (BUILT_IN_TRAP, "trap", BT_FN_VOID, ATTR_NORETURN_NOTHROW_LIST)
+DEF_GCC_BUILTIN (BUILT_IN_UNREACHABLE, "unreachable", BT_FN_VOID, ATTR_NORETURN_NOTHROW_LIST)
DEF_GCC_BUILTIN (BUILT_IN_UNWIND_INIT, "unwind_init", BT_FN_VOID, ATTR_NULL)
DEF_GCC_BUILTIN (BUILT_IN_UPDATE_SETJMP_BUF, "update_setjmp_buf", BT_FN_VOID_PTR_INT, ATTR_NULL)
DEF_GCC_BUILTIN (BUILT_IN_VA_COPY, "va_copy", BT_FN_VOID_VALIST_REF_VALIST_ARG, ATTR_NOTHROW_LIST)
diff --git a/gcc/c-common.c b/gcc/c-common.c
index df6673c000c..43b2c13daed 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -55,180 +55,6 @@ along with GCC; see the file COPYING3. If not see
cpp_reader *parse_in; /* Declared in c-pragma.h. */
-/* We let tm.h override the types used here, to handle trivial differences
- such as the choice of unsigned int or long unsigned int for size_t.
- When machines start needing nontrivial differences in the size type,
- it would be best to do something here to figure out automatically
- from other information what type to use. */
-
-#ifndef SIZE_TYPE
-#define SIZE_TYPE "long unsigned int"
-#endif
-
-#ifndef PID_TYPE
-#define PID_TYPE "int"
-#endif
-
-/* If GCC knows the exact uint_least16_t and uint_least32_t types from
- <stdint.h>, use them for char16_t and char32_t. Otherwise, use
- these guesses; getting the wrong type of a given width will not
- affect C++ name mangling because in C++ these are distinct types
- not typedefs. */
-
-#ifdef UINT_LEAST16_TYPE
-#define CHAR16_TYPE UINT_LEAST16_TYPE
-#else
-#define CHAR16_TYPE "short unsigned int"
-#endif
-
-#ifdef UINT_LEAST32_TYPE
-#define CHAR32_TYPE UINT_LEAST32_TYPE
-#else
-#define CHAR32_TYPE "unsigned int"
-#endif
-
-#ifndef WCHAR_TYPE
-#define WCHAR_TYPE "int"
-#endif
-
-/* WCHAR_TYPE gets overridden by -fshort-wchar. */
-#define MODIFIED_WCHAR_TYPE \
- (flag_short_wchar ? "short unsigned int" : WCHAR_TYPE)
-
-#ifndef PTRDIFF_TYPE
-#define PTRDIFF_TYPE "long int"
-#endif
-
-#ifndef WINT_TYPE
-#define WINT_TYPE "unsigned int"
-#endif
-
-#ifndef INTMAX_TYPE
-#define INTMAX_TYPE ((INT_TYPE_SIZE == LONG_LONG_TYPE_SIZE) \
- ? "int" \
- : ((LONG_TYPE_SIZE == LONG_LONG_TYPE_SIZE) \
- ? "long int" \
- : "long long int"))
-#endif
-
-#ifndef UINTMAX_TYPE
-#define UINTMAX_TYPE ((INT_TYPE_SIZE == LONG_LONG_TYPE_SIZE) \
- ? "unsigned int" \
- : ((LONG_TYPE_SIZE == LONG_LONG_TYPE_SIZE) \
- ? "long unsigned int" \
- : "long long unsigned int"))
-#endif
-
-/* There are no default definitions of these <stdint.h> types. */
-
-#ifndef SIG_ATOMIC_TYPE
-#define SIG_ATOMIC_TYPE ((const char *) NULL)
-#endif
-
-#ifndef INT8_TYPE
-#define INT8_TYPE ((const char *) NULL)
-#endif
-
-#ifndef INT16_TYPE
-#define INT16_TYPE ((const char *) NULL)
-#endif
-
-#ifndef INT32_TYPE
-#define INT32_TYPE ((const char *) NULL)
-#endif
-
-#ifndef INT64_TYPE
-#define INT64_TYPE ((const char *) NULL)
-#endif
-
-#ifndef UINT8_TYPE
-#define UINT8_TYPE ((const char *) NULL)
-#endif
-
-#ifndef UINT16_TYPE
-#define UINT16_TYPE ((const char *) NULL)
-#endif
-
-#ifndef UINT32_TYPE
-#define UINT32_TYPE ((const char *) NULL)
-#endif
-
-#ifndef UINT64_TYPE
-#define UINT64_TYPE ((const char *) NULL)
-#endif
-
-#ifndef INT_LEAST8_TYPE
-#define INT_LEAST8_TYPE ((const char *) NULL)
-#endif
-
-#ifndef INT_LEAST16_TYPE
-#define INT_LEAST16_TYPE ((const char *) NULL)
-#endif
-
-#ifndef INT_LEAST32_TYPE
-#define INT_LEAST32_TYPE ((const char *) NULL)
-#endif
-
-#ifndef INT_LEAST64_TYPE
-#define INT_LEAST64_TYPE ((const char *) NULL)
-#endif
-
-#ifndef UINT_LEAST8_TYPE
-#define UINT_LEAST8_TYPE ((const char *) NULL)
-#endif
-
-#ifndef UINT_LEAST16_TYPE
-#define UINT_LEAST16_TYPE ((const char *) NULL)
-#endif
-
-#ifndef UINT_LEAST32_TYPE
-#define UINT_LEAST32_TYPE ((const char *) NULL)
-#endif
-
-#ifndef UINT_LEAST64_TYPE
-#define UINT_LEAST64_TYPE ((const char *) NULL)
-#endif
-
-#ifndef INT_FAST8_TYPE
-#define INT_FAST8_TYPE ((const char *) NULL)
-#endif
-
-#ifndef INT_FAST16_TYPE
-#define INT_FAST16_TYPE ((const char *) NULL)
-#endif
-
-#ifndef INT_FAST32_TYPE
-#define INT_FAST32_TYPE ((const char *) NULL)
-#endif
-
-#ifndef INT_FAST64_TYPE
-#define INT_FAST64_TYPE ((const char *) NULL)
-#endif
-
-#ifndef UINT_FAST8_TYPE
-#define UINT_FAST8_TYPE ((const char *) NULL)
-#endif
-
-#ifndef UINT_FAST16_TYPE
-#define UINT_FAST16_TYPE ((const char *) NULL)
-#endif
-
-#ifndef UINT_FAST32_TYPE
-#define UINT_FAST32_TYPE ((const char *) NULL)
-#endif
-
-#ifndef UINT_FAST64_TYPE
-#define UINT_FAST64_TYPE ((const char *) NULL)
-#endif
-
-#ifndef INTPTR_TYPE
-#define INTPTR_TYPE ((const char *) NULL)
-#endif
-
-#ifndef UINTPTR_TYPE
-#define UINTPTR_TYPE ((const char *) NULL)
-#endif
-
/* The following symbols are subsumed in the c_global_trees array, and
listed here individually for documentation purposes.
@@ -614,11 +440,11 @@ int max_tinst_depth = 500;
type names and storage classes. It is indexed by a RID_... value. */
tree *ridpointers;
-tree (*make_fname_decl) (tree, int);
+tree (*make_fname_decl) (location_t, tree, int);
-/* Nonzero means the expression being parsed will never be evaluated.
- This is a count, since unevaluated expressions can nest. */
-int skip_evaluation;
+/* Nonzero means don't warn about problems that occur when the code is
+ executed. */
+int c_inhibit_evaluation_warnings;
/* Whether lexing has been completed, so subsequent preprocessor
errors should use the compiler's input_location. */
@@ -1145,7 +971,7 @@ fname_decl (location_t loc, unsigned int rid, tree id)
input_location = UNKNOWN_LOCATION;
stmts = push_stmt_list ();
- decl = (*make_fname_decl) (id, fname_vars[ix].pretty);
+ decl = (*make_fname_decl) (loc, id, fname_vars[ix].pretty);
stmts = pop_stmt_list (stmts);
if (!IS_EMPTY_STMT (stmts))
saved_function_name_decls
@@ -1679,33 +1505,37 @@ constant_expression_error (tree value)
already overflowed. */
void
-overflow_warning (tree value)
+overflow_warning (location_t loc, tree value)
{
- if (skip_evaluation) return;
+ if (c_inhibit_evaluation_warnings != 0)
+ return;
switch (TREE_CODE (value))
{
case INTEGER_CST:
- warning (OPT_Woverflow, "integer overflow in expression");
+ warning_at (loc, OPT_Woverflow, "integer overflow in expression");
break;
case REAL_CST:
- warning (OPT_Woverflow, "floating point overflow in expression");
+ warning_at (loc, OPT_Woverflow,
+ "floating point overflow in expression");
break;
case FIXED_CST:
- warning (OPT_Woverflow, "fixed-point overflow in expression");
+ warning_at (loc, OPT_Woverflow, "fixed-point overflow in expression");
break;
case VECTOR_CST:
- warning (OPT_Woverflow, "vector overflow in expression");
+ warning_at (loc, OPT_Woverflow, "vector overflow in expression");
break;
case COMPLEX_CST:
if (TREE_CODE (TREE_REALPART (value)) == INTEGER_CST)
- warning (OPT_Woverflow, "complex integer overflow in expression");
+ warning_at (loc, OPT_Woverflow,
+ "complex integer overflow in expression");
else if (TREE_CODE (TREE_REALPART (value)) == REAL_CST)
- warning (OPT_Woverflow, "complex floating point overflow in expression");
+ warning_at (loc, OPT_Woverflow,
+ "complex floating point overflow in expression");
break;
default:
@@ -1716,14 +1546,18 @@ overflow_warning (tree value)
/* Warn about uses of logical || / && operator in a context where it
is likely that the bitwise equivalent was intended by the
programmer. We have seen an expression in which CODE is a binary
- operator used to combine expressions OP_LEFT and OP_RIGHT, which
- before folding had CODE_LEFT and CODE_RIGHT. */
-
+ operator used to combine expressions OP_LEFT and OP_RIGHT, which before folding
+ had CODE_LEFT and CODE_RIGHT, into an expression of type TYPE. */
void
-warn_logical_operator (location_t location, enum tree_code code,
+warn_logical_operator (location_t location, enum tree_code code, tree type,
enum tree_code code_left, tree op_left,
enum tree_code ARG_UNUSED (code_right), tree op_right)
{
+ int or_op = (code == TRUTH_ORIF_EXPR || code == TRUTH_OR_EXPR);
+ int in0_p, in1_p, in_p;
+ tree low0, low1, low, high0, high1, high, lhs, rhs, tem;
+ bool strict_overflow_p = false;
+
if (code != TRUTH_ANDIF_EXPR
&& code != TRUTH_AND_EXPR
&& code != TRUTH_ORIF_EXPR
@@ -1743,13 +1577,60 @@ warn_logical_operator (location_t location, enum tree_code code,
&& !integer_zerop (op_right)
&& !integer_onep (op_right))
{
- if (code == TRUTH_ORIF_EXPR || code == TRUTH_OR_EXPR)
+ if (or_op)
warning_at (location, OPT_Wlogical_op, "logical %<or%>"
" applied to non-boolean constant");
else
warning_at (location, OPT_Wlogical_op, "logical %<and%>"
" applied to non-boolean constant");
TREE_NO_WARNING (op_left) = true;
+ return;
+ }
+
+ /* We do not warn for constants because they are typical of macro
+ expansions that test for features. */
+ if (CONSTANT_CLASS_P (op_left) || CONSTANT_CLASS_P (op_right))
+ return;
+
+ /* This warning only makes sense with logical operands. */
+ if (!(truth_value_p (TREE_CODE (op_left))
+ || INTEGRAL_TYPE_P (TREE_TYPE (op_left)))
+ || !(truth_value_p (TREE_CODE (op_right))
+ || INTEGRAL_TYPE_P (TREE_TYPE (op_right))))
+ return;
+
+ lhs = make_range (op_left, &in0_p, &low0, &high0, &strict_overflow_p);
+ rhs = make_range (op_right, &in1_p, &low1, &high1, &strict_overflow_p);
+
+ if (lhs && TREE_CODE (lhs) == C_MAYBE_CONST_EXPR)
+ lhs = C_MAYBE_CONST_EXPR_EXPR (lhs);
+
+ if (rhs && TREE_CODE (rhs) == C_MAYBE_CONST_EXPR)
+ rhs = C_MAYBE_CONST_EXPR_EXPR (rhs);
+
+ /* If this is an OR operation, invert both sides; we will invert
+ again at the end. */
+ if (or_op)
+ in0_p = !in0_p, in1_p = !in1_p;
+
+ /* If both expressions are the same, if we can merge the ranges, and we
+ can build the range test, return it or it inverted. */
+ if (lhs && rhs && operand_equal_p (lhs, rhs, 0)
+ && merge_ranges (&in_p, &low, &high, in0_p, low0, high0,
+ in1_p, low1, high1)
+ && 0 != (tem = build_range_check (type, lhs, in_p, low, high)))
+ {
+ if (TREE_CODE (tem) != INTEGER_CST)
+ return;
+
+ if (or_op)
+ warning_at (location, OPT_Wlogical_op,
+ "logical %<or%> "
+ "of collectively exhaustive tests is always true");
+ else
+ warning_at (location, OPT_Wlogical_op,
+ "logical %<and%> "
+ "of mutually exclusive tests is always false");
}
}
@@ -2345,7 +2226,9 @@ convert_and_check (tree type, tree expr)
result = convert (type, expr);
- if (!skip_evaluation && !TREE_OVERFLOW_P (expr) && result != error_mark_node)
+ if (c_inhibit_evaluation_warnings == 0
+ && !TREE_OVERFLOW_P (expr)
+ && result != error_mark_node)
warnings_for_convert_and_check (type, expr_for_warning, result);
return result;
@@ -3347,7 +3230,8 @@ c_register_builtin_type (tree type, const char* name)
{
tree decl;
- decl = build_decl (TYPE_DECL, get_identifier (name), type);
+ decl = build_decl (UNKNOWN_LOCATION,
+ TYPE_DECL, get_identifier (name), type);
DECL_ARTIFICIAL (decl) = 1;
if (!TYPE_NAME (type))
TYPE_NAME (type) = decl;
@@ -3922,8 +3806,9 @@ c_common_truthvalue_conversion (location_t location, tree expr)
case ORDERED_EXPR: case UNORDERED_EXPR:
if (TREE_TYPE (expr) == truthvalue_type_node)
return expr;
- return build2 (TREE_CODE (expr), truthvalue_type_node,
+ expr = build2 (TREE_CODE (expr), truthvalue_type_node,
TREE_OPERAND (expr, 0), TREE_OPERAND (expr, 1));
+ goto ret;
case TRUTH_ANDIF_EXPR:
case TRUTH_ORIF_EXPR:
@@ -3932,18 +3817,20 @@ c_common_truthvalue_conversion (location_t location, tree expr)
case TRUTH_XOR_EXPR:
if (TREE_TYPE (expr) == truthvalue_type_node)
return expr;
- return build2 (TREE_CODE (expr), truthvalue_type_node,
- c_common_truthvalue_conversion (location,
- TREE_OPERAND (expr, 0)),
- c_common_truthvalue_conversion (location,
- TREE_OPERAND (expr, 1)));
+ expr = build2 (TREE_CODE (expr), truthvalue_type_node,
+ c_common_truthvalue_conversion (location,
+ TREE_OPERAND (expr, 0)),
+ c_common_truthvalue_conversion (location,
+ TREE_OPERAND (expr, 1)));
+ goto ret;
case TRUTH_NOT_EXPR:
if (TREE_TYPE (expr) == truthvalue_type_node)
return expr;
- return build1 (TREE_CODE (expr), truthvalue_type_node,
- c_common_truthvalue_conversion (location,
- TREE_OPERAND (expr, 0)));
+ expr = build1 (TREE_CODE (expr), truthvalue_type_node,
+ c_common_truthvalue_conversion (location,
+ TREE_OPERAND (expr, 0)));
+ goto ret;
case ERROR_MARK:
return expr;
@@ -3989,14 +3876,17 @@ c_common_truthvalue_conversion (location_t location, tree expr)
}
if (TREE_SIDE_EFFECTS (inner))
- return build2 (COMPOUND_EXPR, truthvalue_type_node,
- inner, truthvalue_true_node);
+ {
+ expr = build2 (COMPOUND_EXPR, truthvalue_type_node,
+ inner, truthvalue_true_node);
+ goto ret;
+ }
else
return truthvalue_true_node;
}
case COMPLEX_EXPR:
- return build_binary_op (EXPR_LOCATION (expr),
+ expr = build_binary_op (EXPR_LOCATION (expr),
(TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1))
? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),
c_common_truthvalue_conversion (location,
@@ -4004,6 +3894,7 @@ c_common_truthvalue_conversion (location_t location, tree expr)
c_common_truthvalue_conversion (location,
TREE_OPERAND (expr, 1)),
0);
+ goto ret;
case NEGATE_EXPR:
case ABS_EXPR:
@@ -4017,10 +3908,13 @@ c_common_truthvalue_conversion (location_t location, tree expr)
/* These don't change whether an object is zero or nonzero, but
we can't ignore them if their second arg has side-effects. */
if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1)))
- return build2 (COMPOUND_EXPR, truthvalue_type_node,
- TREE_OPERAND (expr, 1),
- c_common_truthvalue_conversion
- (location, TREE_OPERAND (expr, 0)));
+ {
+ expr = build2 (COMPOUND_EXPR, truthvalue_type_node,
+ TREE_OPERAND (expr, 1),
+ c_common_truthvalue_conversion
+ (location, TREE_OPERAND (expr, 0)));
+ goto ret;
+ }
else
return c_common_truthvalue_conversion (location,
TREE_OPERAND (expr, 0));
@@ -4028,22 +3922,28 @@ c_common_truthvalue_conversion (location_t location, tree expr)
case COND_EXPR:
/* Distribute the conversion into the arms of a COND_EXPR. */
if (c_dialect_cxx ())
- return fold_build3 (COND_EXPR, truthvalue_type_node,
- TREE_OPERAND (expr, 0),
- c_common_truthvalue_conversion (location,
- TREE_OPERAND (expr,
- 1)),
- c_common_truthvalue_conversion (location,
- TREE_OPERAND (expr,
- 2)));
+ {
+ expr = fold_build3 (COND_EXPR, truthvalue_type_node,
+ TREE_OPERAND (expr, 0),
+ c_common_truthvalue_conversion (location,
+ TREE_OPERAND (expr,
+ 1)),
+ c_common_truthvalue_conversion (location,
+ TREE_OPERAND (expr,
+ 2)));
+ goto ret;
+ }
else
- /* Folding will happen later for C. */
- return build3 (COND_EXPR, truthvalue_type_node,
- TREE_OPERAND (expr, 0),
- c_common_truthvalue_conversion (location,
- TREE_OPERAND (expr, 1)),
- c_common_truthvalue_conversion (location,
- TREE_OPERAND (expr, 2)));
+ {
+ /* Folding will happen later for C. */
+ expr = build3 (COND_EXPR, truthvalue_type_node,
+ TREE_OPERAND (expr, 0),
+ c_common_truthvalue_conversion (location,
+ TREE_OPERAND (expr, 1)),
+ c_common_truthvalue_conversion (location,
+ TREE_OPERAND (expr, 2)));
+ goto ret;
+ }
CASE_CONVERT:
/* Don't cancel the effect of a CONVERT_EXPR from a REFERENCE_TYPE,
@@ -4075,7 +3975,7 @@ c_common_truthvalue_conversion (location_t location, tree expr)
if (TREE_CODE (TREE_TYPE (expr)) == COMPLEX_TYPE)
{
tree t = c_save_expr (expr);
- return (build_binary_op
+ expr = (build_binary_op
(EXPR_LOCATION (expr),
(TREE_SIDE_EFFECTS (expr)
? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),
@@ -4086,6 +3986,7 @@ c_common_truthvalue_conversion (location_t location, tree expr)
(location,
build_unary_op (location, IMAGPART_EXPR, t, 0)),
0));
+ goto ret;
}
if (TREE_CODE (TREE_TYPE (expr)) == FIXED_POINT_TYPE)
@@ -4095,8 +3996,12 @@ c_common_truthvalue_conversion (location_t location, tree expr)
(TREE_TYPE (expr))));
return build_binary_op (location, NE_EXPR, expr, fixed_zero_node, 1);
}
+ else
+ return build_binary_op (location, NE_EXPR, expr, integer_zero_node, 1);
- return build_binary_op (location, NE_EXPR, expr, integer_zero_node, 1);
+ ret:
+ protected_set_expr_location (expr, location);
+ return expr;
}
static void def_builtin_1 (enum built_in_function fncode,
@@ -4337,13 +4242,15 @@ c_common_get_alias_set (tree t)
return -1;
}
-/* Compute the value of 'sizeof (TYPE)' or '__alignof__ (TYPE)', where the
- second parameter indicates which OPERATOR is being applied. The COMPLAIN
- flag controls whether we should diagnose possibly ill-formed
- constructs or not. */
+/* Compute the value of 'sizeof (TYPE)' or '__alignof__ (TYPE)', where
+ the second parameter indicates which OPERATOR is being applied.
+ The COMPLAIN flag controls whether we should diagnose possibly
+ ill-formed constructs or not. LOC is the location of the SIZEOF or
+ TYPEOF operator. */
tree
-c_sizeof_or_alignof_type (tree type, bool is_sizeof, int complain)
+c_sizeof_or_alignof_type (location_t loc,
+ tree type, bool is_sizeof, int complain)
{
const char *op_name;
tree value = NULL;
@@ -4356,7 +4263,7 @@ c_sizeof_or_alignof_type (tree type, bool is_sizeof, int complain)
if (is_sizeof)
{
if (complain && (pedantic || warn_pointer_arith))
- pedwarn (input_location, pedantic ? OPT_pedantic : OPT_Wpointer_arith,
+ pedwarn (loc, pedantic ? OPT_pedantic : OPT_Wpointer_arith,
"invalid application of %<sizeof%> to a function type");
else if (!complain)
return error_mark_node;
@@ -4369,7 +4276,7 @@ c_sizeof_or_alignof_type (tree type, bool is_sizeof, int complain)
{
if (type_code == VOID_TYPE
&& complain && (pedantic || warn_pointer_arith))
- pedwarn (input_location, pedantic ? OPT_pedantic : OPT_Wpointer_arith,
+ pedwarn (loc, pedantic ? OPT_pedantic : OPT_Wpointer_arith,
"invalid application of %qs to a void type", op_name);
else if (!complain)
return error_mark_node;
@@ -4378,8 +4285,8 @@ c_sizeof_or_alignof_type (tree type, bool is_sizeof, int complain)
else if (!COMPLETE_TYPE_P (type))
{
if (complain)
- error ("invalid application of %qs to incomplete type %qT ",
- op_name, type);
+ error_at (loc, "invalid application of %qs to incomplete type %qT ",
+ op_name, type);
value = size_zero_node;
}
else
@@ -4406,10 +4313,11 @@ c_sizeof_or_alignof_type (tree type, bool is_sizeof, int complain)
/* Implement the __alignof keyword: Return the minimum required
alignment of EXPR, measured in bytes. For VAR_DECLs,
FUNCTION_DECLs and FIELD_DECLs return DECL_ALIGN (which can be set
- from an "aligned" __attribute__ specification). */
+ from an "aligned" __attribute__ specification). LOC is the
+ location of the ALIGNOF operator. */
tree
-c_alignof_expr (tree expr)
+c_alignof_expr (location_t loc, tree expr)
{
tree t;
@@ -4419,7 +4327,7 @@ c_alignof_expr (tree expr)
else if (TREE_CODE (expr) == COMPONENT_REF
&& DECL_C_BIT_FIELD (TREE_OPERAND (expr, 1)))
{
- error ("%<__alignof%> applied to a bit-field");
+ error_at (loc, "%<__alignof%> applied to a bit-field");
t = size_one_node;
}
else if (TREE_CODE (expr) == COMPONENT_REF
@@ -4442,10 +4350,10 @@ c_alignof_expr (tree expr)
if (thisalign > bestalign)
best = t, bestalign = thisalign;
}
- return c_alignof (TREE_TYPE (TREE_TYPE (best)));
+ return c_alignof (loc, TREE_TYPE (TREE_TYPE (best)));
}
else
- return c_alignof (TREE_TYPE (expr));
+ return c_alignof (loc, TREE_TYPE (expr));
return fold_convert (size_type_node, t);
}
@@ -4693,31 +4601,41 @@ c_common_nodes_and_builtins (void)
/* These are types that c_common_type_for_size and
c_common_type_for_mode use. */
- lang_hooks.decls.pushdecl (build_decl (TYPE_DECL, NULL_TREE,
+ lang_hooks.decls.pushdecl (build_decl (UNKNOWN_LOCATION,
+ TYPE_DECL, NULL_TREE,
intQI_type_node));
- lang_hooks.decls.pushdecl (build_decl (TYPE_DECL, NULL_TREE,
+ lang_hooks.decls.pushdecl (build_decl (UNKNOWN_LOCATION,
+ TYPE_DECL, NULL_TREE,
intHI_type_node));
- lang_hooks.decls.pushdecl (build_decl (TYPE_DECL, NULL_TREE,
+ lang_hooks.decls.pushdecl (build_decl (UNKNOWN_LOCATION,
+ TYPE_DECL, NULL_TREE,
intSI_type_node));
- lang_hooks.decls.pushdecl (build_decl (TYPE_DECL, NULL_TREE,
+ lang_hooks.decls.pushdecl (build_decl (UNKNOWN_LOCATION,
+ TYPE_DECL, NULL_TREE,
intDI_type_node));
#if HOST_BITS_PER_WIDE_INT >= 64
if (targetm.scalar_mode_supported_p (TImode))
- lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
+ lang_hooks.decls.pushdecl (build_decl (UNKNOWN_LOCATION,
+ TYPE_DECL,
get_identifier ("__int128_t"),
intTI_type_node));
#endif
- lang_hooks.decls.pushdecl (build_decl (TYPE_DECL, NULL_TREE,
+ lang_hooks.decls.pushdecl (build_decl (UNKNOWN_LOCATION,
+ TYPE_DECL, NULL_TREE,
unsigned_intQI_type_node));
- lang_hooks.decls.pushdecl (build_decl (TYPE_DECL, NULL_TREE,
+ lang_hooks.decls.pushdecl (build_decl (UNKNOWN_LOCATION,
+ TYPE_DECL, NULL_TREE,
unsigned_intHI_type_node));
- lang_hooks.decls.pushdecl (build_decl (TYPE_DECL, NULL_TREE,
+ lang_hooks.decls.pushdecl (build_decl (UNKNOWN_LOCATION,
+ TYPE_DECL, NULL_TREE,
unsigned_intSI_type_node));
- lang_hooks.decls.pushdecl (build_decl (TYPE_DECL, NULL_TREE,
+ lang_hooks.decls.pushdecl (build_decl (UNKNOWN_LOCATION,
+ TYPE_DECL, NULL_TREE,
unsigned_intDI_type_node));
#if HOST_BITS_PER_WIDE_INT >= 64
if (targetm.scalar_mode_supported_p (TImode))
- lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
+ lang_hooks.decls.pushdecl (build_decl (UNKNOWN_LOCATION,
+ TYPE_DECL,
get_identifier ("__uint128_t"),
unsigned_intTI_type_node));
#endif
@@ -4725,12 +4643,14 @@ c_common_nodes_and_builtins (void)
/* Create the widest literal types. */
widest_integer_literal_type_node
= make_signed_type (HOST_BITS_PER_WIDE_INT * 2);
- lang_hooks.decls.pushdecl (build_decl (TYPE_DECL, NULL_TREE,
+ lang_hooks.decls.pushdecl (build_decl (UNKNOWN_LOCATION,
+ TYPE_DECL, NULL_TREE,
widest_integer_literal_type_node));
widest_unsigned_literal_type_node
= make_unsigned_type (HOST_BITS_PER_WIDE_INT * 2);
- lang_hooks.decls.pushdecl (build_decl (TYPE_DECL, NULL_TREE,
+ lang_hooks.decls.pushdecl (build_decl (UNKNOWN_LOCATION,
+ TYPE_DECL, NULL_TREE,
widest_unsigned_literal_type_node));
/* `unsigned long' is the standard type for sizeof.
@@ -4822,17 +4742,21 @@ c_common_nodes_and_builtins (void)
}
- lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
+ lang_hooks.decls.pushdecl (build_decl (UNKNOWN_LOCATION,
+ TYPE_DECL,
get_identifier ("complex int"),
complex_integer_type_node));
- lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
+ lang_hooks.decls.pushdecl (build_decl (UNKNOWN_LOCATION,
+ TYPE_DECL,
get_identifier ("complex float"),
complex_float_type_node));
- lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
+ lang_hooks.decls.pushdecl (build_decl (UNKNOWN_LOCATION,
+ TYPE_DECL,
get_identifier ("complex double"),
complex_double_type_node));
lang_hooks.decls.pushdecl
- (build_decl (TYPE_DECL, get_identifier ("complex long double"),
+ (build_decl (UNKNOWN_LOCATION,
+ TYPE_DECL, get_identifier ("complex long double"),
complex_long_double_type_node));
if (c_dialect_cxx ())
@@ -5026,7 +4950,8 @@ c_common_nodes_and_builtins (void)
unsigned_ptrdiff_type_node = c_common_unsigned_type (ptrdiff_type_node);
lang_hooks.decls.pushdecl
- (build_decl (TYPE_DECL, get_identifier ("__builtin_va_list"),
+ (build_decl (UNKNOWN_LOCATION,
+ TYPE_DECL, get_identifier ("__builtin_va_list"),
va_list_type_node));
#ifdef TARGET_ENUM_VA_LIST
{
@@ -5036,7 +4961,8 @@ c_common_nodes_and_builtins (void)
for (l = 0; TARGET_ENUM_VA_LIST (l, &pname, &ptype); ++l)
{
lang_hooks.decls.pushdecl
- (build_decl (TYPE_DECL, get_identifier (pname),
+ (build_decl (UNKNOWN_LOCATION,
+ TYPE_DECL, get_identifier (pname),
ptype));
}
@@ -5122,9 +5048,11 @@ set_compound_literal_name (tree decl)
}
tree
-build_va_arg (tree expr, tree type)
+build_va_arg (location_t loc, tree expr, tree type)
{
- return build1 (VA_ARG_EXPR, type, expr);
+ expr = build1 (VA_ARG_EXPR, type, expr);
+ SET_EXPR_LOCATION (expr, loc);
+ return expr;
}
@@ -5306,17 +5234,18 @@ case_compare (splay_tree_key k1, splay_tree_key k2)
return tree_int_cst_compare ((tree) k1, (tree) k2);
}
-/* Process a case label for the range LOW_VALUE ... HIGH_VALUE. If
- LOW_VALUE and HIGH_VALUE are both NULL_TREE then this case label is
- actually a `default' label. If only HIGH_VALUE is NULL_TREE, then
- case label was declared using the usual C/C++ syntax, rather than
- the GNU case range extension. CASES is a tree containing all the
- case ranges processed so far; COND is the condition for the
- switch-statement itself. Returns the CASE_LABEL_EXPR created, or
- ERROR_MARK_NODE if no CASE_LABEL_EXPR is created. */
+/* Process a case label, located at LOC, for the range LOW_VALUE
+ ... HIGH_VALUE. If LOW_VALUE and HIGH_VALUE are both NULL_TREE
+ then this case label is actually a `default' label. If only
+ HIGH_VALUE is NULL_TREE, then case label was declared using the
+ usual C/C++ syntax, rather than the GNU case range extension.
+ CASES is a tree containing all the case ranges processed so far;
+ COND is the condition for the switch-statement itself. Returns the
+ CASE_LABEL_EXPR created, or ERROR_MARK_NODE if no CASE_LABEL_EXPR
+ is created. */
tree
-c_add_case_label (splay_tree cases, tree cond, tree orig_type,
+c_add_case_label (location_t loc, splay_tree cases, tree cond, tree orig_type,
tree low_value, tree high_value)
{
tree type;
@@ -5325,7 +5254,7 @@ c_add_case_label (splay_tree cases, tree cond, tree orig_type,
splay_tree_node node;
/* Create the LABEL_DECL itself. */
- label = create_artificial_label ();
+ label = create_artificial_label (loc);
/* If there was an error processing the switch condition, bail now
before we get more confused. */
@@ -5337,13 +5266,13 @@ c_add_case_label (splay_tree cases, tree cond, tree orig_type,
|| (high_value && TREE_TYPE (high_value)
&& POINTER_TYPE_P (TREE_TYPE (high_value))))
{
- error ("pointers are not permitted as case values");
+ error_at (loc, "pointers are not permitted as case values");
goto error_out;
}
/* Case ranges are a GNU extension. */
if (high_value)
- pedwarn (input_location, OPT_pedantic,
+ pedwarn (loc, OPT_pedantic,
"range expressions in switch statements are non-standard");
type = TREE_TYPE (cond);
@@ -5370,7 +5299,7 @@ c_add_case_label (splay_tree cases, tree cond, tree orig_type,
if (tree_int_cst_equal (low_value, high_value))
high_value = NULL_TREE;
else if (!tree_int_cst_lt (low_value, high_value))
- warning (0, "empty range specified");
+ warning_at (loc, 0, "empty range specified");
}
/* See if the case is in range of the type of the original testing
@@ -5430,24 +5359,26 @@ c_add_case_label (splay_tree cases, tree cond, tree orig_type,
if (high_value)
{
- error ("duplicate (or overlapping) case value");
- error ("%Jthis is the first entry overlapping that value", duplicate);
+ error_at (loc, "duplicate (or overlapping) case value");
+ error_at (DECL_SOURCE_LOCATION (duplicate),
+ "this is the first entry overlapping that value");
}
else if (low_value)
{
- error ("duplicate case value") ;
- error ("%Jpreviously used here", duplicate);
+ error_at (loc, "duplicate case value") ;
+ error_at (DECL_SOURCE_LOCATION (duplicate), "previously used here");
}
else
{
- error ("multiple default labels in one switch");
- error ("%Jthis is the first default label", duplicate);
+ error_at (loc, "multiple default labels in one switch");
+ error_at (DECL_SOURCE_LOCATION (duplicate),
+ "this is the first default label");
}
goto error_out;
}
/* Add a CASE_LABEL to the statement-tree. */
- case_label = add_stmt (build_case_label (low_value, high_value, label));
+ case_label = add_stmt (build_case_label (loc, low_value, high_value, label));
/* Register this case label in the splay tree. */
splay_tree_insert (cases,
(splay_tree_key) low_value,
@@ -5461,8 +5392,8 @@ c_add_case_label (splay_tree cases, tree cond, tree orig_type,
that just leads to duplicates and thence to failure later on. */
if (!cases->root)
{
- tree t = create_artificial_label ();
- add_stmt (build_stmt (LABEL_EXPR, t));
+ tree t = create_artificial_label (loc);
+ add_stmt (build_stmt (loc, LABEL_EXPR, t));
}
return error_mark_node;
}
@@ -5548,7 +5479,6 @@ c_do_switch_warnings (splay_tree cases, location_t switch_location,
splay_tree_node default_node;
splay_tree_node node;
tree chain;
- int saved_warn_switch;
if (!warn_switch && !warn_switch_enum && !warn_switch_default)
return;
@@ -5562,15 +5492,15 @@ c_do_switch_warnings (splay_tree cases, location_t switch_location,
if (!type || TREE_CODE (type) != ENUMERAL_TYPE)
return;
- /* If the switch expression was an enumerated type, check that
- exactly all enumeration literals are covered by the cases.
- The check is made when -Wswitch was specified and there is no
- default case, or when -Wswitch-enum was specified. */
-
- if (!warn_switch_enum
- && !(warn_switch && !default_node))
+ /* From here on, we only care about -Wswitch and -Wswitch-enum. */
+ if (!warn_switch_enum && !warn_switch)
return;
+ /* Check the cases. Warn about case values which are not members of
+ the enumerated type. For -Wswitch-enum, or for -Wswitch when
+ there is no default case, check that exactly all enumeration
+ literals are covered by the cases. */
+
/* Clearing COND if it is not an integer constant simplifies
the tests inside the loop below. */
if (TREE_CODE (cond) != INTEGER_CST)
@@ -5621,13 +5551,15 @@ c_do_switch_warnings (splay_tree cases, location_t switch_location,
continue;
/* If there is a default_node, the only relevant option is
- Wswitch-enum. Otherwise, if both are enabled then we prefer
+ Wswitch-enum. Otherwise, if both are enabled then we prefer
to warn using -Wswitch because -Wswitch is enabled by -Wall
while -Wswitch-enum is explicit. */
- warning ((default_node || !warn_switch)
- ? OPT_Wswitch_enum : OPT_Wswitch,
- "%Henumeration value %qE not handled in switch",
- &switch_location, TREE_PURPOSE (chain));
+ warning_at (switch_location,
+ (default_node || !warn_switch
+ ? OPT_Wswitch_enum
+ : OPT_Wswitch),
+ "enumeration value %qE not handled in switch",
+ TREE_PURPOSE (chain));
}
/* Warn if there are case expressions that don't correspond to
@@ -5639,16 +5571,7 @@ c_do_switch_warnings (splay_tree cases, location_t switch_location,
every disjoint case label, with CASE_LOW_SEEN and CASE_HIGH_SEEN
above. This scan also resets those fields. */
- /* If there is a default_node, the only relevant option is
- Wswitch-enum. Otherwise, if both are enabled then we prefer
- to warn using -Wswitch because -Wswitch is enabled by -Wall
- while -Wswitch-enum is explicit. */
- saved_warn_switch = warn_switch;
- if (default_node)
- warn_switch = 0;
splay_tree_foreach (cases, match_case_to_enum, type);
- warn_switch = saved_warn_switch;
-
}
/* Finish an expression taking the address of LABEL (an
@@ -8746,13 +8669,15 @@ sync_resolve_return (tree first_param, tree result)
function should be called immediately after parsing the call expression
before surrounding code has committed to the type of the expression.
+ LOC is the location of the builtin call.
+
FUNCTION is the DECL that has been invoked; it is known to be a builtin.
PARAMS is the argument list for the call. The return value is non-null
when expansion is complete, and null if normal processing should
continue. */
tree
-resolve_overloaded_builtin (tree function, VEC(tree,gc) *params)
+resolve_overloaded_builtin (location_t loc, tree function, VEC(tree,gc) *params)
{
enum built_in_function orig_code = DECL_FUNCTION_CODE (function);
switch (DECL_BUILT_IN_CLASS (function))
@@ -8761,7 +8686,7 @@ resolve_overloaded_builtin (tree function, VEC(tree,gc) *params)
break;
case BUILT_IN_MD:
if (targetm.resolve_overloaded_builtin)
- return targetm.resolve_overloaded_builtin (function, params);
+ return targetm.resolve_overloaded_builtin (loc, function, params);
else
return NULL_TREE;
default:
@@ -8799,7 +8724,7 @@ resolve_overloaded_builtin (tree function, VEC(tree,gc) *params)
return error_mark_node;
first_param = VEC_index (tree, params, 0);
- result = build_function_call_vec (new_function, params, NULL);
+ result = build_function_call_vec (loc, new_function, params, NULL);
if (orig_code != BUILT_IN_BOOL_COMPARE_AND_SWAP_N
&& orig_code != BUILT_IN_LOCK_RELEASE_N)
result = sync_resolve_return (first_param, result);
@@ -9030,7 +8955,7 @@ warn_for_div_by_zero (location_t loc, tree divisor)
about division by zero. Do not issue a warning if DIVISOR has a
floating-point type, since we consider 0.0/0.0 a valid way of
generating a NaN. */
- if (skip_evaluation == 0
+ if (c_inhibit_evaluation_warnings == 0
&& (integer_zerop (divisor) || fixed_zerop (divisor)))
warning_at (loc, OPT_Wdiv_by_zero, "division by zero");
}
@@ -9255,4 +9180,69 @@ is_typedef_decl (tree x)
&& DECL_ORIGINAL_TYPE (x) != NULL_TREE);
}
+/* The C and C++ parsers both use vectors to hold function arguments.
+ For efficiency, we keep a cache of unused vectors. This is the
+ cache. */
+
+typedef VEC(tree,gc)* tree_gc_vec;
+DEF_VEC_P(tree_gc_vec);
+DEF_VEC_ALLOC_P(tree_gc_vec,gc);
+static GTY((deletable)) VEC(tree_gc_vec,gc) *tree_vector_cache;
+
+/* Return a new vector from the cache. If the cache is empty,
+ allocate a new vector. These vectors are GC'ed, so it is OK if the
+ pointer is not released.. */
+
+VEC(tree,gc) *
+make_tree_vector (void)
+{
+ if (!VEC_empty (tree_gc_vec, tree_vector_cache))
+ return VEC_pop (tree_gc_vec, tree_vector_cache);
+ else
+ {
+ /* Passing 0 to VEC_alloc returns NULL, and our callers require
+ that we always return a non-NULL value. The vector code uses
+ 4 when growing a NULL vector, so we do too. */
+ return VEC_alloc (tree, gc, 4);
+ }
+}
+
+/* Release a vector of trees back to the cache. */
+
+void
+release_tree_vector (VEC(tree,gc) *vec)
+{
+ if (vec != NULL)
+ {
+ VEC_truncate (tree, vec, 0);
+ VEC_safe_push (tree_gc_vec, gc, tree_vector_cache, vec);
+ }
+}
+
+/* Get a new tree vector holding a single tree. */
+
+VEC(tree,gc) *
+make_tree_vector_single (tree t)
+{
+ VEC(tree,gc) *ret = make_tree_vector ();
+ VEC_quick_push (tree, ret, t);
+ return ret;
+}
+
+/* Get a new tree vector which is a copy of an existing one. */
+
+VEC(tree,gc) *
+make_tree_vector_copy (const VEC(tree,gc) *orig)
+{
+ VEC(tree,gc) *ret;
+ unsigned int ix;
+ tree t;
+
+ ret = make_tree_vector ();
+ VEC_reserve (tree, gc, ret, VEC_length (tree, orig));
+ for (ix = 0; VEC_iterate (tree, orig, ix, t); ++ix)
+ VEC_quick_push (tree, ret, t);
+ return ret;
+}
+
#include "gt-c-common.h"
diff --git a/gcc/c-common.h b/gcc/c-common.h
index 250a7ff74fa..04a194597f7 100644
--- a/gcc/c-common.h
+++ b/gcc/c-common.h
@@ -418,7 +418,7 @@ extern void push_cleanup (tree, tree, bool);
extern tree pushdecl_top_level (tree);
extern tree pushdecl (tree);
extern tree build_modify_expr (location_t, tree, tree, enum tree_code,
- tree, tree);
+ location_t, tree, tree);
extern tree build_indirect_ref (location_t, tree, const char *);
extern int c_expand_decl (tree);
@@ -719,10 +719,13 @@ extern int warn_strict_null_sentinel;
extern int max_tinst_depth;
-/* Nonzero means the expression being parsed will never be evaluated.
- This is a count, since unevaluated expressions can nest. */
+/* Nonzero means that we should not issue warnings about problems that
+ occur when the code is executed, because the code being processed
+ is not expected to be executed. This is set during parsing. This
+ is used for cases like sizeof() and "0 ? a : b". This is a count,
+ not a bool, because unexecuted expressions can nest. */
-extern int skip_evaluation;
+extern int c_inhibit_evaluation_warnings;
/* Whether lexing has been completed, so subsequent preprocessor
errors should use the compiler's input_location. */
@@ -754,7 +757,7 @@ extern const struct attribute_spec c_common_format_attribute_table[];
TYPE_DEP indicates whether it depends on type of the function or not
(i.e. __PRETTY_FUNCTION__). */
-extern tree (*make_fname_decl) (tree, int);
+extern tree (*make_fname_decl) (location_t, tree, int);
extern tree identifier_global_value (tree);
extern void record_builtin_type (enum rid, const char *, tree);
@@ -791,8 +794,8 @@ extern tree decl_constant_value_for_optimization (tree);
extern tree c_save_expr (tree);
extern tree c_common_truthvalue_conversion (location_t, tree);
extern void c_apply_type_quals_to_decl (int, tree);
-extern tree c_sizeof_or_alignof_type (tree, bool, int);
-extern tree c_alignof_expr (tree);
+extern tree c_sizeof_or_alignof_type (location_t, tree, bool, int);
+extern tree c_alignof_expr (location_t, tree);
/* Print an error message for invalid operands to arith operation CODE.
NOP_EXPR is used as a special case (see truthvalue_conversion). */
extern void binary_op_error (location_t, enum tree_code, tree, tree);
@@ -803,8 +806,8 @@ extern void constant_expression_error (tree);
extern bool strict_aliasing_warning (tree, tree, tree);
extern void warnings_for_convert_and_check (tree, tree, tree);
extern tree convert_and_check (tree, tree);
-extern void overflow_warning (tree);
-extern void warn_logical_operator (location_t, enum tree_code,
+extern void overflow_warning (location_t, tree);
+extern void warn_logical_operator (location_t, enum tree_code, tree,
enum tree_code, tree, enum tree_code, tree);
extern void check_main_parameter_types (tree decl);
extern bool c_determine_visibility (tree);
@@ -815,8 +818,8 @@ extern void set_float_const_decimal64 (void);
extern void clear_float_const_decimal64 (void);
extern bool float_const_decimal64_p (void);
-#define c_sizeof(T) c_sizeof_or_alignof_type (T, true, 1)
-#define c_alignof(T) c_sizeof_or_alignof_type (T, false, 1)
+#define c_sizeof(LOC, T) c_sizeof_or_alignof_type (LOC, T, true, 1)
+#define c_alignof(LOC, T) c_sizeof_or_alignof_type (LOC, T, false, 1)
/* Subroutine of build_binary_op, used for certain operations. */
extern tree shorten_binary_op (tree result_type, tree op0, tree op1, bool bitwise);
@@ -841,7 +844,7 @@ extern void disable_builtin_function (const char *);
extern void set_compound_literal_name (tree decl);
-extern tree build_va_arg (tree, tree);
+extern tree build_va_arg (location_t, tree, tree);
extern unsigned int c_common_init_options (unsigned int, const char **);
extern bool c_common_post_options (const char **);
@@ -896,9 +899,9 @@ extern void finish_file (void);
#define CLEAR_DECL_C_BIT_FIELD(NODE) \
(DECL_LANG_FLAG_4 (FIELD_DECL_CHECK (NODE)) = 0)
-extern tree do_case (tree, tree);
-extern tree build_stmt (enum tree_code, ...);
-extern tree build_case_label (tree, tree, tree);
+extern tree do_case (location_t, tree, tree);
+extern tree build_stmt (location_t, enum tree_code, ...);
+extern tree build_case_label (location_t, tree, tree, tree);
/* These functions must be defined by each front-end which implements
a variant of the C language. They are used in c-common.c. */
@@ -924,15 +927,16 @@ extern tree boolean_increment (enum tree_code, tree);
extern int case_compare (splay_tree_key, splay_tree_key);
-extern tree c_add_case_label (splay_tree, tree, tree, tree, tree);
+extern tree c_add_case_label (location_t, splay_tree, tree, tree, tree, tree);
extern void c_do_switch_warnings (splay_tree, location_t, tree, tree);
-extern tree build_function_call (tree, tree);
+extern tree build_function_call (location_t, tree, tree);
-extern tree build_function_call_vec (tree, VEC(tree,gc) *, VEC(tree,gc) *);
+extern tree build_function_call_vec (location_t, tree,
+ VEC(tree,gc) *, VEC(tree,gc) *);
-extern tree resolve_overloaded_builtin (tree, VEC(tree,gc) *);
+extern tree resolve_overloaded_builtin (location_t, tree, VEC(tree,gc) *);
extern tree finish_label_address_expr (tree, location_t);
@@ -1013,11 +1017,15 @@ extern void warn_for_sign_compare (location_t,
enum tree_code resultcode);
extern void set_underlying_type (tree x);
extern bool is_typedef_decl (tree x);
+extern VEC(tree,gc) *make_tree_vector (void);
+extern void release_tree_vector (VEC(tree,gc) *);
+extern VEC(tree,gc) *make_tree_vector_single (tree);
+extern VEC(tree,gc) *make_tree_vector_copy (const VEC(tree,gc) *);
/* In c-gimplify.c */
extern void c_genericize (tree);
extern int c_gimplify_expr (tree *, gimple_seq *, gimple_seq *);
-extern tree c_build_bind_expr (tree, tree);
+extern tree c_build_bind_expr (location_t, tree, tree);
/* In c-pch.c */
extern void pch_init (void);
@@ -1061,7 +1069,7 @@ extern void objc_declare_class (tree);
extern void objc_declare_protocols (tree);
extern tree objc_build_message_expr (tree);
extern tree objc_finish_message_expr (tree, tree, tree);
-extern tree objc_build_selector_expr (tree);
+extern tree objc_build_selector_expr (location_t, tree);
extern tree objc_build_protocol_expr (tree);
extern tree objc_build_encode_expr (tree);
extern tree objc_build_string_object (tree);
@@ -1085,7 +1093,7 @@ extern void objc_start_method_definition (tree);
extern void objc_finish_method_definition (tree);
extern void objc_add_instance_variable (tree);
extern tree objc_build_keyword_decl (tree, tree, tree);
-extern tree objc_build_throw_stmt (tree);
+extern tree objc_build_throw_stmt (location_t, tree);
extern void objc_begin_try_stmt (location_t, tree);
extern tree objc_finish_try_stmt (void);
extern void objc_begin_catch_clause (tree);
@@ -1109,15 +1117,15 @@ extern void pp_dir_change (cpp_reader *, const char *);
extern bool check_missing_format_attribute (tree, tree);
/* In c-omp.c */
-extern tree c_finish_omp_master (tree);
-extern tree c_finish_omp_critical (tree, tree);
-extern tree c_finish_omp_ordered (tree);
-extern void c_finish_omp_barrier (void);
-extern tree c_finish_omp_atomic (enum tree_code, tree, tree);
-extern void c_finish_omp_flush (void);
-extern void c_finish_omp_taskwait (void);
+extern tree c_finish_omp_master (location_t, tree);
+extern tree c_finish_omp_critical (location_t, tree, tree);
+extern tree c_finish_omp_ordered (location_t, tree);
+extern void c_finish_omp_barrier (location_t);
+extern tree c_finish_omp_atomic (location_t, enum tree_code, tree, tree);
+extern void c_finish_omp_flush (location_t);
+extern void c_finish_omp_taskwait (location_t);
extern tree c_finish_omp_for (location_t, tree, tree, tree, tree, tree, tree);
-extern void c_split_parallel_clauses (tree, tree *, tree *);
+extern void c_split_parallel_clauses (location_t, tree, tree *, tree *);
extern enum omp_clause_default_kind c_omp_predetermined_sharing (tree);
/* Not in c-omp.c; provided by the front end. */
diff --git a/gcc/c-convert.c b/gcc/c-convert.c
index 4fb680063ad..5349d7a77e8 100644
--- a/gcc/c-convert.c
+++ b/gcc/c-convert.c
@@ -86,6 +86,9 @@ convert (tree type, tree expr)
if (type == TREE_TYPE (expr))
return expr;
+ ret = targetm.convert_to_type (type, expr);
+ if (ret)
+ return ret;
STRIP_TYPE_NOPS (e);
diff --git a/gcc/c-decl.c b/gcc/c-decl.c
index a9929c1a85c..4e48bac7f54 100644
--- a/gcc/c-decl.c
+++ b/gcc/c-decl.c
@@ -188,7 +188,7 @@ bool c_override_global_bindings_to_false;
suppress further errors about that identifier in the current
function.
- The ->type field stores the type of the declaration in this scope;
+ The ->u.type field stores the type of the declaration in this scope;
if NULL, the type is the type of the ->decl field. This is only of
relevance for objects with external or internal linkage which may
be redeclared in inner scopes, forming composite types that only
@@ -198,6 +198,9 @@ bool c_override_global_bindings_to_false;
scope) stores whether an incomplete array type at file scope was
completed at an inner scope to an array size other than 1.
+ The ->u.label field is used for labels. It points to a structure
+ which stores additional information used for warnings.
+
The depth field is copied from the scope structure that holds this
decl. It is used to preserve the proper ordering of the ->shadowed
field (see bind()) and also for a handful of special-case checks.
@@ -208,8 +211,11 @@ bool c_override_global_bindings_to_false;
invisible bit true. */
struct GTY((chain_next ("%h.prev"))) c_binding {
+ union GTY(()) { /* first so GTY desc can use decl */
+ tree GTY((tag ("0"))) type; /* the type in this scope */
+ struct c_label_vars * GTY((tag ("1"))) label; /* for warnings */
+ } GTY((desc ("TREE_CODE (%0.decl) == LABEL_DECL"))) u;
tree decl; /* the decl bound */
- tree type; /* the type in this scope */
tree id; /* the identifier it's bound to */
struct c_binding *prev; /* the previous decl in this scope */
struct c_binding *shadowed; /* the innermost decl shadowed by this one */
@@ -266,6 +272,67 @@ union GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"),
struct lang_identifier GTY ((tag ("1"))) identifier;
};
+/* Track bindings and other things that matter for goto warnings. For
+ efficiency, we do not gather all the decls at the point of
+ definition. Instead, we point into the bindings structure. As
+ scopes are popped, we update these structures and gather the decls
+ that matter at that time. */
+
+struct GTY(()) c_spot_bindings {
+ /* The currently open scope which holds bindings defined when the
+ label was defined or the goto statement was found. */
+ struct c_scope *scope;
+ /* The bindings in the scope field which were defined at the point
+ of the label or goto. This lets us look at older or newer
+ bindings in the scope, as appropriate. */
+ struct c_binding *bindings_in_scope;
+ /* The number of statement expressions that have started since this
+ label or goto statement was defined. This is zero if we are at
+ the same statement expression level. It is positive if we are in
+ a statement expression started since this spot. It is negative
+ if this spot was in a statement expression and we have left
+ it. */
+ int stmt_exprs;
+ /* Whether we started in a statement expression but are no longer in
+ it. This is set to true if stmt_exprs ever goes negative. */
+ bool left_stmt_expr;
+};
+
+/* This structure is used to keep track of bindings seen when a goto
+ statement is defined. This is only used if we see the goto
+ statement before we see the label. */
+
+struct GTY(()) c_goto_bindings {
+ /* The location of the goto statement. */
+ location_t loc;
+ /* The bindings of the goto statement. */
+ struct c_spot_bindings goto_bindings;
+};
+
+typedef struct c_goto_bindings *c_goto_bindings_p;
+DEF_VEC_P(c_goto_bindings_p);
+DEF_VEC_ALLOC_P(c_goto_bindings_p,gc);
+
+/* The additional information we keep track of for a label binding.
+ These fields are updated as scopes are popped. */
+
+struct GTY(()) c_label_vars {
+ /* The shadowed c_label_vars, when one label shadows another (which
+ can only happen using a __label__ declaration). */
+ struct c_label_vars *shadowed;
+ /* The bindings when the label was defined. */
+ struct c_spot_bindings label_bindings;
+ /* A list of decls that we care about: decls about which we should
+ warn if a goto branches to this label from later in the function.
+ Decls are added to this list as scopes are popped. We only add
+ the decls that matter. */
+ VEC(tree,gc) *decls_in_scope;
+ /* A list of goto statements to this label. This is only used for
+ goto statements seen before the label was defined, so that we can
+ issue appropriate warnings for them. */
+ VEC(c_goto_bindings_p,gc) *gotos;
+};
+
/* Each c_scope structure describes the complete contents of one
scope. Four scopes are distinguished specially: the innermost or
current scope, the innermost function scope, the file scope (always
@@ -354,6 +421,11 @@ struct GTY((chain_next ("%h.outer"))) c_scope {
/* True means that an unsuffixed float constant is _Decimal64. */
BOOL_BITFIELD float_const_decimal64 : 1;
+
+ /* True if this scope has any label bindings. This is used to speed
+ up searching for labels when popping scopes, particularly since
+ labels are normally only found at function scope. */
+ BOOL_BITFIELD has_label_bindings : 1;
};
/* The scope currently in effect. */
@@ -443,7 +515,7 @@ static bool next_is_function_body;
/* Forward declarations. */
static tree lookup_name_in_scope (tree, struct c_scope *);
-static tree c_make_fname_decl (tree, int);
+static tree c_make_fname_decl (location_t, tree, int);
static tree grokdeclarator (const struct c_declarator *,
struct c_declspecs *,
enum decl_context, bool, tree *, tree *, tree *,
@@ -518,7 +590,7 @@ bind (tree name, tree decl, struct c_scope *scope, bool invisible,
b->inner_comp = 0;
b->locus = locus;
- b->type = 0;
+ b->u.type = NULL;
b->prev = scope->bindings;
scope->bindings = b;
@@ -569,6 +641,24 @@ free_binding_and_advance (struct c_binding *b)
return prev;
}
+/* Bind a label. Like bind, but skip fields which aren't used for
+ labels, and add the LABEL_VARS value. */
+static void
+bind_label (tree name, tree label, struct c_scope *scope,
+ struct c_label_vars *label_vars)
+{
+ struct c_binding *b;
+
+ bind (name, label, scope, /*invisible=*/false, /*nested=*/false,
+ UNKNOWN_LOCATION);
+
+ scope->has_label_bindings = true;
+
+ b = scope->bindings;
+ gcc_assert (b->decl == label);
+ label_vars->shadowed = b->u.label;
+ b->u.label = label_vars;
+}
/* Hook called at end of compilation to assume 1 elt
for a file-scope tentative array defn that wasn't complete before. */
@@ -584,7 +674,8 @@ c_finish_incomplete_decl (tree decl)
&& !DECL_EXTERNAL (decl)
&& TYPE_DOMAIN (type) == 0)
{
- warning (0, "array %q+D assumed to have one element", decl);
+ warning_at (DECL_SOURCE_LOCATION (decl),
+ 0, "array %q+D assumed to have one element", decl);
complete_array_type (&TREE_TYPE (decl), NULL_TREE, true);
@@ -640,6 +731,73 @@ check_inline_statics (void)
c_inline_statics = NULL;
}
+/* Fill in a c_spot_bindings structure. If DEFINING is true, set it
+ for the current state, otherwise set it to uninitialized. */
+
+static void
+set_spot_bindings (struct c_spot_bindings *p, bool defining)
+{
+ if (defining)
+ {
+ p->scope = current_scope;
+ p->bindings_in_scope = current_scope->bindings;
+ }
+ else
+ {
+ p->scope = NULL;
+ p->bindings_in_scope = NULL;
+ }
+ p->stmt_exprs = 0;
+ p->left_stmt_expr = false;
+}
+
+/* Return true if we will want to say something if a goto statement
+ crosses DECL. */
+
+static bool
+decl_jump_unsafe (tree decl)
+{
+ if (decl == error_mark_node || TREE_TYPE (decl) == error_mark_node)
+ return false;
+
+ /* Always warn about crossing variably modified types. */
+ if ((TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == TYPE_DECL)
+ && variably_modified_type_p (TREE_TYPE (decl), NULL_TREE))
+ return true;
+
+ /* Otherwise, only warn if -Wgoto-misses-init and this is an
+ initialized automatic decl. */
+ if (warn_jump_misses_init
+ && TREE_CODE (decl) == VAR_DECL
+ && !TREE_STATIC (decl)
+ && DECL_INITIAL (decl) != NULL_TREE)
+ return true;
+
+ return false;
+}
+
+/* Update spot bindings P as we pop out of SCOPE. Return true if we
+ should push decls for a label. */
+
+static bool
+update_spot_bindings (struct c_scope *scope, struct c_spot_bindings *p)
+{
+ if (p->scope != scope)
+ {
+ /* This label or goto is defined in some other scope, or it is a
+ label which is not yet defined. There is nothing to
+ update. */
+ return false;
+ }
+
+ /* Adjust the spot bindings to refer to the bindings already defined
+ in the enclosing scope. */
+ p->scope = scope->outer;
+ p->bindings_in_scope = p->scope->bindings;
+
+ return true;
+}
+
/* The Objective-C front-end often needs to determine the current scope. */
void *
@@ -783,6 +941,67 @@ push_scope (void)
}
}
+/* This is called when we are leaving SCOPE. For each label defined
+ in SCOPE, add any appropriate decls to its decls_in_scope fields.
+ These are the decls whose initialization will be skipped by a goto
+ later in the function. */
+
+static void
+update_label_decls (struct c_scope *scope)
+{
+ struct c_scope *s;
+
+ s = scope;
+ while (s != NULL)
+ {
+ if (s->has_label_bindings)
+ {
+ struct c_binding *b;
+
+ for (b = s->bindings; b != NULL; b = b->prev)
+ {
+ struct c_label_vars *label_vars;
+ struct c_binding *b1;
+ unsigned int ix;
+ struct c_goto_bindings *g;
+
+ if (TREE_CODE (b->decl) != LABEL_DECL)
+ continue;
+ label_vars = b->u.label;
+
+ b1 = label_vars->label_bindings.bindings_in_scope;
+ if (update_spot_bindings (scope, &label_vars->label_bindings))
+ {
+ /* This label is defined in this scope. */
+ for (; b1 != NULL; b1 = b1->prev)
+ {
+ /* A goto from later in the function to this
+ label will never see the initialization of
+ B1, if any. Save it to issue a warning if
+ needed. */
+ if (decl_jump_unsafe (b1->decl))
+ VEC_safe_push (tree, gc, label_vars->decls_in_scope,
+ b1->decl);
+ }
+ }
+
+ /* Update the bindings of any goto statements associated
+ with this label. */
+ for (ix = 0;
+ VEC_iterate (c_goto_bindings_p, label_vars->gotos, ix, g);
+ ++ix)
+ update_spot_bindings (scope, &g->goto_bindings);
+ }
+ }
+
+ /* Don't search beyond the current function. */
+ if (s == current_function_scope)
+ break;
+
+ s = s->outer;
+ }
+}
+
/* Set the TYPE_CONTEXT of all of TYPE's variants to CONTEXT. */
static void
@@ -808,7 +1027,7 @@ pop_scope (void)
bool functionbody = scope->function_body;
bool keep = functionbody || scope->keep || scope->bindings;
- c_end_vm_scope (scope->depth);
+ update_label_decls (scope);
/* If appropriate, create a BLOCK to record the decls for the life
of this function. */
@@ -843,7 +1062,8 @@ pop_scope (void)
context = current_function_decl;
else if (scope == file_scope)
{
- tree file_decl = build_decl (TRANSLATION_UNIT_DECL, 0, 0);
+ tree file_decl = build_decl (UNKNOWN_LOCATION,
+ TRANSLATION_UNIT_DECL, 0, 0);
TREE_CHAIN (file_decl) = all_translation_units;
all_translation_units = file_decl;
context = file_decl;
@@ -872,6 +1092,10 @@ pop_scope (void)
BLOCK_VARS (block) = p;
gcc_assert (I_LABEL_BINDING (b->id) == b);
I_LABEL_BINDING (b->id) = b->shadowed;
+
+ /* Also pop back to the shadowed label_vars. */
+ release_tree_vector (b->u.label->decls_in_scope);
+ b->u.label = b->u.label->shadowed;
break;
case ENUMERAL_TYPE:
@@ -997,8 +1221,8 @@ pop_scope (void)
{
gcc_assert (I_SYMBOL_BINDING (b->id) == b);
I_SYMBOL_BINDING (b->id) = b->shadowed;
- if (b->shadowed && b->shadowed->type)
- TREE_TYPE (b->shadowed->decl) = b->shadowed->type;
+ if (b->shadowed && b->shadowed->u.type)
+ TREE_TYPE (b->shadowed->decl) = b->shadowed->u.type;
}
break;
@@ -1085,17 +1309,102 @@ pop_file_scope (void)
maybe_apply_pending_pragma_weaks ();
cgraph_finalize_compilation_unit ();
}
+
+/* Adjust the bindings for the start of a statement expression. */
+
+void
+c_bindings_start_stmt_expr (struct c_spot_bindings* switch_bindings)
+{
+ struct c_scope *scope;
+
+ for (scope = current_scope; scope != NULL; scope = scope->outer)
+ {
+ struct c_binding *b;
+
+ if (!scope->has_label_bindings)
+ continue;
+ for (b = scope->bindings; b != NULL; b = b->prev)
+ {
+ struct c_label_vars *label_vars;
+ unsigned int ix;
+ struct c_goto_bindings *g;
+
+ if (TREE_CODE (b->decl) != LABEL_DECL)
+ continue;
+ label_vars = b->u.label;
+ ++label_vars->label_bindings.stmt_exprs;
+ for (ix = 0;
+ VEC_iterate (c_goto_bindings_p, label_vars->gotos, ix, g);
+ ++ix)
+ ++g->goto_bindings.stmt_exprs;
+ }
+ }
+
+ if (switch_bindings != NULL)
+ ++switch_bindings->stmt_exprs;
+}
+
+/* Adjust the bindings for the end of a statement expression. */
+
+void
+c_bindings_end_stmt_expr (struct c_spot_bindings *switch_bindings)
+{
+ struct c_scope *scope;
+
+ for (scope = current_scope; scope != NULL; scope = scope->outer)
+ {
+ struct c_binding *b;
+
+ if (!scope->has_label_bindings)
+ continue;
+
+ for (b = scope->bindings; b != NULL; b = b->prev)
+ {
+ struct c_label_vars *label_vars;
+ unsigned int ix;
+ struct c_goto_bindings *g;
+
+ if (TREE_CODE (b->decl) != LABEL_DECL)
+ continue;
+ label_vars = b->u.label;
+ --label_vars->label_bindings.stmt_exprs;
+ if (label_vars->label_bindings.stmt_exprs < 0)
+ {
+ label_vars->label_bindings.left_stmt_expr = true;
+ label_vars->label_bindings.stmt_exprs = 0;
+ }
+ for (ix = 0;
+ VEC_iterate (c_goto_bindings_p, label_vars->gotos, ix, g);
+ ++ix)
+ {
+ --g->goto_bindings.stmt_exprs;
+ if (g->goto_bindings.stmt_exprs < 0)
+ {
+ g->goto_bindings.left_stmt_expr = true;
+ g->goto_bindings.stmt_exprs = 0;
+ }
+ }
+ }
+ }
+
+ if (switch_bindings != NULL)
+ {
+ --switch_bindings->stmt_exprs;
+ gcc_assert (switch_bindings->stmt_exprs >= 0);
+ }
+}
/* Push a definition or a declaration of struct, union or enum tag "name".
"type" should be the type node.
- We assume that the tag "name" is not already defined.
+ We assume that the tag "name" is not already defined, and has a location
+ of LOC.
Note that the definition may really be just a forward reference.
In that case, the TYPE_SIZE will be zero. */
static void
-pushtag (tree name, tree type, location_t loc)
+pushtag (location_t loc, tree name, tree type)
{
/* Record the identifier as the type's name if it has none. */
if (name && !TYPE_NAME (type))
@@ -1109,11 +1418,33 @@ pushtag (tree name, tree type, location_t loc)
us a convenient place to record the "scope start" address for the
tagged type. */
- TYPE_STUB_DECL (type) = pushdecl (build_decl (TYPE_DECL, NULL_TREE, type));
+ TYPE_STUB_DECL (type) = pushdecl (build_decl (loc,
+ TYPE_DECL, NULL_TREE, type));
/* An approximation for now, so we can tell this is a function-scope tag.
This will be updated in pop_scope. */
TYPE_CONTEXT (type) = DECL_CONTEXT (TYPE_STUB_DECL (type));
+
+ if (warn_cxx_compat && name != NULL_TREE)
+ {
+ struct c_binding *b = I_SYMBOL_BINDING (name);
+
+ if (b != NULL
+ && b->decl != NULL_TREE
+ && TREE_CODE (b->decl) == TYPE_DECL
+ && (B_IN_CURRENT_SCOPE (b)
+ || (current_scope == file_scope && B_IN_EXTERNAL_SCOPE (b)))
+ && (TYPE_MAIN_VARIANT (TREE_TYPE (b->decl))
+ != TYPE_MAIN_VARIANT (type)))
+ {
+ warning_at (loc, OPT_Wc___compat,
+ ("using %qD as both a typedef and a tag is "
+ "invalid in C++"),
+ b->decl);
+ if (b->locus != UNKNOWN_LOCATION)
+ inform (b->locus, "originally defined here");
+ }
+ }
}
/* Subroutine of compare_decls. Allow harmless mismatches in return
@@ -2157,12 +2488,6 @@ pushdecl (tree x)
|| DECL_INITIAL (x) || !DECL_EXTERNAL (x)))
DECL_CONTEXT (x) = current_function_decl;
- /* If this is of variably modified type, prevent jumping into its
- scope. */
- if ((TREE_CODE (x) == VAR_DECL || TREE_CODE (x) == TYPE_DECL)
- && variably_modified_type_p (TREE_TYPE (x), NULL_TREE))
- c_begin_vm_scope (scope->depth);
-
/* Anonymous decls are just inserted in the scope. */
if (!name)
{
@@ -2201,8 +2526,8 @@ pushdecl (tree x)
if (b_ext)
{
b_use = b_ext;
- if (b_use->type)
- TREE_TYPE (b_use->decl) = b_use->type;
+ if (b_use->u.type)
+ TREE_TYPE (b_use->decl) = b_use->u.type;
}
}
if (duplicate_decls (x, b_use->decl))
@@ -2216,13 +2541,13 @@ pushdecl (tree x)
thistype = composite_type (vistype, type);
else
thistype = TREE_TYPE (b_use->decl);
- b_use->type = TREE_TYPE (b_use->decl);
+ b_use->u.type = TREE_TYPE (b_use->decl);
if (TREE_CODE (b_use->decl) == FUNCTION_DECL
&& DECL_BUILT_IN (b_use->decl))
thistype
= build_type_attribute_variant (thistype,
TYPE_ATTRIBUTES
- (b_use->type));
+ (b_use->u.type));
TREE_TYPE (b_use->decl) = thistype;
}
return b_use->decl;
@@ -2273,7 +2598,7 @@ pushdecl (tree x)
their scopes will not have been re-entered. */
if (DECL_P (b->decl) && DECL_FILE_SCOPE_P (b->decl) && !type_saved)
{
- b->type = TREE_TYPE (b->decl);
+ b->u.type = TREE_TYPE (b->decl);
type_saved = true;
}
if (B_IN_FILE_SCOPE (b)
@@ -2299,8 +2624,8 @@ pushdecl (tree x)
After the consistency checks, it will be reset to the
composite of the visible types only. */
if (b && (TREE_PUBLIC (x) || same_translation_unit_p (x, b->decl))
- && b->type)
- TREE_TYPE (b->decl) = b->type;
+ && b->u.type)
+ TREE_TYPE (b->decl) = b->u.type;
/* The point of the same_translation_unit_p check here is,
we want to detect a duplicate decl for a construct like
@@ -2321,11 +2646,11 @@ pushdecl (tree x)
}
else
thistype = type;
- b->type = TREE_TYPE (b->decl);
+ b->u.type = TREE_TYPE (b->decl);
if (TREE_CODE (b->decl) == FUNCTION_DECL && DECL_BUILT_IN (b->decl))
thistype
= build_type_attribute_variant (thistype,
- TYPE_ATTRIBUTES (b->type));
+ TYPE_ATTRIBUTES (b->u.type));
TREE_TYPE (b->decl) = thistype;
bind (name, b->decl, scope, /*invisible=*/false, /*nested=*/true,
locus);
@@ -2436,11 +2761,11 @@ implicit_decl_warning (tree id, tree olddecl)
}
}
-/* Generate an implicit declaration for identifier FUNCTIONID as a
+/* Generate an implicit declaration for identifier FUNCTIONID at LOC as a
function of type int (). */
tree
-implicitly_declare (tree functionid)
+implicitly_declare (location_t loc, tree functionid)
{
struct c_binding *b;
tree decl = 0;
@@ -2475,8 +2800,8 @@ implicitly_declare (tree functionid)
else
{
tree newtype = default_function_type;
- if (b->type)
- TREE_TYPE (decl) = b->type;
+ if (b->u.type)
+ TREE_TYPE (decl) = b->u.type;
/* Implicit declaration of a function already declared
(somehow) in a different scope, or as a built-in.
If this is the first time this has happened, warn;
@@ -2493,8 +2818,8 @@ implicitly_declare (tree functionid)
(TREE_TYPE (decl)));
if (!comptypes (newtype, TREE_TYPE (decl)))
{
- warning (0, "incompatible implicit declaration of built-in"
- " function %qD", decl);
+ warning_at (loc, 0, "incompatible implicit declaration of "
+ "built-in function %qD", decl);
newtype = TREE_TYPE (decl);
}
}
@@ -2502,12 +2827,11 @@ implicitly_declare (tree functionid)
{
if (!comptypes (newtype, TREE_TYPE (decl)))
{
- error ("incompatible implicit declaration of function %qD",
- decl);
+ error_at (loc, "incompatible implicit declaration of function %qD", decl);
locate_old_decl (decl);
}
}
- b->type = TREE_TYPE (decl);
+ b->u.type = TREE_TYPE (decl);
TREE_TYPE (decl) = newtype;
bind (functionid, decl, current_scope,
/*invisible=*/false, /*nested=*/true,
@@ -2517,7 +2841,7 @@ implicitly_declare (tree functionid)
}
/* Not seen before. */
- decl = build_decl (FUNCTION_DECL, functionid, default_function_type);
+ decl = build_decl (loc, FUNCTION_DECL, functionid, default_function_type);
DECL_EXTERNAL (decl) = 1;
TREE_PUBLIC (decl) = 1;
C_DECL_IMPLICIT (decl) = 1;
@@ -2549,7 +2873,7 @@ implicitly_declare (tree functionid)
in an appropriate scope, which will suppress further errors for the
same identifier. The error message should be given location LOC. */
void
-undeclared_variable (tree id, location_t loc)
+undeclared_variable (location_t loc, tree id)
{
static bool already = false;
struct c_scope *scope;
@@ -2579,16 +2903,25 @@ undeclared_variable (tree id, location_t loc)
}
/* Subroutine of lookup_label, declare_label, define_label: construct a
- LABEL_DECL with all the proper frills. */
+ LABEL_DECL with all the proper frills. Also create a struct
+ c_label_vars initialized for the current scope. */
static tree
-make_label (tree name, location_t location)
+make_label (location_t location, tree name, bool defining,
+ struct c_label_vars **p_label_vars)
{
- tree label = build_decl (LABEL_DECL, name, void_type_node);
+ tree label = build_decl (location, LABEL_DECL, name, void_type_node);
+ struct c_label_vars *label_vars;
DECL_CONTEXT (label) = current_function_decl;
DECL_MODE (label) = VOIDmode;
- DECL_SOURCE_LOCATION (label) = location;
+
+ label_vars = GGC_NEW (struct c_label_vars);
+ label_vars->shadowed = NULL;
+ set_spot_bindings (&label_vars->label_bindings, defining);
+ label_vars->decls_in_scope = make_tree_vector ();
+ label_vars->gotos = VEC_alloc (c_goto_bindings_p, gc, 0);
+ *p_label_vars = label_vars;
return label;
}
@@ -2602,6 +2935,7 @@ tree
lookup_label (tree name)
{
tree label;
+ struct c_label_vars *label_vars;
if (current_function_decl == 0)
{
@@ -2619,17 +2953,91 @@ lookup_label (tree name)
/* If the label has only been declared, update its apparent
location to point here, for better diagnostics if it
turns out not to have been defined. */
- if (!TREE_USED (label))
+ if (DECL_INITIAL (label) == NULL_TREE)
DECL_SOURCE_LOCATION (label) = input_location;
return label;
}
/* No label binding for that identifier; make one. */
- label = make_label (name, input_location);
+ label = make_label (input_location, name, false, &label_vars);
/* Ordinary labels go in the current function scope. */
- bind (name, label, current_function_scope,
- /*invisible=*/false, /*nested=*/false, UNKNOWN_LOCATION);
+ bind_label (name, label, current_function_scope, label_vars);
+
+ return label;
+}
+
+/* Issue a warning about DECL for a goto statement at GOTO_LOC going
+ to LABEL. */
+
+static void
+warn_about_goto (location_t goto_loc, tree label, tree decl)
+{
+ if (variably_modified_type_p (TREE_TYPE (decl), NULL_TREE))
+ error_at (goto_loc,
+ "jump into scope of identifier with variably modified type");
+ else
+ warning_at (goto_loc, OPT_Wjump_misses_init,
+ "jump skips variable initialization");
+ inform (DECL_SOURCE_LOCATION (label), "label %qD defined here", label);
+ inform (DECL_SOURCE_LOCATION (decl), "%qD declared here", decl);
+}
+
+/* Look up a label because of a goto statement. This is like
+ lookup_label, but also issues any appropriate warnings. */
+
+tree
+lookup_label_for_goto (location_t loc, tree name)
+{
+ tree label;
+ struct c_label_vars *label_vars;
+ unsigned int ix;
+ tree decl;
+
+ label = lookup_label (name);
+ if (label == NULL_TREE)
+ return NULL_TREE;
+
+ /* If we are jumping to a different function, we can't issue any
+ useful warnings. */
+ if (DECL_CONTEXT (label) != current_function_decl)
+ {
+ gcc_assert (C_DECLARED_LABEL_FLAG (label));
+ return label;
+ }
+
+ label_vars = I_LABEL_BINDING (name)->u.label;
+
+ /* If the label has not yet been defined, then push this goto on a
+ list for possible later warnings. */
+ if (label_vars->label_bindings.scope == NULL)
+ {
+ struct c_goto_bindings *g;
+
+ g = GGC_NEW (struct c_goto_bindings);
+ g->loc = loc;
+ set_spot_bindings (&g->goto_bindings, true);
+ VEC_safe_push (c_goto_bindings_p, gc, label_vars->gotos, g);
+ return label;
+ }
+
+ /* If there are any decls in label_vars->decls_in_scope, then this
+ goto has missed the declaration of the decl. This happens for a
+ case like
+ int i = 1;
+ lab:
+ ...
+ goto lab;
+ Issue a warning or error. */
+ for (ix = 0; VEC_iterate (tree, label_vars->decls_in_scope, ix, decl); ++ix)
+ warn_about_goto (loc, label, decl);
+
+ if (label_vars->label_bindings.left_stmt_expr)
+ {
+ error_at (loc, "jump into statement expression");
+ inform (DECL_SOURCE_LOCATION (label), "label %qD defined here", label);
+ }
+
return label;
}
@@ -2642,6 +3050,7 @@ declare_label (tree name)
{
struct c_binding *b = I_LABEL_BINDING (name);
tree label;
+ struct c_label_vars *label_vars;
/* Check to make sure that the label hasn't already been declared
at this scope */
@@ -2654,15 +3063,74 @@ declare_label (tree name)
return b->decl;
}
- label = make_label (name, input_location);
+ label = make_label (input_location, name, false, &label_vars);
C_DECLARED_LABEL_FLAG (label) = 1;
/* Declared labels go in the current scope. */
- bind (name, label, current_scope,
- /*invisible=*/false, /*nested=*/false, UNKNOWN_LOCATION);
+ bind_label (name, label, current_scope, label_vars);
+
return label;
}
+/* When we define a label, issue any appropriate warnings if there are
+ any gotos earlier in the function which jump to this label. */
+
+static void
+check_earlier_gotos (tree label, struct c_label_vars* label_vars)
+{
+ unsigned int ix;
+ struct c_goto_bindings *g;
+
+ for (ix = 0;
+ VEC_iterate (c_goto_bindings_p, label_vars->gotos, ix, g);
+ ++ix)
+ {
+ struct c_binding *b;
+ struct c_scope *scope;
+
+ /* We have a goto to this label. The goto is going forward. In
+ g->scope, the goto is going to skip any binding which was
+ defined after g->bindings_in_scope. */
+ for (b = g->goto_bindings.scope->bindings;
+ b != g->goto_bindings.bindings_in_scope;
+ b = b->prev)
+ {
+ if (decl_jump_unsafe (b->decl))
+ warn_about_goto (g->loc, label, b->decl);
+ }
+
+ /* We also need to warn about decls defined in any scopes
+ between the scope of the label and the scope of the goto. */
+ for (scope = label_vars->label_bindings.scope;
+ scope != g->goto_bindings.scope;
+ scope = scope->outer)
+ {
+ gcc_assert (scope != NULL);
+ if (scope == label_vars->label_bindings.scope)
+ b = label_vars->label_bindings.bindings_in_scope;
+ else
+ b = scope->bindings;
+ for (; b != NULL; b = b->prev)
+ {
+ if (decl_jump_unsafe (b->decl))
+ warn_about_goto (g->loc, label, b->decl);
+ }
+ }
+
+ if (g->goto_bindings.stmt_exprs > 0)
+ {
+ error_at (g->loc, "jump into statement expression");
+ inform (DECL_SOURCE_LOCATION (label), "label %qD defined here",
+ label);
+ }
+ }
+
+ /* Now that the label is defined, we will issue warnings about
+ subsequent gotos to this label when we see them. */
+ VEC_truncate (c_goto_bindings_p, label_vars->gotos, 0);
+ label_vars->gotos = NULL;
+}
+
/* Define a label, specifying the location in the source file.
Return the LABEL_DECL node for the label, if the definition is valid.
Otherwise return 0. */
@@ -2675,7 +3143,6 @@ define_label (location_t location, tree name)
if there is a containing function with a declared label with
the same name. */
tree label = I_LABEL_DECL (name);
- struct c_label_list *nlist_se, *nlist_vm;
if (label
&& ((DECL_CONTEXT (label) == current_function_decl
@@ -2683,51 +3150,116 @@ define_label (location_t location, tree name)
|| (DECL_CONTEXT (label) != current_function_decl
&& C_DECLARED_LABEL_FLAG (label))))
{
- error ("%Hduplicate label %qD", &location, label);
+ error_at (location, "duplicate label %qD", label);
locate_old_decl (label);
return 0;
}
else if (label && DECL_CONTEXT (label) == current_function_decl)
{
+ struct c_label_vars *label_vars = I_LABEL_BINDING (name)->u.label;
+
/* The label has been used or declared already in this function,
but not defined. Update its location to point to this
definition. */
- if (C_DECL_UNDEFINABLE_STMT_EXPR (label))
- error ("%Jjump into statement expression", label);
- if (C_DECL_UNDEFINABLE_VM (label))
- error ("%Jjump into scope of identifier with variably modified type",
- label);
DECL_SOURCE_LOCATION (label) = location;
+ set_spot_bindings (&label_vars->label_bindings, true);
+
+ /* Issue warnings as required about any goto statements from
+ earlier in the function. */
+ check_earlier_gotos (label, label_vars);
}
else
{
+ struct c_label_vars *label_vars;
+
/* No label binding for that identifier; make one. */
- label = make_label (name, location);
+ label = make_label (location, name, true, &label_vars);
/* Ordinary labels go in the current function scope. */
- bind (name, label, current_function_scope,
- /*invisible=*/false, /*nested=*/false, UNKNOWN_LOCATION);
+ bind_label (name, label, current_function_scope, label_vars);
}
if (!in_system_header && lookup_name (name))
- warning (OPT_Wtraditional, "%Htraditional C lacks a separate namespace "
- "for labels, identifier %qE conflicts", &location, name);
-
- nlist_se = XOBNEW (&parser_obstack, struct c_label_list);
- nlist_se->next = label_context_stack_se->labels_def;
- nlist_se->label = label;
- label_context_stack_se->labels_def = nlist_se;
-
- nlist_vm = XOBNEW (&parser_obstack, struct c_label_list);
- nlist_vm->next = label_context_stack_vm->labels_def;
- nlist_vm->label = label;
- label_context_stack_vm->labels_def = nlist_vm;
+ warning_at (location, OPT_Wtraditional,
+ "traditional C lacks a separate namespace "
+ "for labels, identifier %qE conflicts", name);
/* Mark label as having been defined. */
DECL_INITIAL (label) = error_mark_node;
return label;
}
+/* Get the bindings for a new switch statement. This is used to issue
+ warnings as appropriate for jumps from the switch to case or
+ default labels. */
+
+struct c_spot_bindings *
+c_get_switch_bindings (void)
+{
+ struct c_spot_bindings *switch_bindings;
+
+ switch_bindings = XNEW (struct c_spot_bindings);
+ set_spot_bindings (switch_bindings, true);
+ return switch_bindings;
+}
+
+void
+c_release_switch_bindings (struct c_spot_bindings *bindings)
+{
+ gcc_assert (bindings->stmt_exprs == 0 && !bindings->left_stmt_expr);
+ XDELETE (bindings);
+}
+
+/* This is called at the point of a case or default label to issue
+ warnings about decls as needed. It returns true if it found an
+ error, not just a warning. */
+
+bool
+c_check_switch_jump_warnings (struct c_spot_bindings *switch_bindings,
+ location_t switch_loc, location_t case_loc)
+{
+ bool saw_error;
+ struct c_scope *scope;
+
+ saw_error = false;
+ for (scope = current_scope;
+ scope != switch_bindings->scope;
+ scope = scope->outer)
+ {
+ struct c_binding *b;
+
+ gcc_assert (scope != NULL);
+ for (b = scope->bindings; b != NULL; b = b->prev)
+ {
+ if (decl_jump_unsafe (b->decl))
+ {
+ if (variably_modified_type_p (TREE_TYPE (b->decl), NULL_TREE))
+ {
+ saw_error = true;
+ error_at (case_loc,
+ ("switch jumps into scope of identifier with "
+ "variably modified type"));
+ }
+ else
+ warning_at (case_loc, OPT_Wjump_misses_init,
+ "switch jumps over variable initialization");
+ inform (switch_loc, "switch starts here");
+ inform (DECL_SOURCE_LOCATION (b->decl), "%qD declared here",
+ b->decl);
+ }
+ }
+ }
+
+ if (switch_bindings->stmt_exprs > 0)
+ {
+ saw_error = true;
+ error_at (case_loc, "switch jumps into statement expression");
+ inform (switch_loc, "switch starts here");
+ }
+
+ return saw_error;
+}
+
/* Given NAME, an IDENTIFIER_NODE,
return the structure (or union or enum) definition for that name.
If THISLEVEL_ONLY is nonzero, searches only the current_scope.
@@ -2861,7 +3393,7 @@ c_init_decl_processing (void)
truthvalue_false_node = integer_zero_node;
/* Even in C99, which has a real boolean type. */
- pushdecl (build_decl (TYPE_DECL, get_identifier ("_Bool"),
+ pushdecl (build_decl (UNKNOWN_LOCATION, TYPE_DECL, get_identifier ("_Bool"),
boolean_type_node));
input_location = save_loc;
@@ -2872,15 +3404,16 @@ c_init_decl_processing (void)
start_fname_decls ();
}
-/* Create the VAR_DECL for __FUNCTION__ etc. ID is the name to give the
- decl, NAME is the initialization string and TYPE_DEP indicates whether
- NAME depended on the type of the function. As we don't yet implement
- delayed emission of static data, we mark the decl as emitted
- so it is not placed in the output. Anything using it must therefore pull
- out the STRING_CST initializer directly. FIXME. */
+/* Create the VAR_DECL at LOC for __FUNCTION__ etc. ID is the name to
+ give the decl, NAME is the initialization string and TYPE_DEP
+ indicates whether NAME depended on the type of the function. As we
+ don't yet implement delayed emission of static data, we mark the
+ decl as emitted so it is not placed in the output. Anything using
+ it must therefore pull out the STRING_CST initializer directly.
+ FIXME. */
static tree
-c_make_fname_decl (tree id, int type_dep)
+c_make_fname_decl (location_t loc, tree id, int type_dep)
{
const char *name = fname_as_string (type_dep);
tree decl, type, init;
@@ -2890,7 +3423,7 @@ c_make_fname_decl (tree id, int type_dep)
build_index_type (size_int (length)));
type = c_build_qualified_type (type, TYPE_QUAL_CONST);
- decl = build_decl (VAR_DECL, id, type);
+ decl = build_decl (loc, VAR_DECL, id, type);
TREE_STATIC (decl) = 1;
TREE_READONLY (decl) = 1;
@@ -2919,7 +3452,7 @@ c_make_fname_decl (tree id, int type_dep)
/*invisible=*/false, /*nested=*/false, UNKNOWN_LOCATION);
}
- finish_decl (decl, init, NULL_TREE, NULL_TREE);
+ finish_decl (decl, loc, init, NULL_TREE, NULL_TREE);
return decl;
}
@@ -3057,7 +3590,7 @@ shadow_tag_warned (const struct c_declspecs *declspecs, int warned)
if (t == 0)
{
t = make_node (code);
- pushtag (name, t, input_location);
+ pushtag (input_location, name, t);
}
}
}
@@ -3153,21 +3686,24 @@ quals_from_declspecs (const struct c_declspecs *specs)
return quals;
}
-/* Construct an array declarator. EXPR is the expression inside [],
- or NULL_TREE. QUALS are the type qualifiers inside the [] (to be
- applied to the pointer to which a parameter array is converted).
- STATIC_P is true if "static" is inside the [], false otherwise.
- VLA_UNSPEC_P is true if the array is [*], a VLA of unspecified
- length which is nevertheless a complete type, false otherwise. The
- field for the contained declarator is left to be filled in by
- set_array_declarator_inner. */
+/* Construct an array declarator. LOC is the location of the
+ beginning of the array (usually the opening brace). EXPR is the
+ expression inside [], or NULL_TREE. QUALS are the type qualifiers
+ inside the [] (to be applied to the pointer to which a parameter
+ array is converted). STATIC_P is true if "static" is inside the
+ [], false otherwise. VLA_UNSPEC_P is true if the array is [*], a
+ VLA of unspecified length which is nevertheless a complete type,
+ false otherwise. The field for the contained declarator is left to
+ be filled in by set_array_declarator_inner. */
struct c_declarator *
-build_array_declarator (tree expr, struct c_declspecs *quals, bool static_p,
+build_array_declarator (location_t loc,
+ tree expr, struct c_declspecs *quals, bool static_p,
bool vla_unspec_p)
{
struct c_declarator *declarator = XOBNEW (&parser_obstack,
struct c_declarator);
+ declarator->id_loc = loc;
declarator->kind = cdk_array;
declarator->declarator = 0;
declarator->u.array.dimen = expr;
@@ -3186,11 +3722,11 @@ build_array_declarator (tree expr, struct c_declspecs *quals, bool static_p,
if (!flag_isoc99)
{
if (static_p || quals != NULL)
- pedwarn (input_location, OPT_pedantic,
+ pedwarn (loc, OPT_pedantic,
"ISO C90 does not support %<static%> or type "
"qualifiers in parameter array declarators");
if (vla_unspec_p)
- pedwarn (input_location, OPT_pedantic,
+ pedwarn (loc, OPT_pedantic,
"ISO C90 does not support %<[*]%> array declarators");
}
if (vla_unspec_p)
@@ -3198,7 +3734,8 @@ build_array_declarator (tree expr, struct c_declspecs *quals, bool static_p,
if (!current_scope->parm_flag)
{
/* C99 6.7.5.2p4 */
- error ("%<[*]%> not allowed in other than function prototype scope");
+ error_at (loc, "%<[*]%> not allowed in other than "
+ "function prototype scope");
declarator->u.array.vla_unspec_p = false;
return NULL;
}
@@ -3493,13 +4030,16 @@ c_maybe_initialize_eh (void)
install its initial value.
If ORIGTYPE is not NULL_TREE, it is the original type of INIT.
If the length of an array type is not known before,
- it must be determined now, from the initial value, or it is an error. */
+ it must be determined now, from the initial value, or it is an error.
+
+ INIT_LOC is the location of the initial value. */
void
-finish_decl (tree decl, tree init, tree origtype, tree asmspec_tree)
+finish_decl (tree decl, location_t init_loc, tree init,
+ tree origtype, tree asmspec_tree)
{
tree type;
- int was_incomplete = (DECL_SIZE (decl) == 0);
+ bool was_incomplete = (DECL_SIZE (decl) == 0);
const char *asmspec = 0;
/* If a name was specified, get the string. */
@@ -3518,7 +4058,7 @@ finish_decl (tree decl, tree init, tree origtype, tree asmspec_tree)
init = 0;
if (init)
- store_init_value (decl, init, origtype);
+ store_init_value (init_loc, decl, init, origtype);
if (c_dialect_objc () && (TREE_CODE (decl) == VAR_DECL
|| TREE_CODE (decl) == FUNCTION_DECL
@@ -3578,10 +4118,10 @@ finish_decl (tree decl, tree init, tree origtype, tree asmspec_tree)
b_ext = b_ext->shadowed;
if (b_ext)
{
- if (b_ext->type)
- b_ext->type = composite_type (b_ext->type, type);
+ if (b_ext->u.type)
+ b_ext->u.type = composite_type (b_ext->u.type, type);
else
- b_ext->type = type;
+ b_ext->u.type = type;
}
}
break;
@@ -3726,7 +4266,8 @@ finish_decl (tree decl, tree init, tree origtype, tree asmspec_tree)
add_stmt (bind);
BIND_EXPR_BODY (bind) = push_stmt_list ();
}
- add_stmt (build_stmt (DECL_EXPR, decl));
+ add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl),
+ DECL_EXPR, decl));
}
}
@@ -3751,7 +4292,7 @@ finish_decl (tree decl, tree init, tree origtype, tree asmspec_tree)
{
if (!DECL_FILE_SCOPE_P (decl)
&& variably_modified_type_p (TREE_TYPE (decl), NULL_TREE))
- add_stmt (build_stmt (DECL_EXPR, decl));
+ add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl), DECL_EXPR, decl));
rest_of_decl_compilation (decl, DECL_FILE_SCOPE_P (decl), 0);
}
@@ -3777,7 +4318,8 @@ finish_decl (tree decl, tree init, tree origtype, tree asmspec_tree)
cleanup = build_unary_op (input_location, ADDR_EXPR, decl, 0);
vec = VEC_alloc (tree, gc, 1);
VEC_quick_push (tree, vec, cleanup);
- cleanup = build_function_call_vec (cleanup_decl, vec, NULL);
+ cleanup = build_function_call_vec (DECL_SOURCE_LOCATION (decl),
+ cleanup_decl, vec, NULL);
VEC_free (tree, gc, vec);
/* Don't warn about decl unused; the cleanup uses it. */
@@ -3821,7 +4363,7 @@ push_parm_decl (const struct c_parm *parm)
decl = pushdecl (decl);
- finish_decl (decl, NULL_TREE, NULL_TREE, NULL_TREE);
+ finish_decl (decl, input_location, NULL_TREE, NULL_TREE, NULL_TREE);
}
/* Mark all the parameter declarations to date as forward decls.
@@ -3846,12 +4388,12 @@ mark_forward_parm_decls (void)
/* Build a COMPOUND_LITERAL_EXPR. TYPE is the type given in the compound
literal, which may be an incomplete array type completed by the
- initializer; INIT is a CONSTRUCTOR that initializes the compound
+ initializer; INIT is a CONSTRUCTOR at LOC that initializes the compound
literal. NON_CONST is true if the initializers contain something
that cannot occur in a constant expression. */
tree
-build_compound_literal (tree type, tree init, bool non_const)
+build_compound_literal (location_t loc, tree type, tree init, bool non_const)
{
/* We do not use start_decl here because we have a type, not a declarator;
and do not use finish_decl because the decl should be stored inside
@@ -3863,7 +4405,7 @@ build_compound_literal (tree type, tree init, bool non_const)
if (type == error_mark_node)
return error_mark_node;
- decl = build_decl (VAR_DECL, NULL_TREE, type);
+ decl = build_decl (loc, VAR_DECL, NULL_TREE, type);
DECL_EXTERNAL (decl) = 0;
TREE_PUBLIC (decl) = 0;
TREE_STATIC (decl) = (current_scope == file_scope);
@@ -3871,7 +4413,7 @@ build_compound_literal (tree type, tree init, bool non_const)
TREE_USED (decl) = 1;
TREE_TYPE (decl) = type;
TREE_READONLY (decl) = TYPE_READONLY (type);
- store_init_value (decl, init, NULL_TREE);
+ store_init_value (loc, decl, init, NULL_TREE);
if (TREE_CODE (type) == ARRAY_TYPE && !COMPLETE_TYPE_P (type))
{
@@ -3886,7 +4428,7 @@ build_compound_literal (tree type, tree init, bool non_const)
if (type == error_mark_node || !COMPLETE_TYPE_P (type))
return error_mark_node;
- stmt = build_stmt (DECL_EXPR, decl);
+ stmt = build_stmt (DECL_SOURCE_LOCATION (decl), DECL_EXPR, decl);
complit = build1 (COMPOUND_LITERAL_EXPR, type, stmt);
TREE_SIDE_EFFECTS (complit) = 1;
@@ -3917,7 +4459,7 @@ build_compound_literal (tree type, tree init, bool non_const)
is valid for C++. */
void
-check_compound_literal_type (struct c_type_name *type_name, location_t loc)
+check_compound_literal_type (location_t loc, struct c_type_name *type_name)
{
if (warn_cxx_compat && type_name->specs->tag_defined_p)
warning_at (loc, OPT_Wc___compat,
@@ -4171,7 +4713,7 @@ grokdeclarator (const struct c_declarator *declarator,
tree name = NULL_TREE;
bool funcdef_flag = false;
bool funcdef_syntax = false;
- int size_varies = 0;
+ bool size_varies = false;
tree decl_attr = declspecs->decl_attr;
int array_ptr_quals = TYPE_UNQUALIFIED;
tree array_ptr_attrs = NULL_TREE;
@@ -4181,6 +4723,8 @@ grokdeclarator (const struct c_declarator *declarator,
bool bitfield = width != NULL;
tree element_type;
struct c_arg_info *arg_info = 0;
+ location_t loc = UNKNOWN_LOCATION;
+ const char *errmsg;
tree expr_dummy;
bool expr_const_operands_dummy;
@@ -4203,8 +4747,11 @@ grokdeclarator (const struct c_declarator *declarator,
while (decl)
switch (decl->kind)
{
- case cdk_function:
case cdk_array:
+ loc = decl->id_loc;
+ /* FALL THRU. */
+
+ case cdk_function:
case cdk_pointer:
funcdef_syntax = (decl->kind == cdk_function);
decl = decl->declarator;
@@ -4215,6 +4762,7 @@ grokdeclarator (const struct c_declarator *declarator,
break;
case cdk_id:
+ loc = decl->id_loc;
if (decl->u.id)
name = decl->u.id;
decl = 0;
@@ -4253,13 +4801,13 @@ grokdeclarator (const struct c_declarator *declarator,
&& variably_modified_type_p (type, NULL_TREE))
{
if (name)
- error ("variably modified %qE at file scope", name);
+ error_at (loc, "variably modified %qE at file scope", name);
else
- error ("variably modified field at file scope");
+ error_at (loc, "variably modified field at file scope");
type = integer_type_node;
}
- size_varies = C_TYPE_VARIABLE_SIZE (type);
+ size_varies = C_TYPE_VARIABLE_SIZE (type) != 0;
/* Diagnose defaulting to "int". */
@@ -4274,7 +4822,7 @@ grokdeclarator (const struct c_declarator *declarator,
else
{
if (name)
- pedwarn_c99 (input_location, flag_isoc99 ? 0 : OPT_Wimplicit_int,
+ pedwarn_c99 (loc, flag_isoc99 ? 0 : OPT_Wimplicit_int,
"type defaults to %<int%> in declaration of %qE",
name);
else
@@ -4308,11 +4856,11 @@ grokdeclarator (const struct c_declarator *declarator,
if (pedantic && !flag_isoc99)
{
if (constp > 1)
- pedwarn (input_location, OPT_pedantic, "duplicate %<const%>");
+ pedwarn (loc, OPT_pedantic, "duplicate %<const%>");
if (restrictp > 1)
- pedwarn (input_location, OPT_pedantic, "duplicate %<restrict%>");
+ pedwarn (loc, OPT_pedantic, "duplicate %<restrict%>");
if (volatilep > 1)
- pedwarn (input_location, OPT_pedantic, "duplicate %<volatile%>");
+ pedwarn (loc, OPT_pedantic, "duplicate %<volatile%>");
}
if (!flag_gen_aux_info && (TYPE_QUALS (element_type)))
type = TYPE_MAIN_VARIANT (type);
@@ -4330,15 +4878,15 @@ grokdeclarator (const struct c_declarator *declarator,
|| storage_class == csc_typedef))
{
if (storage_class == csc_auto)
- pedwarn (input_location,
+ pedwarn (loc,
(current_scope == file_scope) ? 0 : OPT_pedantic,
"function definition declared %<auto%>");
if (storage_class == csc_register)
- error ("function definition declared %<register%>");
+ error_at (loc, "function definition declared %<register%>");
if (storage_class == csc_typedef)
- error ("function definition declared %<typedef%>");
+ error_at (loc, "function definition declared %<typedef%>");
if (threadp)
- error ("function definition declared %<__thread%>");
+ error_at (loc, "function definition declared %<__thread%>");
threadp = false;
if (storage_class == csc_auto
|| storage_class == csc_register
@@ -4355,19 +4903,20 @@ grokdeclarator (const struct c_declarator *declarator,
{
case FIELD:
if (name)
- error ("storage class specified for structure field %qE",
- name);
+ error_at (loc, "storage class specified for structure "
+ "field %qE", name);
else
- error ("storage class specified for structure field");
+ error_at (loc, "storage class specified for structure field");
break;
case PARM:
if (name)
- error ("storage class specified for parameter %qE", name);
+ error_at (loc, "storage class specified for parameter %qE",
+ name);
else
- error ("storage class specified for unnamed parameter");
+ error_at (loc, "storage class specified for unnamed parameter");
break;
default:
- error ("storage class specified for typename");
+ error_at (loc, "storage class specified for typename");
break;
}
storage_class = csc_none;
@@ -4384,15 +4933,17 @@ grokdeclarator (const struct c_declarator *declarator,
/* It is fine to have 'extern const' when compiling at C
and C++ intersection. */
if (!(warn_cxx_compat && constp))
- warning (0, "%qE initialized and declared %<extern%>", name);
+ warning_at (loc, 0, "%qE initialized and declared %<extern%>",
+ name);
}
else
- error ("%qE has both %<extern%> and initializer", name);
+ error_at (loc, "%qE has both %<extern%> and initializer", name);
}
else if (current_scope == file_scope)
{
if (storage_class == csc_auto)
- error ("file-scope declaration of %qE specifies %<auto%>", name);
+ error_at (loc, "file-scope declaration of %qE specifies %<auto%>",
+ name);
if (pedantic && storage_class == csc_register)
pedwarn (input_location, OPT_pedantic,
"file-scope declaration of %qE specifies %<register%>", name);
@@ -4400,12 +4951,12 @@ grokdeclarator (const struct c_declarator *declarator,
else
{
if (storage_class == csc_extern && funcdef_flag)
- error ("nested function %qE declared %<extern%>", name);
+ error_at (loc, "nested function %qE declared %<extern%>", name);
else if (threadp && storage_class == csc_none)
{
- error ("function-scope %qE implicitly auto and declared "
- "%<__thread%>",
- name);
+ error_at (loc, "function-scope %qE implicitly auto and declared "
+ "%<__thread%>",
+ name);
threadp = false;
}
}
@@ -4450,7 +5001,7 @@ grokdeclarator (const struct c_declarator *declarator,
/* Only the innermost declarator (making a parameter be of
array type which is converted to pointer type)
may have static or type qualifiers. */
- error ("static or type qualifiers in non-parameter array declarator");
+ error_at (loc, "static or type qualifiers in non-parameter array declarator");
array_ptr_quals = TYPE_UNQUALIFIED;
array_ptr_attrs = NULL_TREE;
array_parm_static = 0;
@@ -4498,23 +5049,25 @@ grokdeclarator (const struct c_declarator *declarator,
if (VOID_TYPE_P (type))
{
if (name)
- error ("declaration of %qE as array of voids", name);
+ error_at (loc, "declaration of %qE as array of voids", name);
else
- error ("declaration of type name as array of voids");
+ error_at (loc, "declaration of type name as array of voids");
type = error_mark_node;
}
if (TREE_CODE (type) == FUNCTION_TYPE)
{
if (name)
- error ("declaration of %qE as array of functions", name);
+ error_at (loc, "declaration of %qE as array of functions",
+ name);
else
- error ("declaration of type name as array of functions");
+ error_at (loc, "declaration of type name as array of "
+ "functions");
type = error_mark_node;
}
if (pedantic && !in_system_header && flexible_array_type_p (type))
- pedwarn (input_location, OPT_pedantic,
+ pedwarn (loc, OPT_pedantic,
"invalid use of structure with flexible array member");
if (size == error_mark_node)
@@ -4541,9 +5094,11 @@ grokdeclarator (const struct c_declarator *declarator,
if (!INTEGRAL_TYPE_P (TREE_TYPE (size)))
{
if (name)
- error ("size of array %qE has non-integer type", name);
+ error_at (loc, "size of array %qE has non-integer type",
+ name);
else
- error ("size of unnamed array has non-integer type");
+ error_at (loc,
+ "size of unnamed array has non-integer type");
size = integer_one_node;
}
@@ -4552,10 +5107,10 @@ grokdeclarator (const struct c_declarator *declarator,
if (pedantic && size_maybe_const && integer_zerop (size))
{
if (name)
- pedwarn (input_location, OPT_pedantic,
+ pedwarn (loc, OPT_pedantic,
"ISO C forbids zero-size array %qE", name);
else
- pedwarn (input_location, OPT_pedantic,
+ pedwarn (loc, OPT_pedantic,
"ISO C forbids zero-size array");
}
@@ -4565,9 +5120,9 @@ grokdeclarator (const struct c_declarator *declarator,
if (tree_int_cst_sgn (size) < 0)
{
if (name)
- error ("size of array %qE is negative", name);
+ error_at (loc, "size of array %qE is negative", name);
else
- error ("size of unnamed array is negative");
+ error_at (loc, "size of unnamed array is negative");
size = integer_one_node;
}
/* Handle a size folded to an integer constant but
@@ -4585,14 +5140,14 @@ grokdeclarator (const struct c_declarator *declarator,
"variably modified %qE at file scope",
name);
else
- this_size_varies = size_varies = 1;
+ this_size_varies = size_varies = true;
warn_variable_length_array (name, size);
}
}
else if ((decl_context == NORMAL || decl_context == FIELD)
&& current_scope == file_scope)
{
- error ("variably modified %qE at file scope", name);
+ error_at (loc, "variably modified %qE at file scope", name);
size = integer_one_node;
}
else
@@ -4600,7 +5155,7 @@ grokdeclarator (const struct c_declarator *declarator,
/* Make sure the array size remains visibly
nonconstant even if it is (eg) a const variable
with known value. */
- this_size_varies = size_varies = 1;
+ this_size_varies = size_varies = true;
warn_variable_length_array (name, size);
}
@@ -4643,9 +5198,10 @@ grokdeclarator (const struct c_declarator *declarator,
&& TREE_OVERFLOW (itype))
{
if (name)
- error ("size of array %qE is too large", name);
+ error_at (loc, "size of array %qE is too large",
+ name);
else
- error ("size of unnamed array is too large");
+ error_at (loc, "size of unnamed array is too large");
type = error_mark_node;
continue;
}
@@ -4671,7 +5227,7 @@ grokdeclarator (const struct c_declarator *declarator,
the field variably modified, not through being
something other than a declaration with function
prototype scope. */
- size_varies = 1;
+ size_varies = true;
else
{
const struct c_declarator *t = declarator;
@@ -4681,7 +5237,7 @@ grokdeclarator (const struct c_declarator *declarator,
}
if (flexible_array_member
&& pedantic && !flag_isoc99 && !in_system_header)
- pedwarn (input_location, OPT_pedantic,
+ pedwarn (loc, OPT_pedantic,
"ISO C90 does not support flexible array members");
/* ISO C99 Flexible array members are effectively
@@ -4695,7 +5251,7 @@ grokdeclarator (const struct c_declarator *declarator,
if (array_parm_vla_unspec_p)
{
itype = build_range_type (sizetype, size_zero_node, NULL_TREE);
- size_varies = 1;
+ size_varies = true;
}
}
else if (decl_context == TYPENAME)
@@ -4709,14 +5265,14 @@ grokdeclarator (const struct c_declarator *declarator,
otherwise be modified below. */
itype = build_range_type (sizetype, size_zero_node,
NULL_TREE);
- size_varies = 1;
+ size_varies = true;
}
}
/* Complain about arrays of incomplete types. */
if (!COMPLETE_TYPE_P (type))
{
- error ("array type has incomplete element type");
+ error_at (loc, "array type has incomplete element type");
type = error_mark_node;
}
else
@@ -4766,7 +5322,7 @@ grokdeclarator (const struct c_declarator *declarator,
|| array_ptr_attrs != NULL_TREE
|| array_parm_static))
{
- error ("static or type qualifiers in non-parameter array declarator");
+ error_at (loc, "static or type qualifiers in non-parameter array declarator");
array_ptr_quals = TYPE_UNQUALIFIED;
array_ptr_attrs = NULL_TREE;
array_parm_static = 0;
@@ -4793,25 +5349,33 @@ grokdeclarator (const struct c_declarator *declarator,
if (type == error_mark_node)
continue;
- size_varies = 0;
+ size_varies = false;
/* Warn about some types functions can't return. */
if (TREE_CODE (type) == FUNCTION_TYPE)
{
if (name)
- error ("%qE declared as function returning a function",
- name);
+ error_at (loc, "%qE declared as function returning a "
+ "function", name);
else
- error ("type name declared as function "
- "returning a function");
+ error_at (loc, "type name declared as function "
+ "returning a function");
type = integer_type_node;
}
if (TREE_CODE (type) == ARRAY_TYPE)
{
if (name)
- error ("%qE declared as function returning an array", name);
+ error_at (loc, "%qE declared as function returning an array",
+ name);
else
- error ("type name declared as function returning an array");
+ error_at (loc, "type name declared as function returning "
+ "an array");
+ type = integer_type_node;
+ }
+ errmsg = targetm.invalid_return_type (type);
+ if (errmsg)
+ {
+ error (errmsg);
type = integer_type_node;
}
@@ -4833,10 +5397,10 @@ grokdeclarator (const struct c_declarator *declarator,
function definitions in ISO C; GCC used to used
them for noreturn functions. */
if (VOID_TYPE_P (type) && really_funcdef)
- pedwarn (input_location, 0,
+ pedwarn (loc, 0,
"function definition has qualified void return type");
else
- warning (OPT_Wignored_qualifiers,
+ warning_at (loc, OPT_Wignored_qualifiers,
"type qualifiers ignored on function return type");
type = c_build_qualified_type (type, type_quals);
@@ -4866,11 +5430,11 @@ grokdeclarator (const struct c_declarator *declarator,
if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
&& type_quals)
- pedwarn (input_location, OPT_pedantic,
+ pedwarn (loc, OPT_pedantic,
"ISO C forbids qualified function types");
if (type_quals)
type = c_build_qualified_type (type, type_quals);
- size_varies = 0;
+ size_varies = false;
/* When the pointed-to type involves components of variable size,
care must be taken to ensure that the size evaluation code is
@@ -4899,10 +5463,10 @@ grokdeclarator (const struct c_declarator *declarator,
&& (decl_context == NORMAL || decl_context == FIELD)
&& variably_modified_type_p (type, NULL_TREE))
{
- tree decl = build_decl (TYPE_DECL, NULL_TREE, type);
+ tree decl = build_decl (loc, TYPE_DECL, NULL_TREE, type);
DECL_ARTIFICIAL (decl) = 1;
pushdecl (decl);
- finish_decl (decl, NULL_TREE, NULL_TREE, NULL_TREE);
+ finish_decl (decl, loc, NULL_TREE, NULL_TREE, NULL_TREE);
TYPE_NAME (type) = decl;
}
@@ -4936,9 +5500,9 @@ grokdeclarator (const struct c_declarator *declarator,
&& TREE_OVERFLOW (TYPE_SIZE_UNIT (type)))
{
if (name)
- error ("size of array %qE is too large", name);
+ error_at (loc, "size of array %qE is too large", name);
else
- error ("size of unnamed array is too large");
+ error_at (loc, "size of unnamed array is too large");
/* If we proceed with the array type as it is, we'll eventually
crash in tree_low_cst(). */
type = error_mark_node;
@@ -4951,16 +5515,36 @@ grokdeclarator (const struct c_declarator *declarator,
tree decl;
if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
&& type_quals)
- pedwarn (input_location, OPT_pedantic,
+ pedwarn (loc, OPT_pedantic,
"ISO C forbids qualified function types");
if (type_quals)
type = c_build_qualified_type (type, type_quals);
- decl = build_decl (TYPE_DECL, declarator->u.id, type);
- DECL_SOURCE_LOCATION (decl) = declarator->id_loc;
+ decl = build_decl (declarator->id_loc,
+ TYPE_DECL, declarator->u.id, type);
if (declspecs->explicit_signed_p)
C_TYPEDEF_EXPLICITLY_SIGNED (decl) = 1;
if (declspecs->inline_p)
- pedwarn (input_location, 0,"typedef %q+D declared %<inline%>", decl);
+ pedwarn (loc, 0,"typedef %q+D declared %<inline%>", decl);
+
+ if (warn_cxx_compat && declarator->u.id != NULL_TREE)
+ {
+ struct c_binding *b = I_TAG_BINDING (declarator->u.id);
+
+ if (b != NULL
+ && b->decl != NULL_TREE
+ && (B_IN_CURRENT_SCOPE (b)
+ || (current_scope == file_scope && B_IN_EXTERNAL_SCOPE (b)))
+ && TYPE_MAIN_VARIANT (b->decl) != TYPE_MAIN_VARIANT (type))
+ {
+ warning_at (declarator->id_loc, OPT_Wc___compat,
+ ("using %qD as both a typedef and a tag is "
+ "invalid in C++"),
+ decl);
+ if (b->locus != UNKNOWN_LOCATION)
+ inform (b->locus, "originally defined here");
+ }
+ }
+
return decl;
}
@@ -4975,7 +5559,7 @@ grokdeclarator (const struct c_declarator *declarator,
&& !declspecs->inline_p);
if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
&& type_quals)
- pedwarn (input_location, OPT_pedantic,
+ pedwarn (loc, OPT_pedantic,
"ISO C forbids const or volatile function types");
if (type_quals)
type = c_build_qualified_type (type, type_quals);
@@ -4986,8 +5570,8 @@ grokdeclarator (const struct c_declarator *declarator,
&& variably_modified_type_p (type, NULL_TREE))
{
/* C99 6.7.2.1p8 */
- pedwarn (input_location, OPT_pedantic,
- "a member of a structure or union cannot have a variably modified type");
+ pedwarn (loc, OPT_pedantic, "a member of a structure or union cannot "
+ "have a variably modified type");
}
/* Aside from typedefs and type names (handle above),
@@ -5003,7 +5587,7 @@ grokdeclarator (const struct c_declarator *declarator,
&& !(storage_class == csc_static
|| storage_class == csc_register)))))
{
- error ("variable or field %qE declared void", name);
+ error_at (loc, "variable or field %qE declared void", name);
type = integer_type_node;
}
@@ -5033,15 +5617,15 @@ grokdeclarator (const struct c_declarator *declarator,
/* We don't yet implement attributes in this context. */
if (array_ptr_attrs != NULL_TREE)
- warning (OPT_Wattributes,
- "attributes in parameter array declarator ignored");
+ warning_at (loc, OPT_Wattributes,
+ "attributes in parameter array declarator ignored");
- size_varies = 0;
+ size_varies = false;
}
else if (TREE_CODE (type) == FUNCTION_TYPE)
{
if (type_quals)
- pedwarn (input_location, OPT_pedantic,
+ pedwarn (loc, OPT_pedantic,
"ISO C forbids qualified function types");
if (type_quals)
type = c_build_qualified_type (type, type_quals);
@@ -5051,8 +5635,8 @@ grokdeclarator (const struct c_declarator *declarator,
else if (type_quals)
type = c_build_qualified_type (type, type_quals);
- decl = build_decl (PARM_DECL, declarator->u.id, type);
- DECL_SOURCE_LOCATION (decl) = declarator->id_loc;
+ decl = build_decl (declarator->id_loc,
+ PARM_DECL, declarator->u.id, type);
if (size_varies)
C_DECL_VARIABLE_SIZE (decl) = 1;
@@ -5068,7 +5652,7 @@ grokdeclarator (const struct c_declarator *declarator,
DECL_ARG_TYPE (decl) = promoted_type;
if (declspecs->inline_p)
- pedwarn (input_location, 0, "parameter %q+D declared %<inline%>", decl);
+ pedwarn (loc, 0, "parameter %q+D declared %<inline%>", decl);
}
else if (decl_context == FIELD)
{
@@ -5081,21 +5665,21 @@ grokdeclarator (const struct c_declarator *declarator,
if (TREE_CODE (type) == FUNCTION_TYPE)
{
- error ("field %qE declared as a function", name);
+ error_at (loc, "field %qE declared as a function", name);
type = build_pointer_type (type);
}
else if (TREE_CODE (type) != ERROR_MARK
&& !COMPLETE_OR_UNBOUND_ARRAY_TYPE_P (type))
{
if (name)
- error ("field %qE has incomplete type", name);
+ error_at (loc, "field %qE has incomplete type", name);
else
- error ("unnamed field has incomplete type");
+ error_at (loc, "unnamed field has incomplete type");
type = error_mark_node;
}
type = c_build_qualified_type (type, type_quals);
- decl = build_decl (FIELD_DECL, declarator->u.id, type);
- DECL_SOURCE_LOCATION (decl) = declarator->id_loc;
+ decl = build_decl (declarator->id_loc,
+ FIELD_DECL, declarator->u.id, type);
DECL_NONADDRESSABLE_P (decl) = bitfield;
if (bitfield && !declarator->u.id)
TREE_NO_WARNING (decl) = 1;
@@ -5107,7 +5691,7 @@ grokdeclarator (const struct c_declarator *declarator,
{
if (storage_class == csc_register || threadp)
{
- error ("invalid storage class for function %qE", name);
+ error_at (loc, "invalid storage class for function %qE", name);
}
else if (current_scope != file_scope)
{
@@ -5117,11 +5701,11 @@ grokdeclarator (const struct c_declarator *declarator,
GCC allows 'auto', perhaps with 'inline', to support
nested functions. */
if (storage_class == csc_auto)
- pedwarn (input_location, OPT_pedantic,
+ pedwarn (loc, OPT_pedantic,
"invalid storage class for function %qE", name);
else if (storage_class == csc_static)
{
- error ("invalid storage class for function %qE", name);
+ error_at (loc, "invalid storage class for function %qE", name);
if (funcdef_flag)
storage_class = declspecs->storage_class = csc_none;
else
@@ -5129,19 +5713,19 @@ grokdeclarator (const struct c_declarator *declarator,
}
}
- decl = build_decl (FUNCTION_DECL, declarator->u.id, type);
- DECL_SOURCE_LOCATION (decl) = declarator->id_loc;
+ decl = build_decl (declarator->id_loc,
+ FUNCTION_DECL, declarator->u.id, type);
decl = build_decl_attribute_variant (decl, decl_attr);
if (pedantic && type_quals && !DECL_IN_SYSTEM_HEADER (decl))
- pedwarn (input_location, OPT_pedantic,
+ pedwarn (loc, OPT_pedantic,
"ISO C forbids qualified function types");
/* GNU C interprets a volatile-qualified function type to indicate
that the function does not return. */
if ((type_quals & TYPE_QUAL_VOLATILE)
&& !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (decl))))
- warning (0, "%<noreturn%> function returns non-void value");
+ warning_at (loc, 0, "%<noreturn%> function returns non-void value");
/* Every function declaration is an external reference
(DECL_EXTERNAL) except for those which are not at file
@@ -5177,7 +5761,7 @@ grokdeclarator (const struct c_declarator *declarator,
if (flag_hosted && MAIN_NAME_P (declarator->u.id))
{
if (declspecs->inline_p)
- pedwarn (input_location, 0, "cannot inline function %<main%>");
+ pedwarn (loc, 0, "cannot inline function %<main%>");
}
else if (declspecs->inline_p)
/* Record that the function is declared `inline'. */
@@ -5206,17 +5790,17 @@ grokdeclarator (const struct c_declarator *declarator,
&& global_decl != visible_decl
&& TREE_CODE (global_decl) == VAR_DECL
&& !TREE_PUBLIC (global_decl))
- error ("variable previously declared %<static%> redeclared "
- "%<extern%>");
+ error_at (loc, "variable previously declared %<static%> "
+ "redeclared %<extern%>");
}
- decl = build_decl (VAR_DECL, declarator->u.id, type);
- DECL_SOURCE_LOCATION (decl) = declarator->id_loc;
+ decl = build_decl (declarator->id_loc,
+ VAR_DECL, declarator->u.id, type);
if (size_varies)
C_DECL_VARIABLE_SIZE (decl) = 1;
if (declspecs->inline_p)
- pedwarn (input_location, 0, "variable %q+D declared %<inline%>", decl);
+ pedwarn (loc, 0, "variable %q+D declared %<inline%>", decl);
/* At file scope, an initialized extern declaration may follow
a static declaration. In that case, DECL_EXTERNAL will be
@@ -5251,9 +5835,10 @@ grokdeclarator (const struct c_declarator *declarator,
{
/* C99 6.7.5.2p2 */
if (TREE_CODE (type) == FUNCTION_TYPE)
- error ("non-nested function with variably modified type");
+ error_at (loc, "non-nested function with variably modified type");
else
- error ("object with variably modified type must have no linkage");
+ error_at (loc, "object with variably modified type must have "
+ "no linkage");
}
/* Record `register' declaration for warnings on &
@@ -5340,6 +5925,7 @@ grokparms (struct c_arg_info *arg_info, bool funcdef_flag)
{
tree parm, type, typelt;
unsigned int parmno;
+ const char *errmsg;
/* If there is a parameter of incomplete type in a definition,
this is an error. In a declaration this is valid, and a
@@ -5383,6 +5969,14 @@ grokparms (struct c_arg_info *arg_info, bool funcdef_flag)
}
}
+ errmsg = targetm.invalid_parameter_type (type);
+ if (errmsg)
+ {
+ error (errmsg);
+ TREE_VALUE (typelt) = error_mark_node;
+ TREE_TYPE (parm) = error_mark_node;
+ }
+
if (DECL_NAME (parm) && TREE_USED (parm))
warn_if_shadowing (parm);
}
@@ -5577,11 +6171,12 @@ get_parm_info (bool ellipsis)
}
/* Get the struct, enum or union (CODE says which) with tag NAME.
- Define the tag as a forward-reference if it is not defined.
- Return a c_typespec structure for the type specifier. */
+ Define the tag as a forward-reference with location LOC if it is
+ not defined. Return a c_typespec structure for the type
+ specifier. */
struct c_typespec
-parser_xref_tag (enum tree_code code, tree name, location_t loc)
+parser_xref_tag (location_t loc, enum tree_code code, tree name)
{
struct c_typespec ret;
tree ref;
@@ -5660,7 +6255,7 @@ parser_xref_tag (enum tree_code code, tree name, location_t loc)
TYPE_MAX_VALUE (ref) = TYPE_MAX_VALUE (unsigned_type_node);
}
- pushtag (name, ref, loc);
+ pushtag (loc, name, ref);
ret.spec = ref;
return ret;
@@ -5673,11 +6268,12 @@ parser_xref_tag (enum tree_code code, tree name, location_t loc)
tree
xref_tag (enum tree_code code, tree name)
{
- return parser_xref_tag (code, name, UNKNOWN_LOCATION).spec;
+ return parser_xref_tag (input_location, code, name).spec;
}
/* Make sure that the tag NAME is defined *in the current scope*
at least as a forward reference.
+ LOC is the location of the struct's definition.
CODE says which kind of tag NAME ought to be.
This stores the current value of the file static IN_STRUCT in
@@ -5687,8 +6283,9 @@ xref_tag (enum tree_code code, tree name)
finish_struct. */
tree
-start_struct (enum tree_code code, tree name, bool *enclosing_in_struct,
- VEC(tree,heap) **enclosing_struct_types, location_t loc)
+start_struct (location_t loc, enum tree_code code, tree name,
+ bool *enclosing_in_struct,
+ VEC(tree,heap) **enclosing_struct_types)
{
/* If there is already a tag defined at this scope
(as a forward reference), just return it. */
@@ -5730,7 +6327,7 @@ start_struct (enum tree_code code, tree name, bool *enclosing_in_struct,
if (ref == NULL_TREE || TREE_CODE (ref) != code)
{
ref = make_node (code);
- pushtag (name, ref, loc);
+ pushtag (loc, name, ref);
}
C_TYPE_BEING_DEFINED (ref) = 1;
@@ -5824,7 +6421,7 @@ grokfield (location_t loc,
width ? &width : NULL, decl_attrs, NULL, NULL,
DEPRECATED_NORMAL);
- finish_decl (value, NULL_TREE, NULL_TREE, NULL_TREE);
+ finish_decl (value, loc, NULL_TREE, NULL_TREE, NULL_TREE);
DECL_INITIAL (value) = width;
return value;
@@ -5888,6 +6485,7 @@ detect_field_duplicates (tree fieldlist)
}
/* Fill in the fields of a RECORD_TYPE or UNION_TYPE node, T.
+ LOC is the location of the RECORD_TYPE or UNION_TYPE's definition.
FIELDLIST is a chain of FIELD_DECL nodes for the fields.
ATTRIBUTES are attributes to be applied to the structure.
@@ -5897,7 +6495,7 @@ detect_field_duplicates (tree fieldlist)
for any type defined in the current struct. */
tree
-finish_struct (tree t, tree fieldlist, tree attributes,
+finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
bool enclosing_in_struct,
VEC(tree,heap) *enclosing_struct_types)
{
@@ -5924,16 +6522,16 @@ finish_struct (tree t, tree fieldlist, tree attributes,
if (TREE_CODE (t) == UNION_TYPE)
{
if (fieldlist)
- pedwarn (input_location, OPT_pedantic, "union has no named members");
+ pedwarn (loc, OPT_pedantic, "union has no named members");
else
- pedwarn (input_location, OPT_pedantic, "union has no members");
+ pedwarn (loc, OPT_pedantic, "union has no members");
}
else
{
if (fieldlist)
- pedwarn (input_location, OPT_pedantic, "struct has no named members");
+ pedwarn (loc, OPT_pedantic, "struct has no named members");
else
- pedwarn (input_location, OPT_pedantic, "struct has no members");
+ pedwarn (loc, OPT_pedantic, "struct has no members");
}
}
}
@@ -5997,24 +6595,28 @@ finish_struct (tree t, tree fieldlist, tree attributes,
{
if (TREE_CODE (t) == UNION_TYPE)
{
- error ("%Jflexible array member in union", x);
+ error_at (DECL_SOURCE_LOCATION (x),
+ "%Jflexible array member in union", x);
TREE_TYPE (x) = error_mark_node;
}
else if (TREE_CHAIN (x) != NULL_TREE)
{
- error ("%Jflexible array member not at end of struct", x);
+ error_at (DECL_SOURCE_LOCATION (x),
+ "%Jflexible array member not at end of struct", x);
TREE_TYPE (x) = error_mark_node;
}
else if (!saw_named_field)
{
- error ("%Jflexible array member in otherwise empty struct", x);
+ error_at (DECL_SOURCE_LOCATION (x),
+ "%Jflexible array member in otherwise empty struct",
+ x);
TREE_TYPE (x) = error_mark_node;
}
}
if (pedantic && !in_system_header && TREE_CODE (t) == RECORD_TYPE
&& flexible_array_type_p (TREE_TYPE (x)))
- pedwarn (input_location, OPT_pedantic,
+ pedwarn (loc, OPT_pedantic,
"%Jinvalid use of structure with flexible array member", x);
if (DECL_NAME (x))
@@ -6124,7 +6726,7 @@ finish_struct (tree t, tree fieldlist, tree attributes,
&& (!TYPE_FIELDS (t) || TYPE_MODE (t) != DECL_MODE (TYPE_FIELDS (t))))
{
TYPE_TRANSPARENT_UNION (t) = 0;
- warning (0, "union cannot be made transparent");
+ warning_at (loc, 0, "union cannot be made transparent");
}
/* If this structure or union completes the type of any previous
@@ -6155,7 +6757,8 @@ finish_struct (tree t, tree fieldlist, tree attributes,
parsing parameters, then arrange for the size of a variable sized type
to be bound now. */
if (cur_stmt_list && variably_modified_type_p (t, NULL_TREE))
- add_stmt (build_stmt (DECL_EXPR, build_decl (TYPE_DECL, NULL, t)));
+ add_stmt (build_stmt (loc,
+ DECL_EXPR, build_decl (loc, TYPE_DECL, NULL, t)));
/* Set the C_TYPE_DEFINED_IN_STRUCT flag for each type defined in
the current struct. We do this now at the end of the struct
@@ -6190,12 +6793,13 @@ layout_array_type (tree t)
/* Begin compiling the definition of an enumeration type.
NAME is its name (or null if anonymous).
+ LOC is the enum's location.
Returns the type object, as yet incomplete.
Also records info about it so that build_enumerator
may be used to declare the individual values as they are read. */
tree
-start_enum (struct c_enum_contents *the_enum, tree name, location_t loc)
+start_enum (location_t loc, struct c_enum_contents *the_enum, tree name)
{
tree enumtype = NULL_TREE;
location_t enumloc = UNKNOWN_LOCATION;
@@ -6210,7 +6814,7 @@ start_enum (struct c_enum_contents *the_enum, tree name, location_t loc)
if (enumtype == 0 || TREE_CODE (enumtype) != ENUMERAL_TYPE)
{
enumtype = make_node (ENUMERAL_TYPE);
- pushtag (name, enumtype, loc);
+ pushtag (loc, name, enumtype);
}
if (C_TYPE_BEING_DEFINED (enumtype))
@@ -6395,12 +6999,13 @@ finish_enum (tree enumtype, tree values, tree attributes)
/* Build and install a CONST_DECL for one value of the
current enumeration type (one that was begun with start_enum).
+ LOC is the location of the enumerator.
Return a tree-list containing the CONST_DECL and its value.
Assignment of sequential values by default is handled here. */
tree
-build_enumerator (struct c_enum_contents *the_enum, tree name, tree value,
- location_t value_loc)
+build_enumerator (location_t loc,
+ struct c_enum_contents *the_enum, tree name, tree value)
{
tree decl, type;
@@ -6414,7 +7019,8 @@ build_enumerator (struct c_enum_contents *the_enum, tree name, tree value,
value = 0;
else if (!INTEGRAL_TYPE_P (TREE_TYPE (value)))
{
- error ("enumerator value for %qE is not an integer constant", name);
+ error_at (loc, "enumerator value for %qE is not an integer constant",
+ name);
value = 0;
}
else
@@ -6423,7 +7029,7 @@ build_enumerator (struct c_enum_contents *the_enum, tree name, tree value,
{
value = c_fully_fold (value, false, NULL);
if (TREE_CODE (value) == INTEGER_CST)
- pedwarn (value_loc, OPT_pedantic,
+ pedwarn (loc, OPT_pedantic,
"enumerator value for %qE is not an integer "
"constant expression", name);
}
@@ -6448,14 +7054,14 @@ build_enumerator (struct c_enum_contents *the_enum, tree name, tree value,
{
value = the_enum->enum_next_value;
if (the_enum->enum_overflow)
- error ("overflow in enumeration values");
+ error_at (loc, "overflow in enumeration values");
}
/* Even though the underlying type of an enum is unspecified, the
type of enumeration constants is explicitly defined as int
(6.4.4.3/2 in the C99 Standard). GCC allows any integer type as
an extension. */
else if (!int_fits_type_p (value, integer_type_node))
- pedwarn (value_loc, OPT_pedantic,
+ pedwarn (loc, OPT_pedantic,
"ISO C restricts enumerator values to range of %<int%>");
/* The ISO C Standard mandates enumerators to have type int, even
@@ -6486,7 +7092,7 @@ build_enumerator (struct c_enum_contents *the_enum, tree name, tree value,
>= TYPE_PRECISION (integer_type_node)
&& TYPE_UNSIGNED (type)));
- decl = build_decl (CONST_DECL, name, type);
+ decl = build_decl (loc, CONST_DECL, name, type);
DECL_INITIAL (decl) = convert (type, value);
pushdecl (decl);
@@ -6512,8 +7118,7 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
{
tree decl1, old_decl;
tree restype, resdecl;
- struct c_label_context_se *nstack_se;
- struct c_label_context_vm *nstack_vm;
+ location_t loc;
current_function_returns_value = 0; /* Assume, until we see it does. */
current_function_returns_null = 0;
@@ -6521,19 +7126,6 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
warn_about_return_type = 0;
c_switch_stack = NULL;
- nstack_se = XOBNEW (&parser_obstack, struct c_label_context_se);
- nstack_se->labels_def = NULL;
- nstack_se->labels_used = NULL;
- nstack_se->next = label_context_stack_se;
- label_context_stack_se = nstack_se;
-
- nstack_vm = XOBNEW (&parser_obstack, struct c_label_context_vm);
- nstack_vm->labels_def = NULL;
- nstack_vm->labels_used = NULL;
- nstack_vm->scope = 0;
- nstack_vm->next = label_context_stack_vm;
- label_context_stack_vm = nstack_vm;
-
/* Indicate no valid break/continue context by setting these variables
to some non-null, non-label value. We'll notice and emit the proper
error message in c_finish_bc_stmt. */
@@ -6545,19 +7137,18 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
/* If the declarator is not suitable for a function definition,
cause a syntax error. */
if (decl1 == 0)
- {
- label_context_stack_se = label_context_stack_se->next;
- label_context_stack_vm = label_context_stack_vm->next;
- return 0;
- }
+ return 0;
+
+ loc = DECL_SOURCE_LOCATION (decl1);
decl_attributes (&decl1, attributes, 0);
if (DECL_DECLARED_INLINE_P (decl1)
&& DECL_UNINLINABLE (decl1)
&& lookup_attribute ("noinline", DECL_ATTRIBUTES (decl1)))
- warning (OPT_Wattributes, "inline function %q+D given attribute noinline",
- decl1);
+ warning_at (loc, OPT_Wattributes,
+ "inline function %qD given attribute noinline",
+ decl1);
/* Handle gnu_inline attribute. */
if (declspecs->inline_p
@@ -6574,7 +7165,7 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
if (!COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (TREE_TYPE (decl1))))
{
- error ("return type is an incomplete type");
+ error_at (loc, "return type is an incomplete type");
/* Make it return void instead. */
TREE_TYPE (decl1)
= build_function_type (void_type_node,
@@ -6582,7 +7173,7 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
}
if (warn_about_return_type)
- pedwarn_c99 (input_location, flag_isoc99 ? 0
+ pedwarn_c99 (loc, flag_isoc99 ? 0
: (warn_return_type ? OPT_Wreturn_type : OPT_Wimplicit_int),
"return type defaults to %<int%>");
@@ -6628,7 +7219,7 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
{
tree ext_decl, ext_type;
ext_decl = b->decl;
- ext_type = b->type ? b->type : TREE_TYPE (ext_decl);
+ ext_type = b->u.type ? b->u.type : TREE_TYPE (ext_decl);
if (TREE_CODE (ext_type) == FUNCTION_TYPE
&& comptypes (TREE_TYPE (TREE_TYPE (decl1)),
TREE_TYPE (ext_type)))
@@ -6649,15 +7240,16 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
&& old_decl != error_mark_node
&& TYPE_ARG_TYPES (TREE_TYPE (decl1)) == 0
&& C_DECL_ISNT_PROTOTYPE (old_decl))
- warning (OPT_Wstrict_prototypes,
- "function declaration isn%'t a prototype");
+ warning_at (loc, OPT_Wstrict_prototypes,
+ "function declaration isn%'t a prototype");
/* Optionally warn of any global def with no previous prototype. */
else if (warn_missing_prototypes
&& old_decl != error_mark_node
&& TREE_PUBLIC (decl1)
&& !MAIN_NAME_P (DECL_NAME (decl1))
&& C_DECL_ISNT_PROTOTYPE (old_decl))
- warning (OPT_Wmissing_prototypes, "no previous prototype for %q+D", decl1);
+ warning_at (loc, OPT_Wmissing_prototypes,
+ "no previous prototype for %qD", decl1);
/* Optionally warn of any def with no previous prototype
if the function has already been used. */
else if (warn_missing_prototypes
@@ -6665,15 +7257,16 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
&& old_decl != error_mark_node
&& TREE_USED (old_decl)
&& TYPE_ARG_TYPES (TREE_TYPE (old_decl)) == 0)
- warning (OPT_Wmissing_prototypes,
- "%q+D was used with no prototype before its definition", decl1);
+ warning_at (loc, OPT_Wmissing_prototypes,
+ "%qD was used with no prototype before its definition", decl1);
/* Optionally warn of any global def with no previous declaration. */
else if (warn_missing_declarations
&& TREE_PUBLIC (decl1)
&& old_decl == 0
&& !MAIN_NAME_P (DECL_NAME (decl1)))
- warning (OPT_Wmissing_declarations, "no previous declaration for %q+D",
- decl1);
+ warning_at (loc, OPT_Wmissing_declarations,
+ "no previous declaration for %qD",
+ decl1);
/* Optionally warn of any def with no previous declaration
if the function has already been used. */
else if (warn_missing_declarations
@@ -6681,8 +7274,8 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
&& old_decl != error_mark_node
&& TREE_USED (old_decl)
&& C_DECL_IMPLICIT (old_decl))
- warning (OPT_Wmissing_declarations,
- "%q+D was used with no declaration before its definition", decl1);
+ warning_at (loc, OPT_Wmissing_declarations,
+ "%qD was used with no declaration before its definition", decl1);
/* This function exists in static storage.
(This does not mean `static' in the C sense!) */
@@ -6705,12 +7298,13 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
{
if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (decl1)))
!= integer_type_node)
- pedwarn (input_location, OPT_Wmain, "return type of %q+D is not %<int%>", decl1);
+ pedwarn (loc, OPT_Wmain, "return type of %qD is not %<int%>", decl1);
check_main_parameter_types (decl1);
if (!TREE_PUBLIC (decl1))
- pedwarn (input_location, OPT_Wmain, "%q+D is normally a non-static function", decl1);
+ pedwarn (loc, OPT_Wmain,
+ "%qD is normally a non-static function", decl1);
}
/* Record the decl so that the function name is defined.
@@ -6723,7 +7317,7 @@ start_function (struct c_declspecs *declspecs, struct c_declarator *declarator,
declare_parm_level ();
restype = TREE_TYPE (TREE_TYPE (current_function_decl));
- resdecl = build_decl (RESULT_DECL, NULL_TREE, restype);
+ resdecl = build_decl (loc, RESULT_DECL, NULL_TREE, restype);
DECL_ARTIFICIAL (resdecl) = 1;
DECL_IGNORED_P (resdecl) = 1;
DECL_RESULT (current_function_decl) = resdecl;
@@ -6809,8 +7403,8 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info)
struct pointer_set_t *seen_args = pointer_set_create ();
if (!in_system_header)
- warning (OPT_Wold_style_definition, "%Jold-style function definition",
- fndecl);
+ warning_at (DECL_SOURCE_LOCATION (fndecl),
+ OPT_Wold_style_definition, "old-style function definition");
/* Match each formal parameter name with its declaration. Save each
decl in the appropriate TREE_PURPOSE slot of the parmids chain. */
@@ -6818,7 +7412,8 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info)
{
if (TREE_VALUE (parm) == 0)
{
- error ("%Jparameter name missing from parameter list", fndecl);
+ error_at (DECL_SOURCE_LOCATION (fndecl),
+ "parameter name missing from parameter list");
TREE_PURPOSE (parm) = 0;
continue;
}
@@ -6829,12 +7424,14 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info)
decl = b->decl;
/* If we got something other than a PARM_DECL it is an error. */
if (TREE_CODE (decl) != PARM_DECL)
- error ("%q+D declared as a non-parameter", decl);
+ error_at (DECL_SOURCE_LOCATION (decl),
+ "%qD declared as a non-parameter", decl);
/* If the declaration is already marked, we have a duplicate
name. Complain and ignore the duplicate. */
else if (pointer_set_contains (seen_args, decl))
{
- error ("multiple parameters named %q+D", decl);
+ error_at (DECL_SOURCE_LOCATION (decl),
+ "multiple parameters named %qD", decl);
TREE_PURPOSE (parm) = 0;
continue;
}
@@ -6842,7 +7439,8 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info)
an int. */
else if (VOID_TYPE_P (TREE_TYPE (decl)))
{
- error ("parameter %q+D declared with void type", decl);
+ error_at (DECL_SOURCE_LOCATION (decl),
+ "parameter %qD declared with void type", decl);
TREE_TYPE (decl) = integer_type_node;
DECL_ARG_TYPE (decl) = integer_type_node;
layout_decl (decl, 0);
@@ -6852,16 +7450,30 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info)
/* If no declaration found, default to int. */
else
{
- decl = build_decl (PARM_DECL, TREE_VALUE (parm), integer_type_node);
+ /* FIXME diagnostics: This should be the location of the argument,
+ not the FNDECL. E.g., for an old-style declaration
+
+ int f10(v) { blah; }
+
+ We should use the location of the V, not the F10.
+ Unfortunately, the V is an IDENTIFIER_NODE which has no
+ location. In the future we need locations for c_arg_info
+ entries.
+
+ See gcc.dg/Wshadow-3.c for an example of this problem. */
+ decl = build_decl (DECL_SOURCE_LOCATION (fndecl),
+ PARM_DECL, TREE_VALUE (parm), integer_type_node);
DECL_ARG_TYPE (decl) = TREE_TYPE (decl);
- DECL_SOURCE_LOCATION (decl) = DECL_SOURCE_LOCATION (fndecl);
pushdecl (decl);
warn_if_shadowing (decl);
if (flag_isoc99)
- pedwarn (input_location, 0, "type of %q+D defaults to %<int%>", decl);
+ pedwarn (DECL_SOURCE_LOCATION (decl),
+ 0, "type of %qD defaults to %<int%>", decl);
else
- warning (OPT_Wmissing_parameter_type, "type of %q+D defaults to %<int%>", decl);
+ warning_at (DECL_SOURCE_LOCATION (decl),
+ OPT_Wmissing_parameter_type,
+ "type of %qD defaults to %<int%>", decl);
}
TREE_PURPOSE (parm) = decl;
@@ -6880,13 +7492,16 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info)
if (TREE_TYPE (parm) != error_mark_node
&& !COMPLETE_TYPE_P (TREE_TYPE (parm)))
{
- error ("parameter %q+D has incomplete type", parm);
+ error_at (DECL_SOURCE_LOCATION (parm),
+ "parameter %qD has incomplete type", parm);
TREE_TYPE (parm) = error_mark_node;
}
if (!pointer_set_contains (seen_args, parm))
{
- error ("declaration for parameter %q+D but no such parameter", parm);
+ error_at (DECL_SOURCE_LOCATION (parm),
+ "declaration for parameter %qD but no such parameter",
+ parm);
/* Pretend the parameter was not missing.
This gets us to a standard state and minimizes
@@ -6936,13 +7551,22 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info)
|| TYPE_MAIN_VARIANT (TREE_VALUE (type)) == void_type_node)
{
if (current_function_prototype_built_in)
- warning (0, "number of arguments doesn%'t match "
- "built-in prototype");
+ warning_at (DECL_SOURCE_LOCATION (fndecl),
+ 0, "number of arguments doesn%'t match "
+ "built-in prototype");
else
{
- error ("number of arguments doesn%'t match prototype");
- error ("%Hprototype declaration",
- &current_function_prototype_locus);
+ /* FIXME diagnostics: This should be the location of
+ FNDECL, but there is bug when a prototype is
+ declared inside function context, but defined
+ outside of it (e.g., gcc.dg/pr15698-2.c). In
+ which case FNDECL gets the location of the
+ prototype, not the definition. */
+ error_at (input_location,
+ "number of arguments doesn%'t match prototype");
+
+ error_at (current_function_prototype_locus,
+ "prototype declaration");
}
break;
}
@@ -6975,11 +7599,13 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info)
been diagnosed as conflicting with an
old-style definition and discarded? */
if (current_function_prototype_built_in)
- warning (OPT_pedantic, "promoted argument %qD "
- "doesn%'t match built-in prototype", parm);
+ warning_at (DECL_SOURCE_LOCATION (parm),
+ OPT_pedantic, "promoted argument %qD "
+ "doesn%'t match built-in prototype", parm);
else
{
- pedwarn (input_location, OPT_pedantic, "promoted argument %qD "
+ pedwarn (DECL_SOURCE_LOCATION (parm),
+ OPT_pedantic, "promoted argument %qD "
"doesn%'t match prototype", parm);
pedwarn (current_function_prototype_locus, OPT_pedantic,
"prototype declaration");
@@ -6988,13 +7614,15 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info)
else
{
if (current_function_prototype_built_in)
- warning (0, "argument %qD doesn%'t match "
- "built-in prototype", parm);
+ warning_at (DECL_SOURCE_LOCATION (parm),
+ 0, "argument %qD doesn%'t match "
+ "built-in prototype", parm);
else
{
- error ("argument %qD doesn%'t match prototype", parm);
- error ("%Hprototype declaration",
- &current_function_prototype_locus);
+ error_at (DECL_SOURCE_LOCATION (parm),
+ "argument %qD doesn%'t match prototype", parm);
+ error_at (current_function_prototype_locus,
+ "prototype declaration");
}
}
}
@@ -7143,9 +7771,6 @@ finish_function (void)
{
tree fndecl = current_function_decl;
- label_context_stack_se = label_context_stack_se->next;
- label_context_stack_vm = label_context_stack_vm->next;
-
if (TREE_CODE (fndecl) == FUNCTION_DECL
&& targetm.calls.promote_prototypes (TREE_TYPE (fndecl)))
{
@@ -7171,14 +7796,13 @@ finish_function (void)
&& TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (fndecl)))
== integer_type_node && flag_isoc99)
{
- tree stmt = c_finish_return (integer_zero_node, NULL_TREE);
/* Hack. We don't want the middle-end to warn that this return
is unreachable, so we mark its location as special. Using
UNKNOWN_LOCATION has the problem that it gets clobbered in
annotate_one_with_locus. A cleaner solution might be to
ensure ! should_carry_locus_p (stmt), but that needs a flag.
*/
- SET_EXPR_LOCATION (stmt, BUILTINS_LOCATION);
+ c_finish_return (BUILTINS_LOCATION, integer_zero_node, NULL_TREE);
}
/* Tie off the statement tree for this function. */
@@ -7236,7 +7860,6 @@ finish_function (void)
cgraph_add_new_function (fndecl, false);
return;
}
-
cgraph_finalize_function (fndecl, false);
}
else
@@ -7259,10 +7882,11 @@ finish_function (void)
}
/* Check the declarations given in a for-loop for satisfying the C99
- constraints. If exactly one such decl is found, return it. */
+ constraints. If exactly one such decl is found, return it. LOC is
+ the location of the opening parenthesis of the for loop. */
tree
-check_for_loop_decls (void)
+check_for_loop_decls (location_t loc)
{
struct c_binding *b;
tree one_decl = NULL_TREE;
@@ -7274,10 +7898,11 @@ check_for_loop_decls (void)
/* If we get here, declarations have been used in a for loop without
the C99 for loop scope. This doesn't make much sense, so don't
allow it. */
- error ("%<for%> loop initial declarations are only allowed in C99 mode");
+ error_at (loc, "%<for%> loop initial declarations "
+ "are only allowed in C99 mode");
if (hint)
{
- inform (input_location,
+ inform (loc,
"use option -std=c99 or -std=gnu99 to compile your code");
hint = false;
}
@@ -7308,29 +7933,36 @@ check_for_loop_decls (void)
switch (TREE_CODE (decl))
{
case VAR_DECL:
- if (TREE_STATIC (decl))
- error ("declaration of static variable %q+D in %<for%> loop "
- "initial declaration", decl);
- else if (DECL_EXTERNAL (decl))
- error ("declaration of %<extern%> variable %q+D in %<for%> loop "
- "initial declaration", decl);
+ {
+ location_t decl_loc = DECL_SOURCE_LOCATION (decl);
+ if (TREE_STATIC (decl))
+ error_at (decl_loc,
+ "declaration of static variable %qD in %<for%> loop "
+ "initial declaration", decl);
+ else if (DECL_EXTERNAL (decl))
+ error_at (decl_loc,
+ "declaration of %<extern%> variable %qD in %<for%> loop "
+ "initial declaration", decl);
+ }
break;
case RECORD_TYPE:
- error ("%<struct %E%> declared in %<for%> loop initial declaration",
- id);
+ error_at (loc,
+ "%<struct %E%> declared in %<for%> loop initial "
+ "declaration", id);
break;
case UNION_TYPE:
- error ("%<union %E%> declared in %<for%> loop initial declaration",
- id);
+ error_at (loc,
+ "%<union %E%> declared in %<for%> loop initial declaration",
+ id);
break;
case ENUMERAL_TYPE:
- error ("%<enum %E%> declared in %<for%> loop initial declaration",
- id);
+ error_at (loc, "%<enum %E%> declared in %<for%> loop "
+ "initial declaration", id);
break;
default:
- error ("declaration of non-variable %q+D in %<for%> loop "
- "initial declaration", decl);
+ error_at (loc, "declaration of non-variable "
+ "%qD in %<for%> loop initial declaration", decl);
}
n_decls++;
@@ -7450,7 +8082,7 @@ record_builtin_type (enum rid rid_index, const char *name, tree type)
id = ridpointers[(int) rid_index];
else
id = get_identifier (name);
- decl = build_decl (TYPE_DECL, id, type);
+ decl = build_decl (UNKNOWN_LOCATION, TYPE_DECL, id, type);
pushdecl (decl);
if (debug_hooks->type_decl)
debug_hooks->type_decl (decl, false);
diff --git a/gcc/c-format.c b/gcc/c-format.c
index f64cb21b459..3c73564edfa 100644
--- a/gcc/c-format.c
+++ b/gcc/c-format.c
@@ -2865,7 +2865,7 @@ handle_format_attribute (tree *node, tree ARG_UNUSED (name), tree args,
}
/* If this is a custom GCC-internal format type, we have to
- initialize certain bits a runtime. */
+ initialize certain bits at runtime. */
if (info.format_type == asm_fprintf_format_type
|| info.format_type == gcc_gfc_format_type
|| info.format_type == gcc_diag_format_type
diff --git a/gcc/c-gimplify.c b/gcc/c-gimplify.c
index 9cb4a0b2d17..6595fc8fa03 100644
--- a/gcc/c-gimplify.c
+++ b/gcc/c-gimplify.c
@@ -140,7 +140,7 @@ add_block_to_enclosing (tree block)
genericized. */
tree
-c_build_bind_expr (tree block, tree body)
+c_build_bind_expr (location_t loc, tree block, tree body)
{
tree decls, bind;
@@ -162,11 +162,12 @@ c_build_bind_expr (tree block, tree body)
}
if (!body)
- body = build_empty_stmt ();
+ body = build_empty_stmt (loc);
if (decls || block)
{
bind = build3 (BIND_EXPR, void_type_node, decls, body, block);
TREE_SIDE_EFFECTS (bind) = 1;
+ SET_EXPR_LOCATION (bind, loc);
}
else
bind = body;
diff --git a/gcc/c-omp.c b/gcc/c-omp.c
index d31fb07e002..5ec9f94ff68 100644
--- a/gcc/c-omp.c
+++ b/gcc/c-omp.c
@@ -35,72 +35,81 @@ along with GCC; see the file COPYING3. If not see
/* Complete a #pragma omp master construct. STMT is the structured-block
- that follows the pragma. */
+ that follows the pragma. LOC is the l*/
tree
-c_finish_omp_master (tree stmt)
+c_finish_omp_master (location_t loc, tree stmt)
{
- return add_stmt (build1 (OMP_MASTER, void_type_node, stmt));
+ tree t = add_stmt (build1 (OMP_MASTER, void_type_node, stmt));
+ SET_EXPR_LOCATION (t, loc);
+ return t;
}
/* Complete a #pragma omp critical construct. STMT is the structured-block
that follows the pragma, NAME is the identifier in the pragma, or null
- if it was omitted. */
+ if it was omitted. LOC is the location of the #pragma. */
tree
-c_finish_omp_critical (tree body, tree name)
+c_finish_omp_critical (location_t loc, tree body, tree name)
{
tree stmt = make_node (OMP_CRITICAL);
TREE_TYPE (stmt) = void_type_node;
OMP_CRITICAL_BODY (stmt) = body;
OMP_CRITICAL_NAME (stmt) = name;
+ SET_EXPR_LOCATION (stmt, loc);
return add_stmt (stmt);
}
/* Complete a #pragma omp ordered construct. STMT is the structured-block
- that follows the pragma. */
+ that follows the pragma. LOC is the location of the #pragma. */
tree
-c_finish_omp_ordered (tree stmt)
+c_finish_omp_ordered (location_t loc, tree stmt)
{
- return add_stmt (build1 (OMP_ORDERED, void_type_node, stmt));
+ tree t = build1 (OMP_ORDERED, void_type_node, stmt);
+ SET_EXPR_LOCATION (t, loc);
+ return add_stmt (t);
}
-/* Complete a #pragma omp barrier construct. */
+/* Complete a #pragma omp barrier construct. LOC is the location of
+ the #pragma. */
void
-c_finish_omp_barrier (void)
+c_finish_omp_barrier (location_t loc)
{
tree x;
x = built_in_decls[BUILT_IN_GOMP_BARRIER];
x = build_call_expr (x, 0);
+ SET_EXPR_LOCATION (x, loc);
add_stmt (x);
}
-/* Complete a #pragma omp taskwait construct. */
+/* Complete a #pragma omp taskwait construct. LOC is the location of the
+ pragma. */
void
-c_finish_omp_taskwait (void)
+c_finish_omp_taskwait (location_t loc)
{
tree x;
x = built_in_decls[BUILT_IN_GOMP_TASKWAIT];
x = build_call_expr (x, 0);
+ SET_EXPR_LOCATION (x, loc);
add_stmt (x);
}
-/* Complete a #pragma omp atomic construct. The expression to be
- implemented atomically is LHS code= RHS. The value returned is
- either error_mark_node (if the construct was erroneous) or an
- OMP_ATOMIC node which should be added to the current statement tree
- with add_stmt. */
+/* Complete a #pragma omp atomic construct. The expression to be
+ implemented atomically is LHS code= RHS. LOC is the location of
+ the atomic statement. The value returned is either error_mark_node
+ (if the construct was erroneous) or an OMP_ATOMIC node which should
+ be added to the current statement tree with add_stmt.*/
tree
-c_finish_omp_atomic (enum tree_code code, tree lhs, tree rhs)
+c_finish_omp_atomic (location_t loc, enum tree_code code, tree lhs, tree rhs)
{
tree x, type, addr;
@@ -116,7 +125,7 @@ c_finish_omp_atomic (enum tree_code code, tree lhs, tree rhs)
&& !POINTER_TYPE_P (type)
&& !SCALAR_FLOAT_TYPE_P (type))
{
- error ("invalid expression type for %<#pragma omp atomic%>");
+ error_at (loc, "invalid expression type for %<#pragma omp atomic%>");
return error_mark_node;
}
@@ -124,7 +133,7 @@ c_finish_omp_atomic (enum tree_code code, tree lhs, tree rhs)
/* Take and save the address of the lhs. From then on we'll reference it
via indirection. */
- addr = build_unary_op (input_location, ADDR_EXPR, lhs, 0);
+ addr = build_unary_op (loc, ADDR_EXPR, lhs, 0);
if (addr == error_mark_node)
return error_mark_node;
addr = save_expr (addr);
@@ -137,32 +146,37 @@ c_finish_omp_atomic (enum tree_code code, tree lhs, tree rhs)
tree var = create_tmp_var_raw (TREE_TYPE (addr), NULL);
addr = build4 (TARGET_EXPR, TREE_TYPE (addr), var, addr, NULL, NULL);
}
- lhs = build_indirect_ref (input_location, addr, NULL);
+ lhs = build_indirect_ref (loc, addr, NULL);
/* There are lots of warnings, errors, and conversions that need to happen
in the course of interpreting a statement. Use the normal mechanisms
to do this, and then take it apart again. */
- x = build_modify_expr (input_location, lhs, NULL_TREE, code, rhs, NULL_TREE);
+ x = build_modify_expr (input_location, lhs, NULL_TREE, code,
+ input_location, rhs, NULL_TREE);
if (x == error_mark_node)
return error_mark_node;
gcc_assert (TREE_CODE (x) == MODIFY_EXPR);
rhs = TREE_OPERAND (x, 1);
/* Punt the actual generation of atomic operations to common code. */
- return build2 (OMP_ATOMIC, void_type_node, addr, rhs);
+ x = build2 (OMP_ATOMIC, void_type_node, addr, rhs);
+ SET_EXPR_LOCATION (x, loc);
+ return x;
}
-/* Complete a #pragma omp flush construct. We don't do anything with the
- variable list that the syntax allows. */
+/* Complete a #pragma omp flush construct. We don't do anything with
+ the variable list that the syntax allows. LOC is the location of
+ the #pragma. */
void
-c_finish_omp_flush (void)
+c_finish_omp_flush (location_t loc)
{
tree x;
x = built_in_decls[BUILT_IN_SYNCHRONIZE];
x = build_call_expr (x, 0);
+ SET_EXPR_LOCATION (x, loc);
add_stmt (x);
}
@@ -260,7 +274,11 @@ c_finish_omp_for (location_t locus, tree declv, tree initv, tree condv,
fail = true;
}
- init = build_modify_expr (elocus, decl, NULL_TREE, NOP_EXPR, init,
+ init = build_modify_expr (elocus, decl, NULL_TREE, NOP_EXPR,
+ /* FIXME diagnostics: This should
+ be the location of the INIT. */
+ elocus,
+ init,
NULL_TREE);
}
gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
@@ -448,18 +466,20 @@ c_finish_omp_for (location_t locus, tree declv, tree initv, tree condv,
}
-/* Divide CLAUSES into two lists: those that apply to a parallel construct,
- and those that apply to a work-sharing construct. Place the results in
- *PAR_CLAUSES and *WS_CLAUSES respectively. In addition, add a nowait
- clause to the work-sharing list. */
+/* Divide CLAUSES into two lists: those that apply to a parallel
+ construct, and those that apply to a work-sharing construct. Place
+ the results in *PAR_CLAUSES and *WS_CLAUSES respectively. In
+ addition, add a nowait clause to the work-sharing list. LOC is the
+ location of the OMP_PARALLEL*. */
void
-c_split_parallel_clauses (tree clauses, tree *par_clauses, tree *ws_clauses)
+c_split_parallel_clauses (location_t loc, tree clauses,
+ tree *par_clauses, tree *ws_clauses)
{
tree next;
*par_clauses = NULL;
- *ws_clauses = build_omp_clause (OMP_CLAUSE_NOWAIT);
+ *ws_clauses = build_omp_clause (loc, OMP_CLAUSE_NOWAIT);
for (; clauses ; clauses = next)
{
diff --git a/gcc/c-opts.c b/gcc/c-opts.c
index 967be5200a7..4574bb2e920 100644
--- a/gcc/c-opts.c
+++ b/gcc/c-opts.c
@@ -395,6 +395,8 @@ c_common_handle_option (size_t scode, const char *arg, int value)
warn_strict_overflow = value;
warn_array_bounds = value;
warn_volatile_register_var = value;
+ if (warn_jump_misses_init == -1)
+ warn_jump_misses_init = value;
/* Only warn about unknown pragmas that are not in system
headers. */
@@ -445,6 +447,11 @@ c_common_handle_option (size_t scode, const char *arg, int value)
implies -Wenum-compare. */
if (warn_enum_compare == -1 && value)
warn_enum_compare = value;
+ /* Because C++ always warns about a goto which misses an
+ initialization, -Wc++-compat turns on -Wgoto-misses-init. */
+ if (warn_jump_misses_init == -1 && value)
+ warn_jump_misses_init = value;
+ cpp_opts->warn_cxx_operator_names = value;
break;
case OPT_Wdeprecated:
@@ -1073,8 +1080,6 @@ c_common_post_options (const char **pfilename)
warn_override_init = extra_warnings;
if (warn_ignored_qualifiers == -1)
warn_ignored_qualifiers = extra_warnings;
- if (warn_logical_op == -1)
- warn_logical_op = extra_warnings;
/* -Wpointer-sign is disabled by default, but it is enabled if any
of -Wall or -pedantic are given. */
@@ -1085,6 +1090,8 @@ c_common_post_options (const char **pfilename)
warn_strict_aliasing = 0;
if (warn_strict_overflow == -1)
warn_strict_overflow = 0;
+ if (warn_jump_misses_init == -1)
+ warn_jump_misses_init = 0;
/* -Woverlength-strings is off by default, but is enabled by -pedantic.
It is never enabled in C++, as the minimum limit is not normative
diff --git a/gcc/c-parser.c b/gcc/c-parser.c
index beda817c202..2b78c3042fa 100644
--- a/gcc/c-parser.c
+++ b/gcc/c-parser.c
@@ -916,13 +916,12 @@ static struct c_expr c_parser_postfix_expression_after_paren_type (c_parser *,
struct c_type_name *,
location_t);
static struct c_expr c_parser_postfix_expression_after_primary (c_parser *,
+ location_t loc,
struct c_expr);
static struct c_expr c_parser_expression (c_parser *);
static struct c_expr c_parser_expression_conv (c_parser *);
static VEC(tree,gc) *c_parser_expr_list (c_parser *, bool, bool,
VEC(tree,gc) **);
-static void c_parser_release_expr_list (VEC(tree,gc) *);
-static tree c_parser_vec_to_tree_list (VEC(tree,gc) *);
static void c_parser_omp_construct (c_parser *);
static void c_parser_omp_threadprivate (c_parser *);
static void c_parser_omp_barrier (c_parser *);
@@ -1226,6 +1225,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, bool empty_ok,
{
tree d;
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. */
@@ -1234,12 +1234,14 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, bool empty_ok,
if (!d)
d = error_mark_node;
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);
- finish_decl (d, init.value, init.original_type, asm_name);
+ finish_decl (d, init_loc, init.value,
+ init.original_type, asm_name);
}
}
else
@@ -1248,7 +1250,8 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, bool empty_ok,
chainon (postfix_attrs,
all_prefix_attrs));
if (d)
- finish_decl (d, NULL_TREE, NULL_TREE, asm_name);
+ finish_decl (d, UNKNOWN_LOCATION, NULL_TREE,
+ NULL_TREE, asm_name);
}
if (c_parser_next_token_is (parser, CPP_COMMA))
{
@@ -1321,7 +1324,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, bool empty_ok,
add_stmt (fnbody);
finish_function ();
c_pop_function_context ();
- add_stmt (build_stmt (DECL_EXPR, decl));
+ add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl), DECL_EXPR, decl));
}
else
{
@@ -1630,6 +1633,7 @@ c_parser_enum_specifier (c_parser *parser)
enum_loc = c_parser_peek_token (parser)->location;
c_parser_consume_token (parser);
attrs = c_parser_attributes (parser);
+ enum_loc = c_parser_peek_token (parser)->location;
/* Set the location in case we create a decl now. */
c_parser_set_source_position_from_token (c_parser_peek_token (parser));
if (c_parser_next_token_is (parser, CPP_NAME))
@@ -1643,7 +1647,7 @@ c_parser_enum_specifier (c_parser *parser)
{
/* Parse an enum definition. */
struct c_enum_contents the_enum;
- tree type = start_enum (&the_enum, ident, enum_loc);
+ tree type = start_enum (enum_loc, &the_enum, ident);
tree postfix_attrs;
/* We chain the enumerators in reverse order, then put them in
forward order at the end. */
@@ -1679,8 +1683,8 @@ c_parser_enum_specifier (c_parser *parser)
}
else
enum_value = NULL_TREE;
- enum_decl = build_enumerator (&the_enum, enum_id, enum_value,
- value_loc);
+ enum_decl = build_enumerator (value_loc,
+ &the_enum, enum_id, enum_value);
TREE_CHAIN (enum_decl) = values;
values = enum_decl;
seen_comma = false;
@@ -1722,13 +1726,13 @@ c_parser_enum_specifier (c_parser *parser)
ret.expr_const_operands = true;
return ret;
}
- ret = parser_xref_tag (ENUMERAL_TYPE, ident, ident_loc);
+ ret = parser_xref_tag (ident_loc, ENUMERAL_TYPE, ident);
/* In ISO C, enumerated types can be referred to only if already
defined. */
if (pedantic && !COMPLETE_TYPE_P (ret.spec))
{
gcc_assert (ident);
- pedwarn (ident_loc, OPT_pedantic,
+ pedwarn (enum_loc, OPT_pedantic,
"ISO C forbids forward references to %<enum%> types");
}
return ret;
@@ -1796,8 +1800,10 @@ c_parser_struct_or_union_specifier (c_parser *parser)
struct_loc = c_parser_peek_token (parser)->location;
c_parser_consume_token (parser);
attrs = c_parser_attributes (parser);
+
/* Set the location in case we create a decl now. */
c_parser_set_source_position_from_token (c_parser_peek_token (parser));
+
if (c_parser_next_token_is (parser, CPP_NAME))
{
ident = c_parser_peek_token (parser)->value;
@@ -1811,8 +1817,8 @@ c_parser_struct_or_union_specifier (c_parser *parser)
tag before parsing components. */
bool in_struct;
VEC(tree,heap) *struct_types;
- tree type = start_struct (code, ident, &in_struct, &struct_types,
- struct_loc);
+ tree type = start_struct (struct_loc, code, ident,
+ &in_struct, &struct_types);
tree postfix_attrs;
/* We chain the components in reverse order, then put them in
forward order at the end. Each struct-declaration may
@@ -1901,7 +1907,7 @@ c_parser_struct_or_union_specifier (c_parser *parser)
}
}
postfix_attrs = c_parser_attributes (parser);
- ret.spec = finish_struct (type, nreverse (contents),
+ ret.spec = finish_struct (struct_loc, type, nreverse (contents),
chainon (attrs, postfix_attrs),
in_struct, struct_types);
ret.kind = ctsk_tagdef;
@@ -1918,7 +1924,7 @@ c_parser_struct_or_union_specifier (c_parser *parser)
ret.expr_const_operands = true;
return ret;
}
- ret = parser_xref_tag (code, ident, ident_loc);
+ ret = parser_xref_tag (ident_loc, code, ident);
return ret;
}
@@ -2096,18 +2102,18 @@ c_parser_typeof_specifier (c_parser *parser)
ret.expr_const_operands = true;
gcc_assert (c_parser_next_token_is_keyword (parser, RID_TYPEOF));
c_parser_consume_token (parser);
- skip_evaluation++;
+ c_inhibit_evaluation_warnings++;
in_typeof++;
if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
{
- skip_evaluation--;
+ c_inhibit_evaluation_warnings--;
in_typeof--;
return ret;
}
if (c_parser_next_token_starts_typename (parser))
{
struct c_type_name *type = c_parser_type_name (parser);
- skip_evaluation--;
+ c_inhibit_evaluation_warnings--;
in_typeof--;
if (type != NULL)
{
@@ -2120,7 +2126,7 @@ c_parser_typeof_specifier (c_parser *parser)
bool was_vm;
location_t here = c_parser_peek_token (parser)->location;
struct c_expr expr = c_parser_expression (parser);
- skip_evaluation--;
+ c_inhibit_evaluation_warnings--;
in_typeof--;
if (TREE_CODE (expr.value) == COMPONENT_REF
&& DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
@@ -2368,6 +2374,7 @@ c_parser_direct_declarator_inner (c_parser *parser, bool id_present,
/* Parse a sequence of array declarators and parameter lists. */
if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
{
+ location_t brace_loc = c_parser_peek_token (parser)->location;
struct c_declarator *declarator;
struct c_declspecs *quals_attrs = build_null_declspecs ();
bool static_seen;
@@ -2425,8 +2432,8 @@ c_parser_direct_declarator_inner (c_parser *parser, bool id_present,
"expected %<]%>");
return NULL;
}
- declarator = build_array_declarator (dimen, quals_attrs, static_seen,
- star_seen);
+ declarator = build_array_declarator (brace_loc, dimen, quals_attrs,
+ static_seen, star_seen);
if (declarator == NULL)
return NULL;
inner = set_array_declarator_inner (declarator, inner);
@@ -2889,9 +2896,9 @@ c_parser_attributes (c_parser *parser)
tree tree_list;
c_parser_consume_token (parser);
expr_list = c_parser_expr_list (parser, false, true, NULL);
- tree_list = c_parser_vec_to_tree_list (expr_list);
+ tree_list = build_tree_list_vec (expr_list);
attr_args = tree_cons (NULL_TREE, arg1, tree_list);
- c_parser_release_expr_list (expr_list);
+ release_tree_vector (expr_list);
}
}
else
@@ -2901,8 +2908,8 @@ c_parser_attributes (c_parser *parser)
else
{
expr_list = c_parser_expr_list (parser, false, true, NULL);
- attr_args = c_parser_vec_to_tree_list (expr_list);
- c_parser_release_expr_list (expr_list);
+ attr_args = build_tree_list_vec (expr_list);
+ release_tree_vector (expr_list);
}
}
attr = build_tree_list (attr_name, attr_args);
@@ -3022,10 +3029,11 @@ c_parser_initializer (c_parser *parser)
else
{
struct c_expr ret;
+ location_t loc = c_parser_peek_token (parser)->location;
ret = c_parser_expr_no_commas (parser, NULL);
if (TREE_CODE (ret.value) != STRING_CST
&& TREE_CODE (ret.value) != COMPOUND_LITERAL_EXPR)
- ret = default_function_array_conversion (ret);
+ ret = default_function_array_conversion (loc, ret);
return ret;
}
}
@@ -3191,10 +3199,13 @@ c_parser_initelt (c_parser *parser)
while (c_parser_next_token_is (parser, CPP_COMMA))
{
struct c_expr next;
+ location_t comma_loc, exp_loc;
+ comma_loc = c_parser_peek_token (parser)->location;
c_parser_consume_token (parser);
+ exp_loc = c_parser_peek_token (parser)->location;
next = c_parser_expr_no_commas (parser, NULL);
- next = default_function_array_conversion (next);
- rec = build_compound_expr (rec, next.value);
+ next = default_function_array_conversion (exp_loc, next);
+ rec = build_compound_expr (comma_loc, rec, next.value);
}
parse_message_args:
/* Now parse the objc-message-args. */
@@ -3281,11 +3292,12 @@ c_parser_initval (c_parser *parser, struct c_expr *after)
init = c_parser_braced_init (parser, NULL_TREE, true);
else
{
+ location_t loc = c_parser_peek_token (parser)->location;
init = c_parser_expr_no_commas (parser, after);
if (init.value != NULL_TREE
&& TREE_CODE (init.value) != STRING_CST
&& TREE_CODE (init.value) != COMPOUND_LITERAL_EXPR)
- init = default_function_array_conversion (init);
+ init = default_function_array_conversion (loc, init);
}
process_init_element (init, false);
}
@@ -3347,17 +3359,19 @@ static tree
c_parser_compound_statement (c_parser *parser)
{
tree stmt;
+ location_t brace_loc;
+ brace_loc = c_parser_peek_token (parser)->location;
if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
{
/* Ensure a scope is entered and left anyway to avoid confusion
if we have just prepared to enter a function body. */
stmt = c_begin_compound_stmt (true);
- c_end_compound_stmt (stmt, true);
+ c_end_compound_stmt (brace_loc, stmt, true);
return error_mark_node;
}
stmt = c_begin_compound_stmt (true);
c_parser_compound_statement_nostart (parser);
- return c_end_compound_stmt (stmt, true);
+ return c_end_compound_stmt (brace_loc, stmt, true);
}
/* Parse a compound statement except for the opening brace. This is
@@ -3379,12 +3393,12 @@ c_parser_compound_statement_nostart (c_parser *parser)
mark_valid_location_for_stdc_pragma (true);
if (c_parser_next_token_is_keyword (parser, RID_LABEL))
{
- location_t err_loc = c_parser_peek_token (parser)->location;
/* Read zero or more forward-declarations for labels that nested
functions can jump to. */
mark_valid_location_for_stdc_pragma (false);
while (c_parser_next_token_is_keyword (parser, RID_LABEL))
{
+ label_loc = c_parser_peek_token (parser)->location;
c_parser_consume_token (parser);
/* Any identifiers, including those declared as type names,
are OK here. */
@@ -3399,7 +3413,7 @@ c_parser_compound_statement_nostart (c_parser *parser)
label
= declare_label (c_parser_peek_token (parser)->value);
C_DECLARED_LABEL_FLAG (label) = 1;
- add_stmt (build_stmt (DECL_EXPR, label));
+ add_stmt (build_stmt (label_loc, DECL_EXPR, label));
c_parser_consume_token (parser);
if (c_parser_next_token_is (parser, CPP_COMMA))
c_parser_consume_token (parser);
@@ -3408,7 +3422,7 @@ c_parser_compound_statement_nostart (c_parser *parser)
}
c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
}
- pedwarn (err_loc, OPT_pedantic, "ISO C forbids label declarations");
+ pedwarn (label_loc, OPT_pedantic, "ISO C forbids label declarations");
}
/* We must now have at least one statement, label or declaration. */
if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
@@ -3559,14 +3573,14 @@ c_parser_label (c_parser *parser)
if (c_parser_next_token_is (parser, CPP_COLON))
{
c_parser_consume_token (parser);
- label = do_case (exp1, NULL_TREE);
+ label = do_case (loc1, exp1, NULL_TREE);
}
else if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
{
c_parser_consume_token (parser);
exp2 = c_parser_expr_no_commas (parser, NULL).value;
if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
- label = do_case (exp1, exp2);
+ label = do_case (loc1, exp1, exp2);
}
else
c_parser_error (parser, "expected %<:%> or %<...%>");
@@ -3575,7 +3589,7 @@ c_parser_label (c_parser *parser)
{
c_parser_consume_token (parser);
if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
- label = do_case (NULL_TREE, NULL_TREE);
+ label = do_case (loc1, NULL_TREE, NULL_TREE);
}
else
{
@@ -3592,12 +3606,11 @@ c_parser_label (c_parser *parser)
if (tlab)
{
decl_attributes (&tlab, attrs, 0);
- label = add_stmt (build_stmt (LABEL_EXPR, tlab));
+ label = add_stmt (build_stmt (loc1, LABEL_EXPR, tlab));
}
}
if (label)
{
- SET_EXPR_LOCATION (label, loc1);
if (c_parser_next_token_starts_declspecs (parser)
&& !(c_parser_next_token_is (parser, CPP_NAME)
&& c_parser_peek_2nd_token (parser)->type == CPP_COLON))
@@ -3756,36 +3769,38 @@ c_parser_statement_after_labels (c_parser *parser)
c_parser_consume_token (parser);
if (c_parser_next_token_is (parser, CPP_NAME))
{
- stmt = c_finish_goto_label (c_parser_peek_token (parser)->value);
+ stmt = c_finish_goto_label (loc,
+ c_parser_peek_token (parser)->value);
c_parser_consume_token (parser);
}
else if (c_parser_next_token_is (parser, CPP_MULT))
{
c_parser_consume_token (parser);
- stmt = c_finish_goto_ptr (c_parser_expression (parser).value);
+ stmt = c_finish_goto_ptr (loc,
+ c_parser_expression (parser).value);
}
else
c_parser_error (parser, "expected identifier or %<*%>");
goto expect_semicolon;
case RID_CONTINUE:
c_parser_consume_token (parser);
- stmt = c_finish_bc_stmt (&c_cont_label, false);
+ stmt = c_finish_bc_stmt (loc, &c_cont_label, false);
goto expect_semicolon;
case RID_BREAK:
c_parser_consume_token (parser);
- stmt = c_finish_bc_stmt (&c_break_label, true);
+ stmt = c_finish_bc_stmt (loc, &c_break_label, true);
goto expect_semicolon;
case RID_RETURN:
c_parser_consume_token (parser);
if (c_parser_next_token_is (parser, CPP_SEMICOLON))
{
- stmt = c_finish_return (NULL_TREE, NULL_TREE);
+ stmt = c_finish_return (loc, NULL_TREE, NULL_TREE);
c_parser_consume_token (parser);
}
else
{
struct c_expr expr = c_parser_expression_conv (parser);
- stmt = c_finish_return (expr.value, expr.original_type);
+ stmt = c_finish_return (loc, expr.value, expr.original_type);
goto expect_semicolon;
}
break;
@@ -3797,14 +3812,14 @@ c_parser_statement_after_labels (c_parser *parser)
c_parser_consume_token (parser);
if (c_parser_next_token_is (parser, CPP_SEMICOLON))
{
- stmt = objc_build_throw_stmt (NULL_TREE);
+ stmt = objc_build_throw_stmt (loc, NULL_TREE);
c_parser_consume_token (parser);
}
else
{
tree expr = c_parser_expression (parser).value;
expr = c_fully_fold (expr, false, NULL);
- stmt = objc_build_throw_stmt (expr);
+ stmt = objc_build_throw_stmt (loc, expr);
goto expect_semicolon;
}
break;
@@ -3837,7 +3852,7 @@ c_parser_statement_after_labels (c_parser *parser)
break;
default:
expr_stmt:
- stmt = c_finish_expr_stmt (c_parser_expression_conv (parser).value);
+ stmt = c_finish_expr_stmt (loc, c_parser_expression_conv (parser).value);
expect_semicolon:
c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
break;
@@ -3852,7 +3867,9 @@ c_parser_statement_after_labels (c_parser *parser)
(recursively) all of the component statements should already have
line numbers assigned. ??? Can we discard no-op statements
earlier? */
- protected_set_expr_location (stmt, loc);
+ if (CAN_HAVE_LOCATION_P (stmt)
+ && EXPR_LOCATION (stmt) == UNKNOWN_LOCATION)
+ SET_EXPR_LOCATION (stmt, loc);
parser->in_if_block = in_if_block;
}
@@ -3862,9 +3879,8 @@ c_parser_statement_after_labels (c_parser *parser)
static tree
c_parser_condition (c_parser *parser)
{
- location_t loc;
+ location_t loc = c_parser_peek_token (parser)->location;
tree cond;
- loc = c_parser_peek_token (parser)->location;
cond = c_parser_expression_conv (parser).value;
cond = c_objc_common_truthvalue_conversion (loc, cond);
cond = c_fully_fold (cond, false, NULL);
@@ -3895,8 +3911,9 @@ static tree
c_parser_c99_block_statement (c_parser *parser)
{
tree block = c_begin_compound_stmt (flag_isoc99);
+ location_t loc = c_parser_peek_token (parser)->location;
c_parser_statement (parser);
- return c_end_compound_stmt (block, flag_isoc99);
+ return c_end_compound_stmt (loc, block, flag_isoc99);
}
/* Parse the body of an if statement. This is just parsing a
@@ -3911,6 +3928,7 @@ static tree
c_parser_if_body (c_parser *parser, bool *if_p)
{
tree block = c_begin_compound_stmt (flag_isoc99);
+ location_t body_loc = c_parser_peek_token (parser)->location;
while (c_parser_next_token_is_keyword (parser, RID_CASE)
|| c_parser_next_token_is_keyword (parser, RID_DEFAULT)
|| (c_parser_next_token_is (parser, CPP_NAME)
@@ -3920,7 +3938,7 @@ c_parser_if_body (c_parser *parser, bool *if_p)
if (c_parser_next_token_is (parser, CPP_SEMICOLON))
{
location_t loc = c_parser_peek_token (parser)->location;
- add_stmt (build_empty_stmt ());
+ add_stmt (build_empty_stmt (loc));
c_parser_consume_token (parser);
if (!c_parser_next_token_is_keyword (parser, RID_ELSE))
warning_at (loc, OPT_Wempty_body,
@@ -3930,7 +3948,7 @@ c_parser_if_body (c_parser *parser, bool *if_p)
add_stmt (c_parser_compound_statement (parser));
else
c_parser_statement_after_labels (parser);
- return c_end_compound_stmt (block, flag_isoc99);
+ return c_end_compound_stmt (body_loc, block, flag_isoc99);
}
/* Parse the else body of an if statement. This is just parsing a
@@ -3940,6 +3958,7 @@ c_parser_if_body (c_parser *parser, bool *if_p)
static tree
c_parser_else_body (c_parser *parser)
{
+ location_t else_loc = c_parser_peek_token (parser)->location;
tree block = c_begin_compound_stmt (flag_isoc99);
while (c_parser_next_token_is_keyword (parser, RID_CASE)
|| c_parser_next_token_is_keyword (parser, RID_DEFAULT)
@@ -3948,15 +3967,16 @@ c_parser_else_body (c_parser *parser)
c_parser_label (parser);
if (c_parser_next_token_is (parser, CPP_SEMICOLON))
{
- warning_at (c_parser_peek_token (parser)->location,
+ location_t loc = c_parser_peek_token (parser)->location;
+ warning_at (loc,
OPT_Wempty_body,
"suggest braces around empty body in an %<else%> statement");
- add_stmt (build_empty_stmt ());
+ add_stmt (build_empty_stmt (loc));
c_parser_consume_token (parser);
}
else
c_parser_statement_after_labels (parser);
- return c_end_compound_stmt (block, flag_isoc99);
+ return c_end_compound_stmt (else_loc, block, flag_isoc99);
}
/* Parse an if statement (C90 6.6.4, C99 6.8.4).
@@ -3993,7 +4013,7 @@ c_parser_if_statement (c_parser *parser)
else
second_body = NULL_TREE;
c_finish_if_stmt (loc, cond, first_body, second_body, first_if);
- add_stmt (c_end_compound_stmt (block, flag_isoc99));
+ add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
}
/* Parse a switch statement (C90 6.6.4, C99 6.8.4).
@@ -4006,25 +4026,36 @@ static void
c_parser_switch_statement (c_parser *parser)
{
tree block, expr, body, save_break;
+ location_t switch_loc = c_parser_peek_token (parser)->location;
+ location_t switch_cond_loc;
gcc_assert (c_parser_next_token_is_keyword (parser, RID_SWITCH));
c_parser_consume_token (parser);
block = c_begin_compound_stmt (flag_isoc99);
if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
{
+ switch_cond_loc = c_parser_peek_token (parser)->location;
expr = c_parser_expression (parser).value;
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
}
else
- expr = error_mark_node;
- c_start_case (expr);
+ {
+ switch_cond_loc = UNKNOWN_LOCATION;
+ expr = error_mark_node;
+ }
+ c_start_case (switch_loc, switch_cond_loc, expr);
save_break = c_break_label;
c_break_label = NULL_TREE;
body = c_parser_c99_block_statement (parser);
c_finish_case (body);
if (c_break_label)
- add_stmt (build1 (LABEL_EXPR, void_type_node, c_break_label));
+ {
+ location_t here = c_parser_peek_token (parser)->location;
+ tree t = build1 (LABEL_EXPR, void_type_node, c_break_label);
+ SET_EXPR_LOCATION (t, here);
+ add_stmt (t);
+ }
c_break_label = save_break;
- add_stmt (c_end_compound_stmt (block, flag_isoc99));
+ add_stmt (c_end_compound_stmt (switch_loc, block, flag_isoc99));
}
/* Parse a while statement (C90 6.6.5, C99 6.8.5).
@@ -4049,7 +4080,7 @@ c_parser_while_statement (c_parser *parser)
c_cont_label = NULL_TREE;
body = c_parser_c99_block_statement (parser);
c_finish_loop (loc, cond, NULL, body, c_break_label, c_cont_label, true);
- add_stmt (c_end_compound_stmt (block, flag_isoc99));
+ add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
c_break_label = save_break;
c_cont_label = save_cont;
}
@@ -4087,7 +4118,7 @@ c_parser_do_statement (c_parser *parser)
if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
c_parser_skip_to_end_of_block_or_statement (parser);
c_finish_loop (loc, cond, NULL, body, new_break, new_cont, false);
- add_stmt (c_end_compound_stmt (block, flag_isoc99));
+ add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
}
/* Parse a for statement (C90 6.6.5, C99 6.8.5).
@@ -4110,9 +4141,9 @@ static void
c_parser_for_statement (c_parser *parser)
{
tree block, cond, incr, save_break, save_cont, body;
- location_t loc;
+ location_t loc = c_parser_peek_token (parser)->location;
+ location_t for_loc = c_parser_peek_token (parser)->location;
gcc_assert (c_parser_next_token_is_keyword (parser, RID_FOR));
- loc = c_parser_peek_token (parser)->location;
c_parser_consume_token (parser);
block = c_begin_compound_stmt (flag_isoc99);
if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
@@ -4121,12 +4152,12 @@ c_parser_for_statement (c_parser *parser)
if (c_parser_next_token_is (parser, CPP_SEMICOLON))
{
c_parser_consume_token (parser);
- c_finish_expr_stmt (NULL_TREE);
+ c_finish_expr_stmt (loc, NULL_TREE);
}
else if (c_parser_next_token_starts_declspecs (parser))
{
c_parser_declaration_or_fndef (parser, true, true, true, true);
- check_for_loop_decls ();
+ check_for_loop_decls (for_loc);
}
else if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
{
@@ -4145,7 +4176,7 @@ c_parser_for_statement (c_parser *parser)
c_parser_consume_token (parser);
c_parser_declaration_or_fndef (parser, true, true, true, true);
restore_extension_diagnostics (ext);
- check_for_loop_decls ();
+ check_for_loop_decls (for_loc);
}
else
goto init_expr;
@@ -4153,7 +4184,7 @@ c_parser_for_statement (c_parser *parser)
else
{
init_expr:
- c_finish_expr_stmt (c_parser_expression (parser).value);
+ c_finish_expr_stmt (loc, c_parser_expression (parser).value);
c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
}
/* Parse the loop condition. */
@@ -4169,9 +4200,9 @@ c_parser_for_statement (c_parser *parser)
}
/* Parse the increment expression. */
if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
- incr = c_process_expr_stmt (NULL_TREE);
+ incr = c_process_expr_stmt (loc, NULL_TREE);
else
- incr = c_process_expr_stmt (c_parser_expression (parser).value);
+ incr = c_process_expr_stmt (loc, c_parser_expression (parser).value);
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
}
else
@@ -4185,7 +4216,7 @@ c_parser_for_statement (c_parser *parser)
c_cont_label = NULL_TREE;
body = c_parser_c99_block_statement (parser);
c_finish_loop (loc, cond, incr, body, c_break_label, c_cont_label, true);
- add_stmt (c_end_compound_stmt (block, flag_isoc99));
+ add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
c_break_label = save_break;
c_cont_label = save_cont;
}
@@ -4211,6 +4242,7 @@ c_parser_asm_statement (c_parser *parser)
{
tree quals, str, outputs, inputs, clobbers, ret;
bool simple;
+ location_t asm_loc = c_parser_peek_token (parser)->location;
gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
c_parser_consume_token (parser);
if (c_parser_next_token_is_keyword (parser, RID_VOLATILE))
@@ -4306,7 +4338,7 @@ c_parser_asm_statement (c_parser *parser)
}
if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
c_parser_skip_to_end_of_block_or_statement (parser);
- ret = build_asm_stmt (quals, build_asm_expr (str, outputs, inputs,
+ ret = build_asm_stmt (quals, build_asm_expr (asm_loc, str, outputs, inputs,
clobbers, simple));
return ret;
}
@@ -4328,6 +4360,7 @@ static tree
c_parser_asm_operands (c_parser *parser, bool convert_p)
{
tree list = NULL_TREE;
+ location_t loc;
while (true)
{
tree name, str;
@@ -4362,9 +4395,10 @@ c_parser_asm_operands (c_parser *parser, bool convert_p)
parser->lex_untranslated_string = true;
return NULL_TREE;
}
+ loc = c_parser_peek_token (parser)->location;
expr = c_parser_expression (parser);
if (convert_p)
- expr = default_function_array_conversion (expr);
+ expr = default_function_array_conversion (loc, expr);
expr.value = c_fully_fold (expr.value, false, NULL);
parser->lex_untranslated_string = true;
if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
@@ -4429,7 +4463,7 @@ c_parser_expr_no_commas (c_parser *parser, struct c_expr *after)
{
struct c_expr lhs, rhs, ret;
enum tree_code code;
- location_t op_location;
+ location_t op_location, exp_location;
gcc_assert (!after || c_dialect_objc ());
lhs = c_parser_conditional_expression (parser, after);
op_location = c_parser_peek_token (parser)->location;
@@ -4472,10 +4506,12 @@ c_parser_expr_no_commas (c_parser *parser, struct c_expr *after)
return lhs;
}
c_parser_consume_token (parser);
+ exp_location = c_parser_peek_token (parser)->location;
rhs = c_parser_expr_no_commas (parser, NULL);
- rhs = default_function_array_conversion (rhs);
+ rhs = default_function_array_conversion (exp_location, rhs);
ret.value = build_modify_expr (op_location, lhs.value, lhs.original_type,
- code, rhs.value, rhs.original_type);
+ code, exp_location, rhs.value,
+ rhs.original_type);
if (code == NOP_EXPR)
ret.original_code = MODIFY_EXPR;
else
@@ -4505,16 +4541,16 @@ static struct c_expr
c_parser_conditional_expression (c_parser *parser, struct c_expr *after)
{
struct c_expr cond, exp1, exp2, ret;
- location_t cond_loc;
+ location_t cond_loc, colon_loc;
gcc_assert (!after || c_dialect_objc ());
- cond_loc = c_parser_peek_token (parser)->location;
cond = c_parser_binary_expression (parser, after);
if (c_parser_next_token_is_not (parser, CPP_QUERY))
return cond;
- cond = default_function_array_conversion (cond);
+ cond_loc = c_parser_peek_token (parser)->location;
+ cond = default_function_array_conversion (cond_loc, cond);
c_parser_consume_token (parser);
if (c_parser_next_token_is (parser, CPP_COLON))
{
@@ -4532,30 +4568,36 @@ c_parser_conditional_expression (c_parser *parser, struct c_expr *after)
exp1.value = build1 (EXCESS_PRECISION_EXPR, eptype, exp1.value);
exp1.original_type = NULL;
cond.value = c_objc_common_truthvalue_conversion (cond_loc, exp1.value);
- skip_evaluation += cond.value == truthvalue_true_node;
+ c_inhibit_evaluation_warnings += cond.value == truthvalue_true_node;
}
else
{
cond.value
= c_objc_common_truthvalue_conversion
(cond_loc, default_conversion (cond.value));
- skip_evaluation += cond.value == truthvalue_false_node;
+ c_inhibit_evaluation_warnings += cond.value == truthvalue_false_node;
exp1 = c_parser_expression_conv (parser);
- skip_evaluation += ((cond.value == truthvalue_true_node)
- - (cond.value == truthvalue_false_node));
+ c_inhibit_evaluation_warnings +=
+ ((cond.value == truthvalue_true_node)
+ - (cond.value == truthvalue_false_node));
}
+
+ colon_loc = c_parser_peek_token (parser)->location;
if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
{
- skip_evaluation -= cond.value == truthvalue_true_node;
+ c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
ret.value = error_mark_node;
ret.original_code = ERROR_MARK;
ret.original_type = NULL;
return ret;
}
- exp2 = c_parser_conditional_expression (parser, NULL);
- exp2 = default_function_array_conversion (exp2);
- skip_evaluation -= cond.value == truthvalue_true_node;
- ret.value = build_conditional_expr (cond.value,
+ {
+ location_t exp2_loc = c_parser_peek_token (parser)->location;
+ exp2 = c_parser_conditional_expression (parser, NULL);
+ exp2 = default_function_array_conversion (exp2_loc, exp2);
+ }
+ c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
+ ret.value = build_conditional_expr (colon_loc, cond.value,
cond.original_code == C_MAYBE_CONST_EXPR,
exp1.value, exp2.value);
ret.original_code = ERROR_MARK;
@@ -4655,8 +4697,8 @@ c_parser_binary_expression (c_parser *parser, struct c_expr *after)
the stack has lower precedence than the new operator or there is
only one element on the stack; then the top expression is the LHS
of the new operator. In the case of logical AND and OR
- expressions, we also need to adjust skip_evaluation as
- appropriate when the operators are pushed and popped. */
+ expressions, we also need to adjust c_inhibit_evaluation_warnings
+ as appropriate when the operators are pushed and popped. */
/* The precedence levels, where 0 is a dummy lowest level used for
the bottom of the stack. */
@@ -4693,18 +4735,21 @@ c_parser_binary_expression (c_parser *parser, struct c_expr *after)
switch (stack[sp].op) \
{ \
case TRUTH_ANDIF_EXPR: \
- skip_evaluation -= stack[sp - 1].expr.value == truthvalue_false_node; \
+ c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
+ == truthvalue_false_node); \
break; \
case TRUTH_ORIF_EXPR: \
- skip_evaluation -= stack[sp - 1].expr.value == truthvalue_true_node; \
+ c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
+ == truthvalue_true_node); \
break; \
default: \
break; \
} \
stack[sp - 1].expr \
- = default_function_array_conversion (stack[sp - 1].expr); \
+ = default_function_array_conversion (stack[sp - 1].loc, \
+ stack[sp - 1].expr); \
stack[sp].expr \
- = default_function_array_conversion (stack[sp].expr); \
+ = default_function_array_conversion (stack[sp].loc, stack[sp].expr); \
stack[sp - 1].expr = parser_build_binary_op (stack[sp].loc, \
stack[sp].op, \
stack[sp - 1].expr, \
@@ -4809,17 +4854,21 @@ c_parser_binary_expression (c_parser *parser, struct c_expr *after)
{
case TRUTH_ANDIF_EXPR:
stack[sp].expr
- = default_function_array_conversion (stack[sp].expr);
+ = default_function_array_conversion (stack[sp].loc,
+ stack[sp].expr);
stack[sp].expr.value = c_objc_common_truthvalue_conversion
(stack[sp].loc, default_conversion (stack[sp].expr.value));
- skip_evaluation += stack[sp].expr.value == truthvalue_false_node;
+ c_inhibit_evaluation_warnings += (stack[sp].expr.value
+ == truthvalue_false_node);
break;
case TRUTH_ORIF_EXPR:
stack[sp].expr
- = default_function_array_conversion (stack[sp].expr);
+ = default_function_array_conversion (stack[sp].loc,
+ stack[sp].expr);
stack[sp].expr.value = c_objc_common_truthvalue_conversion
(stack[sp].loc, default_conversion (stack[sp].expr.value));
- skip_evaluation += stack[sp].expr.value == truthvalue_true_node;
+ c_inhibit_evaluation_warnings += (stack[sp].expr.value
+ == truthvalue_true_node);
break;
default:
break;
@@ -4829,6 +4878,7 @@ c_parser_binary_expression (c_parser *parser, struct c_expr *after)
stack[sp].expr = c_parser_cast_expression (parser, NULL);
stack[sp].prec = oprec;
stack[sp].op = ocode;
+ stack[sp].loc = binary_loc;
}
out:
while (sp > 0)
@@ -4849,9 +4899,11 @@ c_parser_binary_expression (c_parser *parser, struct c_expr *after)
static struct c_expr
c_parser_cast_expression (c_parser *parser, struct c_expr *after)
{
+ location_t cast_loc = c_parser_peek_token (parser)->location;
gcc_assert (!after || c_dialect_objc ());
if (after)
- return c_parser_postfix_expression_after_primary (parser, *after);
+ return c_parser_postfix_expression_after_primary (parser,
+ cast_loc, *after);
/* If the expression begins with a parenthesized type name, it may
be either a cast or a compound literal; we need to see whether
the next character is '{' to tell the difference. If not, it is
@@ -4859,12 +4911,10 @@ c_parser_cast_expression (c_parser *parser, struct c_expr *after)
if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
&& c_token_starts_typename (c_parser_peek_2nd_token (parser)))
{
- location_t loc;
struct c_type_name *type_name;
struct c_expr ret;
struct c_expr expr;
c_parser_consume_token (parser);
- loc = c_parser_peek_token (parser)->location;
type_name = c_parser_type_name (parser);
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
if (type_name == NULL)
@@ -4880,10 +4930,13 @@ c_parser_cast_expression (c_parser *parser, struct c_expr *after)
if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
return c_parser_postfix_expression_after_paren_type (parser, type_name,
- loc);
- expr = c_parser_cast_expression (parser, NULL);
- expr = default_function_array_conversion (expr);
- ret.value = c_cast_expr (type_name, expr.value, loc);
+ cast_loc);
+ {
+ location_t expr_loc = c_parser_peek_token (parser)->location;
+ expr = c_parser_cast_expression (parser, NULL);
+ expr = default_function_array_conversion (expr_loc, expr);
+ }
+ ret.value = c_cast_expr (cast_loc, type_name, expr.value);
ret.original_code = ERROR_MARK;
ret.original_type = NULL;
return ret;
@@ -4924,63 +4977,70 @@ c_parser_unary_expression (c_parser *parser)
{
int ext;
struct c_expr ret, op;
- location_t loc = c_parser_peek_token (parser)->location;
+ location_t op_loc = c_parser_peek_token (parser)->location;
+ location_t exp_loc;
ret.original_code = ERROR_MARK;
ret.original_type = NULL;
switch (c_parser_peek_token (parser)->type)
{
case CPP_PLUS_PLUS:
c_parser_consume_token (parser);
+ exp_loc = c_parser_peek_token (parser)->location;
op = c_parser_cast_expression (parser, NULL);
- op = default_function_array_conversion (op);
- return parser_build_unary_op (PREINCREMENT_EXPR, op, loc);
+ op = default_function_array_conversion (exp_loc, op);
+ return parser_build_unary_op (op_loc, PREINCREMENT_EXPR, op);
case CPP_MINUS_MINUS:
c_parser_consume_token (parser);
+ exp_loc = c_parser_peek_token (parser)->location;
op = c_parser_cast_expression (parser, NULL);
- op = default_function_array_conversion (op);
- return parser_build_unary_op (PREDECREMENT_EXPR, op, loc);
+ op = default_function_array_conversion (exp_loc, op);
+ return parser_build_unary_op (op_loc, PREDECREMENT_EXPR, op);
case CPP_AND:
c_parser_consume_token (parser);
- return parser_build_unary_op (ADDR_EXPR,
- c_parser_cast_expression (parser, NULL),
- loc);
+ return parser_build_unary_op (op_loc, ADDR_EXPR,
+ c_parser_cast_expression (parser, NULL));
case CPP_MULT:
c_parser_consume_token (parser);
+ exp_loc = c_parser_peek_token (parser)->location;
op = c_parser_cast_expression (parser, NULL);
- op = default_function_array_conversion (op);
- ret.value = build_indirect_ref (loc, op.value, "unary *");
+ op = default_function_array_conversion (exp_loc, op);
+ ret.value = build_indirect_ref (op_loc, op.value, "unary *");
return ret;
case CPP_PLUS:
if (!c_dialect_objc () && !in_system_header)
- warning_at (c_parser_peek_token (parser)->location,
+ warning_at (op_loc,
OPT_Wtraditional,
"traditional C rejects the unary plus operator");
c_parser_consume_token (parser);
+ exp_loc = c_parser_peek_token (parser)->location;
op = c_parser_cast_expression (parser, NULL);
- op = default_function_array_conversion (op);
- return parser_build_unary_op (CONVERT_EXPR, op, loc);
+ op = default_function_array_conversion (exp_loc, op);
+ return parser_build_unary_op (op_loc, CONVERT_EXPR, op);
case CPP_MINUS:
c_parser_consume_token (parser);
+ exp_loc = c_parser_peek_token (parser)->location;
op = c_parser_cast_expression (parser, NULL);
- op = default_function_array_conversion (op);
- return parser_build_unary_op (NEGATE_EXPR, op, loc);
+ op = default_function_array_conversion (exp_loc, op);
+ return parser_build_unary_op (op_loc, NEGATE_EXPR, op);
case CPP_COMPL:
c_parser_consume_token (parser);
+ exp_loc = c_parser_peek_token (parser)->location;
op = c_parser_cast_expression (parser, NULL);
- op = default_function_array_conversion (op);
- return parser_build_unary_op (BIT_NOT_EXPR, op, loc);
+ op = default_function_array_conversion (exp_loc, op);
+ return parser_build_unary_op (op_loc, BIT_NOT_EXPR, op);
case CPP_NOT:
c_parser_consume_token (parser);
+ exp_loc = c_parser_peek_token (parser)->location;
op = c_parser_cast_expression (parser, NULL);
- op = default_function_array_conversion (op);
- return parser_build_unary_op (TRUTH_NOT_EXPR, op, loc);
+ op = default_function_array_conversion (exp_loc, op);
+ return parser_build_unary_op (op_loc, TRUTH_NOT_EXPR, op);
case CPP_AND_AND:
/* Refer to the address of a label as a pointer. */
c_parser_consume_token (parser);
if (c_parser_next_token_is (parser, CPP_NAME))
{
ret.value = finish_label_address_expr
- (c_parser_peek_token (parser)->value, loc);
+ (c_parser_peek_token (parser)->value, op_loc);
c_parser_consume_token (parser);
}
else
@@ -5004,14 +5064,16 @@ c_parser_unary_expression (c_parser *parser)
return ret;
case RID_REALPART:
c_parser_consume_token (parser);
+ exp_loc = c_parser_peek_token (parser)->location;
op = c_parser_cast_expression (parser, NULL);
- op = default_function_array_conversion (op);
- return parser_build_unary_op (REALPART_EXPR, op, loc);
+ op = default_function_array_conversion (exp_loc, op);
+ return parser_build_unary_op (op_loc, REALPART_EXPR, op);
case RID_IMAGPART:
c_parser_consume_token (parser);
+ exp_loc = c_parser_peek_token (parser)->location;
op = c_parser_cast_expression (parser, NULL);
- op = default_function_array_conversion (op);
- return parser_build_unary_op (IMAGPART_EXPR, op, loc);
+ op = default_function_array_conversion (exp_loc, op);
+ return parser_build_unary_op (op_loc, IMAGPART_EXPR, op);
default:
return c_parser_postfix_expression (parser);
}
@@ -5029,7 +5091,7 @@ c_parser_sizeof_expression (c_parser *parser)
location_t expr_loc;
gcc_assert (c_parser_next_token_is_keyword (parser, RID_SIZEOF));
c_parser_consume_token (parser);
- skip_evaluation++;
+ c_inhibit_evaluation_warnings++;
in_sizeof++;
if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
&& c_token_starts_typename (c_parser_peek_2nd_token (parser)))
@@ -5044,7 +5106,7 @@ c_parser_sizeof_expression (c_parser *parser)
if (type_name == NULL)
{
struct c_expr ret;
- skip_evaluation--;
+ c_inhibit_evaluation_warnings--;
in_sizeof--;
ret.value = error_mark_node;
ret.original_code = ERROR_MARK;
@@ -5059,21 +5121,21 @@ c_parser_sizeof_expression (c_parser *parser)
goto sizeof_expr;
}
/* sizeof ( type-name ). */
- skip_evaluation--;
+ c_inhibit_evaluation_warnings--;
in_sizeof--;
- return c_expr_sizeof_type (type_name);
+ return c_expr_sizeof_type (expr_loc, type_name);
}
else
{
expr_loc = c_parser_peek_token (parser)->location;
expr = c_parser_unary_expression (parser);
sizeof_expr:
- skip_evaluation--;
+ c_inhibit_evaluation_warnings--;
in_sizeof--;
if (TREE_CODE (expr.value) == COMPONENT_REF
&& DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
error_at (expr_loc, "%<sizeof%> applied to a bit-field");
- return c_expr_sizeof_expr (expr);
+ return c_expr_sizeof_expr (expr_loc, expr);
}
}
@@ -5083,9 +5145,10 @@ static struct c_expr
c_parser_alignof_expression (c_parser *parser)
{
struct c_expr expr;
+ location_t loc = c_parser_peek_token (parser)->location;
gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNOF));
c_parser_consume_token (parser);
- skip_evaluation++;
+ c_inhibit_evaluation_warnings++;
in_alignof++;
if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
&& c_token_starts_typename (c_parser_peek_2nd_token (parser)))
@@ -5102,7 +5165,7 @@ c_parser_alignof_expression (c_parser *parser)
if (type_name == NULL)
{
struct c_expr ret;
- skip_evaluation--;
+ c_inhibit_evaluation_warnings--;
in_alignof--;
ret.value = error_mark_node;
ret.original_code = ERROR_MARK;
@@ -5117,9 +5180,9 @@ c_parser_alignof_expression (c_parser *parser)
goto alignof_expr;
}
/* alignof ( type-name ). */
- skip_evaluation--;
+ c_inhibit_evaluation_warnings--;
in_alignof--;
- ret.value = c_alignof (groktypename (type_name, NULL, NULL));
+ ret.value = c_alignof (loc, groktypename (type_name, NULL, NULL));
ret.original_code = ERROR_MARK;
ret.original_type = NULL;
return ret;
@@ -5129,9 +5192,9 @@ c_parser_alignof_expression (c_parser *parser)
struct c_expr ret;
expr = c_parser_unary_expression (parser);
alignof_expr:
- skip_evaluation--;
+ c_inhibit_evaluation_warnings--;
in_alignof--;
- ret.value = c_alignof_expr (expr.value);
+ ret.value = c_alignof_expr (loc, expr.value);
ret.original_code = ERROR_MARK;
ret.original_type = NULL;
return ret;
@@ -5196,7 +5259,7 @@ c_parser_postfix_expression (c_parser *parser)
{
struct c_expr expr, e1, e2, e3;
struct c_type_name *t1, *t2;
- location_t loc;
+ location_t loc = c_parser_peek_token (parser)->location;;
expr.original_code = ERROR_MARK;
expr.original_type = NULL;
switch (c_parser_peek_token (parser)->type)
@@ -5242,11 +5305,10 @@ c_parser_postfix_expression (c_parser *parser)
}
{
tree id = c_parser_peek_token (parser)->value;
- location_t loc = c_parser_peek_token (parser)->location;
c_parser_consume_token (parser);
- expr.value = build_external_ref (id,
+ expr.value = build_external_ref (loc, id,
(c_parser_peek_token (parser)->type
- == CPP_OPEN_PAREN), loc,
+ == CPP_OPEN_PAREN),
&expr.original_type);
}
break;
@@ -5257,12 +5319,13 @@ c_parser_postfix_expression (c_parser *parser)
{
/* A statement expression. */
tree stmt;
- location_t here = c_parser_peek_token (parser)->location;
+ location_t brace_loc;
c_parser_consume_token (parser);
+ brace_loc = c_parser_peek_token (parser)->location;
c_parser_consume_token (parser);
if (cur_stmt_list == NULL)
{
- error_at (here, "braced-group within expression allowed "
+ error_at (loc, "braced-group within expression allowed "
"only inside a function");
parser->error = true;
c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
@@ -5274,9 +5337,9 @@ c_parser_postfix_expression (c_parser *parser)
c_parser_compound_statement_nostart (parser);
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
"expected %<)%>");
- pedwarn (here, OPT_pedantic,
+ pedwarn (loc, OPT_pedantic,
"ISO C forbids braced-groups within expressions");
- expr.value = c_finish_stmt_expr (stmt);
+ expr.value = c_finish_stmt_expr (brace_loc, stmt);
}
else if (c_token_starts_typename (c_parser_peek_2nd_token (parser)))
{
@@ -5320,7 +5383,7 @@ c_parser_postfix_expression (c_parser *parser)
case RID_FUNCTION_NAME:
case RID_PRETTY_FUNCTION_NAME:
case RID_C99_FUNCTION_NAME:
- expr.value = fname_decl (c_parser_peek_token (parser)->location,
+ expr.value = fname_decl (loc,
c_parser_peek_token (parser)->keyword,
c_parser_peek_token (parser)->value);
c_parser_consume_token (parser);
@@ -5340,6 +5403,7 @@ c_parser_postfix_expression (c_parser *parser)
expr.value = error_mark_node;
break;
}
+ loc = c_parser_peek_token (parser)->location;
t1 = c_parser_type_name (parser);
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
"expected %<)%>");
@@ -5350,9 +5414,8 @@ c_parser_postfix_expression (c_parser *parser)
else
{
tree type_expr = NULL_TREE;
- expr.value = build_va_arg (e1.value, groktypename (t1,
- &type_expr,
- NULL));
+ expr.value = c_build_va_arg (loc, e1.value,
+ groktypename (t1, &type_expr, NULL));
if (type_expr)
{
expr.value = build2 (C_MAYBE_CONST_EXPR,
@@ -5387,14 +5450,17 @@ c_parser_postfix_expression (c_parser *parser)
if (type == error_mark_node)
offsetof_ref = error_mark_node;
else
- offsetof_ref = build1 (INDIRECT_REF, type, null_pointer_node);
+ {
+ offsetof_ref = build1 (INDIRECT_REF, type, null_pointer_node);
+ SET_EXPR_LOCATION (offsetof_ref, loc);
+ }
/* Parse the second argument to __builtin_offsetof. We
must have one identifier, and beyond that we want to
accept sub structure and sub array references. */
if (c_parser_next_token_is (parser, CPP_NAME))
{
offsetof_ref = build_component_ref
- (offsetof_ref, c_parser_peek_token (parser)->value);
+ (loc, offsetof_ref, c_parser_peek_token (parser)->value);
c_parser_consume_token (parser);
while (c_parser_next_token_is (parser, CPP_DOT)
|| c_parser_next_token_is (parser,
@@ -5405,9 +5471,9 @@ c_parser_postfix_expression (c_parser *parser)
if (c_parser_next_token_is (parser, CPP_DEREF))
{
loc = c_parser_peek_token (parser)->location;
- offsetof_ref = build_array_ref (offsetof_ref,
- integer_zero_node,
- loc);
+ offsetof_ref = build_array_ref (loc,
+ offsetof_ref,
+ integer_zero_node);
goto do_dot;
}
else if (c_parser_next_token_is (parser, CPP_DOT))
@@ -5421,7 +5487,7 @@ c_parser_postfix_expression (c_parser *parser)
break;
}
offsetof_ref = build_component_ref
- (offsetof_ref,
+ (loc, offsetof_ref,
c_parser_peek_token (parser)->value);
c_parser_consume_token (parser);
}
@@ -5434,7 +5500,7 @@ c_parser_postfix_expression (c_parser *parser)
idx = c_fully_fold (idx, false, NULL);
c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
"expected %<]%>");
- offsetof_ref = build_array_ref (offsetof_ref, idx, loc);
+ offsetof_ref = build_array_ref (loc, offsetof_ref, idx);
}
}
}
@@ -5533,7 +5599,7 @@ c_parser_postfix_expression (c_parser *parser)
tree sel = c_parser_objc_selector_arg (parser);
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
"expected %<)%>");
- expr.value = objc_build_selector_expr (sel);
+ expr.value = objc_build_selector_expr (loc, sel);
}
break;
case RID_AT_PROTOCOL:
@@ -5607,7 +5673,7 @@ c_parser_postfix_expression (c_parser *parser)
expr.value = error_mark_node;
break;
}
- return c_parser_postfix_expression_after_primary (parser, expr);
+ return c_parser_postfix_expression_after_primary (parser, loc, expr);
}
/* Parse a postfix expression after a parenthesized type name: the
@@ -5632,7 +5698,7 @@ c_parser_postfix_expression_after_paren_type (c_parser *parser,
location_t start_loc;
tree type_expr = NULL_TREE;
bool type_expr_const = true;
- check_compound_literal_type (type_name, type_loc);
+ check_compound_literal_type (type_loc, type_name);
start_init (NULL_TREE, NULL, 0);
type = groktypename (type_name, &type_expr, &type_expr_const);
start_loc = c_parser_peek_token (parser)->location;
@@ -5651,7 +5717,7 @@ c_parser_postfix_expression_after_paren_type (c_parser *parser,
? CONSTRUCTOR_NON_CONST (init.value)
: init.original_code == C_MAYBE_CONST_EXPR);
non_const |= !type_expr_const;
- expr.value = build_compound_literal (type, init.value, non_const);
+ expr.value = build_compound_literal (start_loc, type, init.value, non_const);
expr.original_code = ERROR_MARK;
expr.original_type = NULL;
if (type_expr)
@@ -5668,33 +5734,35 @@ c_parser_postfix_expression_after_paren_type (c_parser *parser,
type_expr, expr.value);
}
}
- return c_parser_postfix_expression_after_primary (parser, expr);
+ return c_parser_postfix_expression_after_primary (parser, start_loc, expr);
}
/* Parse a postfix expression after the initial primary or compound
- literal; that is, parse a series of postfix operators. */
+ literal; that is, parse a series of postfix operators.
+
+ EXPR_LOC is the location of the primary expression. */
static struct c_expr
c_parser_postfix_expression_after_primary (c_parser *parser,
+ location_t expr_loc,
struct c_expr expr)
{
struct c_expr orig_expr;
tree ident, idx;
VEC(tree,gc) *exprlist;
VEC(tree,gc) *origtypes;
- location_t loc = c_parser_peek_token (parser)->location;
while (true)
{
+ location_t op_loc = c_parser_peek_token (parser)->location;
switch (c_parser_peek_token (parser)->type)
{
case CPP_OPEN_SQUARE:
/* Array reference. */
- loc = c_parser_peek_token (parser)->location;
c_parser_consume_token (parser);
idx = c_parser_expression (parser).value;
c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
"expected %<]%>");
- expr.value = build_array_ref (expr.value, idx, loc);
+ expr.value = build_array_ref (op_loc, expr.value, idx);
expr.original_code = ERROR_MARK;
expr.original_type = NULL;
break;
@@ -5708,7 +5776,9 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
"expected %<)%>");
orig_expr = expr;
- expr.value = build_function_call_vec (expr.value, exprlist,
+ /* FIXME diagnostics: Ideally we want the FUNCNAME, not the
+ "(" after the FUNCNAME, which is what we have now. */
+ expr.value = build_function_call_vec (op_loc, expr.value, exprlist,
origtypes);
expr.original_code = ERROR_MARK;
if (TREE_CODE (expr.value) == INTEGER_CST
@@ -5719,14 +5789,14 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
expr.original_type = NULL;
if (exprlist != NULL)
{
- c_parser_release_expr_list (exprlist);
- c_parser_release_expr_list (origtypes);
+ release_tree_vector (exprlist);
+ release_tree_vector (origtypes);
}
break;
case CPP_DOT:
/* Structure element reference. */
c_parser_consume_token (parser);
- expr = default_function_array_conversion (expr);
+ expr = default_function_array_conversion (expr_loc, expr);
if (c_parser_next_token_is (parser, CPP_NAME))
ident = c_parser_peek_token (parser)->value;
else
@@ -5738,7 +5808,7 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
return expr;
}
c_parser_consume_token (parser);
- expr.value = build_component_ref (expr.value, ident);
+ expr.value = build_component_ref (op_loc, expr.value, ident);
expr.original_code = ERROR_MARK;
if (TREE_CODE (expr.value) != COMPONENT_REF)
expr.original_type = NULL;
@@ -5755,7 +5825,7 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
case CPP_DEREF:
/* Structure element reference. */
c_parser_consume_token (parser);
- expr = default_function_array_conversion (expr);
+ expr = default_function_array_conversion (expr_loc, expr);
if (c_parser_next_token_is (parser, CPP_NAME))
ident = c_parser_peek_token (parser)->value;
else
@@ -5767,7 +5837,8 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
return expr;
}
c_parser_consume_token (parser);
- expr.value = build_component_ref (build_indirect_ref (loc,
+ expr.value = build_component_ref (op_loc,
+ build_indirect_ref (op_loc,
expr.value,
"->"),
ident);
@@ -5787,8 +5858,8 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
case CPP_PLUS_PLUS:
/* Postincrement. */
c_parser_consume_token (parser);
- expr = default_function_array_conversion (expr);
- expr.value = build_unary_op (loc,
+ expr = default_function_array_conversion (expr_loc, expr);
+ expr.value = build_unary_op (op_loc,
POSTINCREMENT_EXPR, expr.value, 0);
expr.original_code = ERROR_MARK;
expr.original_type = NULL;
@@ -5796,8 +5867,8 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
case CPP_MINUS_MINUS:
/* Postdecrement. */
c_parser_consume_token (parser);
- expr = default_function_array_conversion (expr);
- expr.value = build_unary_op (loc,
+ expr = default_function_array_conversion (expr_loc, expr);
+ expr.value = build_unary_op (op_loc,
POSTDECREMENT_EXPR, expr.value, 0);
expr.original_code = ERROR_MARK;
expr.original_type = NULL;
@@ -5823,10 +5894,13 @@ c_parser_expression (c_parser *parser)
while (c_parser_next_token_is (parser, CPP_COMMA))
{
struct c_expr next;
+ location_t loc = c_parser_peek_token (parser)->location;
+ location_t expr_loc;
c_parser_consume_token (parser);
+ expr_loc = c_parser_peek_token (parser)->location;
next = c_parser_expr_no_commas (parser, NULL);
- next = default_function_array_conversion (next);
- expr.value = build_compound_expr (expr.value, next.value);
+ next = default_function_array_conversion (expr_loc, next);
+ expr.value = build_compound_expr (loc, expr.value, next.value);
expr.original_code = COMPOUND_EXPR;
expr.original_type = next.original_type;
}
@@ -5840,8 +5914,9 @@ static struct c_expr
c_parser_expression_conv (c_parser *parser)
{
struct c_expr expr;
+ location_t loc = c_parser_peek_token (parser)->location;
expr = c_parser_expression (parser);
- expr = default_function_array_conversion (expr);
+ expr = default_function_array_conversion (loc, expr);
return expr;
}
@@ -5853,10 +5928,6 @@ c_parser_expression_conv (c_parser *parser)
nonempty-expr-list , assignment-expression
*/
-/* We cache two vectors, to save most allocation and deallocation. */
-static GTY((deletable)) VEC(tree,gc) *cached_expr_list_1;
-static GTY((deletable)) VEC(tree,gc) *cached_expr_list_2;
-
static VEC(tree,gc) *
c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p,
VEC(tree,gc) **p_orig_types)
@@ -5864,39 +5935,17 @@ c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p,
VEC(tree,gc) *ret;
VEC(tree,gc) *orig_types;
struct c_expr expr;
+ location_t loc = c_parser_peek_token (parser)->location;
- if (cached_expr_list_1 != NULL)
- {
- ret = cached_expr_list_1;
- cached_expr_list_1 = NULL;
- VEC_truncate (tree, ret, 0);
- }
- else if (cached_expr_list_2 != NULL)
- {
- ret = cached_expr_list_2;
- cached_expr_list_2 = NULL;
- VEC_truncate (tree, ret, 0);
- }
- else
- ret = VEC_alloc (tree, gc, 16);
-
+ ret = make_tree_vector ();
if (p_orig_types == NULL)
orig_types = NULL;
else
- {
- if (cached_expr_list_2 != NULL)
- {
- orig_types = cached_expr_list_2;
- cached_expr_list_2 = NULL;
- VEC_truncate (tree, orig_types, 0);
- }
- else
- orig_types = VEC_alloc (tree, gc, 16);
- }
+ orig_types = make_tree_vector ();
expr = c_parser_expr_no_commas (parser, NULL);
if (convert_p)
- expr = default_function_array_conversion (expr);
+ expr = default_function_array_conversion (loc, expr);
if (fold_p)
expr.value = c_fully_fold (expr.value, false, NULL);
VEC_quick_push (tree, ret, expr.value);
@@ -5905,9 +5954,10 @@ c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p,
while (c_parser_next_token_is (parser, CPP_COMMA))
{
c_parser_consume_token (parser);
+ loc = c_parser_peek_token (parser)->location;
expr = c_parser_expr_no_commas (parser, NULL);
if (convert_p)
- expr = default_function_array_conversion (expr);
+ expr = default_function_array_conversion (loc, expr);
if (fold_p)
expr.value = c_fully_fold (expr.value, false, NULL);
VEC_safe_push (tree, gc, ret, expr.value);
@@ -5918,37 +5968,6 @@ c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p,
*p_orig_types = orig_types;
return ret;
}
-
-/* Release a vector returned by c_parser_expr_list. */
-
-static void
-c_parser_release_expr_list (VEC(tree,gc) *vec)
-{
- if (cached_expr_list_1 == NULL)
- cached_expr_list_1 = vec;
- else if (cached_expr_list_2 == NULL)
- cached_expr_list_2 = vec;
- else
- VEC_free (tree, gc, vec);
-}
-
-/* Convert a vector, as returned by c_parser_expr_list, to a
- tree_list. */
-
-static tree
-c_parser_vec_to_tree_list (VEC(tree,gc) *vec)
-{
- tree ret = NULL_TREE;
- tree *pp = &ret;
- unsigned int i;
- tree t;
- for (i = 0; VEC_iterate (tree, vec, i, t); ++i)
- {
- *pp = build_tree_list (NULL, t);
- pp = &TREE_CHAIN (*pp);
- }
- return ret;
-}
/* Parse Objective-C-specific constructs. */
@@ -6830,9 +6849,9 @@ c_parser_objc_keywordexpr (c_parser *parser)
else
{
/* We have a comma expression, we will collapse later. */
- ret = c_parser_vec_to_tree_list (expr_list);
+ ret = build_tree_list_vec (expr_list);
}
- c_parser_release_expr_list (expr_list);
+ release_tree_vector (expr_list);
return ret;
}
@@ -7055,7 +7074,8 @@ check_no_duplicate_clause (tree clauses, enum omp_clause_code code,
for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
if (OMP_CLAUSE_CODE (c) == code)
{
- error ("too many %qs clauses", name);
+ location_t loc = OMP_CLAUSE_LOCATION (c);
+ error_at (loc, "too many %qs clauses", name);
break;
}
}
@@ -7065,14 +7085,17 @@ check_no_duplicate_clause (tree clauses, enum omp_clause_code code,
identifier
variable-list , identifier
- If KIND is nonzero, create the appropriate node and install the decl
- in OMP_CLAUSE_DECL and add the node to the head of the list.
+ If KIND is nonzero, create the appropriate node and install the
+ decl in OMP_CLAUSE_DECL and add the node to the head of the list.
+ If KIND is nonzero, CLAUSE_LOC is the location of the clause.
If KIND is zero, create a TREE_LIST with the decl in TREE_PURPOSE;
return the list created. */
static tree
-c_parser_omp_variable_list (c_parser *parser, enum omp_clause_code kind,
+c_parser_omp_variable_list (c_parser *parser,
+ location_t clause_loc,
+ enum omp_clause_code kind,
tree list)
{
if (c_parser_next_token_is_not (parser, CPP_NAME)
@@ -7085,13 +7108,13 @@ c_parser_omp_variable_list (c_parser *parser, enum omp_clause_code kind,
tree t = lookup_name (c_parser_peek_token (parser)->value);
if (t == NULL_TREE)
- undeclared_variable (c_parser_peek_token (parser)->value,
- c_parser_peek_token (parser)->location);
+ undeclared_variable (c_parser_peek_token (parser)->location,
+ c_parser_peek_token (parser)->value);
else if (t == error_mark_node)
;
else if (kind != 0)
{
- tree u = build_omp_clause (kind);
+ tree u = build_omp_clause (clause_loc, kind);
OMP_CLAUSE_DECL (u) = t;
OMP_CLAUSE_CHAIN (u) = list;
list = u;
@@ -7117,9 +7140,12 @@ static tree
c_parser_omp_var_list_parens (c_parser *parser, enum omp_clause_code kind,
tree list)
{
+ /* The clauses location. */
+ location_t loc = c_parser_peek_token (parser)->location;
+
if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
{
- list = c_parser_omp_variable_list (parser, kind, list);
+ list = c_parser_omp_variable_list (parser, loc, kind, list);
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
}
return list;
@@ -7154,7 +7180,7 @@ c_parser_omp_clause_collapse (c_parser *parser, tree list)
"collapse argument needs positive constant integer expression");
return list;
}
- c = build_omp_clause (OMP_CLAUSE_COLLAPSE);
+ c = build_omp_clause (loc, OMP_CLAUSE_COLLAPSE);
OMP_CLAUSE_COLLAPSE_EXPR (c) = num;
OMP_CLAUSE_CHAIN (c) = list;
return c;
@@ -7185,6 +7211,7 @@ static tree
c_parser_omp_clause_default (c_parser *parser, tree list)
{
enum omp_clause_default_kind kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
+ location_t loc = c_parser_peek_token (parser)->location;
tree c;
if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
@@ -7224,7 +7251,7 @@ c_parser_omp_clause_default (c_parser *parser, tree list)
return list;
check_no_duplicate_clause (list, OMP_CLAUSE_DEFAULT, "default");
- c = build_omp_clause (OMP_CLAUSE_DEFAULT);
+ c = build_omp_clause (loc, OMP_CLAUSE_DEFAULT);
OMP_CLAUSE_CHAIN (c) = list;
OMP_CLAUSE_DEFAULT_KIND (c) = kind;
@@ -7246,6 +7273,7 @@ c_parser_omp_clause_firstprivate (c_parser *parser, tree list)
static tree
c_parser_omp_clause_if (c_parser *parser, tree list)
{
+ location_t loc = c_parser_peek_token (parser)->location;
if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
{
tree t = c_parser_paren_condition (parser);
@@ -7253,7 +7281,7 @@ c_parser_omp_clause_if (c_parser *parser, tree list)
check_no_duplicate_clause (list, OMP_CLAUSE_IF, "if");
- c = build_omp_clause (OMP_CLAUSE_IF);
+ c = build_omp_clause (loc, OMP_CLAUSE_IF);
OMP_CLAUSE_IF_EXPR (c) = t;
OMP_CLAUSE_CHAIN (c) = list;
list = c;
@@ -7280,10 +7308,11 @@ static tree
c_parser_omp_clause_nowait (c_parser *parser ATTRIBUTE_UNUSED, tree list)
{
tree c;
+ location_t loc = c_parser_peek_token (parser)->location;
check_no_duplicate_clause (list, OMP_CLAUSE_NOWAIT, "nowait");
- c = build_omp_clause (OMP_CLAUSE_NOWAIT);
+ c = build_omp_clause (loc, OMP_CLAUSE_NOWAIT);
OMP_CLAUSE_CHAIN (c) = list;
return c;
}
@@ -7294,6 +7323,7 @@ c_parser_omp_clause_nowait (c_parser *parser ATTRIBUTE_UNUSED, tree list)
static tree
c_parser_omp_clause_num_threads (c_parser *parser, tree list)
{
+ location_t num_threads_loc = c_parser_peek_token (parser)->location;
if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
{
location_t expr_loc = c_parser_peek_token (parser)->location;
@@ -7311,6 +7341,8 @@ c_parser_omp_clause_num_threads (c_parser *parser, tree list)
/* Attempt to statically determine when the number isn't positive. */
c = fold_build2 (LE_EXPR, boolean_type_node, t,
build_int_cst (TREE_TYPE (t), 0));
+ if (CAN_HAVE_LOCATION_P (c))
+ SET_EXPR_LOCATION (c, expr_loc);
if (c == boolean_true_node)
{
warning_at (expr_loc, 0,
@@ -7320,7 +7352,7 @@ c_parser_omp_clause_num_threads (c_parser *parser, tree list)
check_no_duplicate_clause (list, OMP_CLAUSE_NUM_THREADS, "num_threads");
- c = build_omp_clause (OMP_CLAUSE_NUM_THREADS);
+ c = build_omp_clause (num_threads_loc, OMP_CLAUSE_NUM_THREADS);
OMP_CLAUSE_NUM_THREADS_EXPR (c) = t;
OMP_CLAUSE_CHAIN (c) = list;
list = c;
@@ -7333,14 +7365,16 @@ c_parser_omp_clause_num_threads (c_parser *parser, tree list)
ordered */
static tree
-c_parser_omp_clause_ordered (c_parser *parser ATTRIBUTE_UNUSED, tree list)
+c_parser_omp_clause_ordered (c_parser *parser, tree list)
{
tree c;
check_no_duplicate_clause (list, OMP_CLAUSE_ORDERED, "ordered");
- c = build_omp_clause (OMP_CLAUSE_ORDERED);
+ c = build_omp_clause (c_parser_peek_token (parser)->location,
+ OMP_CLAUSE_ORDERED);
OMP_CLAUSE_CHAIN (c) = list;
+
return c;
}
@@ -7362,6 +7396,7 @@ c_parser_omp_clause_private (c_parser *parser, tree list)
static tree
c_parser_omp_clause_reduction (c_parser *parser, tree list)
{
+ location_t clause_loc = c_parser_peek_token (parser)->location;
if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
{
enum tree_code code;
@@ -7404,7 +7439,8 @@ c_parser_omp_clause_reduction (c_parser *parser, tree list)
{
tree nl, c;
- nl = c_parser_omp_variable_list (parser, OMP_CLAUSE_REDUCTION, list);
+ nl = c_parser_omp_variable_list (parser, clause_loc,
+ OMP_CLAUSE_REDUCTION, list);
for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
OMP_CLAUSE_REDUCTION_CODE (c) = code;
@@ -7427,11 +7463,12 @@ static tree
c_parser_omp_clause_schedule (c_parser *parser, tree list)
{
tree c, t;
+ location_t loc = c_parser_peek_token (parser)->location;
if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
return list;
- c = build_omp_clause (OMP_CLAUSE_SCHEDULE);
+ c = build_omp_clause (loc, OMP_CLAUSE_SCHEDULE);
if (c_parser_next_token_is (parser, CPP_NAME))
{
@@ -7527,8 +7564,10 @@ c_parser_omp_clause_untied (c_parser *parser ATTRIBUTE_UNUSED, tree list)
/* FIXME: Should we allow duplicates? */
check_no_duplicate_clause (list, OMP_CLAUSE_UNTIED, "untied");
- c = build_omp_clause (OMP_CLAUSE_UNTIED);
+ c = build_omp_clause (c_parser_peek_token (parser)->location,
+ OMP_CLAUSE_UNTIED);
OMP_CLAUSE_CHAIN (c) = list;
+
return c;
}
@@ -7664,10 +7703,12 @@ c_parser_omp_structured_block (c_parser *parser)
binop:
+, *, -, /, &, ^, |, <<, >>
- where x is an lvalue expression with scalar type. */
+ where x is an lvalue expression with scalar type.
+
+ LOC is the location of the #pragma token. */
static void
-c_parser_omp_atomic (c_parser *parser)
+c_parser_omp_atomic (location_t loc, c_parser *parser)
{
tree lhs, rhs;
tree stmt;
@@ -7736,13 +7777,16 @@ c_parser_omp_atomic (c_parser *parser)
}
c_parser_consume_token (parser);
- rhs_expr = c_parser_expression (parser);
- rhs_expr = default_function_array_conversion (rhs_expr);
+ {
+ location_t rhs_loc = c_parser_peek_token (parser)->location;
+ rhs_expr = c_parser_expression (parser);
+ rhs_expr = default_function_array_conversion (rhs_loc, rhs_expr);
+ }
rhs = rhs_expr.value;
rhs = c_fully_fold (rhs, false, NULL);
break;
}
- stmt = c_finish_omp_atomic (code, lhs, rhs);
+ stmt = c_finish_omp_atomic (loc, code, lhs, rhs);
if (stmt != error_mark_node)
add_stmt (stmt);
c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
@@ -7756,19 +7800,21 @@ c_parser_omp_atomic (c_parser *parser)
static void
c_parser_omp_barrier (c_parser *parser)
{
+ location_t loc = c_parser_peek_token (parser)->location;
c_parser_consume_pragma (parser);
c_parser_skip_to_pragma_eol (parser);
- c_finish_omp_barrier ();
+ c_finish_omp_barrier (loc);
}
/* OpenMP 2.5:
# pragma omp critical [(name)] new-line
structured-block
-*/
+
+ LOC is the location of the #pragma itself. */
static tree
-c_parser_omp_critical (c_parser *parser)
+c_parser_omp_critical (location_t loc, c_parser *parser)
{
tree stmt, name = NULL;
@@ -7789,7 +7835,7 @@ c_parser_omp_critical (c_parser *parser)
c_parser_skip_to_pragma_eol (parser);
stmt = c_parser_omp_structured_block (parser);
- return c_finish_omp_critical (stmt, name);
+ return c_finish_omp_critical (loc, stmt, name);
}
/* OpenMP 2.5:
@@ -7801,6 +7847,7 @@ c_parser_omp_critical (c_parser *parser)
static void
c_parser_omp_flush (c_parser *parser)
{
+ location_t loc = c_parser_peek_token (parser)->location;
c_parser_consume_pragma (parser);
if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
@@ -7808,21 +7855,23 @@ c_parser_omp_flush (c_parser *parser)
c_parser_error (parser, "expected %<(%> or end of line");
c_parser_skip_to_pragma_eol (parser);
- c_finish_omp_flush ();
+ c_finish_omp_flush (loc);
}
/* Parse the restricted form of the for statement allowed by OpenMP.
The real trick here is to determine the loop control variable early
- so that we can push a new decl if necessary to make it private. */
+ so that we can push a new decl if necessary to make it private.
+ LOC is the location of the OMP in "#pragma omp". */
static tree
-c_parser_omp_for_loop (c_parser *parser, tree clauses, tree *par_clauses)
+c_parser_omp_for_loop (location_t loc,
+ c_parser *parser, tree clauses, tree *par_clauses)
{
tree decl, cond, incr, save_break, save_cont, body, init, stmt, cl;
tree declv, condv, incrv, initv, for_block = NULL, ret = NULL;
- location_t loc;
bool fail = false, open_brace_parsed = false;
int i, collapse = 1, nbraces = 0;
+ location_t for_loc;
for (cl = clauses; cl; cl = OMP_CLAUSE_CHAIN (cl))
if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_COLLAPSE)
@@ -7840,7 +7889,7 @@ c_parser_omp_for_loop (c_parser *parser, tree clauses, tree *par_clauses)
c_parser_error (parser, "for statement expected");
return NULL;
}
- loc = c_parser_peek_token (parser)->location;
+ for_loc = c_parser_peek_token (parser)->location;
c_parser_consume_token (parser);
for (i = 0; i < collapse; i++)
@@ -7857,7 +7906,7 @@ c_parser_omp_for_loop (c_parser *parser, tree clauses, tree *par_clauses)
for_block
= tree_cons (NULL, c_begin_compound_stmt (true), for_block);
c_parser_declaration_or_fndef (parser, true, true, true, true);
- decl = check_for_loop_decls ();
+ decl = check_for_loop_decls (for_loc);
if (decl == NULL)
goto error_init;
if (DECL_INITIAL (decl) == error_mark_node)
@@ -7875,14 +7924,14 @@ c_parser_omp_for_loop (c_parser *parser, tree clauses, tree *par_clauses)
decl = decl_exp.value;
c_parser_require (parser, CPP_EQ, "expected %<=%>");
- init_loc = c_parser_peek_token (parser)->location;
+ init_loc = c_parser_peek_token (parser)->location;
init_exp = c_parser_expr_no_commas (parser, NULL);
- init_exp = default_function_array_conversion (init_exp);
+ init_exp = default_function_array_conversion (init_loc, init_exp);
init = build_modify_expr (init_loc, decl, decl_exp.original_type,
- NOP_EXPR, init_exp.value,
+ NOP_EXPR, init_loc, init_exp.value,
init_exp.original_type);
- init = c_process_expr_stmt (init);
+ init = c_process_expr_stmt (init_loc, init);
c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
}
@@ -7930,8 +7979,8 @@ c_parser_omp_for_loop (c_parser *parser, tree clauses, tree *par_clauses)
{
location_t incr_loc = c_parser_peek_token (parser)->location;
- incr = c_process_expr_stmt (c_parser_expression (parser).value);
- protected_set_expr_location (incr, incr_loc);
+ incr = c_process_expr_stmt (incr_loc,
+ c_parser_expression (parser).value);
}
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
@@ -7994,14 +8043,19 @@ c_parser_omp_for_loop (c_parser *parser, tree clauses, tree *par_clauses)
if (open_brace_parsed)
{
+ location_t here = c_parser_peek_token (parser)->location;
stmt = c_begin_compound_stmt (true);
c_parser_compound_statement_nostart (parser);
- add_stmt (c_end_compound_stmt (stmt, true));
+ add_stmt (c_end_compound_stmt (here, stmt, true));
}
else
add_stmt (c_parser_c99_block_statement (parser));
if (c_cont_label)
- add_stmt (build1 (LABEL_EXPR, void_type_node, c_cont_label));
+ {
+ tree t = build1 (LABEL_EXPR, void_type_node, c_cont_label);
+ SET_EXPR_LOCATION (t, loc);
+ add_stmt (t);
+ }
body = pop_stmt_list (body);
c_break_label = save_break;
@@ -8021,10 +8075,11 @@ c_parser_omp_for_loop (c_parser *parser, tree clauses, tree *par_clauses)
c_parser_error (parser, "collapsed loops not perfectly nested");
while (nbraces)
{
+ location_t here = c_parser_peek_token (parser)->location;
stmt = c_begin_compound_stmt (true);
add_stmt (body);
c_parser_compound_statement_nostart (parser);
- body = c_end_compound_stmt (stmt, true);
+ body = c_end_compound_stmt (here, stmt, true);
nbraces--;
}
goto pop_scopes;
@@ -8064,7 +8119,8 @@ c_parser_omp_for_loop (c_parser *parser, tree clauses, tree *par_clauses)
/* Copy lastprivate (decl) clause to OMP_FOR_CLAUSES,
change it to shared (decl) in
OMP_PARALLEL_CLAUSES. */
- tree l = build_omp_clause (OMP_CLAUSE_LASTPRIVATE);
+ tree l = build_omp_clause (OMP_CLAUSE_LOCATION (*c),
+ OMP_CLAUSE_LASTPRIVATE);
OMP_CLAUSE_DECL (l) = OMP_CLAUSE_DECL (*c);
OMP_CLAUSE_CHAIN (l) = clauses;
clauses = l;
@@ -8079,7 +8135,10 @@ c_parser_omp_for_loop (c_parser *parser, tree clauses, tree *par_clauses)
pop_scopes:
while (for_block)
{
- stmt = c_end_compound_stmt (TREE_VALUE (for_block), true);
+ /* FIXME diagnostics: LOC below should be the actual location of
+ this particular for block. We need to build a list of
+ locations to go along with FOR_BLOCK. */
+ stmt = c_end_compound_stmt (loc, TREE_VALUE (for_block), true);
add_stmt (stmt);
for_block = TREE_CHAIN (for_block);
}
@@ -8089,6 +8148,8 @@ pop_scopes:
/* OpenMP 2.5:
#pragma omp for for-clause[optseq] new-line
for-loop
+
+ LOC is the location of the #pragma token.
*/
#define OMP_FOR_CLAUSE_MASK \
@@ -8102,7 +8163,7 @@ pop_scopes:
| (1u << PRAGMA_OMP_CLAUSE_NOWAIT))
static tree
-c_parser_omp_for (c_parser *parser)
+c_parser_omp_for (location_t loc, c_parser *parser)
{
tree block, clauses, ret;
@@ -8110,8 +8171,8 @@ c_parser_omp_for (c_parser *parser)
"#pragma omp for");
block = c_begin_compound_stmt (true);
- ret = c_parser_omp_for_loop (parser, clauses, NULL);
- block = c_end_compound_stmt (block, true);
+ ret = c_parser_omp_for_loop (loc, parser, clauses, NULL);
+ block = c_end_compound_stmt (loc, block, true);
add_stmt (block);
return ret;
@@ -8120,25 +8181,29 @@ c_parser_omp_for (c_parser *parser)
/* OpenMP 2.5:
# pragma omp master new-line
structured-block
+
+ LOC is the location of the #pragma token.
*/
static tree
-c_parser_omp_master (c_parser *parser)
+c_parser_omp_master (location_t loc, c_parser *parser)
{
c_parser_skip_to_pragma_eol (parser);
- return c_finish_omp_master (c_parser_omp_structured_block (parser));
+ return c_finish_omp_master (loc, c_parser_omp_structured_block (parser));
}
/* OpenMP 2.5:
# pragma omp ordered new-line
structured-block
+
+ LOC is the location of the #pragma itself.
*/
static tree
-c_parser_omp_ordered (c_parser *parser)
+c_parser_omp_ordered (location_t loc, c_parser *parser)
{
c_parser_skip_to_pragma_eol (parser);
- return c_finish_omp_ordered (c_parser_omp_structured_block (parser));
+ return c_finish_omp_ordered (loc, c_parser_omp_structured_block (parser));
}
/* OpenMP 2.5:
@@ -8148,15 +8213,18 @@ c_parser_omp_ordered (c_parser *parser)
section-sequence:
section-directive[opt] structured-block
- section-sequence section-directive structured-block */
+ section-sequence section-directive structured-block
+
+ SECTIONS_LOC is the location of the #pragma omp sections. */
static tree
-c_parser_omp_sections_scope (c_parser *parser)
+c_parser_omp_sections_scope (location_t sections_loc, c_parser *parser)
{
tree stmt, substmt;
bool error_suppress = false;
location_t loc;
+ loc = c_parser_peek_token (parser)->location;
if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
{
/* Avoid skipping until the end of the block. */
@@ -8166,7 +8234,6 @@ c_parser_omp_sections_scope (c_parser *parser)
stmt = push_stmt_list ();
- loc = c_parser_peek_token (parser)->location;
if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_SECTION)
{
substmt = push_stmt_list ();
@@ -8220,6 +8287,7 @@ c_parser_omp_sections_scope (c_parser *parser)
substmt = pop_stmt_list (stmt);
stmt = make_node (OMP_SECTIONS);
+ SET_EXPR_LOCATION (stmt, sections_loc);
TREE_TYPE (stmt) = void_type_node;
OMP_SECTIONS_BODY (stmt) = substmt;
@@ -8229,6 +8297,8 @@ c_parser_omp_sections_scope (c_parser *parser)
/* OpenMP 2.5:
# pragma omp sections sections-clause[optseq] newline
sections-scope
+
+ LOC is the location of the #pragma token.
*/
#define OMP_SECTIONS_CLAUSE_MASK \
@@ -8239,7 +8309,7 @@ c_parser_omp_sections_scope (c_parser *parser)
| (1u << PRAGMA_OMP_CLAUSE_NOWAIT))
static tree
-c_parser_omp_sections (c_parser *parser)
+c_parser_omp_sections (location_t loc, c_parser *parser)
{
tree block, clauses, ret;
@@ -8247,10 +8317,10 @@ c_parser_omp_sections (c_parser *parser)
"#pragma omp sections");
block = c_begin_compound_stmt (true);
- ret = c_parser_omp_sections_scope (parser);
+ ret = c_parser_omp_sections_scope (loc, parser);
if (ret)
OMP_SECTIONS_CLAUSES (ret) = clauses;
- block = c_end_compound_stmt (block, true);
+ block = c_end_compound_stmt (loc, block, true);
add_stmt (block);
return ret;
@@ -8260,6 +8330,8 @@ c_parser_omp_sections (c_parser *parser)
# pragma parallel parallel-clause new-line
# pragma parallel for parallel-for-clause new-line
# pragma parallel sections parallel-sections-clause new-line
+
+ LOC is the location of the #pragma token.
*/
#define OMP_PARALLEL_CLAUSE_MASK \
@@ -8273,7 +8345,7 @@ c_parser_omp_sections (c_parser *parser)
| (1u << PRAGMA_OMP_CLAUSE_NUM_THREADS))
static tree
-c_parser_omp_parallel (c_parser *parser)
+c_parser_omp_parallel (location_t loc, c_parser *parser)
{
enum pragma_kind p_kind = PRAGMA_OMP_PARALLEL;
const char *p_name = "#pragma omp parallel";
@@ -8308,24 +8380,24 @@ c_parser_omp_parallel (c_parser *parser)
case PRAGMA_OMP_PARALLEL:
block = c_begin_omp_parallel ();
c_parser_statement (parser);
- stmt = c_finish_omp_parallel (clauses, block);
+ stmt = c_finish_omp_parallel (loc, clauses, block);
break;
case PRAGMA_OMP_PARALLEL_FOR:
block = c_begin_omp_parallel ();
- c_split_parallel_clauses (clauses, &par_clause, &ws_clause);
- c_parser_omp_for_loop (parser, ws_clause, &par_clause);
- stmt = c_finish_omp_parallel (par_clause, block);
+ c_split_parallel_clauses (loc, clauses, &par_clause, &ws_clause);
+ c_parser_omp_for_loop (loc, parser, ws_clause, &par_clause);
+ stmt = c_finish_omp_parallel (loc, par_clause, block);
OMP_PARALLEL_COMBINED (stmt) = 1;
break;
case PRAGMA_OMP_PARALLEL_SECTIONS:
block = c_begin_omp_parallel ();
- c_split_parallel_clauses (clauses, &par_clause, &ws_clause);
- stmt = c_parser_omp_sections_scope (parser);
+ c_split_parallel_clauses (loc, clauses, &par_clause, &ws_clause);
+ stmt = c_parser_omp_sections_scope (loc, parser);
if (stmt)
OMP_SECTIONS_CLAUSES (stmt) = ws_clause;
- stmt = c_finish_omp_parallel (par_clause, block);
+ stmt = c_finish_omp_parallel (loc, par_clause, block);
OMP_PARALLEL_COMBINED (stmt) = 1;
break;
@@ -8339,6 +8411,8 @@ c_parser_omp_parallel (c_parser *parser)
/* OpenMP 2.5:
# pragma omp single single-clause[optseq] new-line
structured-block
+
+ LOC is the location of the #pragma.
*/
#define OMP_SINGLE_CLAUSE_MASK \
@@ -8348,9 +8422,10 @@ c_parser_omp_parallel (c_parser *parser)
| (1u << PRAGMA_OMP_CLAUSE_NOWAIT))
static tree
-c_parser_omp_single (c_parser *parser)
+c_parser_omp_single (location_t loc, c_parser *parser)
{
tree stmt = make_node (OMP_SINGLE);
+ SET_EXPR_LOCATION (stmt, loc);
TREE_TYPE (stmt) = void_type_node;
OMP_SINGLE_CLAUSES (stmt)
@@ -8363,6 +8438,8 @@ c_parser_omp_single (c_parser *parser)
/* OpenMP 3.0:
# pragma omp task task-clause[optseq] new-line
+
+ LOC is the location of the #pragma.
*/
#define OMP_TASK_CLAUSE_MASK \
@@ -8374,7 +8451,7 @@ c_parser_omp_single (c_parser *parser)
| (1u << PRAGMA_OMP_CLAUSE_SHARED))
static tree
-c_parser_omp_task (c_parser *parser)
+c_parser_omp_task (location_t loc, c_parser *parser)
{
tree clauses, block;
@@ -8383,7 +8460,7 @@ c_parser_omp_task (c_parser *parser)
block = c_begin_omp_task ();
c_parser_statement (parser);
- return c_finish_omp_task (clauses, block);
+ return c_finish_omp_task (loc, clauses, block);
}
/* OpenMP 3.0:
@@ -8393,10 +8470,11 @@ c_parser_omp_task (c_parser *parser)
static void
c_parser_omp_taskwait (c_parser *parser)
{
+ location_t loc = c_parser_peek_token (parser)->location;
c_parser_consume_pragma (parser);
c_parser_skip_to_pragma_eol (parser);
- c_finish_omp_taskwait ();
+ c_finish_omp_taskwait (loc);
}
/* Main entry point to parsing most OpenMP pragmas. */
@@ -8421,38 +8499,38 @@ c_parser_omp_construct (c_parser *parser)
switch (p_kind)
{
case PRAGMA_OMP_ATOMIC:
- c_parser_omp_atomic (parser);
+ c_parser_omp_atomic (loc, parser);
return;
case PRAGMA_OMP_CRITICAL:
- stmt = c_parser_omp_critical (parser);
+ stmt = c_parser_omp_critical (loc, parser);
break;
case PRAGMA_OMP_FOR:
- stmt = c_parser_omp_for (parser);
+ stmt = c_parser_omp_for (loc, parser);
break;
case PRAGMA_OMP_MASTER:
- stmt = c_parser_omp_master (parser);
+ stmt = c_parser_omp_master (loc, parser);
break;
case PRAGMA_OMP_ORDERED:
- stmt = c_parser_omp_ordered (parser);
+ stmt = c_parser_omp_ordered (loc, parser);
break;
case PRAGMA_OMP_PARALLEL:
- stmt = c_parser_omp_parallel (parser);
+ stmt = c_parser_omp_parallel (loc, parser);
break;
case PRAGMA_OMP_SECTIONS:
- stmt = c_parser_omp_sections (parser);
+ stmt = c_parser_omp_sections (loc, parser);
break;
case PRAGMA_OMP_SINGLE:
- stmt = c_parser_omp_single (parser);
+ stmt = c_parser_omp_single (loc, parser);
break;
case PRAGMA_OMP_TASK:
- stmt = c_parser_omp_task (parser);
+ stmt = c_parser_omp_task (loc, parser);
break;
default:
gcc_unreachable ();
}
if (stmt)
- SET_EXPR_LOCATION (stmt, loc);
+ gcc_assert (EXPR_LOCATION (stmt) != UNKNOWN_LOCATION);
}
@@ -8463,8 +8541,10 @@ static void
c_parser_omp_threadprivate (c_parser *parser)
{
tree vars, t;
+ location_t loc;
c_parser_consume_pragma (parser);
+ loc = c_parser_peek_token (parser)->location;
vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
/* Mark every variable in VARS to be assigned thread local storage. */
@@ -8472,18 +8552,24 @@ c_parser_omp_threadprivate (c_parser *parser)
{
tree v = TREE_PURPOSE (t);
+ /* FIXME diagnostics: Ideally we should keep individual
+ locations for all the variables in the var list to make the
+ following errors more precise. Perhaps
+ c_parser_omp_var_list_parens() should construct a list of
+ locations to go along with the var list. */
+
/* If V had already been marked threadprivate, it doesn't matter
whether it had been used prior to this point. */
if (TREE_CODE (v) != VAR_DECL)
- error ("%qD is not a variable", v);
+ error_at (loc, "%qD is not a variable", v);
else if (TREE_USED (v) && !C_DECL_THREADPRIVATE_P (v))
- error ("%qE declared %<threadprivate%> after first use", v);
+ error_at (loc, "%qE declared %<threadprivate%> after first use", v);
else if (! TREE_STATIC (v) && ! DECL_EXTERNAL (v))
- error ("automatic variable %qE cannot be %<threadprivate%>", v);
+ error_at (loc, "automatic variable %qE cannot be %<threadprivate%>", v);
else if (TREE_TYPE (v) == error_mark_node)
;
else if (! COMPLETE_TYPE_P (TREE_TYPE (v)))
- error ("%<threadprivate%> %qE has incomplete type", v);
+ error_at (loc, "%<threadprivate%> %qE has incomplete type", v);
else
{
if (! DECL_THREAD_LOCAL_P (v))
diff --git a/gcc/c-pragma.c b/gcc/c-pragma.c
index bd71d1d79e8..c91ee991dba 100644
--- a/gcc/c-pragma.c
+++ b/gcc/c-pragma.c
@@ -455,7 +455,8 @@ maybe_apply_pending_pragma_weaks (void)
if (TREE_VALUE (t) == NULL)
continue;
- decl = build_decl (FUNCTION_DECL, alias_id, default_function_type);
+ decl = build_decl (UNKNOWN_LOCATION,
+ FUNCTION_DECL, alias_id, default_function_type);
DECL_ARTIFICIAL (decl) = 1;
TREE_PUBLIC (decl) = 1;
@@ -1180,7 +1181,7 @@ valid_location_for_stdc_pragma_p (void)
return valid_location_for_stdc_pragma;
}
-enum pragma_switch_t { ON, OFF, DEFAULT, BAD };
+enum pragma_switch_t { PRAGMA_ON, PRAGMA_OFF, PRAGMA_DEFAULT, PRAGMA_BAD };
/* A STDC pragma must appear outside of external declarations or
preceding all explicit declarations and statements inside a compound
@@ -1198,33 +1199,33 @@ handle_stdc_pragma (const char *pname)
{
warning (OPT_Wpragmas, "invalid location for %<pragma %s%>, ignored",
pname);
- return BAD;
+ return PRAGMA_BAD;
}
if (pragma_lex (&t) != CPP_NAME)
{
warning (OPT_Wpragmas, "malformed %<#pragma %s%>, ignored", pname);
- return BAD;
+ return PRAGMA_BAD;
}
arg = IDENTIFIER_POINTER (t);
if (!strcmp (arg, "ON"))
- ret = ON;
+ ret = PRAGMA_ON;
else if (!strcmp (arg, "OFF"))
- ret = OFF;
+ ret = PRAGMA_OFF;
else if (!strcmp (arg, "DEFAULT"))
- ret = DEFAULT;
+ ret = PRAGMA_DEFAULT;
else
{
warning (OPT_Wpragmas, "malformed %<#pragma %s%>, ignored", pname);
- return BAD;
+ return PRAGMA_BAD;
}
if (pragma_lex (&t) != CPP_EOF)
{
warning (OPT_Wpragmas, "junk at end of %<#pragma %s%>", pname);
- return BAD;
+ return PRAGMA_BAD;
}
return ret;
@@ -1260,14 +1261,14 @@ handle_pragma_float_const_decimal64 (cpp_reader *ARG_UNUSED (dummy))
switch (handle_stdc_pragma ("STDC FLOAT_CONST_DECIMAL64"))
{
- case ON:
+ case PRAGMA_ON:
set_float_const_decimal64 ();
break;
- case OFF:
- case DEFAULT:
+ case PRAGMA_OFF:
+ case PRAGMA_DEFAULT:
clear_float_const_decimal64 ();
break;
- case BAD:
+ case PRAGMA_BAD:
break;
}
}
diff --git a/gcc/c-semantics.c b/gcc/c-semantics.c
index b6c3a27c5ab..2bfad472db0 100644
--- a/gcc/c-semantics.c
+++ b/gcc/c-semantics.c
@@ -103,12 +103,12 @@ pop_stmt_list (tree t)
/* Build a generic statement based on the given type of node and
arguments. Similar to `build_nt', except that we set
- EXPR_LOCATION to be the current source location. */
+ EXPR_LOCATION to LOC. */
/* ??? This should be obsolete with the lineno_stmt productions
in the grammar. */
tree
-build_stmt (enum tree_code code, ...)
+build_stmt (location_t loc, enum tree_code code, ...)
{
tree ret;
int length, i;
@@ -123,7 +123,7 @@ build_stmt (enum tree_code code, ...)
ret = make_node (code);
TREE_TYPE (ret) = void_type_node;
length = TREE_CODE_LENGTH (code);
- SET_EXPR_LOCATION (ret, input_location);
+ SET_EXPR_LOCATION (ret, loc);
/* TREE_SIDE_EFFECTS will already be set for statements with
implicit side effects. Here we make sure it is set for other
@@ -148,7 +148,8 @@ build_stmt (enum tree_code code, ...)
/* Create a CASE_LABEL_EXPR tree node and return it. */
tree
-build_case_label (tree low_value, tree high_value, tree label_decl)
+build_case_label (location_t loc,
+ tree low_value, tree high_value, tree label_decl)
{
- return build_stmt (CASE_LABEL_EXPR, low_value, high_value, label_decl);
+ return build_stmt (loc, CASE_LABEL_EXPR, low_value, high_value, label_decl);
}
diff --git a/gcc/c-tree.h b/gcc/c-tree.h
index 6062d59982d..f565df58f31 100644
--- a/gcc/c-tree.h
+++ b/gcc/c-tree.h
@@ -108,29 +108,6 @@ struct GTY(()) lang_type {
sizeof and typeof it is set for other function decls as well. */
#define C_DECL_USED(EXP) DECL_LANG_FLAG_5 (FUNCTION_DECL_CHECK (EXP))
-/* Record whether a label was defined in a statement expression which
- has finished and so can no longer be jumped to. */
-#define C_DECL_UNJUMPABLE_STMT_EXPR(EXP) \
- DECL_LANG_FLAG_6 (LABEL_DECL_CHECK (EXP))
-
-/* Record whether a label was the subject of a goto from outside the
- current level of statement expression nesting and so cannot be
- defined right now. */
-#define C_DECL_UNDEFINABLE_STMT_EXPR(EXP) \
- DECL_LANG_FLAG_7 (LABEL_DECL_CHECK (EXP))
-
-/* Record whether a label was defined in the scope of an identifier
- with variably modified type which has finished and so can no longer
- be jumped to. */
-#define C_DECL_UNJUMPABLE_VM(EXP) \
- DECL_LANG_FLAG_3 (LABEL_DECL_CHECK (EXP))
-
-/* Record whether a label was the subject of a goto from outside the
- current level of scopes of identifiers with variably modified type
- and so cannot be defined right now. */
-#define C_DECL_UNDEFINABLE_VM(EXP) \
- DECL_LANG_FLAG_5 (LABEL_DECL_CHECK (EXP))
-
/* Record whether a variable has been declared threadprivate by
#pragma omp threadprivate. */
#define C_DECL_THREADPRIVATE_P(DECL) DECL_LANG_FLAG_3 (VAR_DECL_CHECK (DECL))
@@ -360,7 +337,7 @@ struct c_declarator {
enum c_declarator_kind kind;
/* Except for cdk_id, the contained declarator. For cdk_id, NULL. */
struct c_declarator *declarator;
- location_t id_loc; /* Currently only set for cdk_id. */
+ location_t id_loc; /* Currently only set for cdk_id, cdk_array. */
union {
/* For identifiers, an IDENTIFIER_NODE or NULL_TREE if an abstract
declarator. */
@@ -421,45 +398,6 @@ struct GTY(()) language_function {
int warn_about_return_type;
};
-/* Save lists of labels used or defined in particular contexts.
- Allocated on the parser obstack. */
-
-struct c_label_list
-{
- /* The label at the head of the list. */
- tree label;
- /* The rest of the list. */
- struct c_label_list *next;
-};
-
-/* Statement expression context. */
-
-struct c_label_context_se
-{
- /* The labels defined at this level of nesting. */
- struct c_label_list *labels_def;
- /* The labels used at this level of nesting. */
- struct c_label_list *labels_used;
- /* The next outermost context. */
- struct c_label_context_se *next;
-};
-
-/* Context of variably modified declarations. */
-
-struct c_label_context_vm
-{
- /* The labels defined at this level of nesting. */
- struct c_label_list *labels_def;
- /* The labels used at this level of nesting. */
- struct c_label_list *labels_used;
- /* The scope of this context. Multiple contexts may be at the same
- numbered scope, since each variably modified declaration starts a
- new context. */
- unsigned scope;
- /* The next outermost context. */
- struct c_label_context_vm *next;
-};
-
/* Used when parsing an enum. Initialized by start_enum. */
struct c_enum_contents
{
@@ -491,6 +429,7 @@ extern void c_parse_init (void);
extern void gen_aux_info_record (tree, int, int, int);
/* in c-decl.c */
+struct c_spot_bindings;
extern struct obstack parser_obstack;
extern tree c_break_label;
extern tree c_cont_label;
@@ -498,6 +437,8 @@ extern tree c_cont_label;
extern int global_bindings_p (void);
extern void push_scope (void);
extern tree pop_scope (void);
+extern void c_bindings_start_stmt_expr (struct c_spot_bindings *);
+extern void c_bindings_end_stmt_expr (struct c_spot_bindings *);
extern void record_inline_static (location_t, tree, tree,
enum c_inline_static_type);
@@ -505,26 +446,32 @@ extern void c_init_decl_processing (void);
extern void c_dup_lang_specific_decl (tree);
extern void c_print_identifier (FILE *, tree, int);
extern int quals_from_declspecs (const struct c_declspecs *);
-extern struct c_declarator *build_array_declarator (tree, struct c_declspecs *,
+extern struct c_declarator *build_array_declarator (location_t, tree,
+ struct c_declspecs *,
bool, bool);
-extern tree build_enumerator (struct c_enum_contents *, tree, tree, location_t);
-extern tree check_for_loop_decls (void);
+extern tree build_enumerator (location_t, struct c_enum_contents *, tree, tree);
+extern tree check_for_loop_decls (location_t);
extern void mark_forward_parm_decls (void);
extern void declare_parm_level (void);
-extern void undeclared_variable (tree, location_t);
+extern void undeclared_variable (location_t, tree);
+extern tree lookup_label_for_goto (location_t, tree);
extern tree declare_label (tree);
extern tree define_label (location_t, tree);
+extern struct c_spot_bindings *c_get_switch_bindings (void);
+extern void c_release_switch_bindings (struct c_spot_bindings *);
+extern bool c_check_switch_jump_warnings (struct c_spot_bindings *,
+ location_t, location_t);
extern void c_maybe_initialize_eh (void);
-extern void finish_decl (tree, tree, tree, tree);
+extern void finish_decl (tree, location_t, tree, tree, tree);
extern tree finish_enum (tree, tree, tree);
extern void finish_function (void);
-extern tree finish_struct (tree, tree, tree, bool, VEC(tree,heap) *);
+extern tree finish_struct (location_t, tree, tree, tree, bool, VEC(tree,heap) *);
extern struct c_arg_info *get_parm_info (bool);
extern tree grokfield (location_t, struct c_declarator *,
struct c_declspecs *, tree, tree *);
extern tree groktypename (struct c_type_name *, tree *, bool *);
extern tree grokparm (const struct c_parm *);
-extern tree implicitly_declare (tree);
+extern tree implicitly_declare (location_t, tree);
extern void keep_next_level (void);
extern void pending_xref_error (void);
extern void c_push_function_context (void);
@@ -536,16 +483,15 @@ extern tree c_builtin_function (tree);
extern tree c_builtin_function_ext_scope (tree);
extern void shadow_tag (const struct c_declspecs *);
extern void shadow_tag_warned (const struct c_declspecs *, int);
-extern tree start_enum (struct c_enum_contents *, tree, location_t);
+extern tree start_enum (location_t, struct c_enum_contents *, tree);
extern int start_function (struct c_declspecs *, struct c_declarator *, tree);
extern tree start_decl (struct c_declarator *, struct c_declspecs *, bool,
tree);
-extern tree start_struct (enum tree_code, tree, bool *, VEC(tree,heap) **,
- location_t);
+extern tree start_struct (location_t, enum tree_code, tree, bool *, VEC(tree,heap) **);
extern void store_parm_decls (void);
extern void store_parm_decls_from (struct c_arg_info *);
extern tree xref_tag (enum tree_code, tree);
-extern struct c_typespec parser_xref_tag (enum tree_code, tree, location_t);
+extern struct c_typespec parser_xref_tag (location_t, enum tree_code, tree);
extern int c_expand_decl (tree);
extern struct c_parm *build_c_parm (struct c_declspecs *, tree,
struct c_declarator *);
@@ -583,8 +529,6 @@ extern int in_sizeof;
extern int in_typeof;
extern struct c_switch *c_switch_stack;
-extern struct c_label_context_se *label_context_stack_se;
-extern struct c_label_context_vm *label_context_stack_vm;
extern tree c_objc_common_truthvalue_conversion (location_t, tree);
extern tree require_complete_type (tree);
@@ -594,24 +538,25 @@ extern bool c_vla_type_p (const_tree);
extern bool c_mark_addressable (tree);
extern void c_incomplete_type_error (const_tree, const_tree);
extern tree c_type_promotes_to (tree);
-extern struct c_expr default_function_array_conversion (struct c_expr);
+extern struct c_expr default_function_array_conversion (location_t,
+ struct c_expr);
extern tree composite_type (tree, tree);
-extern tree build_component_ref (tree, tree);
-extern tree build_array_ref (tree, tree, location_t);
-extern tree build_external_ref (tree, int, location_t, tree *);
+extern tree build_component_ref (location_t, tree, tree);
+extern tree build_array_ref (location_t, tree, tree);
+extern tree build_external_ref (location_t, tree, int, tree *);
extern void pop_maybe_used (bool);
-extern struct c_expr c_expr_sizeof_expr (struct c_expr);
-extern struct c_expr c_expr_sizeof_type (struct c_type_name *);
-extern struct c_expr parser_build_unary_op (enum tree_code, struct c_expr,
- location_t);
+extern struct c_expr c_expr_sizeof_expr (location_t, struct c_expr);
+extern struct c_expr c_expr_sizeof_type (location_t, struct c_type_name *);
+extern struct c_expr parser_build_unary_op (location_t, enum tree_code,
+ struct c_expr);
extern struct c_expr parser_build_binary_op (location_t,
enum tree_code, struct c_expr,
struct c_expr);
-extern tree build_conditional_expr (tree, bool, tree, tree);
-extern tree build_compound_expr (tree, tree);
-extern tree c_cast_expr (struct c_type_name *, tree, location_t);
-extern tree build_c_cast (tree, tree);
-extern void store_init_value (tree, tree, tree);
+extern tree build_conditional_expr (location_t, tree, bool, tree, tree);
+extern tree build_compound_expr (location_t, tree, tree);
+extern tree c_cast_expr (location_t, struct c_type_name *, tree);
+extern tree build_c_cast (location_t, tree, tree);
+extern void store_init_value (location_t, tree, tree, tree);
extern void error_init (const char *);
extern void pedwarn_init (location_t, int opt, const char *);
extern void maybe_warn_string_init (tree, struct c_expr);
@@ -623,33 +568,32 @@ extern struct c_expr pop_init_level (int);
extern void set_init_index (tree, tree);
extern void set_init_label (tree);
extern void process_init_element (struct c_expr, bool);
-extern tree build_compound_literal (tree, tree, bool);
-extern void check_compound_literal_type (struct c_type_name *, location_t);
-extern tree c_start_case (tree);
+extern tree build_compound_literal (location_t, tree, tree, bool);
+extern void check_compound_literal_type (location_t, struct c_type_name *);
+extern tree c_start_case (location_t, location_t, tree);
extern void c_finish_case (tree);
-extern tree build_asm_expr (tree, tree, tree, tree, bool);
+extern tree build_asm_expr (location_t, tree, tree, tree, tree, bool);
extern tree build_asm_stmt (tree, tree);
extern int c_types_compatible_p (tree, tree);
extern tree c_begin_compound_stmt (bool);
-extern tree c_end_compound_stmt (tree, bool);
+extern tree c_end_compound_stmt (location_t, tree, bool);
extern void c_finish_if_stmt (location_t, tree, tree, tree, bool);
extern void c_finish_loop (location_t, tree, tree, tree, tree, tree, bool);
extern tree c_begin_stmt_expr (void);
-extern tree c_finish_stmt_expr (tree);
-extern tree c_process_expr_stmt (tree);
-extern tree c_finish_expr_stmt (tree);
-extern tree c_finish_return (tree, tree);
-extern tree c_finish_bc_stmt (tree *, bool);
-extern tree c_finish_goto_label (tree);
-extern tree c_finish_goto_ptr (tree);
-extern void c_begin_vm_scope (unsigned int);
-extern void c_end_vm_scope (unsigned int);
+extern tree c_finish_stmt_expr (location_t, tree);
+extern tree c_process_expr_stmt (location_t, tree);
+extern tree c_finish_expr_stmt (location_t, tree);
+extern tree c_finish_return (location_t, tree, tree);
+extern tree c_finish_bc_stmt (location_t, tree *, bool);
+extern tree c_finish_goto_label (location_t, tree);
+extern tree c_finish_goto_ptr (location_t, tree);
extern tree c_expr_to_decl (tree, bool *, bool *);
extern tree c_begin_omp_parallel (void);
-extern tree c_finish_omp_parallel (tree, tree);
+extern tree c_finish_omp_parallel (location_t, tree, tree);
extern tree c_begin_omp_task (void);
-extern tree c_finish_omp_task (tree, tree);
+extern tree c_finish_omp_task (location_t, tree, tree);
extern tree c_finish_omp_clauses (tree);
+extern tree c_build_va_arg (location_t, tree, tree);
/* Set to 0 at beginning of a function definition, set to 1 if
a return statement that specifies a return value is seen. */
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c
index f1dc7a34c59..07d51a4d5d8 100644
--- a/gcc/c-typeck.c
+++ b/gcc/c-typeck.c
@@ -70,9 +70,6 @@ int in_sizeof;
/* The level of nesting inside "typeof". */
int in_typeof;
-struct c_label_context_se *label_context_stack_se;
-struct c_label_context_vm *label_context_stack_vm;
-
/* Nonzero if we've already printed a "missing braces around initializer"
message within this initializer. */
static int missing_braces_mentioned;
@@ -82,23 +79,23 @@ static int require_constant_elements;
static bool null_pointer_constant_p (const_tree);
static tree qualify_type (tree, tree);
-static int tagged_types_tu_compatible_p (const_tree, const_tree);
-static int comp_target_types (tree, tree);
-static int function_types_compatible_p (const_tree, const_tree);
-static int type_lists_compatible_p (const_tree, const_tree);
+static int tagged_types_tu_compatible_p (const_tree, const_tree, bool *);
+static int comp_target_types (location_t, tree, tree);
+static int function_types_compatible_p (const_tree, const_tree, bool *);
+static int type_lists_compatible_p (const_tree, const_tree, bool *);
static tree lookup_field (tree, tree);
static int convert_arguments (tree, VEC(tree,gc) *, VEC(tree,gc) *, tree,
tree);
static tree pointer_diff (tree, tree);
-static tree convert_for_assignment (tree, tree, tree, enum impl_conv, bool,
- tree, tree, int);
+static tree convert_for_assignment (location_t, tree, tree, tree,
+ enum impl_conv, bool, tree, tree, int);
static tree valid_compound_expr_initializer (tree, tree);
static void push_string (const char *);
static void push_member_name (tree);
static int spelling_length (void);
static char *print_spelling (char *);
static void warning_init (int, const char *);
-static tree digest_init (tree, tree, tree, bool, bool, int);
+static tree digest_init (location_t, tree, tree, tree, bool, bool, int);
static void output_init_element (tree, tree, bool, tree, tree, int, bool);
static void output_pending_init_elements (int);
static int set_designator (int);
@@ -111,7 +108,7 @@ static void readonly_error (tree, enum lvalue_use);
static void readonly_warning (tree, enum lvalue_use);
static int lvalue_or_else (const_tree, enum lvalue_use);
static void record_maybe_used_decl (tree);
-static int comptypes_internal (const_tree, const_tree);
+static int comptypes_internal (const_tree, const_tree, bool *);
/* Return true if EXP is a null pointer constant, false otherwise. */
@@ -919,7 +916,22 @@ comptypes (tree type1, tree type2)
const struct tagged_tu_seen_cache * tagged_tu_seen_base1 = tagged_tu_seen_base;
int val;
- val = comptypes_internal (type1, type2);
+ val = comptypes_internal (type1, type2, NULL);
+ free_all_tagged_tu_seen_up_to (tagged_tu_seen_base1);
+
+ return val;
+}
+
+/* Like comptypes, but if it returns non-zero because enum and int are
+ compatible, it sets *ENUM_AND_INT_P to true. */
+
+static int
+comptypes_check_enum_int (tree type1, tree type2, bool *enum_and_int_p)
+{
+ const struct tagged_tu_seen_cache * tagged_tu_seen_base1 = tagged_tu_seen_base;
+ int val;
+
+ val = comptypes_internal (type1, type2, enum_and_int_p);
free_all_tagged_tu_seen_up_to (tagged_tu_seen_base1);
return val;
@@ -927,11 +939,14 @@ comptypes (tree type1, tree type2)
/* Return 1 if TYPE1 and TYPE2 are compatible types for assignment
or various other operations. Return 2 if they are compatible
- but a warning may be needed if you use them together. This
- differs from comptypes, in that we don't free the seen types. */
+ but a warning may be needed if you use them together. If
+ ENUM_AND_INT_P is not NULL, and one type is an enum and the other a
+ compatible integer type, then this sets *ENUM_AND_INT_P to true;
+ *ENUM_AND_INT_P is never set to false. This differs from
+ comptypes, in that we don't free the seen types. */
static int
-comptypes_internal (const_tree type1, const_tree type2)
+comptypes_internal (const_tree type1, const_tree type2, bool *enum_and_int_p)
{
const_tree t1 = type1;
const_tree t2 = type2;
@@ -959,9 +974,17 @@ comptypes_internal (const_tree type1, const_tree type2)
are compatible with each other only if they are the same type. */
if (TREE_CODE (t1) == ENUMERAL_TYPE && TREE_CODE (t2) != ENUMERAL_TYPE)
- t1 = c_common_type_for_size (TYPE_PRECISION (t1), TYPE_UNSIGNED (t1));
+ {
+ t1 = c_common_type_for_size (TYPE_PRECISION (t1), TYPE_UNSIGNED (t1));
+ if (enum_and_int_p != NULL && TREE_CODE (t2) != VOID_TYPE)
+ *enum_and_int_p = true;
+ }
else if (TREE_CODE (t2) == ENUMERAL_TYPE && TREE_CODE (t1) != ENUMERAL_TYPE)
- t2 = c_common_type_for_size (TYPE_PRECISION (t2), TYPE_UNSIGNED (t2));
+ {
+ t2 = c_common_type_for_size (TYPE_PRECISION (t2), TYPE_UNSIGNED (t2));
+ if (enum_and_int_p != NULL && TREE_CODE (t1) != VOID_TYPE)
+ *enum_and_int_p = true;
+ }
if (t1 == t2)
return 1;
@@ -999,11 +1022,12 @@ comptypes_internal (const_tree type1, const_tree type2)
|| TYPE_REF_CAN_ALIAS_ALL (t1) != TYPE_REF_CAN_ALIAS_ALL (t2))
break;
val = (TREE_TYPE (t1) == TREE_TYPE (t2)
- ? 1 : comptypes_internal (TREE_TYPE (t1), TREE_TYPE (t2)));
+ ? 1 : comptypes_internal (TREE_TYPE (t1), TREE_TYPE (t2),
+ enum_and_int_p));
break;
case FUNCTION_TYPE:
- val = function_types_compatible_p (t1, t2);
+ val = function_types_compatible_p (t1, t2, enum_and_int_p);
break;
case ARRAY_TYPE:
@@ -1016,7 +1040,8 @@ comptypes_internal (const_tree type1, const_tree type2)
/* Target types must match incl. qualifiers. */
if (TREE_TYPE (t1) != TREE_TYPE (t2)
- && 0 == (val = comptypes_internal (TREE_TYPE (t1), TREE_TYPE (t2))))
+ && 0 == (val = comptypes_internal (TREE_TYPE (t1), TREE_TYPE (t2),
+ enum_and_int_p)))
return 0;
/* Sizes must match unless one is missing or variable. */
@@ -1060,14 +1085,15 @@ comptypes_internal (const_tree type1, const_tree type2)
break;
if (attrval != 2)
- return tagged_types_tu_compatible_p (t1, t2);
- val = tagged_types_tu_compatible_p (t1, t2);
+ return tagged_types_tu_compatible_p (t1, t2, enum_and_int_p);
+ val = tagged_types_tu_compatible_p (t1, t2, enum_and_int_p);
}
break;
case VECTOR_TYPE:
- val = TYPE_VECTOR_SUBPARTS (t1) == TYPE_VECTOR_SUBPARTS (t2)
- && comptypes_internal (TREE_TYPE (t1), TREE_TYPE (t2));
+ val = (TYPE_VECTOR_SUBPARTS (t1) == TYPE_VECTOR_SUBPARTS (t2)
+ && comptypes_internal (TREE_TYPE (t1), TREE_TYPE (t2),
+ enum_and_int_p));
break;
default:
@@ -1080,10 +1106,11 @@ comptypes_internal (const_tree type1, const_tree type2)
ignoring their qualifiers. */
static int
-comp_target_types (tree ttl, tree ttr)
+comp_target_types (location_t location, tree ttl, tree ttr)
{
int val;
tree mvl, mvr;
+ bool enum_and_int_p;
/* Do not lose qualifiers on element types of array types that are
pointer targets by taking their TYPE_MAIN_VARIANT. */
@@ -1093,10 +1120,16 @@ comp_target_types (tree ttl, tree ttr)
mvl = TYPE_MAIN_VARIANT (mvl);
if (TREE_CODE (mvr) != ARRAY_TYPE)
mvr = TYPE_MAIN_VARIANT (mvr);
- val = comptypes (mvl, mvr);
+ enum_and_int_p = false;
+ val = comptypes_check_enum_int (mvl, mvr, &enum_and_int_p);
if (val == 2)
- pedwarn (input_location, OPT_pedantic, "types are not quite compatible");
+ pedwarn (location, OPT_pedantic, "types are not quite compatible");
+
+ if (val == 1 && enum_and_int_p && warn_cxx_compat)
+ warning_at (location, OPT_Wc___compat,
+ "pointer target types incompatible in C++");
+
return val;
}
@@ -1184,10 +1217,11 @@ free_all_tagged_tu_seen_up_to (const struct tagged_tu_seen_cache *tu_til)
compatible. If the two types are not the same (which has been
checked earlier), this can only happen when multiple translation
units are being compiled. See C99 6.2.7 paragraph 1 for the exact
- rules. */
+ rules. ENUM_AND_INT_P is as in comptypes_internal. */
static int
-tagged_types_tu_compatible_p (const_tree t1, const_tree t2)
+tagged_types_tu_compatible_p (const_tree t1, const_tree t2,
+ bool *enum_and_int_p)
{
tree s1, s2;
bool needs_warning = false;
@@ -1297,7 +1331,8 @@ tagged_types_tu_compatible_p (const_tree t1, const_tree t2)
if (DECL_NAME (s1) != DECL_NAME (s2))
break;
- result = comptypes_internal (TREE_TYPE (s1), TREE_TYPE (s2));
+ result = comptypes_internal (TREE_TYPE (s1), TREE_TYPE (s2),
+ enum_and_int_p);
if (result != 1 && !DECL_NAME (s1))
break;
@@ -1332,7 +1367,8 @@ tagged_types_tu_compatible_p (const_tree t1, const_tree t2)
{
int result;
- result = comptypes_internal (TREE_TYPE (s1), TREE_TYPE (s2));
+ result = comptypes_internal (TREE_TYPE (s1), TREE_TYPE (s2),
+ enum_and_int_p);
if (result != 1 && !DECL_NAME (s1))
continue;
@@ -1374,7 +1410,8 @@ tagged_types_tu_compatible_p (const_tree t1, const_tree t2)
if (TREE_CODE (s1) != TREE_CODE (s2)
|| DECL_NAME (s1) != DECL_NAME (s2))
break;
- result = comptypes_internal (TREE_TYPE (s1), TREE_TYPE (s2));
+ result = comptypes_internal (TREE_TYPE (s1), TREE_TYPE (s2),
+ enum_and_int_p);
if (result == 0)
break;
if (result == 2)
@@ -1402,10 +1439,12 @@ tagged_types_tu_compatible_p (const_tree t1, const_tree t2)
the other must specify a fixed number of self-promoting arg types.
Otherwise, if one type specifies only the number of arguments,
the other must specify that number of self-promoting arg types.
- Otherwise, the argument types must match. */
+ Otherwise, the argument types must match.
+ ENUM_AND_INT_P is as in comptypes_internal. */
static int
-function_types_compatible_p (const_tree f1, const_tree f2)
+function_types_compatible_p (const_tree f1, const_tree f2,
+ bool *enum_and_int_p)
{
tree args1, args2;
/* 1 if no need for warning yet, 2 if warning cause has been seen. */
@@ -1426,7 +1465,7 @@ function_types_compatible_p (const_tree f1, const_tree f2)
if (TYPE_VOLATILE (ret2))
ret2 = build_qualified_type (TYPE_MAIN_VARIANT (ret2),
TYPE_QUALS (ret2) & ~TYPE_QUAL_VOLATILE);
- val = comptypes_internal (ret1, ret2);
+ val = comptypes_internal (ret1, ret2, enum_and_int_p);
if (val == 0)
return 0;
@@ -1444,7 +1483,8 @@ function_types_compatible_p (const_tree f1, const_tree f2)
compare that with the other type's arglist.
If they don't match, ask for a warning (but no error). */
if (TYPE_ACTUAL_ARG_TYPES (f1)
- && 1 != type_lists_compatible_p (args2, TYPE_ACTUAL_ARG_TYPES (f1)))
+ && 1 != type_lists_compatible_p (args2, TYPE_ACTUAL_ARG_TYPES (f1),
+ enum_and_int_p))
val = 2;
return val;
}
@@ -1453,22 +1493,24 @@ function_types_compatible_p (const_tree f1, const_tree f2)
if (!self_promoting_args_p (args1))
return 0;
if (TYPE_ACTUAL_ARG_TYPES (f2)
- && 1 != type_lists_compatible_p (args1, TYPE_ACTUAL_ARG_TYPES (f2)))
+ && 1 != type_lists_compatible_p (args1, TYPE_ACTUAL_ARG_TYPES (f2),
+ enum_and_int_p))
val = 2;
return val;
}
/* Both types have argument lists: compare them and propagate results. */
- val1 = type_lists_compatible_p (args1, args2);
+ val1 = type_lists_compatible_p (args1, args2, enum_and_int_p);
return val1 != 1 ? val1 : val;
}
-/* Check two lists of types for compatibility,
- returning 0 for incompatible, 1 for compatible,
- or 2 for compatible with warning. */
+/* Check two lists of types for compatibility, returning 0 for
+ incompatible, 1 for compatible, or 2 for compatible with
+ warning. ENUM_AND_INT_P is as in comptypes_internal. */
static int
-type_lists_compatible_p (const_tree args1, const_tree args2)
+type_lists_compatible_p (const_tree args1, const_tree args2,
+ bool *enum_and_int_p)
{
/* 1 if no need for warning yet, 2 if warning cause has been seen. */
int val = 1;
@@ -1507,7 +1549,7 @@ type_lists_compatible_p (const_tree args1, const_tree args2)
else if (TREE_CODE (a1) == ERROR_MARK
|| TREE_CODE (a2) == ERROR_MARK)
;
- else if (!(newval = comptypes_internal (mv1, mv2)))
+ else if (!(newval = comptypes_internal (mv1, mv2, enum_and_int_p)))
{
/* Allow wait (union {union wait *u; int *i} *)
and wait (union wait *) to be compatible. */
@@ -1526,7 +1568,7 @@ type_lists_compatible_p (const_tree args1, const_tree args2)
if (mv3 && mv3 != error_mark_node
&& TREE_CODE (mv3) != ARRAY_TYPE)
mv3 = TYPE_MAIN_VARIANT (mv3);
- if (comptypes_internal (mv3, mv2))
+ if (comptypes_internal (mv3, mv2, enum_and_int_p))
break;
}
if (memb == 0)
@@ -1547,7 +1589,7 @@ type_lists_compatible_p (const_tree args1, const_tree args2)
if (mv3 && mv3 != error_mark_node
&& TREE_CODE (mv3) != ARRAY_TYPE)
mv3 = TYPE_MAIN_VARIANT (mv3);
- if (comptypes_internal (mv3, mv1))
+ if (comptypes_internal (mv3, mv1, enum_and_int_p))
break;
}
if (memb == 0)
@@ -1614,7 +1656,7 @@ decl_constant_value (tree decl)
/* Convert the array expression EXP to a pointer. */
static tree
-array_to_pointer_conversion (tree exp)
+array_to_pointer_conversion (location_t loc, tree exp)
{
tree orig_exp = exp;
tree type = TREE_TYPE (exp);
@@ -1634,13 +1676,13 @@ array_to_pointer_conversion (tree exp)
if (TREE_CODE (exp) == INDIRECT_REF)
return convert (ptrtype, TREE_OPERAND (exp, 0));
- adr = build_unary_op (EXPR_LOCATION (exp), ADDR_EXPR, exp, 1);
+ adr = build_unary_op (loc, ADDR_EXPR, exp, 1);
return convert (ptrtype, adr);
}
/* Convert the function expression EXP to a pointer. */
static tree
-function_to_pointer_conversion (tree exp)
+function_to_pointer_conversion (location_t loc, tree exp)
{
tree orig_exp = exp;
@@ -1651,15 +1693,17 @@ function_to_pointer_conversion (tree exp)
if (TREE_NO_WARNING (orig_exp))
TREE_NO_WARNING (exp) = 1;
- return build_unary_op (EXPR_LOCATION (exp), ADDR_EXPR, exp, 0);
+ return build_unary_op (loc, ADDR_EXPR, exp, 0);
}
/* Perform the default conversion of arrays and functions to pointers.
Return the result of converting EXP. For any other expression, just
- return EXP. */
+ return EXP.
+
+ LOC is the location of the expression. */
struct c_expr
-default_function_array_conversion (struct c_expr exp)
+default_function_array_conversion (location_t loc, struct c_expr exp)
{
tree orig_exp = exp.value;
tree type = TREE_TYPE (exp.value);
@@ -1694,11 +1738,11 @@ default_function_array_conversion (struct c_expr exp)
return exp;
}
- exp.value = array_to_pointer_conversion (exp.value);
+ exp.value = array_to_pointer_conversion (loc, exp.value);
}
break;
case FUNCTION_TYPE:
- exp.value = function_to_pointer_conversion (exp.value);
+ exp.value = function_to_pointer_conversion (loc, exp.value);
break;
default:
break;
@@ -1766,6 +1810,7 @@ default_conversion (tree exp)
tree orig_exp;
tree type = TREE_TYPE (exp);
enum tree_code code = TREE_CODE (type);
+ tree promoted_type;
/* Functions and arrays have been converted during parsing. */
gcc_assert (code != FUNCTION_TYPE);
@@ -1793,6 +1838,10 @@ default_conversion (tree exp)
if (exp == error_mark_node)
return error_mark_node;
+ promoted_type = targetm.promoted_type (type);
+ if (promoted_type)
+ return convert (promoted_type, exp);
+
if (INTEGRAL_TYPE_P (type))
return perform_integral_promotions (exp);
@@ -1894,11 +1943,12 @@ lookup_field (tree decl, tree component)
return tree_cons (NULL_TREE, field, NULL_TREE);
}
-/* Make an expression to refer to the COMPONENT field of
- structure or union value DATUM. COMPONENT is an IDENTIFIER_NODE. */
+/* Make an expression to refer to the COMPONENT field of structure or
+ union value DATUM. COMPONENT is an IDENTIFIER_NODE. LOC is the
+ location of the COMPONENT_REF. */
tree
-build_component_ref (tree datum, tree component)
+build_component_ref (location_t loc, tree datum, tree component)
{
tree type = TREE_TYPE (datum);
enum tree_code code = TREE_CODE (type);
@@ -1923,7 +1973,7 @@ build_component_ref (tree datum, tree component)
if (!field)
{
- error ("%qT has no member named %qE", type, component);
+ error_at (loc, "%qT has no member named %qE", type, component);
return error_mark_node;
}
@@ -1956,6 +2006,7 @@ build_component_ref (tree datum, tree component)
ref = build3 (COMPONENT_REF, subtype, datum, subdatum,
NULL_TREE);
+ SET_EXPR_LOCATION (ref, loc);
if (TREE_READONLY (subdatum)
|| (use_datum_quals && TREE_READONLY (datum)))
TREE_READONLY (ref) = 1;
@@ -1975,8 +2026,9 @@ build_component_ref (tree datum, tree component)
return ref;
}
else if (code != ERROR_MARK)
- error ("request for member %qE in something not a structure or union",
- component);
+ error_at (loc,
+ "request for member %qE in something not a structure or union",
+ component);
return error_mark_node;
}
@@ -2027,7 +2079,7 @@ build_indirect_ref (location_t loc, tree ptr, const char *errorstring)
error_at (loc, "dereferencing pointer to incomplete type");
return error_mark_node;
}
- if (VOID_TYPE_P (t) && skip_evaluation == 0)
+ if (VOID_TYPE_P (t) && c_inhibit_evaluation_warnings == 0)
warning_at (loc, 0, "dereferencing %<void *%> pointer");
/* We *must* set TREE_READONLY when dereferencing a pointer to const,
@@ -2063,7 +2115,7 @@ build_indirect_ref (location_t loc, tree ptr, const char *errorstring)
LOC is the location to use for the returned expression. */
tree
-build_array_ref (tree array, tree index, location_t loc)
+build_array_ref (location_t loc, tree array, tree index)
{
tree ret;
bool swapped = false;
@@ -2193,7 +2245,7 @@ build_array_ref (tree array, tree index, location_t loc)
for CONST_DECLs defined as enum constants. If the type of the
identifier is not available, *TYPE is set to NULL. */
tree
-build_external_ref (tree id, int fun, location_t loc, tree *type)
+build_external_ref (location_t loc, tree id, int fun, tree *type)
{
tree ref;
tree decl = lookup_name (id);
@@ -2210,14 +2262,14 @@ build_external_ref (tree id, int fun, location_t loc, tree *type)
}
else if (fun)
/* Implicit function declaration. */
- ref = implicitly_declare (id);
+ ref = implicitly_declare (loc, id);
else if (decl == error_mark_node)
/* Don't complain about something that's already been
complained about. */
return error_mark_node;
else
{
- undeclared_variable (id, loc);
+ undeclared_variable (loc, id);
return error_mark_node;
}
@@ -2343,7 +2395,7 @@ pop_maybe_used (bool used)
/* Return the result of sizeof applied to EXPR. */
struct c_expr
-c_expr_sizeof_expr (struct c_expr expr)
+c_expr_sizeof_expr (location_t loc, struct c_expr expr)
{
struct c_expr ret;
if (expr.value == error_mark_node)
@@ -2358,7 +2410,7 @@ c_expr_sizeof_expr (struct c_expr expr)
bool expr_const_operands = true;
tree folded_expr = c_fully_fold (expr.value, require_constant_value,
&expr_const_operands);
- ret.value = c_sizeof (TREE_TYPE (folded_expr));
+ ret.value = c_sizeof (loc, TREE_TYPE (folded_expr));
ret.original_code = ERROR_MARK;
ret.original_type = NULL;
if (c_vla_type_p (TREE_TYPE (folded_expr)))
@@ -2367,6 +2419,7 @@ c_expr_sizeof_expr (struct c_expr expr)
ret.value = build2 (C_MAYBE_CONST_EXPR, TREE_TYPE (ret.value),
folded_expr, ret.value);
C_MAYBE_CONST_EXPR_NON_CONST (ret.value) = !expr_const_operands;
+ SET_EXPR_LOCATION (ret.value, loc);
}
pop_maybe_used (C_TYPE_VARIABLE_SIZE (TREE_TYPE (folded_expr)));
}
@@ -2374,17 +2427,18 @@ c_expr_sizeof_expr (struct c_expr expr)
}
/* Return the result of sizeof applied to T, a structure for the type
- name passed to sizeof (rather than the type itself). */
+ name passed to sizeof (rather than the type itself). LOC is the
+ location of the original expression. */
struct c_expr
-c_expr_sizeof_type (struct c_type_name *t)
+c_expr_sizeof_type (location_t loc, struct c_type_name *t)
{
tree type;
struct c_expr ret;
tree type_expr = NULL_TREE;
bool type_expr_const = true;
type = groktypename (t, &type_expr, &type_expr_const);
- ret.value = c_sizeof (type);
+ ret.value = c_sizeof (loc, type);
ret.original_code = ERROR_MARK;
ret.original_type = NULL;
if ((type_expr || TREE_CODE (ret.value) == INTEGER_CST)
@@ -2409,12 +2463,13 @@ c_expr_sizeof_type (struct c_type_name *t)
}
/* Build a function call to function FUNCTION with parameters PARAMS.
+ The function call is at LOC.
PARAMS is a list--a chain of TREE_LIST nodes--in which the
TREE_VALUE of each node is a parameter-expression.
FUNCTION's data type may be a function type or a pointer-to-function. */
tree
-build_function_call (tree function, tree params)
+build_function_call (location_t loc, tree function, tree params)
{
VEC(tree,gc) *vec;
tree ret;
@@ -2422,7 +2477,7 @@ build_function_call (tree function, tree params)
vec = VEC_alloc (tree, gc, list_length (params));
for (; params; params = TREE_CHAIN (params))
VEC_quick_push (tree, vec, TREE_VALUE (params));
- ret = build_function_call_vec (function, vec, NULL);
+ ret = build_function_call_vec (loc, function, vec, NULL);
VEC_free (tree, gc, vec);
return ret;
}
@@ -2436,7 +2491,7 @@ build_function_call (tree function, tree params)
PARAMS. */
tree
-build_function_call_vec (tree function, VEC(tree,gc) *params,
+build_function_call_vec (location_t loc, tree function, VEC(tree,gc) *params,
VEC(tree,gc) *origtypes)
{
tree fntype, fundecl = 0;
@@ -2456,7 +2511,7 @@ build_function_call_vec (tree function, VEC(tree,gc) *params,
resolve_overloaded_builtin and targetm.resolve_overloaded_builtin
handle all the type checking. The result is a complete expression
that implements this function call. */
- tem = resolve_overloaded_builtin (function, params);
+ tem = resolve_overloaded_builtin (loc, function, params);
if (tem)
return tem;
@@ -2464,7 +2519,7 @@ build_function_call_vec (tree function, VEC(tree,gc) *params,
fundecl = function;
}
if (TREE_CODE (TREE_TYPE (function)) == FUNCTION_TYPE)
- function = function_to_pointer_conversion (function);
+ function = function_to_pointer_conversion (loc, function);
/* For Objective-C, convert any calls via a cast to OBJC_TYPE_REF
expressions, like those used for ObjC messenger dispatches. */
@@ -2482,7 +2537,7 @@ build_function_call_vec (tree function, VEC(tree,gc) *params,
if (!(TREE_CODE (fntype) == POINTER_TYPE
&& TREE_CODE (TREE_TYPE (fntype)) == FUNCTION_TYPE))
{
- error ("called object %qE is not a function", function);
+ error_at (loc, "called object %qE is not a function", function);
return error_mark_node;
}
@@ -2511,17 +2566,17 @@ build_function_call_vec (tree function, VEC(tree,gc) *params,
&& !comptypes (fntype, TREE_TYPE (tem)))
{
tree return_type = TREE_TYPE (fntype);
- tree trap = build_function_call (built_in_decls[BUILT_IN_TRAP],
+ tree trap = build_function_call (loc, built_in_decls[BUILT_IN_TRAP],
NULL_TREE);
int i;
/* This situation leads to run-time undefined behavior. We can't,
therefore, simply error unless we can prove that all possible
executions of the program must execute the code. */
- if (warning (0, "function called through a non-compatible type"))
+ if (warning_at (loc, 0, "function called through a non-compatible type"))
/* We can, however, treat "undefined" any way we please.
Call abort to encourage the user to fix the program. */
- inform (input_location, "if this code is reached, the program will abort");
+ inform (loc, "if this code is reached, the program will abort");
/* Before the abort, allow the function arguments to exit or
call longjmp. */
for (i = 0; i < nargs; i++)
@@ -2540,7 +2595,7 @@ build_function_call_vec (tree function, VEC(tree,gc) *params,
tree rhs;
if (AGGREGATE_TYPE_P (return_type))
- rhs = build_compound_literal (return_type,
+ rhs = build_compound_literal (loc, return_type,
build_constructor (return_type, 0),
false);
else
@@ -2806,7 +2861,8 @@ convert_arguments (tree typelist, VEC(tree,gc) *values,
and the actual arg is that enum type. */
;
else if (formal_prec != TYPE_PRECISION (type1))
- warning (OPT_Wtraditional_conversion, "passing argument %d of %qE "
+ warning (OPT_Wtraditional_conversion,
+ "passing argument %d of %qE "
"with different width due to prototype",
argnum, rname);
else if (TYPE_UNSIGNED (type) == TYPE_UNSIGNED (type1))
@@ -2829,11 +2885,13 @@ convert_arguments (tree typelist, VEC(tree,gc) *values,
&& TYPE_UNSIGNED (valtype))
;
else if (TYPE_UNSIGNED (type))
- warning (OPT_Wtraditional_conversion, "passing argument %d of %qE "
+ warning (OPT_Wtraditional_conversion,
+ "passing argument %d of %qE "
"as unsigned due to prototype",
argnum, rname);
else
- warning (OPT_Wtraditional_conversion, "passing argument %d of %qE "
+ warning (OPT_Wtraditional_conversion,
+ "passing argument %d of %qE "
"as signed due to prototype", argnum, rname);
}
}
@@ -2845,8 +2903,8 @@ convert_arguments (tree typelist, VEC(tree,gc) *values,
origtype = (origtypes == NULL
? NULL_TREE
: VEC_index (tree, origtypes, parmnum));
- parmval = convert_for_assignment (type, val, origtype,
- ic_argpass, npc,
+ parmval = convert_for_assignment (input_location, type, val,
+ origtype, ic_argpass, npc,
fundecl, function,
parmnum + 1);
@@ -2907,7 +2965,7 @@ convert_arguments (tree typelist, VEC(tree,gc) *values,
*/
struct c_expr
-parser_build_unary_op (enum tree_code code, struct c_expr arg, location_t loc)
+parser_build_unary_op (location_t loc, enum tree_code code, struct c_expr arg)
{
struct c_expr result;
@@ -2916,7 +2974,7 @@ parser_build_unary_op (enum tree_code code, struct c_expr arg, location_t loc)
result.original_type = NULL;
if (TREE_OVERFLOW_P (result.value) && !TREE_OVERFLOW_P (arg.value))
- overflow_warning (result.value);
+ overflow_warning (loc, result.value);
return result;
}
@@ -2961,7 +3019,7 @@ parser_build_binary_op (location_t location, enum tree_code code,
warn_about_parentheses (code, code1, arg1.value, code2, arg2.value);
if (warn_logical_op)
- warn_logical_operator (input_location, code,
+ warn_logical_operator (input_location, code, TREE_TYPE (result.value),
code1, arg1.value, code2, arg2.value);
/* Warn about comparisons against string literals, with the exception
@@ -2970,16 +3028,18 @@ parser_build_binary_op (location_t location, enum tree_code code,
{
if ((code1 == STRING_CST && !integer_zerop (arg2.value))
|| (code2 == STRING_CST && !integer_zerop (arg1.value)))
- warning (OPT_Waddress, "comparison with string literal results in unspecified behavior");
+ warning_at (location, OPT_Waddress,
+ "comparison with string literal results in unspecified behavior");
}
else if (TREE_CODE_CLASS (code) == tcc_comparison
&& (code1 == STRING_CST || code2 == STRING_CST))
- warning (OPT_Waddress, "comparison with string literal results in unspecified behavior");
+ warning_at (location, OPT_Waddress,
+ "comparison with string literal results in unspecified behavior");
if (TREE_OVERFLOW_P (result.value)
&& !TREE_OVERFLOW_P (arg1.value)
&& !TREE_OVERFLOW_P (arg2.value))
- overflow_warning (result.value);
+ overflow_warning (location, result.value);
/* Warn about comparisons of different enum types. */
if (warn_enum_compare
@@ -3267,6 +3327,16 @@ build_unary_op (location_t location,
: lv_decrement)))
return error_mark_node;
+ if (warn_cxx_compat && TREE_CODE (TREE_TYPE (arg)) == ENUMERAL_TYPE)
+ {
+ if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
+ warning_at (location, OPT_Wc___compat,
+ "increment of enumeration value is invalid in C++");
+ else
+ warning_at (location, OPT_Wc___compat,
+ "decrement of enumeration value is invalid in C++");
+ }
+
/* Ensure the argument is fully folded inside any SAVE_EXPR. */
arg = c_fully_fold (arg, false, NULL);
@@ -3418,7 +3488,8 @@ build_unary_op (location_t location,
return error_mark_node;
return build_binary_op (location, PLUS_EXPR,
(TREE_CODE (TREE_TYPE (op0)) == ARRAY_TYPE
- ? array_to_pointer_conversion (op0)
+ ? array_to_pointer_conversion (location,
+ op0)
: op0),
TREE_OPERAND (arg, 1), 1);
}
@@ -3695,10 +3766,11 @@ c_mark_addressable (tree exp)
IFEXP_BCP then the condition is a call to __builtin_constant_p, and
if folded to an integer constant then the unselected half may
contain arbitrary operations not normally permitted in constant
- expressions. */
+ expressions. Set the location of the expression to LOC. */
tree
-build_conditional_expr (tree ifexp, bool ifexp_bcp, tree op1, tree op2)
+build_conditional_expr (location_t colon_loc, tree ifexp, bool ifexp_bcp,
+ tree op1, tree op2)
{
tree type1;
tree type2;
@@ -3743,7 +3815,7 @@ build_conditional_expr (tree ifexp, bool ifexp_bcp, tree op1, tree op2)
In C99 they will be pointers by now. */
if (code1 == ARRAY_TYPE || code2 == ARRAY_TYPE)
{
- error ("non-lvalue array in conditional expression");
+ error_at (colon_loc, "non-lvalue array in conditional expression");
return error_mark_node;
}
@@ -3792,7 +3864,7 @@ build_conditional_expr (tree ifexp, bool ifexp_bcp, tree op1, tree op2)
and later code won't know it used to be different.
Do this check on the original types, so that explicit casts
will be considered, but default promotions won't. */
- if (!skip_evaluation)
+ if (c_inhibit_evaluation_warnings == 0)
{
int unsigned_op1 = TYPE_UNSIGNED (TREE_TYPE (orig_op1));
int unsigned_op2 = TYPE_UNSIGNED (TREE_TYPE (orig_op2));
@@ -3832,7 +3904,9 @@ build_conditional_expr (tree ifexp, bool ifexp_bcp, tree op1, tree op2)
&& tree_expr_nonnegative_warnv_p (op2, &ovf)))
/* OK */;
else
- warning (OPT_Wsign_compare, "signed and unsigned type in conditional expression");
+ warning_at (colon_loc, OPT_Wsign_compare,
+ ("signed and unsigned type in "
+ "conditional expression"));
}
if (!op1_maybe_const || TREE_CODE (op1) != INTEGER_CST)
{
@@ -3853,13 +3927,13 @@ build_conditional_expr (tree ifexp, bool ifexp_bcp, tree op1, tree op2)
else if (code1 == VOID_TYPE || code2 == VOID_TYPE)
{
if (code1 != VOID_TYPE || code2 != VOID_TYPE)
- pedwarn (input_location, OPT_pedantic,
+ pedwarn (colon_loc, OPT_pedantic,
"ISO C forbids conditional expr with only one void side");
result_type = void_type_node;
}
else if (code1 == POINTER_TYPE && code2 == POINTER_TYPE)
{
- if (comp_target_types (type1, type2))
+ if (comp_target_types (colon_loc, type1, type2))
result_type = common_pointer_type (type1, type2);
else if (null_pointer_constant_p (orig_op1))
result_type = qualify_type (type2, type1);
@@ -3868,7 +3942,7 @@ build_conditional_expr (tree ifexp, bool ifexp_bcp, tree op1, tree op2)
else if (VOID_TYPE_P (TREE_TYPE (type1)))
{
if (TREE_CODE (TREE_TYPE (type2)) == FUNCTION_TYPE)
- pedwarn (input_location, OPT_pedantic,
+ pedwarn (colon_loc, OPT_pedantic,
"ISO C forbids conditional expr between "
"%<void *%> and function pointer");
result_type = build_pointer_type (qualify_type (TREE_TYPE (type1),
@@ -3877,7 +3951,7 @@ build_conditional_expr (tree ifexp, bool ifexp_bcp, tree op1, tree op2)
else if (VOID_TYPE_P (TREE_TYPE (type2)))
{
if (TREE_CODE (TREE_TYPE (type1)) == FUNCTION_TYPE)
- pedwarn (input_location, OPT_pedantic,
+ pedwarn (colon_loc, OPT_pedantic,
"ISO C forbids conditional expr between "
"%<void *%> and function pointer");
result_type = build_pointer_type (qualify_type (TREE_TYPE (type2),
@@ -3886,7 +3960,7 @@ build_conditional_expr (tree ifexp, bool ifexp_bcp, tree op1, tree op2)
else
{
if (!objc_ok)
- pedwarn (input_location, 0,
+ pedwarn (colon_loc, 0,
"pointer type mismatch in conditional expression");
result_type = build_pointer_type (void_type_node);
}
@@ -3894,7 +3968,7 @@ build_conditional_expr (tree ifexp, bool ifexp_bcp, tree op1, tree op2)
else if (code1 == POINTER_TYPE && code2 == INTEGER_TYPE)
{
if (!null_pointer_constant_p (orig_op2))
- pedwarn (input_location, 0,
+ pedwarn (colon_loc, 0,
"pointer/integer type mismatch in conditional expression");
else
{
@@ -3905,7 +3979,7 @@ build_conditional_expr (tree ifexp, bool ifexp_bcp, tree op1, tree op2)
else if (code2 == POINTER_TYPE && code1 == INTEGER_TYPE)
{
if (!null_pointer_constant_p (orig_op1))
- pedwarn (input_location, 0,
+ pedwarn (colon_loc, 0,
"pointer/integer type mismatch in conditional expression");
else
{
@@ -3920,7 +3994,7 @@ build_conditional_expr (tree ifexp, bool ifexp_bcp, tree op1, tree op2)
result_type = void_type_node;
else
{
- error ("type mismatch in conditional expression");
+ error_at (colon_loc, "type mismatch in conditional expression");
return error_mark_node;
}
}
@@ -3969,14 +4043,17 @@ build_conditional_expr (tree ifexp, bool ifexp_bcp, tree op1, tree op2)
if (ep_result_type)
ret = build1 (EXCESS_PRECISION_EXPR, ep_result_type, ret);
+ protected_set_expr_location (ret, colon_loc);
return ret;
}
/* Return a compound expression that performs two expressions and
- returns the value of the second of them. */
+ returns the value of the second of them.
+
+ LOC is the location of the COMPOUND_EXPR. */
tree
-build_compound_expr (tree expr1, tree expr2)
+build_compound_expr (location_t loc, tree expr1, tree expr2)
{
bool expr1_int_operands, expr2_int_operands;
tree eptype = NULL_TREE;
@@ -4012,8 +4089,8 @@ build_compound_expr (tree expr1, tree expr2)
&& CONVERT_EXPR_P (TREE_OPERAND (expr1, 1)))
; /* (void) a, (void) b, c */
else
- warning (OPT_Wunused_value,
- "left-hand operand of comma expression has no effect");
+ warning_at (loc, OPT_Wunused_value,
+ "left-hand operand of comma expression has no effect");
}
}
@@ -4022,7 +4099,7 @@ build_compound_expr (tree expr1, tree expr2)
`foo() + bar(), baz()' the result of the `+' operator is not used,
so we should issue a warning. */
else if (warn_unused_value)
- warn_if_unused_value (expr1, input_location);
+ warn_if_unused_value (expr1, loc);
if (expr2 == error_mark_node)
return error_mark_node;
@@ -4037,13 +4114,102 @@ build_compound_expr (tree expr1, tree expr2)
if (eptype)
ret = build1 (EXCESS_PRECISION_EXPR, eptype, ret);
+ protected_set_expr_location (ret, loc);
return ret;
}
-/* Build an expression representing a cast to type TYPE of expression EXPR. */
+/* Issue -Wcast-qual warnings when appropriate. TYPE is the type to
+ which we are casting. OTYPE is the type of the expression being
+ cast. Both TYPE and OTYPE are pointer types. -Wcast-qual appeared
+ on the command line. */
+
+static void
+handle_warn_cast_qual (tree type, tree otype)
+{
+ tree in_type = type;
+ tree in_otype = otype;
+ int added = 0;
+ int discarded = 0;
+ bool is_const;
+
+ /* Check that the qualifiers on IN_TYPE are a superset of the
+ qualifiers of IN_OTYPE. The outermost level of POINTER_TYPE
+ nodes is uninteresting and we stop as soon as we hit a
+ non-POINTER_TYPE node on either type. */
+ do
+ {
+ in_otype = TREE_TYPE (in_otype);
+ in_type = TREE_TYPE (in_type);
+
+ /* GNU C allows cv-qualified function types. 'const' means the
+ function is very pure, 'volatile' means it can't return. We
+ need to warn when such qualifiers are added, not when they're
+ taken away. */
+ if (TREE_CODE (in_otype) == FUNCTION_TYPE
+ && TREE_CODE (in_type) == FUNCTION_TYPE)
+ added |= (TYPE_QUALS (in_type) & ~TYPE_QUALS (in_otype));
+ else
+ discarded |= (TYPE_QUALS (in_otype) & ~TYPE_QUALS (in_type));
+ }
+ while (TREE_CODE (in_type) == POINTER_TYPE
+ && TREE_CODE (in_otype) == POINTER_TYPE);
+
+ if (added)
+ warning (OPT_Wcast_qual, "cast adds new qualifiers to function type");
+
+ if (discarded)
+ /* There are qualifiers present in IN_OTYPE that are not present
+ in IN_TYPE. */
+ warning (OPT_Wcast_qual,
+ "cast discards qualifiers from pointer target type");
+
+ if (added || discarded)
+ return;
+
+ /* A cast from **T to const **T is unsafe, because it can cause a
+ const value to be changed with no additional warning. We only
+ issue this warning if T is the same on both sides, and we only
+ issue the warning if there are the same number of pointers on
+ both sides, as otherwise the cast is clearly unsafe anyhow. A
+ cast is unsafe when a qualifier is added at one level and const
+ is not present at all outer levels.
+
+ To issue this warning, we check at each level whether the cast
+ adds new qualifiers not already seen. We don't need to special
+ case function types, as they won't have the same
+ TYPE_MAIN_VARIANT. */
+
+ if (TYPE_MAIN_VARIANT (in_type) != TYPE_MAIN_VARIANT (in_otype))
+ return;
+ if (TREE_CODE (TREE_TYPE (type)) != POINTER_TYPE)
+ return;
+
+ in_type = type;
+ in_otype = otype;
+ is_const = TYPE_READONLY (TREE_TYPE (in_type));
+ do
+ {
+ in_type = TREE_TYPE (in_type);
+ in_otype = TREE_TYPE (in_otype);
+ if ((TYPE_QUALS (in_type) &~ TYPE_QUALS (in_otype)) != 0
+ && !is_const)
+ {
+ warning (OPT_Wcast_qual,
+ ("new qualifiers in middle of multi-level non-const cast "
+ "are unsafe"));
+ break;
+ }
+ if (is_const)
+ is_const = TYPE_READONLY (in_type);
+ }
+ while (TREE_CODE (in_type) == POINTER_TYPE);
+}
+
+/* Build an expression representing a cast to type TYPE of expression EXPR.
+ LOC is the location of the cast-- typically the open paren of the cast. */
tree
-build_c_cast (tree type, tree expr)
+build_c_cast (location_t loc, tree type, tree expr)
{
tree value;
@@ -4065,13 +4231,13 @@ build_c_cast (tree type, tree expr)
if (TREE_CODE (type) == ARRAY_TYPE)
{
- error ("cast specifies array type");
+ error_at (loc, "cast specifies array type");
return error_mark_node;
}
if (TREE_CODE (type) == FUNCTION_TYPE)
{
- error ("cast specifies function type");
+ error_at (loc, "cast specifies function type");
return error_mark_node;
}
@@ -4086,7 +4252,7 @@ build_c_cast (tree type, tree expr)
{
if (TREE_CODE (type) == RECORD_TYPE
|| TREE_CODE (type) == UNION_TYPE)
- pedwarn (input_location, OPT_pedantic,
+ pedwarn (loc, OPT_pedantic,
"ISO C forbids casting nonscalar to the same type");
}
else if (TREE_CODE (type) == UNION_TYPE)
@@ -4103,15 +4269,14 @@ build_c_cast (tree type, tree expr)
{
tree t;
- pedwarn (input_location, OPT_pedantic,
- "ISO C forbids casts to union type");
- t = digest_init (type,
+ pedwarn (loc, OPT_pedantic, "ISO C forbids casts to union type");
+ t = digest_init (loc, type,
build_constructor_single (type, field, value),
NULL_TREE, false, true, 0);
TREE_CONSTANT (t) = TREE_CONSTANT (value);
return t;
}
- error ("cast to union type from type not present in union");
+ error_at (loc, "cast to union type from type not present in union");
return error_mark_node;
}
else
@@ -4119,51 +4284,19 @@ build_c_cast (tree type, tree expr)
tree otype, ovalue;
if (type == void_type_node)
- return build1 (CONVERT_EXPR, type, value);
+ {
+ tree t = build1 (CONVERT_EXPR, type, value);
+ SET_EXPR_LOCATION (t, loc);
+ return t;
+ }
otype = TREE_TYPE (value);
/* Optionally warn about potentially worrisome casts. */
-
if (warn_cast_qual
&& TREE_CODE (type) == POINTER_TYPE
&& TREE_CODE (otype) == POINTER_TYPE)
- {
- tree in_type = type;
- tree in_otype = otype;
- int added = 0;
- int discarded = 0;
-
- /* Check that the qualifiers on IN_TYPE are a superset of
- the qualifiers of IN_OTYPE. The outermost level of
- POINTER_TYPE nodes is uninteresting and we stop as soon
- as we hit a non-POINTER_TYPE node on either type. */
- do
- {
- in_otype = TREE_TYPE (in_otype);
- in_type = TREE_TYPE (in_type);
-
- /* GNU C allows cv-qualified function types. 'const'
- means the function is very pure, 'volatile' means it
- can't return. We need to warn when such qualifiers
- are added, not when they're taken away. */
- if (TREE_CODE (in_otype) == FUNCTION_TYPE
- && TREE_CODE (in_type) == FUNCTION_TYPE)
- added |= (TYPE_QUALS (in_type) & ~TYPE_QUALS (in_otype));
- else
- discarded |= (TYPE_QUALS (in_otype) & ~TYPE_QUALS (in_type));
- }
- while (TREE_CODE (in_type) == POINTER_TYPE
- && TREE_CODE (in_otype) == POINTER_TYPE);
-
- if (added)
- warning (OPT_Wcast_qual, "cast adds new qualifiers to function type");
-
- if (discarded)
- /* There are qualifiers present in IN_OTYPE that are not
- present in IN_TYPE. */
- warning (OPT_Wcast_qual, "cast discards qualifiers from pointer target type");
- }
+ handle_warn_cast_qual (type, otype);
/* Warn about possible alignment problems. */
if (STRICT_ALIGNMENT
@@ -4177,8 +4310,8 @@ build_c_cast (tree type, tree expr)
|| TREE_CODE (TREE_TYPE (otype)) == RECORD_TYPE)
&& TYPE_MODE (TREE_TYPE (otype)) == VOIDmode)
&& TYPE_ALIGN (TREE_TYPE (type)) > TYPE_ALIGN (TREE_TYPE (otype)))
- warning (OPT_Wcast_align,
- "cast increases required alignment of target type");
+ warning_at (loc, OPT_Wcast_align,
+ "cast increases required alignment of target type");
if (TREE_CODE (type) == INTEGER_TYPE
&& TREE_CODE (otype) == POINTER_TYPE
@@ -4188,21 +4321,23 @@ build_c_cast (tree type, tree expr)
of cases such as SIG_*, warn about converting constant
pointers to integers. In some cases it may cause unwanted
sign extension, and a warning is appropriate. */
- warning (OPT_Wpointer_to_int_cast,
- "cast from pointer to integer of different size");
+ warning_at (loc, OPT_Wpointer_to_int_cast,
+ "cast from pointer to integer of different size");
if (TREE_CODE (value) == CALL_EXPR
&& TREE_CODE (type) != TREE_CODE (otype))
- warning (OPT_Wbad_function_cast, "cast from function call of type %qT "
- "to non-matching type %qT", otype, type);
+ warning_at (loc, OPT_Wbad_function_cast,
+ "cast from function call of type %qT "
+ "to non-matching type %qT", otype, type);
if (TREE_CODE (type) == POINTER_TYPE
&& TREE_CODE (otype) == INTEGER_TYPE
&& TYPE_PRECISION (type) != TYPE_PRECISION (otype)
/* Don't warn about converting any constant. */
&& !TREE_CONSTANT (value))
- warning (OPT_Wint_to_pointer_cast, "cast to pointer from integer "
- "of different size");
+ warning_at (loc,
+ OPT_Wint_to_pointer_cast, "cast to pointer from integer "
+ "of different size");
if (warn_strict_aliasing <= 2)
strict_aliasing_warning (otype, type, expr);
@@ -4215,7 +4350,7 @@ build_c_cast (tree type, tree expr)
&& TREE_CODE (otype) == POINTER_TYPE
&& TREE_CODE (TREE_TYPE (otype)) == FUNCTION_TYPE
&& TREE_CODE (TREE_TYPE (type)) != FUNCTION_TYPE)
- pedwarn (input_location, OPT_pedantic, "ISO C forbids "
+ pedwarn (loc, OPT_pedantic, "ISO C forbids "
"conversion of function pointer to object pointer type");
if (pedantic
@@ -4224,7 +4359,7 @@ build_c_cast (tree type, tree expr)
&& TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE
&& TREE_CODE (TREE_TYPE (otype)) != FUNCTION_TYPE
&& !null_pointer_constant_p (value))
- pedwarn (input_location, OPT_pedantic, "ISO C forbids "
+ pedwarn (loc, OPT_pedantic, "ISO C forbids "
"conversion of object pointer to function pointer type");
ovalue = value;
@@ -4268,12 +4403,16 @@ build_c_cast (tree type, tree expr)
|| TREE_CODE (expr) == COMPLEX_CST)))
value = build1 (NOP_EXPR, type, value);
+ if (CAN_HAVE_LOCATION_P (value))
+ SET_EXPR_LOCATION (value, loc);
return value;
}
-/* Interpret a cast of expression EXPR to type TYPE. */
+/* Interpret a cast of expression EXPR to type TYPE. LOC is the
+ location of the open paren of the cast, or the position of the cast
+ expr. */
tree
-c_cast_expr (struct c_type_name *type_name, tree expr, location_t loc)
+c_cast_expr (location_t loc, struct c_type_name *type_name, tree expr)
{
tree type;
tree type_expr = NULL_TREE;
@@ -4288,11 +4427,12 @@ c_cast_expr (struct c_type_name *type_name, tree expr, location_t loc)
type = groktypename (type_name, &type_expr, &type_expr_const);
warn_strict_prototypes = saved_wsp;
- ret = build_c_cast (type, expr);
+ ret = build_c_cast (loc, type, expr);
if (type_expr)
{
ret = build2 (C_MAYBE_CONST_EXPR, TREE_TYPE (ret), type_expr, ret);
C_MAYBE_CONST_EXPR_NON_CONST (ret) = !type_expr_const;
+ SET_EXPR_LOCATION (ret, loc);
}
if (CAN_HAVE_LOCATION_P (ret) && !EXPR_HAS_LOCATION (ret))
@@ -4315,11 +4455,13 @@ c_cast_expr (struct c_type_name *type_name, tree expr, location_t loc)
If RHS_ORIGTYPE is not NULL_TREE, it is the original type of RHS,
which may differ from TREE_TYPE (RHS) for an enum value.
- LOCATION is the location of the MODIFYCODE operator. */
+ LOCATION is the location of the MODIFYCODE operator.
+ RHS_LOC is the location of the RHS. */
tree
build_modify_expr (location_t location, tree lhs, tree lhs_origtype,
- enum tree_code modifycode, tree rhs, tree rhs_origtype)
+ enum tree_code modifycode,
+ location_t rhs_loc, tree rhs, tree rhs_origtype)
{
tree result;
tree newrhs;
@@ -4349,7 +4491,7 @@ build_modify_expr (location_t location, tree lhs, tree lhs_origtype,
if (TREE_CODE (lhs) == C_MAYBE_CONST_EXPR)
{
tree inner = build_modify_expr (location, C_MAYBE_CONST_EXPR_EXPR (lhs),
- lhs_origtype, modifycode, rhs,
+ lhs_origtype, modifycode, rhs_loc, rhs,
rhs_origtype);
if (inner == error_mark_node)
return error_mark_node;
@@ -4435,8 +4577,8 @@ build_modify_expr (location_t location, tree lhs, tree lhs_origtype,
newrhs = c_fully_fold (newrhs, false, NULL);
if (rhs_semantic_type)
newrhs = build1 (EXCESS_PRECISION_EXPR, rhs_semantic_type, newrhs);
- newrhs = convert_for_assignment (lhstype, newrhs, rhs_origtype, ic_assign,
- npc, NULL_TREE, NULL_TREE, 0);
+ newrhs = convert_for_assignment (location, lhstype, newrhs, rhs_origtype,
+ ic_assign, npc, NULL_TREE, NULL_TREE, 0);
if (TREE_CODE (newrhs) == ERROR_MARK)
return error_mark_node;
@@ -4465,8 +4607,8 @@ build_modify_expr (location_t location, tree lhs, tree lhs_origtype,
if (olhstype == TREE_TYPE (result))
return result;
- result = convert_for_assignment (olhstype, result, rhs_origtype, ic_assign,
- false, NULL_TREE, NULL_TREE, 0);
+ result = convert_for_assignment (location, olhstype, result, rhs_origtype,
+ ic_assign, false, NULL_TREE, NULL_TREE, 0);
protected_set_expr_location (result, location);
return result;
}
@@ -4482,13 +4624,15 @@ build_modify_expr (location_t location, tree lhs, tree lhs_origtype,
ERRTYPE says whether it is argument passing, assignment,
initialization or return.
+ LOCATION is the location of the RHS.
FUNCTION is a tree for the function being called.
PARMNUM is the number of the argument, for printing in error messages. */
static tree
-convert_for_assignment (tree type, tree rhs, tree origtype,
- enum impl_conv errtype, bool null_pointer_constant,
- tree fundecl, tree function, int parmnum)
+convert_for_assignment (location_t location, tree type, tree rhs,
+ tree origtype, enum impl_conv errtype,
+ bool null_pointer_constant, tree fundecl,
+ tree function, int parmnum)
{
enum tree_code codel = TREE_CODE (type);
tree orig_rhs = rhs;
@@ -4519,14 +4663,14 @@ convert_for_assignment (tree type, tree rhs, tree origtype,
/* This macro is used to emit diagnostics to ensure that all format
strings are complete sentences, visible to gettext and checked at
compile time. */
-#define WARN_FOR_ASSIGNMENT(LOCATION, OPT, AR, AS, IN, RE) \
+#define WARN_FOR_ASSIGNMENT(LOCATION, OPT, AR, AS, IN, RE) \
do { \
switch (errtype) \
{ \
case ic_argpass: \
if (pedwarn (LOCATION, OPT, AR, parmnum, rname)) \
- inform ((fundecl && !DECL_IS_BUILTIN (fundecl)) \
- ? DECL_SOURCE_LOCATION (fundecl) : LOCATION, \
+ inform ((fundecl && !DECL_IS_BUILTIN (fundecl)) \
+ ? DECL_SOURCE_LOCATION (fundecl) : LOCATION, \
"expected %qT but argument is of type %qT", \
type, rhstype); \
break; \
@@ -4537,7 +4681,7 @@ convert_for_assignment (tree type, tree rhs, tree origtype,
pedwarn (LOCATION, OPT, IN); \
break; \
case ic_return: \
- pedwarn (LOCATION, OPT, RE); \
+ pedwarn (LOCATION, OPT, RE); \
break; \
default: \
gcc_unreachable (); \
@@ -4608,7 +4752,7 @@ convert_for_assignment (tree type, tree rhs, tree origtype,
an unprototyped function, it is compile-time undefined;
making it a constraint in that case was rejected in
DR#252. */
- error ("void value not ignored as it ought to be");
+ error_at (location, "void value not ignored as it ought to be");
return error_mark_node;
}
rhs = require_complete_type (rhs);
@@ -4622,12 +4766,13 @@ convert_for_assignment (tree type, tree rhs, tree origtype,
{
if (!lvalue_p (rhs))
{
- error ("cannot pass rvalue to reference parameter");
+ error_at (location, "cannot pass rvalue to reference parameter");
return error_mark_node;
}
if (!c_mark_addressable (rhs))
return error_mark_node;
rhs = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (rhs)), rhs);
+ SET_EXPR_LOCATION (rhs, location);
/* We already know that these two types are compatible, but they
may not be exactly identical. In fact, `TREE_TYPE (type)' is
@@ -4635,9 +4780,13 @@ convert_for_assignment (tree type, tree rhs, tree origtype,
likely to be va_list, a typedef to __builtin_va_list, which
is different enough that it will cause problems later. */
if (TREE_TYPE (TREE_TYPE (rhs)) != TREE_TYPE (type))
- rhs = build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (type)), rhs);
+ {
+ rhs = build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (type)), rhs);
+ SET_EXPR_LOCATION (rhs, location);
+ }
rhs = build1 (NOP_EXPR, type, rhs);
+ SET_EXPR_LOCATION (rhs, location);
return rhs;
}
/* Some types can interconvert without explicit casts. */
@@ -4698,7 +4847,7 @@ convert_for_assignment (tree type, tree rhs, tree origtype,
Meanwhile, the lhs target must have all the qualifiers of
the rhs. */
if (VOID_TYPE_P (ttl) || VOID_TYPE_P (ttr)
- || comp_target_types (memb_type, rhstype))
+ || comp_target_types (location, memb_type, rhstype))
{
/* If this type won't generate any warnings, use it. */
if (TYPE_QUALS (ttl) == TYPE_QUALS (ttr)
@@ -4744,7 +4893,7 @@ convert_for_assignment (tree type, tree rhs, tree origtype,
function where an ordinary one is wanted, but not
vice-versa. */
if (TYPE_QUALS (ttl) & ~TYPE_QUALS (ttr))
- WARN_FOR_ASSIGNMENT (input_location, 0,
+ WARN_FOR_ASSIGNMENT (location, 0,
G_("passing argument %d of %qE "
"makes qualified function "
"pointer from unqualified"),
@@ -4758,7 +4907,7 @@ convert_for_assignment (tree type, tree rhs, tree origtype,
"pointer from unqualified"));
}
else if (TYPE_QUALS (ttr) & ~TYPE_QUALS (ttl))
- WARN_FOR_ASSIGNMENT (input_location, 0,
+ WARN_FOR_ASSIGNMENT (location, 0,
G_("passing argument %d of %qE discards "
"qualifiers from pointer target type"),
G_("assignment discards qualifiers "
@@ -4772,7 +4921,7 @@ convert_for_assignment (tree type, tree rhs, tree origtype,
}
if (!fundecl || !DECL_IN_SYSTEM_HEADER (fundecl))
- pedwarn (input_location, OPT_pedantic,
+ pedwarn (location, OPT_pedantic,
"ISO C prohibits argument conversion to union type");
rhs = fold_convert (TREE_TYPE (memb), rhs);
@@ -4806,8 +4955,9 @@ convert_for_assignment (tree type, tree rhs, tree origtype,
where NULL is typically defined in C to be '(void *) 0'. */
if (VOID_TYPE_P (ttr) && rhs != null_pointer_node && !VOID_TYPE_P (ttl))
- warning (OPT_Wc___compat, "request for implicit conversion from "
- "%qT to %qT not permitted in C++", rhstype, type);
+ warning_at (location, OPT_Wc___compat,
+ "request for implicit conversion "
+ "from %qT to %qT not permitted in C++", rhstype, type);
/* Check if the right-hand side has a format attribute but the
left-hand side doesn't. */
@@ -4817,25 +4967,25 @@ convert_for_assignment (tree type, tree rhs, tree origtype,
switch (errtype)
{
case ic_argpass:
- warning (OPT_Wmissing_format_attribute,
- "argument %d of %qE might be "
- "a candidate for a format attribute",
- parmnum, rname);
+ warning_at (location, OPT_Wmissing_format_attribute,
+ "argument %d of %qE might be "
+ "a candidate for a format attribute",
+ parmnum, rname);
break;
case ic_assign:
- warning (OPT_Wmissing_format_attribute,
- "assignment left-hand side might be "
- "a candidate for a format attribute");
+ warning_at (location, OPT_Wmissing_format_attribute,
+ "assignment left-hand side might be "
+ "a candidate for a format attribute");
break;
case ic_init:
- warning (OPT_Wmissing_format_attribute,
- "initialization left-hand side might be "
- "a candidate for a format attribute");
+ warning_at (location, OPT_Wmissing_format_attribute,
+ "initialization left-hand side might be "
+ "a candidate for a format attribute");
break;
case ic_return:
- warning (OPT_Wmissing_format_attribute,
- "return type might be "
- "a candidate for a format attribute");
+ warning_at (location, OPT_Wmissing_format_attribute,
+ "return type might be "
+ "a candidate for a format attribute");
break;
default:
gcc_unreachable ();
@@ -4846,7 +4996,7 @@ convert_for_assignment (tree type, tree rhs, tree origtype,
and vice versa; otherwise, targets must be the same.
Meanwhile, the lhs target must have all the qualifiers of the rhs. */
if (VOID_TYPE_P (ttl) || VOID_TYPE_P (ttr)
- || (target_cmp = comp_target_types (type, rhstype))
+ || (target_cmp = comp_target_types (location, type, rhstype))
|| is_opaque_pointer
|| (c_common_unsigned_type (mvl)
== c_common_unsigned_type (mvr)))
@@ -4857,7 +5007,7 @@ convert_for_assignment (tree type, tree rhs, tree origtype,
(VOID_TYPE_P (ttr)
&& !null_pointer_constant
&& TREE_CODE (ttl) == FUNCTION_TYPE)))
- WARN_FOR_ASSIGNMENT (input_location, OPT_pedantic,
+ WARN_FOR_ASSIGNMENT (location, OPT_pedantic,
G_("ISO C forbids passing argument %d of "
"%qE between function pointer "
"and %<void *%>"),
@@ -4878,7 +5028,7 @@ convert_for_assignment (tree type, tree rhs, tree origtype,
qualifier are acceptable if the 'volatile' has been added
in by the Objective-C EH machinery. */
if (!objc_type_quals_match (ttl, ttr))
- WARN_FOR_ASSIGNMENT (input_location, 0,
+ WARN_FOR_ASSIGNMENT (location, 0,
G_("passing argument %d of %qE discards "
"qualifiers from pointer target type"),
G_("assignment discards qualifiers "
@@ -4895,7 +5045,7 @@ convert_for_assignment (tree type, tree rhs, tree origtype,
;
/* If there is a mismatch, do warn. */
else if (warn_pointer_sign)
- WARN_FOR_ASSIGNMENT (input_location, OPT_Wpointer_sign,
+ WARN_FOR_ASSIGNMENT (location, OPT_Wpointer_sign,
G_("pointer targets in passing argument "
"%d of %qE differ in signedness"),
G_("pointer targets in assignment "
@@ -4913,7 +5063,7 @@ convert_for_assignment (tree type, tree rhs, tree origtype,
it is okay to use a const or volatile function
where an ordinary one is wanted, but not vice-versa. */
if (TYPE_QUALS (ttl) & ~TYPE_QUALS (ttr))
- WARN_FOR_ASSIGNMENT (input_location, 0,
+ WARN_FOR_ASSIGNMENT (location, 0,
G_("passing argument %d of %qE makes "
"qualified function pointer "
"from unqualified"),
@@ -4928,7 +5078,7 @@ convert_for_assignment (tree type, tree rhs, tree origtype,
else
/* Avoid warning about the volatile ObjC EH puts on decls. */
if (!objc_ok)
- WARN_FOR_ASSIGNMENT (input_location, 0,
+ WARN_FOR_ASSIGNMENT (location, 0,
G_("passing argument %d of %qE from "
"incompatible pointer type"),
G_("assignment from incompatible pointer type"),
@@ -4942,7 +5092,7 @@ convert_for_assignment (tree type, tree rhs, tree origtype,
{
/* ??? This should not be an error when inlining calls to
unprototyped functions. */
- error ("invalid use of non-lvalue array");
+ error_at (location, "invalid use of non-lvalue array");
return error_mark_node;
}
else if (codel == POINTER_TYPE && coder == INTEGER_TYPE)
@@ -4951,7 +5101,7 @@ convert_for_assignment (tree type, tree rhs, tree origtype,
or one that results from arithmetic, even including
a cast to integer type. */
if (!null_pointer_constant)
- WARN_FOR_ASSIGNMENT (input_location, 0,
+ WARN_FOR_ASSIGNMENT (location, 0,
G_("passing argument %d of %qE makes "
"pointer from integer without a cast"),
G_("assignment makes pointer from integer "
@@ -4965,7 +5115,7 @@ convert_for_assignment (tree type, tree rhs, tree origtype,
}
else if (codel == INTEGER_TYPE && coder == POINTER_TYPE)
{
- WARN_FOR_ASSIGNMENT (input_location, 0,
+ WARN_FOR_ASSIGNMENT (location, 0,
G_("passing argument %d of %qE makes integer "
"from pointer without a cast"),
G_("assignment makes integer from pointer "
@@ -4989,22 +5139,24 @@ convert_for_assignment (tree type, tree rhs, tree origtype,
switch (errtype)
{
case ic_argpass:
- error ("incompatible type for argument %d of %qE", parmnum, rname);
+ error_at (location, "incompatible type for argument %d of %qE", parmnum, rname);
inform ((fundecl && !DECL_IS_BUILTIN (fundecl))
? DECL_SOURCE_LOCATION (fundecl) : input_location,
"expected %qT but argument is of type %qT", type, rhstype);
break;
case ic_assign:
- error ("incompatible types when assigning to type %qT from type %qT",
- type, rhstype);
+ error_at (location, "incompatible types when assigning to type %qT from "
+ "type %qT", type, rhstype);
break;
case ic_init:
- error ("incompatible types when initializing type %qT using type %qT",
- type, rhstype);
+ error_at (location,
+ "incompatible types when initializing type %qT using type %qT",
+ type, rhstype);
break;
case ic_return:
- error ("incompatible types when returning type %qT but %qT was expected",
- rhstype, type);
+ error_at (location,
+ "incompatible types when returning type %qT but %qT was "
+ "expected", rhstype, type);
break;
default:
gcc_unreachable ();
@@ -5040,10 +5192,12 @@ valid_compound_expr_initializer (tree value, tree endtype)
store it in the declaration DECL,
and print any error messages that are appropriate.
If ORIGTYPE is not NULL_TREE, it is the original type of INIT.
- If the init is invalid, store an ERROR_MARK. */
+ If the init is invalid, store an ERROR_MARK.
+
+ INIT_LOC is the location of the initial value. */
void
-store_init_value (tree decl, tree init, tree origtype)
+store_init_value (location_t init_loc, tree decl, tree init, tree origtype)
{
tree value, type;
bool npc = false;
@@ -5058,7 +5212,8 @@ store_init_value (tree decl, tree init, tree origtype)
if (init)
npc = null_pointer_constant_p (init);
- value = digest_init (type, init, origtype, npc, true, TREE_STATIC (decl));
+ value = digest_init (init_loc, type, init, origtype, npc,
+ true, TREE_STATIC (decl));
/* Store the expression if valid; else report error. */
@@ -5299,12 +5454,15 @@ maybe_warn_string_init (tree type, struct c_expr expr)
unparenthesized or we should not warn here for it being parenthesized.
For other types of INIT, STRICT_STRING is not used.
+ INIT_LOC is the location of the INIT.
+
REQUIRE_CONSTANT requests an error if non-constant initializers or
elements are seen. */
static tree
-digest_init (tree type, tree init, tree origtype, bool null_pointer_constant,
- bool strict_string, int require_constant)
+digest_init (location_t init_loc, tree type, tree init, tree origtype,
+ bool null_pointer_constant, bool strict_string,
+ int require_constant)
{
enum tree_code code = TREE_CODE (type);
tree inside_init = init;
@@ -5354,7 +5512,7 @@ digest_init (tree type, tree init, tree origtype, bool null_pointer_constant,
maybe_warn_string_init (type, expr);
if (TYPE_DOMAIN (type) && !TYPE_MAX_VALUE (TYPE_DOMAIN (type)))
- pedwarn_init (input_location, OPT_pedantic,
+ pedwarn_init (init_loc, OPT_pedantic,
"initialization of a flexible array member");
if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)),
@@ -5396,7 +5554,7 @@ digest_init (tree type, tree init, tree origtype, bool null_pointer_constant,
TREE_STRING_LENGTH (inside_init)
- (TYPE_PRECISION (typ1)
/ BITS_PER_UNIT)))
- pedwarn_init (input_location, 0,
+ pedwarn_init (init_loc, 0,
"initializer-string for array of chars is too long");
return inside_init;
@@ -5467,7 +5625,8 @@ digest_init (tree type, tree init, tree origtype, bool null_pointer_constant,
{
if (TREE_CODE (inside_init) == STRING_CST
|| TREE_CODE (inside_init) == COMPOUND_LITERAL_EXPR)
- inside_init = array_to_pointer_conversion (inside_init);
+ inside_init = array_to_pointer_conversion
+ (init_loc, inside_init);
else
{
error_init ("invalid use of non-lvalue array");
@@ -5512,7 +5671,7 @@ digest_init (tree type, tree init, tree origtype, bool null_pointer_constant,
if (inside_init == error_mark_node)
error_init ("initializer element is not constant");
else
- pedwarn_init (input_location, OPT_pedantic,
+ pedwarn_init (init_loc, OPT_pedantic,
"initializer element is not constant");
if (flag_pedantic_errors)
inside_init = error_mark_node;
@@ -5525,12 +5684,13 @@ digest_init (tree type, tree init, tree origtype, bool null_pointer_constant,
inside_init = error_mark_node;
}
else if (require_constant && !maybe_const)
- pedwarn_init (input_location, 0,
+ pedwarn_init (init_loc, 0,
"initializer element is not a constant expression");
/* Added to enable additional -Wmissing-format-attribute warnings. */
if (TREE_CODE (TREE_TYPE (inside_init)) == POINTER_TYPE)
- inside_init = convert_for_assignment (type, inside_init, origtype,
+ inside_init = convert_for_assignment (init_loc, type, inside_init,
+ origtype,
ic_init, null_pointer_constant,
NULL_TREE, NULL_TREE, 0);
return inside_init;
@@ -5545,13 +5705,13 @@ digest_init (tree type, tree init, tree origtype, bool null_pointer_constant,
if (TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE
&& (TREE_CODE (init) == STRING_CST
|| TREE_CODE (init) == COMPOUND_LITERAL_EXPR))
- inside_init = init = array_to_pointer_conversion (init);
+ inside_init = init = array_to_pointer_conversion (init_loc, init);
if (semantic_type)
inside_init = build1 (EXCESS_PRECISION_EXPR, semantic_type,
inside_init);
inside_init
- = convert_for_assignment (type, inside_init, origtype, ic_init,
- null_pointer_constant,
+ = convert_for_assignment (init_loc, type, inside_init, origtype,
+ ic_init, null_pointer_constant,
NULL_TREE, NULL_TREE, 0);
/* Check to see if we have already given an error message. */
@@ -5570,7 +5730,7 @@ digest_init (tree type, tree init, tree origtype, bool null_pointer_constant,
inside_init = error_mark_node;
}
else if (require_constant && !maybe_const)
- pedwarn_init (input_location, 0,
+ pedwarn_init (init_loc, 0,
"initializer element is not a constant expression");
return inside_init;
@@ -6976,7 +7136,7 @@ output_init_element (tree value, tree origtype, bool strict_string, tree type,
&& INTEGRAL_TYPE_P (TREE_TYPE (type)))
&& !comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (value)),
TYPE_MAIN_VARIANT (type)))
- value = array_to_pointer_conversion (value);
+ value = array_to_pointer_conversion (input_location, value);
if (TREE_CODE (value) == COMPOUND_LITERAL_EXPR
&& require_constant_value && !flag_isoc99 && pending)
@@ -7055,8 +7215,8 @@ output_init_element (tree value, tree origtype, bool strict_string, tree type,
if (semantic_type)
value = build1 (EXCESS_PRECISION_EXPR, semantic_type, value);
- value = digest_init (type, value, origtype, npc, strict_string,
- require_constant_value);
+ value = digest_init (input_location, type, value, origtype, npc,
+ strict_string, require_constant_value);
if (value == error_mark_node)
{
constructor_erroneous = 1;
@@ -7715,8 +7875,8 @@ build_asm_stmt (tree cv_qualifier, tree args)
string in the asm expression -- asm("blah") and asm("blah" : )
are subtly different. We use a ASM_EXPR node to represent this. */
tree
-build_asm_expr (tree string, tree outputs, tree inputs, tree clobbers,
- bool simple)
+build_asm_expr (location_t loc, tree string, tree outputs, tree inputs,
+ tree clobbers, bool simple)
{
tree tail;
tree args;
@@ -7800,7 +7960,7 @@ build_asm_expr (tree string, tree outputs, tree inputs, tree clobbers,
TREE_VALUE (tail) = input;
}
- args = build_stmt (ASM_EXPR, string, outputs, inputs, clobbers);
+ args = build_stmt (loc, ASM_EXPR, string, outputs, inputs, clobbers);
/* asm statements without outputs, including simple ones, are treated
as volatile. */
@@ -7810,78 +7970,53 @@ build_asm_expr (tree string, tree outputs, tree inputs, tree clobbers,
return args;
}
-/* Generate a goto statement to LABEL. */
+/* Generate a goto statement to LABEL. LOC is the location of the
+ GOTO. */
tree
-c_finish_goto_label (tree label)
+c_finish_goto_label (location_t loc, tree label)
{
- tree decl = lookup_label (label);
+ tree decl = lookup_label_for_goto (loc, label);
if (!decl)
return NULL_TREE;
-
- if (C_DECL_UNJUMPABLE_STMT_EXPR (decl))
- {
- error ("jump into statement expression");
- return NULL_TREE;
- }
-
- if (C_DECL_UNJUMPABLE_VM (decl))
- {
- error ("jump into scope of identifier with variably modified type");
- return NULL_TREE;
- }
-
- if (!C_DECL_UNDEFINABLE_STMT_EXPR (decl))
- {
- /* No jump from outside this statement expression context, so
- record that there is a jump from within this context. */
- struct c_label_list *nlist;
- nlist = XOBNEW (&parser_obstack, struct c_label_list);
- nlist->next = label_context_stack_se->labels_used;
- nlist->label = decl;
- label_context_stack_se->labels_used = nlist;
- }
-
- if (!C_DECL_UNDEFINABLE_VM (decl))
- {
- /* No jump from outside this context context of identifiers with
- variably modified type, so record that there is a jump from
- within this context. */
- struct c_label_list *nlist;
- nlist = XOBNEW (&parser_obstack, struct c_label_list);
- nlist->next = label_context_stack_vm->labels_used;
- nlist->label = decl;
- label_context_stack_vm->labels_used = nlist;
- }
-
TREE_USED (decl) = 1;
- return add_stmt (build1 (GOTO_EXPR, void_type_node, decl));
+ {
+ tree t = build1 (GOTO_EXPR, void_type_node, decl);
+ SET_EXPR_LOCATION (t, loc);
+ return add_stmt (t);
+ }
}
-/* Generate a computed goto statement to EXPR. */
+/* Generate a computed goto statement to EXPR. LOC is the location of
+ the GOTO. */
tree
-c_finish_goto_ptr (tree expr)
+c_finish_goto_ptr (location_t loc, tree expr)
{
- pedwarn (input_location, OPT_pedantic, "ISO C forbids %<goto *expr;%>");
+ tree t;
+ pedwarn (loc, OPT_pedantic, "ISO C forbids %<goto *expr;%>");
expr = c_fully_fold (expr, false, NULL);
expr = convert (ptr_type_node, expr);
- return add_stmt (build1 (GOTO_EXPR, void_type_node, expr));
+ t = build1 (GOTO_EXPR, void_type_node, expr);
+ SET_EXPR_LOCATION (t, loc);
+ return add_stmt (t);
}
/* Generate a C `return' statement. RETVAL is the expression for what
- to return, or a null pointer for `return;' with no value. If
- ORIGTYPE is not NULL_TREE, it is the original type of RETVAL. */
+ to return, or a null pointer for `return;' with no value. LOC is
+ the location of the return statement. If ORIGTYPE is not NULL_TREE, it
+ is the original type of RETVAL. */
tree
-c_finish_return (tree retval, tree origtype)
+c_finish_return (location_t loc, tree retval, tree origtype)
{
tree valtype = TREE_TYPE (TREE_TYPE (current_function_decl)), ret_stmt;
bool no_warning = false;
bool npc = false;
if (TREE_THIS_VOLATILE (current_function_decl))
- warning (0, "function declared %<noreturn%> has a %<return%> statement");
+ warning_at (loc, 0,
+ "function declared %<noreturn%> has a %<return%> statement");
if (retval)
{
@@ -7903,7 +8038,7 @@ c_finish_return (tree retval, tree origtype)
if ((warn_return_type || flag_isoc99)
&& valtype != 0 && TREE_CODE (valtype) != VOID_TYPE)
{
- pedwarn_c99 (input_location, flag_isoc99 ? 0 : OPT_Wreturn_type,
+ pedwarn_c99 (loc, flag_isoc99 ? 0 : OPT_Wreturn_type,
"%<return%> with no value, in "
"function returning non-void");
no_warning = true;
@@ -7913,15 +8048,16 @@ c_finish_return (tree retval, tree origtype)
{
current_function_returns_null = 1;
if (TREE_CODE (TREE_TYPE (retval)) != VOID_TYPE)
- pedwarn (input_location, 0,
+ pedwarn (loc, 0,
"%<return%> with a value, in function returning void");
else
- pedwarn (input_location, OPT_pedantic, "ISO C forbids "
+ pedwarn (loc, OPT_pedantic, "ISO C forbids "
"%<return%> with expression, in function returning void");
}
else
{
- tree t = convert_for_assignment (valtype, retval, origtype, ic_return,
+ tree t = convert_for_assignment (loc, valtype, retval, origtype,
+ ic_return,
npc, NULL_TREE, NULL_TREE, 0);
tree res = DECL_RESULT (current_function_decl);
tree inner;
@@ -7975,7 +8111,8 @@ c_finish_return (tree retval, tree origtype)
&& !DECL_EXTERNAL (inner)
&& !TREE_STATIC (inner)
&& DECL_CONTEXT (inner) == current_function_decl)
- warning (0, "function returns address of local variable");
+ warning_at (loc,
+ 0, "function returns address of local variable");
break;
default:
@@ -7986,12 +8123,13 @@ c_finish_return (tree retval, tree origtype)
}
retval = build2 (MODIFY_EXPR, TREE_TYPE (res), res, t);
+ SET_EXPR_LOCATION (retval, loc);
if (warn_sequence_point)
verify_sequence_points (retval);
}
- ret_stmt = build_stmt (RETURN_EXPR, retval);
+ ret_stmt = build_stmt (loc, RETURN_EXPR, retval);
TREE_NO_WARNING (ret_stmt) |= no_warning;
return add_stmt (ret_stmt);
}
@@ -8011,15 +8149,9 @@ struct c_switch {
of the GNU case range extension. */
splay_tree cases;
- /* Number of nested statement expressions within this switch
- statement; if nonzero, case and default labels may not
- appear. */
- unsigned int blocked_stmt_expr;
-
- /* Scope of outermost declarations of identifiers with variably
- modified type within this switch statement; if nonzero, case and
- default labels may not appear. */
- unsigned int blocked_vm;
+ /* The bindings at the point of the switch. This is used for
+ warnings crossing decls when branching to a case label. */
+ struct c_spot_bindings *bindings;
/* The next node on the stack. */
struct c_switch *next;
@@ -8034,10 +8166,13 @@ struct c_switch {
struct c_switch *c_switch_stack;
/* Start a C switch statement, testing expression EXP. Return the new
- SWITCH_EXPR. */
+ SWITCH_EXPR. SWITCH_LOC is the location of the `switch'.
+ SWITCH_COND_LOC is the location of the switch's condition. */
tree
-c_start_case (tree exp)
+c_start_case (location_t switch_loc,
+ location_t switch_cond_loc,
+ tree exp)
{
tree orig_type = error_mark_node;
struct c_switch *cs;
@@ -8050,7 +8185,7 @@ c_start_case (tree exp)
{
if (orig_type != error_mark_node)
{
- error ("switch quantity not an integer");
+ error_at (switch_cond_loc, "switch quantity not an integer");
orig_type = error_mark_node;
}
exp = integer_zero_node;
@@ -8062,8 +8197,9 @@ c_start_case (tree exp)
if (!in_system_header
&& (type == long_integer_type_node
|| type == long_unsigned_type_node))
- warning (OPT_Wtraditional, "%<long%> switch expression not "
- "converted to %<int%> in ISO C");
+ warning_at (switch_cond_loc,
+ OPT_Wtraditional, "%<long%> switch expression not "
+ "converted to %<int%> in ISO C");
exp = c_fully_fold (exp, false, NULL);
exp = default_conversion (exp);
@@ -8076,20 +8212,20 @@ c_start_case (tree exp)
/* Add this new SWITCH_EXPR to the stack. */
cs = XNEW (struct c_switch);
cs->switch_expr = build3 (SWITCH_EXPR, orig_type, exp, NULL_TREE, NULL_TREE);
+ SET_EXPR_LOCATION (cs->switch_expr, switch_loc);
cs->orig_type = orig_type;
cs->cases = splay_tree_new (case_compare, NULL, NULL);
- cs->blocked_stmt_expr = 0;
- cs->blocked_vm = 0;
+ cs->bindings = c_get_switch_bindings ();
cs->next = c_switch_stack;
c_switch_stack = cs;
return add_stmt (cs->switch_expr);
}
-/* Process a case label. */
+/* Process a case label at location LOC. */
tree
-do_case (tree low_value, tree high_value)
+do_case (location_t loc, tree low_value, tree high_value)
{
tree label = NULL_TREE;
@@ -8109,39 +8245,26 @@ do_case (tree low_value, tree high_value)
"case label is not an integer constant expression");
}
- if (c_switch_stack && !c_switch_stack->blocked_stmt_expr
- && !c_switch_stack->blocked_vm)
- {
- label = c_add_case_label (c_switch_stack->cases,
- SWITCH_COND (c_switch_stack->switch_expr),
- c_switch_stack->orig_type,
- low_value, high_value);
- if (label == error_mark_node)
- label = NULL_TREE;
- }
- else if (c_switch_stack && c_switch_stack->blocked_stmt_expr)
- {
- if (low_value)
- error ("case label in statement expression not containing "
- "enclosing switch statement");
- else
- error ("%<default%> label in statement expression not containing "
- "enclosing switch statement");
- }
- else if (c_switch_stack && c_switch_stack->blocked_vm)
+ if (c_switch_stack == NULL)
{
if (low_value)
- error ("case label in scope of identifier with variably modified "
- "type not containing enclosing switch statement");
+ error_at (loc, "case label not within a switch statement");
else
- error ("%<default%> label in scope of identifier with variably "
- "modified type not containing enclosing switch statement");
+ error_at (loc, "%<default%> label not within a switch statement");
+ return NULL_TREE;
}
- else if (low_value)
- error ("case label not within a switch statement");
- else
- error ("%<default%> label not within a switch statement");
+ if (c_check_switch_jump_warnings (c_switch_stack->bindings,
+ EXPR_LOCATION (c_switch_stack->switch_expr),
+ loc))
+ return NULL_TREE;
+
+ label = c_add_case_label (loc, c_switch_stack->cases,
+ SWITCH_COND (c_switch_stack->switch_expr),
+ c_switch_stack->orig_type,
+ low_value, high_value);
+ if (label == error_mark_node)
+ label = NULL_TREE;
return label;
}
@@ -8155,16 +8278,8 @@ c_finish_case (tree body)
SWITCH_BODY (cs->switch_expr) = body;
- /* We must not be within a statement expression nested in the switch
- at this point; we might, however, be within the scope of an
- identifier with variably modified type nested in the switch. */
- gcc_assert (!cs->blocked_stmt_expr);
-
/* Emit warnings as needed. */
- if (EXPR_HAS_LOCATION (cs->switch_expr))
- switch_location = EXPR_LOCATION (cs->switch_expr);
- else
- switch_location = input_location;
+ switch_location = EXPR_LOCATION (cs->switch_expr);
c_do_switch_warnings (cs->cases, switch_location,
TREE_TYPE (cs->switch_expr),
SWITCH_COND (cs->switch_expr));
@@ -8172,6 +8287,7 @@ c_finish_case (tree body)
/* Pop the stack. */
c_switch_stack = cs->next;
splay_tree_delete (cs->cases);
+ c_release_switch_bindings (cs->bindings);
XDELETE (cs);
}
@@ -8301,7 +8417,7 @@ c_finish_loop (location_t start_locus, tree cond, tree incr, tree body,
}
tree
-c_finish_bc_stmt (tree *label_p, bool is_break)
+c_finish_bc_stmt (location_t loc, tree *label_p, bool is_break)
{
bool skip;
tree label = *label_p;
@@ -8318,7 +8434,7 @@ c_finish_bc_stmt (tree *label_p, bool is_break)
if (!label)
{
if (!skip)
- *label_p = label = create_artificial_label ();
+ *label_p = label = create_artificial_label (loc);
}
else if (TREE_CODE (label) == LABEL_DECL)
;
@@ -8326,14 +8442,14 @@ c_finish_bc_stmt (tree *label_p, bool is_break)
{
case 0:
if (is_break)
- error ("break statement not within loop or switch");
+ error_at (loc, "break statement not within loop or switch");
else
- error ("continue statement not within a loop");
+ error_at (loc, "continue statement not within a loop");
return NULL_TREE;
case 1:
gcc_assert (is_break);
- error ("break statement used with OpenMP for loop");
+ error_at (loc, "break statement used with OpenMP for loop");
return NULL_TREE;
default:
@@ -8352,25 +8468,25 @@ c_finish_bc_stmt (tree *label_p, bool is_break)
/* A helper routine for c_process_expr_stmt and c_finish_stmt_expr. */
static void
-emit_side_effect_warnings (tree expr)
+emit_side_effect_warnings (location_t loc, tree expr)
{
if (expr == error_mark_node)
;
else if (!TREE_SIDE_EFFECTS (expr))
{
if (!VOID_TYPE_P (TREE_TYPE (expr)) && !TREE_NO_WARNING (expr))
- warning (OPT_Wunused_value, "%Hstatement with no effect",
- EXPR_HAS_LOCATION (expr) ? EXPR_LOCUS (expr) : &input_location);
+ warning_at (loc, OPT_Wunused_value, "statement with no effect");
}
else
- warn_if_unused_value (expr, input_location);
+ warn_if_unused_value (expr, loc);
}
/* Process an expression as if it were a complete statement. Emit
- diagnostics, but do not call ADD_STMT. */
+ diagnostics, but do not call ADD_STMT. LOC is the location of the
+ statement. */
tree
-c_process_expr_stmt (tree expr)
+c_process_expr_stmt (location_t loc, tree expr)
{
if (!expr)
return NULL_TREE;
@@ -8383,33 +8499,34 @@ c_process_expr_stmt (tree expr)
if (TREE_TYPE (expr) != error_mark_node
&& !COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (expr))
&& TREE_CODE (TREE_TYPE (expr)) != ARRAY_TYPE)
- error ("expression statement has incomplete type");
+ error_at (loc, "expression statement has incomplete type");
/* If we're not processing a statement expression, warn about unused values.
Warnings for statement expressions will be emitted later, once we figure
out which is the result. */
if (!STATEMENT_LIST_STMT_EXPR (cur_stmt_list)
&& warn_unused_value)
- emit_side_effect_warnings (expr);
+ emit_side_effect_warnings (loc, expr);
/* If the expression is not of a type to which we cannot assign a line
number, wrap the thing in a no-op NOP_EXPR. */
if (DECL_P (expr) || CONSTANT_CLASS_P (expr))
- expr = build1 (NOP_EXPR, TREE_TYPE (expr), expr);
-
- if (CAN_HAVE_LOCATION_P (expr))
- SET_EXPR_LOCATION (expr, input_location);
+ {
+ expr = build1 (NOP_EXPR, TREE_TYPE (expr), expr);
+ SET_EXPR_LOCATION (expr, loc);
+ }
return expr;
}
-/* Emit an expression as a statement. */
+/* Emit an expression as a statement. LOC is the location of the
+ expression. */
tree
-c_finish_expr_stmt (tree expr)
+c_finish_expr_stmt (location_t loc, tree expr)
{
if (expr)
- return add_stmt (c_process_expr_stmt (expr));
+ return add_stmt (c_process_expr_stmt (loc, expr));
else
return NULL;
}
@@ -8421,30 +8538,16 @@ tree
c_begin_stmt_expr (void)
{
tree ret;
- struct c_label_context_se *nstack;
- struct c_label_list *glist;
/* We must force a BLOCK for this level so that, if it is not expanded
later, there is a way to turn off the entire subtree of blocks that
are contained in it. */
keep_next_level ();
ret = c_begin_compound_stmt (true);
- if (c_switch_stack)
- {
- c_switch_stack->blocked_stmt_expr++;
- gcc_assert (c_switch_stack->blocked_stmt_expr != 0);
- }
- for (glist = label_context_stack_se->labels_used;
- glist != NULL;
- glist = glist->next)
- {
- C_DECL_UNDEFINABLE_STMT_EXPR (glist->label) = 1;
- }
- nstack = XOBNEW (&parser_obstack, struct c_label_context_se);
- nstack->labels_def = NULL;
- nstack->labels_used = NULL;
- nstack->next = label_context_stack_se;
- label_context_stack_se = nstack;
+
+ c_bindings_start_stmt_expr (c_switch_stack == NULL
+ ? NULL
+ : c_switch_stack->bindings);
/* Mark the current statement list as belonging to a statement list. */
STATEMENT_LIST_STMT_EXPR (ret) = 1;
@@ -8452,42 +8555,20 @@ c_begin_stmt_expr (void)
return ret;
}
+/* LOC is the location of the compound statement to which this body
+ belongs. */
+
tree
-c_finish_stmt_expr (tree body)
+c_finish_stmt_expr (location_t loc, tree body)
{
tree last, type, tmp, val;
tree *last_p;
- struct c_label_list *dlist, *glist, *glist_prev = NULL;
- body = c_end_compound_stmt (body, true);
- if (c_switch_stack)
- {
- gcc_assert (c_switch_stack->blocked_stmt_expr != 0);
- c_switch_stack->blocked_stmt_expr--;
- }
- /* It is no longer possible to jump to labels defined within this
- statement expression. */
- for (dlist = label_context_stack_se->labels_def;
- dlist != NULL;
- dlist = dlist->next)
- {
- C_DECL_UNJUMPABLE_STMT_EXPR (dlist->label) = 1;
- }
- /* It is again possible to define labels with a goto just outside
- this statement expression. */
- for (glist = label_context_stack_se->next->labels_used;
- glist != NULL;
- glist = glist->next)
- {
- C_DECL_UNDEFINABLE_STMT_EXPR (glist->label) = 0;
- glist_prev = glist;
- }
- if (glist_prev != NULL)
- glist_prev->next = label_context_stack_se->labels_used;
- else
- label_context_stack_se->next->labels_used
- = label_context_stack_se->labels_used;
- label_context_stack_se = label_context_stack_se->next;
+ body = c_end_compound_stmt (loc, body, true);
+
+ c_bindings_end_stmt_expr (c_switch_stack == NULL
+ ? NULL
+ : c_switch_stack->bindings);
/* Locate the last statement in BODY. See c_end_compound_stmt
about always returning a BIND_EXPR. */
@@ -8508,7 +8589,13 @@ c_finish_stmt_expr (tree body)
if (warn_unused_value)
{
for (i = tsi_start (last); !tsi_one_before_end_p (i); tsi_next (&i))
- emit_side_effect_warnings (tsi_stmt (i));
+ {
+ location_t tloc;
+ tree t = tsi_stmt (i);
+
+ tloc = EXPR_HAS_LOCATION (t) ? EXPR_LOCATION (t) : loc;
+ emit_side_effect_warnings (tloc, t);
+ }
}
else
i = tsi_last (last);
@@ -8565,81 +8652,11 @@ c_finish_stmt_expr (tree body)
*last_p = build2 (MODIFY_EXPR, void_type_node, tmp, val);
SET_EXPR_LOCUS (*last_p, EXPR_LOCUS (last));
- return build4 (TARGET_EXPR, type, tmp, body, NULL_TREE, NULL_TREE);
-}
-
-/* Begin the scope of an identifier of variably modified type, scope
- number SCOPE. Jumping from outside this scope to inside it is not
- permitted. */
-
-void
-c_begin_vm_scope (unsigned int scope)
-{
- struct c_label_context_vm *nstack;
- struct c_label_list *glist;
-
- gcc_assert (scope > 0);
-
- /* At file_scope, we don't have to do any processing. */
- if (label_context_stack_vm == NULL)
- return;
-
- if (c_switch_stack && !c_switch_stack->blocked_vm)
- c_switch_stack->blocked_vm = scope;
- for (glist = label_context_stack_vm->labels_used;
- glist != NULL;
- glist = glist->next)
- {
- C_DECL_UNDEFINABLE_VM (glist->label) = 1;
- }
- nstack = XOBNEW (&parser_obstack, struct c_label_context_vm);
- nstack->labels_def = NULL;
- nstack->labels_used = NULL;
- nstack->scope = scope;
- nstack->next = label_context_stack_vm;
- label_context_stack_vm = nstack;
-}
-
-/* End a scope which may contain identifiers of variably modified
- type, scope number SCOPE. */
-
-void
-c_end_vm_scope (unsigned int scope)
-{
- if (label_context_stack_vm == NULL)
- return;
- if (c_switch_stack && c_switch_stack->blocked_vm == scope)
- c_switch_stack->blocked_vm = 0;
- /* We may have a number of nested scopes of identifiers with
- variably modified type, all at this depth. Pop each in turn. */
- while (label_context_stack_vm->scope == scope)
- {
- struct c_label_list *dlist, *glist, *glist_prev = NULL;
-
- /* It is no longer possible to jump to labels defined within this
- scope. */
- for (dlist = label_context_stack_vm->labels_def;
- dlist != NULL;
- dlist = dlist->next)
- {
- C_DECL_UNJUMPABLE_VM (dlist->label) = 1;
- }
- /* It is again possible to define labels with a goto just outside
- this scope. */
- for (glist = label_context_stack_vm->next->labels_used;
- glist != NULL;
- glist = glist->next)
- {
- C_DECL_UNDEFINABLE_VM (glist->label) = 0;
- glist_prev = glist;
- }
- if (glist_prev != NULL)
- glist_prev->next = label_context_stack_vm->labels_used;
- else
- label_context_stack_vm->next->labels_used
- = label_context_stack_vm->labels_used;
- label_context_stack_vm = label_context_stack_vm->next;
- }
+ {
+ tree t = build4 (TARGET_EXPR, type, tmp, body, NULL_TREE, NULL_TREE);
+ SET_EXPR_LOCATION (t, loc);
+ return t;
+ }
}
/* Begin and end compound statements. This is as simple as pushing
@@ -8654,8 +8671,12 @@ c_begin_compound_stmt (bool do_scope)
return stmt;
}
+/* End a compound statement. STMT is the statement. LOC is the
+ location of the compound statement-- this is usually the location
+ of the opening brace. */
+
tree
-c_end_compound_stmt (tree stmt, bool do_scope)
+c_end_compound_stmt (location_t loc, tree stmt, bool do_scope)
{
tree block = NULL;
@@ -8667,7 +8688,7 @@ c_end_compound_stmt (tree stmt, bool do_scope)
}
stmt = pop_stmt_list (stmt);
- stmt = c_build_bind_expr (block, stmt);
+ stmt = c_build_bind_expr (loc, block, stmt);
/* If this compound statement is nested immediately inside a statement
expression, then force a BIND_EXPR to be created. Otherwise we'll
@@ -8680,6 +8701,7 @@ c_end_compound_stmt (tree stmt, bool do_scope)
{
stmt = build3 (BIND_EXPR, void_type_node, NULL, stmt, NULL);
TREE_SIDE_EFFECTS (stmt) = 1;
+ SET_EXPR_LOCATION (stmt, loc);
}
return stmt;
@@ -8690,14 +8712,14 @@ c_end_compound_stmt (tree stmt, bool do_scope)
meant to apply to normal control flow transfer. */
void
-push_cleanup (tree ARG_UNUSED (decl), tree cleanup, bool eh_only)
+push_cleanup (tree decl, tree cleanup, bool eh_only)
{
enum tree_code code;
tree stmt, list;
bool stmt_expr;
code = eh_only ? TRY_CATCH_EXPR : TRY_FINALLY_EXPR;
- stmt = build_stmt (code, NULL, cleanup);
+ stmt = build_stmt (DECL_SOURCE_LOCATION (decl), code, NULL, cleanup);
add_stmt (stmt);
stmt_expr = STATEMENT_LIST_STMT_EXPR (cur_stmt_list);
list = push_stmt_list ();
@@ -8905,7 +8927,7 @@ build_binary_op (location_t location, enum tree_code code,
/* Subtraction of two similar pointers.
We must subtract them as integers, then divide by object size. */
if (code0 == POINTER_TYPE && code1 == POINTER_TYPE
- && comp_target_types (type0, type1))
+ && comp_target_types (location, type0, type1))
{
ret = pointer_diff (op0, op1);
goto return_build_binary_op;
@@ -8978,7 +9000,11 @@ build_binary_op (location_t location, enum tree_code code,
case FLOOR_MOD_EXPR:
warn_for_div_by_zero (location, op1);
- if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
+ if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE
+ && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE
+ && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE)
+ common = 1;
+ else if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
{
/* Although it would be tempting to shorten always here, that loses
on some targets, since the modulo instruction is undefined if the
@@ -9048,7 +9074,7 @@ build_binary_op (location_t location, enum tree_code code,
if (tree_int_cst_sgn (op1) < 0)
{
int_const = false;
- if (skip_evaluation == 0)
+ if (c_inhibit_evaluation_warnings == 0)
warning (0, "right shift count is negative");
}
else
@@ -9059,7 +9085,7 @@ build_binary_op (location_t location, enum tree_code code,
if (compare_tree_int (op1, TYPE_PRECISION (type0)) >= 0)
{
int_const = false;
- if (skip_evaluation == 0)
+ if (c_inhibit_evaluation_warnings == 0)
warning (0, "right shift count >= width of type");
}
}
@@ -9085,14 +9111,14 @@ build_binary_op (location_t location, enum tree_code code,
if (tree_int_cst_sgn (op1) < 0)
{
int_const = false;
- if (skip_evaluation == 0)
+ if (c_inhibit_evaluation_warnings == 0)
warning (0, "left shift count is negative");
}
else if (compare_tree_int (op1, TYPE_PRECISION (type0)) >= 0)
{
int_const = false;
- if (skip_evaluation == 0)
+ if (c_inhibit_evaluation_warnings == 0)
warning (0, "left shift count >= width of type");
}
}
@@ -9129,7 +9155,7 @@ build_binary_op (location_t location, enum tree_code code,
/* Anything compares with void *. void * compares with anything.
Otherwise, the targets must be compatible
and both must be object or both incomplete. */
- if (comp_target_types (type0, type1))
+ if (comp_target_types (location, type0, type1))
result_type = common_pointer_type (type0, type1);
else if (VOID_TYPE_P (tt0))
{
@@ -9198,7 +9224,7 @@ build_binary_op (location_t location, enum tree_code code,
short_compare = 1;
else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
{
- if (comp_target_types (type0, type1))
+ if (comp_target_types (location, type0, type1))
{
result_type = common_pointer_type (type0, type1);
if (!COMPLETE_TYPE_P (TREE_TYPE (type0))
@@ -9432,7 +9458,7 @@ build_binary_op (location_t location, enum tree_code code,
converted = 1;
resultcode = xresultcode;
- if (!skip_evaluation)
+ if (c_inhibit_evaluation_warnings == 0)
{
bool op0_maybe_const = true;
bool op1_maybe_const = true;
@@ -9628,19 +9654,21 @@ c_begin_omp_parallel (void)
return block;
}
-/* Generate OMP_PARALLEL, with CLAUSES and BLOCK as its compound statement. */
+/* Generate OMP_PARALLEL, with CLAUSES and BLOCK as its compound
+ statement. LOC is the location of the OMP_PARALLEL. */
tree
-c_finish_omp_parallel (tree clauses, tree block)
+c_finish_omp_parallel (location_t loc, tree clauses, tree block)
{
tree stmt;
- block = c_end_compound_stmt (block, true);
+ block = c_end_compound_stmt (loc, block, true);
stmt = make_node (OMP_PARALLEL);
TREE_TYPE (stmt) = void_type_node;
OMP_PARALLEL_CLAUSES (stmt) = clauses;
OMP_PARALLEL_BODY (stmt) = block;
+ SET_EXPR_LOCATION (stmt, loc);
return add_stmt (stmt);
}
@@ -9658,19 +9686,21 @@ c_begin_omp_task (void)
return block;
}
-/* Generate OMP_TASK, with CLAUSES and BLOCK as its compound statement. */
+/* Generate OMP_TASK, with CLAUSES and BLOCK as its compound
+ statement. LOC is the location of the #pragma. */
tree
-c_finish_omp_task (tree clauses, tree block)
+c_finish_omp_task (location_t loc, tree clauses, tree block)
{
tree stmt;
- block = c_end_compound_stmt (block, true);
+ block = c_end_compound_stmt (loc, block, true);
stmt = make_node (OMP_TASK);
TREE_TYPE (stmt) = void_type_node;
OMP_TASK_CLAUSES (stmt) = clauses;
OMP_TASK_BODY (stmt) = block;
+ SET_EXPR_LOCATION (stmt, loc);
return add_stmt (stmt);
}
@@ -9716,7 +9746,8 @@ c_finish_omp_clauses (tree clauses)
if (AGGREGATE_TYPE_P (TREE_TYPE (t))
|| POINTER_TYPE_P (TREE_TYPE (t)))
{
- error ("%qE has invalid type for %<reduction%>", t);
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "%qE has invalid type for %<reduction%>", t);
remove = true;
}
else if (FLOAT_TYPE_P (TREE_TYPE (t)))
@@ -9750,8 +9781,9 @@ c_finish_omp_clauses (tree clauses)
}
if (r_name)
{
- error ("%qE has invalid type for %<reduction(%s)%>",
- t, r_name);
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "%qE has invalid type for %<reduction(%s)%>",
+ t, r_name);
remove = true;
}
}
@@ -9766,7 +9798,8 @@ c_finish_omp_clauses (tree clauses)
t = OMP_CLAUSE_DECL (c);
if (TREE_CODE (t) != VAR_DECL || !DECL_THREAD_LOCAL_P (t))
{
- error ("%qE must be %<threadprivate%> for %<copyin%>", t);
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "%qE must be %<threadprivate%> for %<copyin%>", t);
remove = true;
}
goto check_dup_generic;
@@ -9775,14 +9808,16 @@ c_finish_omp_clauses (tree clauses)
t = OMP_CLAUSE_DECL (c);
if (TREE_CODE (t) != VAR_DECL && TREE_CODE (t) != PARM_DECL)
{
- error ("%qE is not a variable in clause %qs", t, name);
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "%qE is not a variable in clause %qs", t, name);
remove = true;
}
else if (bitmap_bit_p (&generic_head, DECL_UID (t))
|| bitmap_bit_p (&firstprivate_head, DECL_UID (t))
|| bitmap_bit_p (&lastprivate_head, DECL_UID (t)))
{
- error ("%qE appears more than once in data clauses", t);
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "%qE appears more than once in data clauses", t);
remove = true;
}
else
@@ -9796,13 +9831,15 @@ c_finish_omp_clauses (tree clauses)
need_implicitly_determined = true;
if (TREE_CODE (t) != VAR_DECL && TREE_CODE (t) != PARM_DECL)
{
- error ("%qE is not a variable in clause %<firstprivate%>", t);
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "%qE is not a variable in clause %<firstprivate%>", t);
remove = true;
}
else if (bitmap_bit_p (&generic_head, DECL_UID (t))
|| bitmap_bit_p (&firstprivate_head, DECL_UID (t)))
{
- error ("%qE appears more than once in data clauses", t);
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "%qE appears more than once in data clauses", t);
remove = true;
}
else
@@ -9816,13 +9853,15 @@ c_finish_omp_clauses (tree clauses)
need_implicitly_determined = true;
if (TREE_CODE (t) != VAR_DECL && TREE_CODE (t) != PARM_DECL)
{
- error ("%qE is not a variable in clause %<lastprivate%>", t);
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "%qE is not a variable in clause %<lastprivate%>", t);
remove = true;
}
else if (bitmap_bit_p (&generic_head, DECL_UID (t))
|| bitmap_bit_p (&lastprivate_head, DECL_UID (t)))
{
- error ("%qE appears more than once in data clauses", t);
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "%qE appears more than once in data clauses", t);
remove = true;
}
else
@@ -9876,8 +9915,9 @@ c_finish_omp_clauses (tree clauses)
}
if (share_name)
{
- error ("%qE is predetermined %qs for %qs",
- t, share_name, name);
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "%qE is predetermined %qs for %qs",
+ t, share_name, name);
remove = true;
}
}
@@ -9957,3 +9997,14 @@ c_build_qualified_type (tree type, int type_quals)
return build_qualified_type (type, type_quals);
}
+
+/* Build a VA_ARG_EXPR for the C parser. */
+
+tree
+c_build_va_arg (location_t loc, tree expr, tree type)
+{
+ if (warn_cxx_compat && TREE_CODE (type) == ENUMERAL_TYPE)
+ warning_at (loc, OPT_Wc___compat,
+ "C++ requires promoted type, not enum type, in %<va_arg%>");
+ return build_va_arg (loc, expr, type);
+}
diff --git a/gcc/c.opt b/gcc/c.opt
index fc34ff57f78..e8a9a31a382 100644
--- a/gcc/c.opt
+++ b/gcc/c.opt
@@ -284,8 +284,12 @@ Winvalid-pch
C ObjC C++ ObjC++ Warning
Warn about PCH files that are found but not used
+Wjump-misses-init
+C Objc Var(warn_jump_misses_init) Init(-1) Warning
+Warn when a jump misses a variable initialization
+
Wlogical-op
-C ObjC C++ ObjC++ Var(warn_logical_op) Init(-1) Warning
+C ObjC C++ ObjC++ Var(warn_logical_op) Init(0) Warning
Warn when a logical operator is suspiciously always evaluating to true or false
Wlong-long
diff --git a/gcc/calls.c b/gcc/calls.c
index 219b1d3afa6..c10b0cd3aba 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -3445,7 +3445,7 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
for (; count < nargs; count++)
{
rtx val = va_arg (p, rtx);
- enum machine_mode mode = va_arg (p, enum machine_mode);
+ enum machine_mode mode = (enum machine_mode) va_arg (p, int);
/* We cannot convert the arg value to the mode the library wants here;
must do it earlier where we know the signedness of the arg. */
diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c
index a2e28e20b47..2233a819f74 100644
--- a/gcc/cfgcleanup.c
+++ b/gcc/cfgcleanup.c
@@ -1009,40 +1009,6 @@ old_insns_match_p (int mode ATTRIBUTE_UNUSED, rtx i1, rtx i2)
? rtx_renumbered_equal_p (p1, p2) : rtx_equal_p (p1, p2))
return true;
- /* Do not do EQUIV substitution after reload. First, we're undoing the
- work of reload_cse. Second, we may be undoing the work of the post-
- reload splitting pass. */
- /* ??? Possibly add a new phase switch variable that can be used by
- targets to disallow the troublesome insns after splitting. */
- if (!reload_completed)
- {
- /* The following code helps take care of G++ cleanups. */
- rtx equiv1 = find_reg_equal_equiv_note (i1);
- rtx equiv2 = find_reg_equal_equiv_note (i2);
-
- if (equiv1 && equiv2
- /* If the equivalences are not to a constant, they may
- reference pseudos that no longer exist, so we can't
- use them. */
- && (! reload_completed
- || (CONSTANT_P (XEXP (equiv1, 0))
- && rtx_equal_p (XEXP (equiv1, 0), XEXP (equiv2, 0)))))
- {
- rtx s1 = single_set (i1);
- rtx s2 = single_set (i2);
- if (s1 != 0 && s2 != 0
- && rtx_renumbered_equal_p (SET_DEST (s1), SET_DEST (s2)))
- {
- validate_change (i1, &SET_SRC (s1), XEXP (equiv1, 0), 1);
- validate_change (i2, &SET_SRC (s2), XEXP (equiv2, 0), 1);
- if (! rtx_renumbered_equal_p (p1, p2))
- cancel_changes (0);
- else if (apply_change_group ())
- return true;
- }
- }
- }
-
return false;
}
@@ -1680,7 +1646,7 @@ try_crossjump_to_edge (int mode, edge e1, edge e2)
while (DEBUG_INSN_P (newpos1))
newpos1 = NEXT_INSN (newpos1);
- if (NOTE_P (newpos1))
+ if (NOTE_INSN_BASIC_BLOCK_P (newpos1))
newpos1 = NEXT_INSN (newpos1);
while (DEBUG_INSN_P (newpos1))
@@ -1884,8 +1850,12 @@ try_optimize_cfg (int mode)
edge s;
bool changed_here = false;
- /* Delete trivially dead basic blocks. */
- if (EDGE_COUNT (b->preds) == 0)
+ /* Delete trivially dead basic blocks. This is either
+ blocks with no predecessors, or empty blocks with no
+ successors. Empty blocks may result from expanding
+ __builtin_unreachable (). */
+ if (EDGE_COUNT (b->preds) == 0
+ || (EDGE_COUNT (b->succs) == 0 && BB_HEAD (b) == BB_END (b)))
{
c = b->prev_bb;
if (dump_file)
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index 289f300453e..2f07aada656 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -455,6 +455,28 @@ set_rtl (tree t, rtx x)
SA.partition_to_pseudo[var_to_partition (SA.map, t)] = x;
if (x && !MEM_P (x))
set_reg_attrs_for_decl_rtl (SSA_NAME_VAR (t), x);
+ /* For the benefit of debug information at -O0 (where vartracking
+ doesn't run) record the place also in the base DECL if it's
+ a normal variable (not a parameter). */
+ if (x && x != pc_rtx && TREE_CODE (SSA_NAME_VAR (t)) == VAR_DECL)
+ {
+ tree var = SSA_NAME_VAR (t);
+ /* If we don't yet have something recorded, just record it now. */
+ if (!DECL_RTL_SET_P (var))
+ SET_DECL_RTL (var, x);
+ /* If we have it set alrady to "multiple places" don't
+ change this. */
+ else if (DECL_RTL (var) == pc_rtx)
+ ;
+ /* If we have something recorded and it's not the same place
+ as we want to record now, we have multiple partitions for the
+ same base variable, with different places. We can't just
+ randomly chose one, hence we have to say that we don't know.
+ This only happens with optimization, and there var-tracking
+ will figure out the right thing. */
+ else if (DECL_RTL (var) != x)
+ SET_DECL_RTL (var, pc_rtx);
+ }
}
else
SET_DECL_RTL (t, x);
@@ -542,8 +564,8 @@ get_decl_align_unit (tree decl)
So here we only make sure stack_alignment_needed >= align. */
if (crtl->stack_alignment_needed < align)
crtl->stack_alignment_needed = align;
- if (crtl->max_used_stack_slot_alignment < crtl->stack_alignment_needed)
- crtl->max_used_stack_slot_alignment = crtl->stack_alignment_needed;
+ if (crtl->max_used_stack_slot_alignment < align)
+ crtl->max_used_stack_slot_alignment = align;
return align / BITS_PER_UNIT;
}
@@ -1161,7 +1183,6 @@ expand_one_var (tree var, bool toplevel, bool really_expand)
|| (!DECL_EXTERNAL (var)
&& !DECL_HAS_VALUE_EXPR_P (var)
&& !TREE_STATIC (var)
- && !DECL_RTL_SET_P (var)
&& TREE_TYPE (var) != error_mark_node
&& !DECL_HARD_REGISTER (var)
&& really_expand));
@@ -1174,7 +1195,7 @@ expand_one_var (tree var, bool toplevel, bool really_expand)
;
else if (TREE_STATIC (var))
;
- else if (DECL_RTL_SET_P (var))
+ else if (TREE_CODE (origvar) != SSA_NAME && DECL_RTL_SET_P (var))
;
else if (TREE_TYPE (var) == error_mark_node)
{
@@ -1389,7 +1410,8 @@ add_stack_protection_conflicts (void)
static void
create_stack_guard (void)
{
- tree guard = build_decl (VAR_DECL, NULL, ptr_type_node);
+ tree guard = build_decl (DECL_SOURCE_LOCATION (current_function_decl),
+ VAR_DECL, NULL, ptr_type_node);
TREE_THIS_VOLATILE (guard) = 1;
TREE_USED (guard) = 1;
expand_one_stack_var (guard);
@@ -1561,7 +1583,11 @@ expand_used_vars (void)
/* Expanded above already. */
if (is_gimple_reg (var))
- ;
+ {
+ TREE_USED (var) = 0;
+ ggc_free (t);
+ continue;
+ }
/* We didn't set a block for static or extern because it's hard
to tell the difference between a global variable (re)declared
in a local scope, and one that's really declared there to
@@ -2912,7 +2938,7 @@ expand_gimple_basic_block (basic_block bb)
return new_bb;
}
}
- else if (gimple_code (stmt) != GIMPLE_CHANGE_DYNAMIC_TYPE)
+ else
{
def_operand_p def_p;
tree stmt_tree;
@@ -3133,7 +3159,8 @@ discover_nonconstant_array_refs_r (tree * tp, int *walk_subtrees,
if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
{
t = get_base_address (t);
- if (t && DECL_P (t))
+ if (t && DECL_P (t)
+ && DECL_MODE (t) != BLKmode)
TREE_ADDRESSABLE (t) = 1;
}
@@ -3306,6 +3333,12 @@ gimple_expand_cfg (void)
&& !SA.partition_to_pseudo[i])
SA.partition_to_pseudo[i] = DECL_RTL_IF_SET (var);
gcc_assert (SA.partition_to_pseudo[i]);
+
+ /* If this decl was marked as living in multiple places, reset
+ this now to NULL. */
+ if (DECL_RTL_IF_SET (var) == pc_rtx)
+ SET_DECL_RTL (var, NULL);
+
/* Some RTL parts really want to look at DECL_RTL(x) when x
was a decl marked in REG_ATTR or MEM_ATTR. We could use
SET_DECL_RTL here making this available, but that would mean
diff --git a/gcc/cfglayout.c b/gcc/cfglayout.c
index ba2b87fc8bd..73f8badca95 100644
--- a/gcc/cfglayout.c
+++ b/gcc/cfglayout.c
@@ -1124,7 +1124,7 @@ cfg_layout_can_duplicate_bb_p (const_basic_block bb)
rtx
duplicate_insn_chain (rtx from, rtx to)
{
- rtx insn, last;
+ rtx insn, last, copy;
/* Avoid updating of boundaries of previous basic block. The
note will get removed from insn stream in fixup. */
@@ -1146,7 +1146,8 @@ duplicate_insn_chain (rtx from, rtx to)
if (GET_CODE (PATTERN (insn)) == ADDR_VEC
|| GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
break;
- emit_copy_of_insn_after (insn, get_last_insn ());
+ copy = emit_copy_of_insn_after (insn, get_last_insn ());
+ maybe_copy_epilogue_insn (insn, copy);
break;
case CODE_LABEL:
@@ -1166,23 +1167,18 @@ duplicate_insn_chain (rtx from, rtx to)
case NOTE_INSN_DELETED:
case NOTE_INSN_DELETED_LABEL:
/* No problem to strip these. */
- case NOTE_INSN_EPILOGUE_BEG:
- /* Debug code expect these notes to exist just once.
- Keep them in the master copy.
- ??? It probably makes more sense to duplicate them for each
- epilogue copy. */
case NOTE_INSN_FUNCTION_BEG:
/* There is always just single entry to function. */
case NOTE_INSN_BASIC_BLOCK:
break;
+ case NOTE_INSN_EPILOGUE_BEG:
case NOTE_INSN_SWITCH_TEXT_SECTIONS:
emit_note_copy (insn);
break;
default:
- /* All other notes should have already been eliminated.
- */
+ /* All other notes should have already been eliminated. */
gcc_unreachable ();
}
break;
diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c
index ec35cc0e4df..ad64e536860 100644
--- a/gcc/cfgrtl.c
+++ b/gcc/cfgrtl.c
@@ -86,8 +86,16 @@ static void rtl_make_forwarder_block (edge);
static int
can_delete_note_p (const_rtx note)
{
- return (NOTE_KIND (note) == NOTE_INSN_DELETED
- || NOTE_KIND (note) == NOTE_INSN_BASIC_BLOCK);
+ switch (NOTE_KIND (note))
+ {
+ case NOTE_INSN_DELETED:
+ case NOTE_INSN_BASIC_BLOCK:
+ case NOTE_INSN_EPILOGUE_BEG:
+ return true;
+
+ default:
+ return false;
+ }
}
/* True if a given label can be deleted. */
@@ -2054,15 +2062,17 @@ rtl_verify_flow_info (void)
rtx insn;
/* Ensure existence of barrier in BB with no fallthru edges. */
- for (insn = BB_END (bb); !insn || !BARRIER_P (insn);
- insn = NEXT_INSN (insn))
- if (!insn
- || NOTE_INSN_BASIC_BLOCK_P (insn))
+ for (insn = NEXT_INSN (BB_END (bb)); ; insn = NEXT_INSN (insn))
+ {
+ if (!insn || NOTE_INSN_BASIC_BLOCK_P (insn))
{
error ("missing barrier after block %i", bb->index);
err = 1;
break;
}
+ if (BARRIER_P (insn))
+ break;
+ }
}
else if (e->src != ENTRY_BLOCK_PTR
&& e->dest != EXIT_BLOCK_PTR)
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index 4472170b55c..4b3a962fbd3 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -701,8 +701,9 @@ cgraph_create_edge_including_clones (struct cgraph_node *orig, struct cgraph_nod
{
struct cgraph_node *node;
- cgraph_create_edge (orig, callee, stmt, count, freq, loop_depth)->inline_failed =
- reason;
+ if (!cgraph_edge (orig, stmt))
+ cgraph_create_edge (orig, callee, stmt,
+ count, freq, loop_depth)->inline_failed = reason;
if (orig->clones)
for (node = orig->clones; node != orig;)
@@ -1394,11 +1395,18 @@ dump_cgraph_node (FILE *f, struct cgraph_node *node)
if (node->count)
fprintf (f, " executed "HOST_WIDEST_INT_PRINT_DEC"x",
(HOST_WIDEST_INT)node->count);
- if (node->local.inline_summary.self_insns)
- fprintf (f, " %i insns", node->local.inline_summary.self_insns);
- if (node->global.insns && node->global.insns
- != node->local.inline_summary.self_insns)
- fprintf (f, " (%i after inlining)", node->global.insns);
+ if (node->local.inline_summary.self_time)
+ fprintf (f, " %i time, %i benefit", node->local.inline_summary.self_time,
+ node->local.inline_summary.time_inlining_benefit);
+ if (node->global.time && node->global.time
+ != node->local.inline_summary.self_time)
+ fprintf (f, " (%i after inlining)", node->global.time);
+ if (node->local.inline_summary.self_size)
+ fprintf (f, " %i size, %i benefit", node->local.inline_summary.self_size,
+ node->local.inline_summary.size_inlining_benefit);
+ if (node->global.size && node->global.size
+ != node->local.inline_summary.self_size)
+ fprintf (f, " (%i after inlining)", node->global.size);
if (node->local.inline_summary.estimated_self_stack_size)
fprintf (f, " %i bytes stack usage", (int)node->local.inline_summary.estimated_self_stack_size);
if (node->global.estimated_stack_size != node->local.inline_summary.estimated_self_stack_size)
@@ -1702,7 +1710,7 @@ cgraph_create_virtual_clone (struct cgraph_node *old_node,
??? We cannot use COMDAT linkage because there is no
ABI support for this. */
DECL_EXTERNAL (new_node->decl) = 0;
- DECL_ONE_ONLY (new_node->decl) = 0;
+ DECL_COMDAT_GROUP (new_node->decl) = 0;
TREE_PUBLIC (new_node->decl) = 0;
DECL_COMDAT (new_node->decl) = 0;
DECL_WEAK (new_node->decl) = 0;
@@ -1863,4 +1871,32 @@ cgraph_add_new_function (tree fndecl, bool lowered)
}
}
+/* Return true if NODE can be made local for API change.
+ Extern inline functions and C++ COMDAT functions can be made local
+ at the expense of possible code size growth if function is used in multiple
+ compilation units. */
+bool
+cgraph_node_can_be_local_p (struct cgraph_node *node)
+{
+ return !node->needed;
+}
+
+/* Bring NODE local. */
+void
+cgraph_make_node_local (struct cgraph_node *node)
+{
+ gcc_assert (cgraph_node_can_be_local_p (node));
+ if (DECL_COMDAT (node->decl) || DECL_EXTERNAL (node->decl))
+ {
+ DECL_COMDAT (node->decl) = 0;
+ DECL_COMDAT_GROUP (node->decl) = 0;
+ TREE_PUBLIC (node->decl) = 0;
+ DECL_WEAK (node->decl) = 0;
+ DECL_EXTERNAL (node->decl) = 0;
+ node->local.externally_visible = false;
+ node->local.local = true;
+ gcc_assert (cgraph_function_body_availability (node) == AVAIL_LOCAL);
+ }
+}
+
#include "gt-cgraph.h"
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index 58ae06852cf..bf3f320e4f3 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -55,8 +55,14 @@ struct GTY(()) inline_summary
/* Estimated stack frame consumption by the function. */
HOST_WIDE_INT estimated_self_stack_size;
- /* Size of the function before inlining. */
- int self_insns;
+ /* Size of the function body. */
+ int self_size;
+ /* How many instructions are likely going to disappear after inlining. */
+ int size_inlining_benefit;
+ /* Estimated time spent executing the function body. */
+ int self_time;
+ /* How much time is going to be saved by inlining. */
+ int time_inlining_benefit;
};
/* Information about the function collected locally.
@@ -108,7 +114,8 @@ struct GTY(()) cgraph_global_info {
struct cgraph_node *inlined_to;
/* Estimated size of the function after inlining. */
- int insns;
+ int time;
+ int size;
/* Estimated growth after inlining. INT_MIN if not computed. */
int estimated_growth;
@@ -211,11 +218,8 @@ struct GTY((chain_next ("%h.next"), chain_prev ("%h.previous"))) cgraph_node {
unsigned process : 1;
/* Set for aliases once they got through assemble_alias. */
unsigned alias : 1;
-
- /* In non-unit-at-a-time mode the function body of inline candidates is saved
- into clone before compiling so the function in original form can be
- inlined later. This pointer points to the clone. */
- tree inline_decl;
+ /* Set for nodes that was constructed and finalized by frontend. */
+ unsigned finalized_by_frontend : 1;
};
typedef struct cgraph_node *cgraph_node_ptr;
@@ -501,6 +505,8 @@ void dump_varpool_node (FILE *, struct varpool_node *);
void varpool_finalize_decl (tree);
bool decide_is_variable_needed (struct varpool_node *, tree);
enum availability cgraph_variable_initializer_availability (struct varpool_node *);
+void cgraph_make_node_local (struct cgraph_node *);
+bool cgraph_node_can_be_local_p (struct cgraph_node *);
bool varpool_assemble_pending_decls (void);
bool varpool_assemble_decl (struct varpool_node *node);
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index a73eabc44e3..53d99bf9cc3 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -510,6 +510,7 @@ cgraph_finalize_function (tree decl, bool nested)
notice_global_symbol (decl);
node->local.finalized = true;
node->lowered = DECL_STRUCT_FUNCTION (decl)->cfg != NULL;
+ node->finalized_by_frontend = true;
record_cdtor_fn (node->decl);
if (node->nested)
lower_nested_functions (decl);
@@ -1090,7 +1091,8 @@ cgraph_expand_function (struct cgraph_node *node)
gcc_assert (node->lowered);
/* Generate RTL for the body of DECL. */
- if (lang_hooks.callgraph.emit_associated_thunks)
+ if (lang_hooks.callgraph.emit_associated_thunks
+ && node->finalized_by_frontend)
lang_hooks.callgraph.emit_associated_thunks (decl);
tree_rest_of_compilation (decl);
@@ -1427,11 +1429,12 @@ cgraph_build_static_cdtor (char which, tree body, int priority)
sprintf (which_buf, "%c_%.5d_%d", which, priority, counter++);
name = get_file_function_name (which_buf);
- decl = build_decl (FUNCTION_DECL, name,
+ decl = build_decl (input_location, FUNCTION_DECL, name,
build_function_type (void_type_node, void_list_node));
current_function_decl = decl;
- resdecl = build_decl (RESULT_DECL, NULL_TREE, void_type_node);
+ resdecl = build_decl (input_location,
+ RESULT_DECL, NULL_TREE, void_type_node);
DECL_ARTIFICIAL (resdecl) = 1;
DECL_RESULT (decl) = resdecl;
DECL_CONTEXT (resdecl) = decl;
@@ -1613,7 +1616,7 @@ cgraph_function_versioning (struct cgraph_node *old_version_node,
??? We cannot use COMDAT linkage because there is no
ABI support for this. */
DECL_EXTERNAL (new_version_node->decl) = 0;
- DECL_ONE_ONLY (new_version_node->decl) = 0;
+ DECL_COMDAT_GROUP (new_version_node->decl) = NULL_TREE;
TREE_PUBLIC (new_version_node->decl) = 0;
DECL_COMDAT (new_version_node->decl) = 0;
DECL_WEAK (new_version_node->decl) = 0;
@@ -1683,9 +1686,12 @@ save_inline_function_body (struct cgraph_node *node)
tree_function_versioning (node->decl, first_clone->decl, NULL, true, NULL);
DECL_EXTERNAL (first_clone->decl) = 0;
- DECL_ONE_ONLY (first_clone->decl) = 0;
+ DECL_COMDAT_GROUP (first_clone->decl) = NULL_TREE;
TREE_PUBLIC (first_clone->decl) = 0;
DECL_COMDAT (first_clone->decl) = 0;
+ VEC_free (ipa_opt_pass, heap,
+ DECL_STRUCT_FUNCTION (first_clone->decl)->ipa_transforms_to_apply);
+ DECL_STRUCT_FUNCTION (first_clone->decl)->ipa_transforms_to_apply = NULL;
#ifdef ENABLE_CHECKING
verify_cgraph_node (first_clone);
diff --git a/gcc/collect2-aix.c b/gcc/collect2-aix.c
new file mode 100644
index 00000000000..7d25e7e6b89
--- /dev/null
+++ b/gcc/collect2-aix.c
@@ -0,0 +1,371 @@
+/* AIX cross support for collect2.
+ Copyright (C) 2009 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/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "collect2-aix.h"
+
+#ifdef CROSS_AIX_SUPPORT
+
+#include <sys/mman.h>
+
+/* Read SIZE bytes starting at DATA as a big-endian value. */
+
+static inline bfd_vma
+read_value (char *data, unsigned int size)
+{
+ bfd_vma value;
+ unsigned int i;
+
+ value = 0;
+ for (i = 0; i < size; i++)
+ {
+ value <<= 8;
+ value += (unsigned char) data[i];
+ }
+ return value;
+}
+
+/* FIELD is a char array. Read the contents as a big-endian integer. */
+#define READ_FIELD(FIELD) \
+ read_value (FIELD, sizeof (FIELD))
+
+/* OBJECT is a char pointer to an in-file object of type struct TYPE.
+ Return the address of field FIELD. */
+#define OBJECT_FIELD(OBJECT, TYPE, FIELD) \
+ (OBJECT) + offsetof (struct TYPE, FIELD)
+
+/* Return the size of FIELD, which is a field of struct TYPE. */
+#define FIELD_SIZE(TYPE, FIELD) \
+ sizeof (((struct TYPE *) (0))->FIELD)
+
+/* OBJECT is a char pointer to an in-file object of type struct TYPE.
+ Read the value of field FIELD as a big-endian integer. */
+#define READ_OBJECT(OBJECT, TYPE, FIELD) \
+ read_value (OBJECT_FIELD (OBJECT, TYPE, FIELD), FIELD_SIZE (TYPE, FIELD))
+
+/* Copy FIELD from an external structure of type TYPE at address FROM
+ to an internal structure pointed to by TO. */
+#define COPY_FIELD(TO, FROM, TYPE, FIELD) \
+ ((TO)->FIELD = READ_OBJECT (FROM, TYPE, FIELD))
+
+/* Return true if STRING is less than SIZE bytes long. EXTRA_TERMINATOR
+ is another character (besides '\0') that acts as a terminator,
+ or '\0' if none. */
+
+static bool
+string_within_bounds_p (const char *string, size_t size, char extra_terminator)
+{
+ const char *p;
+
+ for (p = string; p < string + size; p++)
+ if (*p == '\0' || *p == extra_terminator)
+ return true;
+ return false;
+}
+
+/* STRING is a pointer to a char array. Try to read its value as an
+ ASCII-encoded integer. On success, return true and store the result
+ in TARGET. */
+#define PARSE_INTEGER(TARGET, STRING) \
+ (string_within_bounds_p (&(STRING)[0], sizeof (STRING), ' ') \
+ && ((TARGET) = strtoul (STRING, NULL, 0), true))
+
+/* Check that LDFILE's current object has SIZE bytes starting at OFFSET. */
+
+static inline bool
+within_object_p (LDFILE *ldfile, size_t offset, size_t size)
+{
+ return offset <= ldfile->object_size && offset + size <= ldfile->object_size;
+}
+
+/* Try to read the file header for an XCOFF object at OFFSET bytes into
+ LDFILE. The object is expected to be OBJECT_SIZE bytes in size.
+ If the object is a member of an archive, NEXT_MEMBER is the offset
+ of the next member, otherwise it is -1.
+
+ Return true on success, recording the object information in LDFILE. */
+
+static bool
+read_xcoff_object (LDFILE *ldfile, size_t offset, size_t object_size,
+ off_t next_member)
+{
+ struct internal_filehdr *internal;
+ char *external;
+ void *map;
+ size_t page_size;
+
+ /* First try to map the file into memory. */
+ page_size = getpagesize ();
+ ldfile->page_offset = offset & (page_size - 1);
+ map = mmap (NULL, object_size + ldfile->page_offset, PROT_READ,
+ MAP_SHARED, ldfile->fd, offset - ldfile->page_offset);
+ if (map == MAP_FAILED)
+ return false;
+
+ /* Record the success. */
+ ldfile->object = (char *) map + ldfile->page_offset;
+ ldfile->object_size = object_size;
+ ldfile->next_member = next_member;
+
+ /* Read the magic value to determine the type of file. */
+ if (!within_object_p (ldfile, 0, F_MAGIC_SIZE))
+ return false;
+
+ internal = &ldfile->filehdr;
+ external = ldfile->object;
+ internal->f_magic = read_value (external, F_MAGIC_SIZE);
+ if (internal->f_magic == U802TOCMAGIC)
+ {
+ if (!within_object_p (ldfile, 0, sizeof (struct external_filehdr_32)))
+ return false;
+
+ COPY_FIELD (internal, external, external_filehdr_32, f_nscns);
+ COPY_FIELD (internal, external, external_filehdr_32, f_timdat);
+ COPY_FIELD (internal, external, external_filehdr_32, f_symptr);
+ COPY_FIELD (internal, external, external_filehdr_32, f_nsyms);
+ COPY_FIELD (internal, external, external_filehdr_32, f_opthdr);
+ COPY_FIELD (internal, external, external_filehdr_32, f_flags);
+ return true;
+ }
+ else if (internal->f_magic == U803XTOCMAGIC
+ || internal->f_magic == U64_TOCMAGIC)
+ {
+ if (!within_object_p (ldfile, 0, sizeof (struct external_filehdr_64)))
+ return false;
+
+ COPY_FIELD (internal, external, external_filehdr_64, f_nscns);
+ COPY_FIELD (internal, external, external_filehdr_64, f_timdat);
+ COPY_FIELD (internal, external, external_filehdr_64, f_symptr);
+ COPY_FIELD (internal, external, external_filehdr_64, f_nsyms);
+ COPY_FIELD (internal, external, external_filehdr_64, f_opthdr);
+ COPY_FIELD (internal, external, external_filehdr_64, f_flags);
+ return true;
+ }
+ return false;
+}
+
+/* Try to read an archive member at OFFSET bytes into LDFILE.
+ Return true on success, recording the member and object
+ information in LDFILE. */
+
+static bool
+read_archive_member (LDFILE *ldfile, size_t offset)
+{
+ struct external_big_ar_member member;
+ size_t namlen;
+ size_t size;
+ off_t next_member;
+
+ if (lseek (ldfile->fd, offset, SEEK_SET) >= 0
+ && read (ldfile->fd, &member, sizeof (member)) == sizeof (member)
+ && PARSE_INTEGER (namlen, member.ar_namlen)
+ /* Stop once we reach the member table entry, which has a name
+ of length 0. */
+ && namlen > 0
+ && PARSE_INTEGER (size, member.ar_size)
+ && PARSE_INTEGER (next_member, member.ar_nextoff))
+ {
+ /* The archive is followed by an even-padded name, then by
+ a magic string of length SXCOFFARFMAG. The object itself
+ starts after that. */
+ offset += sizeof (member) + namlen + SXCOFFARFMAG;
+ offset += offset & 1;
+ return read_xcoff_object (ldfile, offset, size, next_member);
+ }
+ return false;
+}
+
+/* Try to treat LDFILE as a non-empty big archive. Return true
+ on success, storing the member and object information for
+ the first member in LDFILE. */
+
+static bool
+read_big_archive (LDFILE *ldfile)
+{
+ struct external_big_ar_filehdr filehdr;
+ size_t offset;
+
+ return (lseek (ldfile->fd, 0L, SEEK_SET) == 0
+ && read (ldfile->fd, &filehdr, sizeof (filehdr)) == sizeof (filehdr)
+ && memcmp (filehdr.fl_magic, FL_MAGIC_BIG_AR, FL_MAGIC_SIZE) == 0
+ && PARSE_INTEGER (offset, filehdr.fl_firstmemoff)
+ && read_archive_member (ldfile, offset));
+}
+
+/* LDFILE is a zero-initialized structure. Try to open FILENAME,
+ returning true on success. */
+
+static bool
+open_file (LDFILE *ldfile, const char *filename)
+{
+ struct stat st;
+
+ ldfile->fd = open (filename, O_RDONLY);
+ if (ldfile->fd < 0)
+ return false;
+
+ if (read_big_archive (ldfile))
+ return true;
+
+ if (fstat (ldfile->fd, &st) < 0)
+ return false;
+
+ return read_xcoff_object (ldfile, 0, st.st_size, -1);
+}
+
+/* Release the memory associated with the current object, if one has
+ been mapped. */
+
+static void
+free_object (LDFILE *ldfile)
+{
+ if (ldfile->object)
+ munmap (ldfile->object - ldfile->page_offset,
+ ldfile->object_size + ldfile->page_offset);
+}
+
+/* Free LDFILE and all resources associated with it. */
+
+static void
+free_ldfile (LDFILE *ldfile)
+{
+ if (ldfile->fd >= 0)
+ close (ldfile->fd);
+ XDELETE (ldfile);
+}
+
+/* Implement the API-defined ldopen function. */
+
+LDFILE *
+ldopen (char *filename, LDFILE *ldfile)
+{
+ if (ldfile == NULL)
+ {
+ ldfile = XCNEW (LDFILE);
+ if (!open_file (ldfile, filename))
+ {
+ free_object (ldfile);
+ free_ldfile (ldfile);
+ return NULL;
+ }
+ }
+ return ldfile;
+}
+
+/* Implement the API-defined ldtbread function. */
+
+int
+ldtbread (LDFILE *ldfile, long index, SYMENT *internal)
+{
+ size_t offset, name_length;
+ char *external;
+
+ /* Make sure that the symbol index is valid. */
+ if (index < 0 || index >= HEADER (ldfile).f_nsyms)
+ return FAILURE;
+
+ /* Work out the offset of the symbol table entry. */
+ offset = HEADER (ldfile).f_symptr + index * sizeof (struct external_syment);
+ if (!within_object_p (ldfile, offset, sizeof (struct external_syment)))
+ return FAILURE;
+
+ /* Read all the fields. The format differs between 32-bit and
+ 64-bit files. */
+ external = ldfile->object + offset;
+ if (HEADER (ldfile).f_magic == U802TOCMAGIC)
+ {
+ /* Copy the n_zeroes/n_offset interpretation. */
+ internal->n_zeroes = READ_OBJECT (external, external_syment,
+ u.xcoff32.u.u.n_zeroes);
+ internal->n_offset = READ_OBJECT (external, external_syment,
+ u.xcoff32.u.u.n_offset);
+
+ /* Copy the n_name interpretation. The internal version has room
+ for a null terminator. */
+ name_length = FIELD_SIZE (external_syment, u.xcoff32.u.n_name);
+ memcpy (internal->n_name,
+ external + offsetof (struct external_syment, u.xcoff32.u.n_name),
+ name_length);
+ internal->n_name[name_length] = 0;
+
+ internal->n_value = READ_OBJECT (external, external_syment,
+ u.xcoff32.n_value);
+ }
+ else
+ {
+ internal->n_zeroes = 0;
+ internal->n_offset = READ_OBJECT (external, external_syment,
+ u.xcoff64.n_offset);
+ internal->n_value = READ_OBJECT (external, external_syment,
+ u.xcoff64.n_value);
+ }
+ COPY_FIELD (internal, external, external_syment, n_scnum);
+ COPY_FIELD (internal, external, external_syment, n_type);
+ COPY_FIELD (internal, external, external_syment, n_sclass);
+ COPY_FIELD (internal, external, external_syment, n_numaux);
+ return SUCCESS;
+}
+
+/* Implement the API-defined ldgetname function. */
+
+char *
+ldgetname (LDFILE *ldfile, SYMENT *symbol)
+{
+ char *name;
+ size_t offset;
+
+ /* If the zeroes field is nonzero, the name is in the symbol table
+ entry itself. */
+ if (symbol->n_zeroes != 0)
+ return symbol->n_name;
+
+ /* Otherwise, the symbol table entry contains an offset into the
+ string table, which starts after the end of the symbol table. */
+ offset = (HEADER (ldfile).f_symptr
+ + HEADER (ldfile).f_nsyms * sizeof (struct external_syment)
+ + symbol->n_offset);
+ if (offset >= ldfile->object_size)
+ return NULL;
+
+ /* Make sure that the name is entirely contained within the object. */
+ name = ldfile->object + offset;
+ if (!string_within_bounds_p (name, ldfile->object_size - offset, '\0'))
+ return NULL;
+
+ return name;
+}
+
+/* Implement the API-defined ldclose function. */
+
+int
+ldclose (LDFILE *ldfile)
+{
+ free_object (ldfile);
+ if (ldfile->next_member >= 0
+ && read_archive_member (ldfile, ldfile->next_member))
+ return FAILURE;
+
+ free_ldfile (ldfile);
+ return SUCCESS;
+}
+
+#endif
diff --git a/gcc/collect2-aix.h b/gcc/collect2-aix.h
new file mode 100644
index 00000000000..1ab313d0f34
--- /dev/null
+++ b/gcc/collect2-aix.h
@@ -0,0 +1,301 @@
+/* AIX cross support for collect2.
+ Copyright (C) 2009 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/>. */
+
+/* collect2-aix.c requires mmap support. It should otherwise be
+ fairly portable. */
+#if defined(CROSS_DIRECTORY_STRUCTURE) \
+ && defined(TARGET_AIX_VERSION) \
+ && HAVE_MMAP
+
+#define CROSS_AIX_SUPPORT 1
+
+/* -------------------------------------------------------------------------
+ Definitions adapted from bfd. (Fairly heavily adapted in some cases.)
+ ------------------------------------------------------------------------- */
+
+/* Compatiblity types for bfd. */
+typedef unsigned HOST_WIDE_INT bfd_vma;
+
+/* The size of an archive's fl_magic field. */
+#define FL_MAGIC_SIZE 8
+
+/* The expected contents of fl_magic for big archives. */
+#define FL_MAGIC_BIG_AR "<bigaf>\012"
+
+/* The size of each offset string in the header of a big archive. */
+#define AR_BIG_OFFSET_SIZE 20
+
+/* The format of the file header in a "big" XCOFF archive. */
+struct external_big_ar_filehdr
+{
+ /* Magic string. */
+ char fl_magic[FL_MAGIC_SIZE];
+
+ /* Offset of the member table (decimal ASCII string). */
+ char fl_memoff[AR_BIG_OFFSET_SIZE];
+
+ /* Offset of the global symbol table for 32-bit objects (decimal ASCII
+ string). */
+ char fl_symoff[AR_BIG_OFFSET_SIZE];
+
+ /* Offset of the global symbol table for 64-bit objects (decimal ASCII
+ string). */
+ char fl_symoff64[AR_BIG_OFFSET_SIZE];
+
+ /* Offset of the first member in the archive (decimal ASCII string). */
+ char fl_firstmemoff[AR_BIG_OFFSET_SIZE];
+
+ /* Offset of the last member in the archive (decimal ASCII string). */
+ char fl_lastmemoff[AR_BIG_OFFSET_SIZE];
+
+ /* Offset of the first member on the free list (decimal ASCII
+ string). */
+ char fl_freeoff[AR_BIG_OFFSET_SIZE];
+};
+
+/* Each archive name is followed by this many bytes of magic string. */
+#define SXCOFFARFMAG 2
+
+/* The format of a member header in a "big" XCOFF archive. */
+struct external_big_ar_member
+{
+ /* File size not including the header (decimal ASCII string). */
+ char ar_size[AR_BIG_OFFSET_SIZE];
+
+ /* File offset of next archive member (decimal ASCII string). */
+ char ar_nextoff[AR_BIG_OFFSET_SIZE];
+
+ /* File offset of previous archive member (decimal ASCII string). */
+ char ar_prevoff[AR_BIG_OFFSET_SIZE];
+
+ /* File mtime (decimal ASCII string). */
+ char ar_date[12];
+
+ /* File UID (decimal ASCII string). */
+ char ar_uid[12];
+
+ /* File GID (decimal ASCII string). */
+ char ar_gid[12];
+
+ /* File mode (octal ASCII string). */
+ char ar_mode[12];
+
+ /* Length of file name (decimal ASCII string). */
+ char ar_namlen[4];
+
+ /* This structure is followed by the file name. The length of the
+ name is given in the namlen field. If the length of the name is
+ odd, the name is followed by a null byte. The name and optional
+ null byte are followed by XCOFFARFMAG, which is not included in
+ namlen. The contents of the archive member follow; the number of
+ bytes is given in the size field. */
+};
+
+/* The known values of f_magic in an XCOFF file header. */
+#define U802WRMAGIC 0730 /* Writeable text segments. */
+#define U802ROMAGIC 0735 /* Readonly sharable text segments. */
+#define U802TOCMAGIC 0737 /* Readonly text segments and TOC. */
+#define U803XTOCMAGIC 0757 /* Aix 4.3 64-bit XCOFF. */
+#define U64_TOCMAGIC 0767 /* AIX 5+ 64-bit XCOFF. */
+
+/* The number of bytes in an XCOFF file's f_magic field. */
+#define F_MAGIC_SIZE 2
+
+/* The format of a 32-bit XCOFF file header. */
+struct external_filehdr_32
+{
+ /* The magic number. */
+ char f_magic[F_MAGIC_SIZE];
+
+ /* The number of sections. */
+ char f_nscns[2];
+
+ /* Time & date stamp. */
+ char f_timdat[4];
+
+ /* The offset of the symbol table from the start of the file. */
+ char f_symptr[4];
+
+ /* The number of entries in the symbol table. */
+ char f_nsyms[4];
+
+ /* The size of the auxillary header. */
+ char f_opthdr[2];
+
+ /* Flags. */
+ char f_flags[2];
+};
+
+/* The format of a 64-bit XCOFF file header. */
+struct external_filehdr_64
+{
+ /* The magic number. */
+ char f_magic[F_MAGIC_SIZE];
+
+ /* The number of sections. */
+ char f_nscns[2];
+
+ /* Time & date stamp. */
+ char f_timdat[4];
+
+ /* The offset of the symbol table from the start of the file. */
+ char f_symptr[8];
+
+ /* The size of the auxillary header. */
+ char f_opthdr[2];
+
+ /* Flags. */
+ char f_flags[2];
+
+ /* The number of entries in the symbol table. */
+ char f_nsyms[4];
+};
+
+/* An internal representation of the XCOFF file header. */
+struct internal_filehdr
+{
+ unsigned short f_magic;
+ unsigned short f_nscns;
+ long f_timdat;
+ bfd_vma f_symptr;
+ long f_nsyms;
+ unsigned short f_opthdr;
+ unsigned short f_flags;
+};
+
+/* Symbol classes have their names in the debug section if this flag
+ is set. */
+#define DBXMASK 0x80
+
+/* The format of an XCOFF symbol-table entry. */
+struct external_syment
+{
+ union {
+ struct {
+ union {
+ /* The name of the symbol. There is an implicit null character
+ after the end of the array. */
+ char n_name[8];
+ struct {
+ /* If n_zeroes is zero, n_offset is the offset the name from
+ the start of the string table. */
+ char n_zeroes[4];
+ char n_offset[4];
+ } u;
+ } u;
+
+ /* The symbol's value. */
+ char n_value[4];
+ } xcoff32;
+ struct {
+ /* The symbol's value. */
+ char n_value[8];
+
+ /* The offset of the symbol from the start of the string table. */
+ char n_offset[4];
+ } xcoff64;
+ } u;
+
+ /* The number of the section to which this symbol belongs. */
+ char n_scnum[2];
+
+ /* The type of symbol. (It can be interpreted as an n_lang
+ and an n_cpu byte, but we don't care about that here.) */
+ char n_type[2];
+
+ /* The class of symbol (a C_* value). */
+ char n_sclass[1];
+
+ /* The number of auxillary symbols attached to this entry. */
+ char n_numaux[1];
+};
+
+/* Definitions required by collect2. */
+#define C_EXT 2
+
+#define F_SHROBJ 0x2000
+
+#define N_UNDEF ((short) 0)
+#define N_TMASK 060
+#define N_BTSHFT 4
+
+#define DT_NON 0
+#define DT_FCN 2
+
+/* -------------------------------------------------------------------------
+ Local code.
+ ------------------------------------------------------------------------- */
+
+/* An internal representation of an XCOFF symbol-table entry,
+ which is associated with the API-defined SYMENT type. */
+struct internal_syment
+{
+ char n_name[9];
+ unsigned int n_zeroes;
+ bfd_vma n_offset;
+ bfd_vma n_value;
+ short n_scnum;
+ unsigned short n_flags;
+ unsigned short n_type;
+ unsigned char n_sclass;
+ unsigned char n_numaux;
+};
+typedef struct internal_syment SYMENT;
+
+/* The internal representation of the API-defined LDFILE type. */
+struct internal_ldfile
+{
+ /* The file handle for the associated file, or -1 if it hasn't been
+ opened yet. */
+ int fd;
+
+ /* The start of the current XCOFF object, if one has been mapped
+ into memory. Null otherwise. */
+ char *object;
+
+ /* The offset of OBJECT from the start of the containing page. */
+ size_t page_offset;
+
+ /* The size of the file pointed to by OBJECT. Valid iff OFFSET
+ is nonnull. */
+ size_t object_size;
+
+ /* The offset of the next member in an archive after OBJECT,
+ or -1 if this isn't an archive. Valid iff OFFSET is nonnull. */
+ off_t next_member;
+
+ /* The parsed version of the XCOFF file header. */
+ struct internal_filehdr filehdr;
+};
+typedef struct internal_ldfile LDFILE;
+
+/* The API allows the file header to be directly accessed via this macro. */
+#define HEADER(FILE) ((FILE)->filehdr)
+
+/* API-defined return codes. SUCCESS must be > 0 and FAILURE must be <= 0. */
+#define SUCCESS 1
+#define FAILURE 0
+
+/* API-defined functions. */
+extern LDFILE *ldopen (char *, LDFILE *);
+extern char *ldgetname (LDFILE *, SYMENT *);
+extern int ldtbread (LDFILE *, long, SYMENT *);
+extern int ldclose (LDFILE *);
+
+#endif
diff --git a/gcc/collect2.c b/gcc/collect2.c
index 277ddd6dc4c..efb00871755 100644
--- a/gcc/collect2.c
+++ b/gcc/collect2.c
@@ -42,6 +42,7 @@ along with GCC; see the file COPYING3. If not see
#define COLLECT
#include "collect2.h"
+#include "collect2-aix.h"
#include "demangle.h"
#include "obstack.h"
#include "intl.h"
@@ -54,7 +55,9 @@ along with GCC; see the file COPYING3. If not see
cross-versions are in the proper directories. */
#ifdef CROSS_DIRECTORY_STRUCTURE
+#ifndef CROSS_AIX_SUPPORT
#undef OBJECT_FORMAT_COFF
+#endif
#undef MD_EXEC_PREFIX
#undef REAL_LD_FILE_NAME
#undef REAL_NM_FILE_NAME
@@ -72,6 +75,7 @@ along with GCC; see the file COPYING3. If not see
#ifdef OBJECT_FORMAT_COFF
+#ifndef CROSS_DIRECTORY_STRUCTURE
#include <a.out.h>
#include <ar.h>
@@ -86,6 +90,7 @@ along with GCC; see the file COPYING3. If not see
#endif
#include <ldfcn.h>
+#endif
/* Some systems have an ISCOFF macro, but others do not. In some cases
the macro may be wrong. MY_ISCOFF is defined in tm.h files for machines
@@ -212,6 +217,14 @@ static char *response_file; /* Name of any current response file */
struct obstack temporary_obstack;
char * temporary_firstobj;
+/* A string that must be prepended to a target OS path in order to find
+ it on the host system. */
+#ifdef TARGET_SYSTEM_ROOT
+static const char *target_system_root = TARGET_SYSTEM_ROOT;
+#else
+static const char *target_system_root = "";
+#endif
+
/* Structure to hold all the directories in which to search for files to
execute. */
@@ -857,9 +870,12 @@ main (int argc, char **argv)
/* Do not invoke xcalloc before this point, since locale needs to be
set first, in case a diagnostic is issued. */
- ld1 = (const char **)(ld1_argv = XCNEWVEC (char *, argc+4));
- ld2 = (const char **)(ld2_argv = XCNEWVEC (char *, argc+11));
- object = (const char **)(object_lst = XCNEWVEC (char *, argc));
+ ld1_argv = XCNEWVEC (char *, argc + 4);
+ ld1 = CONST_CAST2 (const char **, char **, ld1_argv);
+ ld2_argv = XCNEWVEC (char *, argc + 11);
+ ld2 = CONST_CAST2 (const char **, char **, ld2_argv);
+ object_lst = XCNEWVEC (char *, argc);
+ object = CONST_CAST2 (const char **, char **, object_lst);
#ifdef DEBUG
debug = 1;
@@ -904,7 +920,8 @@ main (int argc, char **argv)
-fno-exceptions -w */
num_c_args += 5;
- c_ptr = (const char **) (c_argv = XCNEWVEC (char *, num_c_args));
+ c_argv = XCNEWVEC (char *, num_c_args);
+ c_ptr = CONST_CAST2 (const char **, char **, c_argv);
if (argc < 2)
fatal ("no arguments");
@@ -1150,7 +1167,9 @@ main (int argc, char **argv)
#else
#if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES
case 'L':
- if (is_in_args (arg, (const char **) ld1_argv, ld1-1))
+ if (is_in_args (arg,
+ CONST_CAST2 (const char **, char **, ld1_argv),
+ ld1 - 1))
--ld1;
break;
#endif /* LINK_ELIMINATE_DUPLICATE_LDIRECTORIES */
@@ -1215,6 +1234,8 @@ main (int argc, char **argv)
ld1--;
ld2--;
}
+ else if (strncmp (arg, "--sysroot=", 10) == 0)
+ target_system_root = arg + 10;
break;
}
}
@@ -1406,7 +1427,8 @@ main (int argc, char **argv)
if (strip_flag)
{
char **real_strip_argv = XCNEWVEC (char *, 3);
- const char ** strip_argv = (const char **) real_strip_argv;
+ const char ** strip_argv = CONST_CAST2 (const char **, char **,
+ real_strip_argv);
strip_argv[0] = strip_file_name;
strip_argv[1] = output_file;
@@ -2090,7 +2112,7 @@ scan_prog_file (const char *prog_name, enum pass which_pass)
void (*quit_handler) (int);
#endif
char *real_nm_argv[4];
- const char **nm_argv = (const char **) real_nm_argv;
+ const char **nm_argv = CONST_CAST2 (const char **, char**, real_nm_argv);
int argc = 0;
struct pex_obj *pex;
const char *errmsg;
@@ -2404,7 +2426,7 @@ scan_libraries (const char *prog_name)
# define GCC_SYMZERO(X) 0
/* 0757 = U803XTOCMAGIC (AIX 4.3) and 0767 = U64_TOCMAGIC (AIX V5) */
-#ifdef _AIX51
+#if TARGET_AIX_VERSION >= 51
# define GCC_CHECK_HDR(X) \
((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \
|| (HEADER (X).f_magic == 0767 && aix64_flag))
@@ -2443,9 +2465,19 @@ static int ignore_library (const char *);
static int
ignore_library (const char *name)
{
- const char *const *p = &aix_std_libs[0];
- while (*p++ != NULL)
- if (! strcmp (name, *p)) return 1;
+ const char *const *p;
+ size_t length;
+
+ if (target_system_root[0] != '\0')
+ {
+ length = strlen (target_system_root);
+ if (strncmp (name, target_system_root, length) != 0)
+ return 0;
+ name += length;
+ }
+ for (p = &aix_std_libs[0]; *p != NULL; ++p)
+ if (strcmp (name, *p) == 0)
+ return 1;
return 0;
}
#endif /* COLLECT_EXPORT_LIST */
diff --git a/gcc/combine-stack-adj.c b/gcc/combine-stack-adj.c
index 3ec197f1beb..dc922fe1877 100644
--- a/gcc/combine-stack-adj.c
+++ b/gcc/combine-stack-adj.c
@@ -549,7 +549,7 @@ struct rtl_opt_pass pass_stack_adjustments =
NULL, /* sub */
NULL, /* next */
0, /* static_pass_number */
- TV_NONE, /* tv_id */
+ TV_COMBINE_STACK_ADJUST, /* tv_id */
0, /* properties_required */
0, /* properties_provided */
0, /* properties_destroyed */
diff --git a/gcc/combine.c b/gcc/combine.c
index 4ba893cf5a5..a3b2494f58e 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -5095,24 +5095,6 @@ combine_simplify_rtx (rtx x, enum machine_mode op0_mode, int in_dest)
return gen_lowpart (mode, XEXP (x, 0));
break;
-#ifdef HAVE_cc0
- case COMPARE:
- /* Convert (compare FOO (const_int 0)) to FOO unless we aren't
- using cc0, in which case we want to leave it as a COMPARE
- so we can distinguish it from a register-register-copy. */
- if (XEXP (x, 1) == const0_rtx)
- return XEXP (x, 0);
-
- /* x - 0 is the same as x unless x's mode has signed zeros and
- allows rounding towards -infinity. Under those conditions,
- 0 - 0 is -0. */
- if (!(HONOR_SIGNED_ZEROS (GET_MODE (XEXP (x, 0)))
- && HONOR_SIGN_DEPENDENT_ROUNDING (GET_MODE (XEXP (x, 0))))
- && XEXP (x, 1) == CONST0_RTX (GET_MODE (XEXP (x, 0))))
- return XEXP (x, 0);
- break;
-#endif
-
case CONST:
/* (const (const X)) can become (const X). Do it this way rather than
returning the inner CONST since CONST can be shared with a
@@ -5947,17 +5929,6 @@ simplify_set (rtx x)
if (other_changed)
undobuf.other_insn = other_insn;
-#ifdef HAVE_cc0
- /* If we are now comparing against zero, change our source if
- needed. If we do not use cc0, we always have a COMPARE. */
- if (op1 == const0_rtx && dest == cc0_rtx)
- {
- SUBST (SET_SRC (x), op0);
- src = op0;
- }
- else
-#endif
-
/* Otherwise, if we didn't previously have a COMPARE in the
correct mode, we need one. */
if (GET_CODE (src) != COMPARE || GET_MODE (src) != compare_mode)
diff --git a/gcc/common.opt b/gcc/common.opt
index 0ce470da015..9e28b4d61f9 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -392,6 +392,14 @@ fconserve-stack
Common Var(flag_conserve_stack) Optimization
Do not perform optimizations increasing noticeably stack usage
+fcompare-debug=
+Common JoinedOrMissing RejectNegative Var(flag_compare_debug_opt)
+-fcompare-debug[=<opts>] Compile with and without e.g. -gtoggle, and compare the final-insns dump
+
+fcompare-debug-second
+Common RejectNegative Var(flag_compare_debug)
+Run only the second compilation of -fcompare-debug
+
fcprop-registers
Common Report Var(flag_cprop_registers) Optimization
Perform a register copy-propagation optimization pass
@@ -478,6 +486,10 @@ fdwarf2-cfi-asm
Common Report Var(flag_dwarf2_cfi_asm) Init(HAVE_GAS_CFI_DIRECTIVE)
Enable CFI tables via GAS assembler directives.
+fdump-unnumbered-links
+Common Report Var(flag_dump_unnumbered_links) VarExists
+Suppress output of previous and next insn numbers in debugging dumps
+
fearly-inlining
Common Report Var(flag_early_inlining) Init(1) Optimization
Perform early inlining
@@ -1069,8 +1081,8 @@ Common Report Var(flag_see) Init(0)
Eliminate redundant sign extensions using LCM.
fshow-column
-Common C ObjC C++ ObjC++ Report Var(flag_show_column) Init(0)
-Show column numbers in diagnostics, when available. Default off
+Common C ObjC C++ ObjC++ Report Var(flag_show_column) Init(1)
+Show column numbers in diagnostics, when available. Default on
fsignaling-nans
Common Report Var(flag_signaling_nans) Optimization
@@ -1230,6 +1242,10 @@ ftree-dse
Common Report Var(flag_tree_dse) Optimization
Enable dead store elimination
+ftree-forwprop
+Common Report Var(flag_tree_forwprop) Init(1) Optimization
+Enable forward propagation on trees
+
ftree-fre
Common Report Var(flag_tree_fre) Optimization
Enable Full Redundancy Elimination (FRE) on trees
@@ -1258,10 +1274,18 @@ ftree-parallelize-loops=
Common Report Joined UInteger Var(flag_tree_parallelize_loops) Init(1)
Enable automatic parallelization of loops
+ftree-phiprop
+Common Report Var(flag_tree_phiprop) Init(1) Optimization
+Enable hoisting loads from conditional pointers.
+
ftree-pre
Common Report Var(flag_tree_pre) Optimization
Enable SSA-PRE optimization on trees
+ftree-pta
+Common Report Var(flag_tree_pta) Init(1) Optimization
+Perform function-local points-to analysis on trees.
+
ftree-reassoc
Common Report Var(flag_tree_reassoc) Init(1) Optimization
Enable reassociation on tree level
@@ -1354,6 +1378,10 @@ ftree-vectorize
Common Report Var(flag_tree_vectorize) Optimization
Enable loop vectorization on trees
+ftree-slp-vectorize
+Common Report Var(flag_tree_slp_vectorize) Init(2) Optimization
+Enable basic block vectorization (SLP) on trees
+
fvect-cost-model
Common Report Var(flag_vect_cost_model) Optimization
Enable use of cost model in vectorization
@@ -1414,12 +1442,12 @@ Common JoinedOrMissing
Generate debug information in default format
gcoff
-Common JoinedOrMissing Negative(gdwarf-2)
+Common JoinedOrMissing Negative(gdwarf-)
Generate debug information in COFF format
-gdwarf-2
-Common JoinedOrMissing Negative(gstabs)
-Generate debug information in DWARF v2 format
+gdwarf-
+Common Joined UInteger Var(dwarf_version) Init(2) Negative(gstabs)
+Generate debug information in DWARF v2 (or later) format
ggdb
Common JoinedOrMissing
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 503babea088..7b599173371 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -274,6 +274,8 @@ crisv32-*)
;;
frv*) cpu_type=frv
;;
+moxie*) cpu_type=moxie
+ ;;
fido-*-*)
cpu_type=m68k
extra_headers=math-68881.h
@@ -286,7 +288,7 @@ i[34567]86-*-*)
pmmintrin.h tmmintrin.h ammintrin.h smmintrin.h
nmmintrin.h bmmintrin.h mmintrin-common.h
wmmintrin.h immintrin.h x86intrin.h avxintrin.h
- cross-stdarg.h"
+ ia32intrin.h cross-stdarg.h"
;;
x86_64-*-*)
cpu_type=i386
@@ -296,7 +298,7 @@ x86_64-*-*)
pmmintrin.h tmmintrin.h ammintrin.h smmintrin.h
nmmintrin.h bmmintrin.h mmintrin-common.h
wmmintrin.h immintrin.h x86intrin.h avxintrin.h
- cross-stdarg.h"
+ ia32intrin.h cross-stdarg.h"
need_64bit_hwint=yes
;;
ia64-*-*)
@@ -371,6 +373,12 @@ then
fi
case ${target} in
+i[34567]86-w64-*)
+ tm_file="i386/biarch32.h ${tm_file}"
+ ;;
+esac
+
+case ${target} in
i[34567]86-*-*)
if test "x$enable_cld" = xyes; then
tm_defines="${tm_defines} USE_IX86_CLD=1"
@@ -413,6 +421,7 @@ case ${target} in
extra_objs="darwin.o"
extra_gcc_objs="darwin-driver.o"
default_use_cxa_atexit=yes
+ use_gcc_stdint=wrap
case ${enable_threads} in
"" | yes | posix) thread_file='posix' ;;
esac
@@ -468,7 +477,8 @@ case ${target} in
exit 1
;;
esac
- fbsd_tm_file="${fbsd_tm_file} freebsd-spec.h freebsd.h"
+ fbsd_tm_file="${fbsd_tm_file} freebsd-spec.h freebsd.h freebsd-stdint.h"
+ use_gcc_stdint=wrap
;;
*-*-linux* | frv-*-*linux* | *-*-kfreebsd*-gnu | *-*-knetbsd*-gnu | *-*-gnu* | *-*-kopensolaris*-gnu)
extra_parts="crtbegin.o crtbeginS.o crtbeginT.o crtend.o crtendS.o"
@@ -873,6 +883,13 @@ frv-*-*linux*)
linux.h glibc-stdint.h frv/linux.h frv/frv-abi.h"
tmake_file="${tmake_file} frv/t-frv frv/t-linux"
;;
+moxie-*-elf)
+ gas=yes
+ gnu_ld=yes
+ tm_file="dbxelf.h elfos.h svr4.h ${tm_file}"
+ extra_parts="crti.o crtn.o crtbegin.o crtend.o"
+ tmake_file="${tmake_file} moxie/t-moxie moxie/t-moxie-softfp soft-fp/t-softfp"
+ ;;
h8300-*-rtems*)
tmake_file="h8300/t-h8300 h8300/t-elf t-rtems h8300/t-rtems"
tm_file="h8300/h8300.h dbxelf.h elfos.h h8300/elf.h h8300/rtems.h rtems.h newlib-stdint.h"
@@ -1308,8 +1325,7 @@ i[34567]86-*-mingw* | x86_64-*-mingw*)
default_use_cxa_atexit=yes
use_gcc_stdint=wrap
case ${enable_threads} in
- "" | yes | win32)
- thread_file='win32'
+ "" | yes | win32) thread_file='win32'
tmake_file="${tmake_file} i386/t-gthr-win32"
;;
esac
@@ -2869,7 +2885,7 @@ case "${target}" in
;;
mips*-*-*)
- supported_defaults="abi arch float tune divide llsc mips-plt"
+ supported_defaults="abi arch arch_32 arch_64 float tune tune_32 tune_64 divide llsc mips-plt"
case ${with_float} in
"" | soft | hard)
@@ -3120,6 +3136,9 @@ case ${target} in
i[34567]86-*-linux* | x86_64-*-linux* | i[34567]86-*-kfreebsd*-gnu | x86_64-*-kfreebsd*-gnu)
tmake_file="${tmake_file} i386/t-fprules-softfp soft-fp/t-softfp i386/t-linux"
;;
+ i[34567]86-*-cygwin*)
+ tmake_file="${tmake_file} i386/t-fprules-softfp soft-fp/t-softfp"
+ ;;
ia64*-*-linux*)
tmake_file="${tmake_file} ia64/t-fprules-softfp soft-fp/t-softfp"
;;
diff --git a/gcc/config.in b/gcc/config.in
index 76a7810f3d4..adccc18506f 100644
--- a/gcc/config.in
+++ b/gcc/config.in
@@ -844,6 +844,13 @@
#endif
+/* Define if your assembler supports specifying the alignment of objects
+ allocated using the GAS .comm command. */
+#ifndef USED_FOR_TARGET
+#undef HAVE_GAS_ALIGNED_COMM
+#endif
+
+
/* Define if your assembler supports .balign and .p2align. */
#ifndef USED_FOR_TARGET
#undef HAVE_GAS_BALIGN_AND_P2ALIGN
@@ -862,6 +869,12 @@
#endif
+/* Define if your assembler supports the .loc discriminator sub-directive. */
+#ifndef USED_FOR_TARGET
+#undef HAVE_GAS_DISCRIMINATOR
+#endif
+
+
/* Define if your assembler and linker support .hidden. */
#undef HAVE_GAS_HIDDEN
@@ -1367,6 +1380,12 @@
#endif
+/* Define if mpc is in use. */
+#ifndef USED_FOR_TARGET
+#undef HAVE_mpc
+#endif
+
+
/* Define as const if the declaration of iconv() needs const. */
#ifndef USED_FOR_TARGET
#undef ICONV_CONST
diff --git a/gcc/config/alpha/alpha-protos.h b/gcc/config/alpha/alpha-protos.h
index 66c68aebc91..80c1e4f8f63 100644
--- a/gcc/config/alpha/alpha-protos.h
+++ b/gcc/config/alpha/alpha-protos.h
@@ -38,7 +38,6 @@ extern rtx alpha_tablejump_addr_vec (rtx);
extern rtx alpha_tablejump_best_label (rtx);
extern bool alpha_legitimate_constant_p (rtx);
-extern bool alpha_legitimate_address_p (enum machine_mode, rtx, int);
extern rtx alpha_legitimize_reload_address (rtx, enum machine_mode,
int, int, int);
@@ -88,8 +87,8 @@ extern int check_float_value (enum machine_mode, REAL_VALUE_TYPE *, int);
#endif
#ifdef RTX_CODE
-extern rtx alpha_emit_conditional_branch (enum rtx_code);
-extern rtx alpha_emit_setcc (enum rtx_code);
+extern void alpha_emit_conditional_branch (rtx[], enum machine_mode);
+extern bool alpha_emit_setcc (rtx[], enum machine_mode);
extern int alpha_split_conditional_move (enum rtx_code, rtx, rtx, rtx, rtx);
extern void alpha_emit_xfloating_arith (enum rtx_code, rtx[]);
extern void alpha_emit_xfloating_cvt (enum rtx_code, rtx[]);
diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c
index bb6542a37f9..1e7de8e7c24 100644
--- a/gcc/config/alpha/alpha.c
+++ b/gcc/config/alpha/alpha.c
@@ -81,11 +81,6 @@ enum alpha_fp_rounding_mode alpha_fprm;
enum alpha_fp_trap_mode alpha_fptm;
-/* Save information from a "cmpxx" operation until the branch or scc is
- emitted. */
-
-struct alpha_compare alpha_compare;
-
/* Nonzero if inside of a function, because the Alpha asm can't
handle .files inside of functions. */
@@ -806,8 +801,8 @@ alpha_linkage_symbol_p (const char *symname)
any of those forms can be surrounded with an AND that clear the
low-order three bits; this is an "unaligned" access. */
-bool
-alpha_legitimate_address_p (enum machine_mode mode, rtx x, int strict)
+static bool
+alpha_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
{
/* If this is an ldq_u type address, discard the outer AND. */
if (mode == DImode
@@ -2424,19 +2419,20 @@ alpha_emit_floatuns (rtx operands[2])
/* Generate the comparison for a conditional branch. */
-rtx
-alpha_emit_conditional_branch (enum rtx_code code)
+void
+alpha_emit_conditional_branch (rtx operands[], enum machine_mode cmp_mode)
{
enum rtx_code cmp_code, branch_code;
- enum machine_mode cmp_mode, branch_mode = VOIDmode;
- rtx op0 = alpha_compare.op0, op1 = alpha_compare.op1;
+ enum machine_mode branch_mode = VOIDmode;
+ enum rtx_code code = GET_CODE (operands[0]);
+ rtx op0 = operands[1], op1 = operands[2];
rtx tem;
- if (alpha_compare.fp_p && GET_MODE (op0) == TFmode)
+ if (cmp_mode == TFmode)
{
op0 = alpha_emit_xfloating_compare (&code, op0, op1);
op1 = const0_rtx;
- alpha_compare.fp_p = 0;
+ cmp_mode = DImode;
}
/* The general case: fold the comparison code to the types of compares
@@ -2457,7 +2453,7 @@ alpha_emit_conditional_branch (enum rtx_code code)
case GE: case GT: case GEU: case GTU:
/* For FP, we swap them, for INT, we reverse them. */
- if (alpha_compare.fp_p)
+ if (cmp_mode == DFmode)
{
cmp_code = swap_condition (code);
branch_code = NE;
@@ -2474,9 +2470,8 @@ alpha_emit_conditional_branch (enum rtx_code code)
gcc_unreachable ();
}
- if (alpha_compare.fp_p)
+ if (cmp_mode == DFmode)
{
- cmp_mode = DFmode;
if (flag_unsafe_math_optimizations && cmp_code != UNORDERED)
{
/* When we are not as concerned about non-finite values, and we
@@ -2501,8 +2496,6 @@ alpha_emit_conditional_branch (enum rtx_code code)
}
else
{
- cmp_mode = DImode;
-
/* The following optimizations are only for signed compares. */
if (code != LEU && code != LTU && code != GEU && code != GTU)
{
@@ -2544,36 +2537,38 @@ alpha_emit_conditional_branch (enum rtx_code code)
emit_move_insn (tem, gen_rtx_fmt_ee (cmp_code, cmp_mode, op0, op1));
}
- /* Zero the operands. */
- memset (&alpha_compare, 0, sizeof (alpha_compare));
-
- /* Return the branch comparison. */
- return gen_rtx_fmt_ee (branch_code, branch_mode, tem, CONST0_RTX (cmp_mode));
+ /* Emit the branch instruction. */
+ tem = gen_rtx_SET (VOIDmode, pc_rtx,
+ gen_rtx_IF_THEN_ELSE (VOIDmode,
+ gen_rtx_fmt_ee (branch_code,
+ branch_mode, tem,
+ CONST0_RTX (cmp_mode)),
+ gen_rtx_LABEL_REF (VOIDmode,
+ operands[3]),
+ pc_rtx));
+ emit_jump_insn (tem);
}
/* Certain simplifications can be done to make invalid setcc operations
valid. Return the final comparison, or NULL if we can't work. */
-rtx
-alpha_emit_setcc (enum rtx_code code)
+bool
+alpha_emit_setcc (rtx operands[], enum machine_mode cmp_mode)
{
enum rtx_code cmp_code;
- rtx op0 = alpha_compare.op0, op1 = alpha_compare.op1;
- int fp_p = alpha_compare.fp_p;
+ enum rtx_code code = GET_CODE (operands[1]);
+ rtx op0 = operands[2], op1 = operands[3];
rtx tmp;
- /* Zero the operands. */
- memset (&alpha_compare, 0, sizeof (alpha_compare));
-
- if (fp_p && GET_MODE (op0) == TFmode)
+ if (cmp_mode == TFmode)
{
op0 = alpha_emit_xfloating_compare (&code, op0, op1);
op1 = const0_rtx;
- fp_p = 0;
+ cmp_mode = DImode;
}
- if (fp_p && !TARGET_FIX)
- return NULL_RTX;
+ if (cmp_mode == DFmode && !TARGET_FIX)
+ return 0;
/* The general case: fold the comparison code to the types of compares
that we have, choosing the branch as necessary. */
@@ -2584,12 +2579,12 @@ alpha_emit_setcc (enum rtx_code code)
case EQ: case LE: case LT: case LEU: case LTU:
case UNORDERED:
/* We have these compares. */
- if (fp_p)
+ if (cmp_mode == DFmode)
cmp_code = code, code = NE;
break;
case NE:
- if (!fp_p && op1 == const0_rtx)
+ if (cmp_mode == DImode && op1 == const0_rtx)
break;
/* FALLTHRU */
@@ -2601,10 +2596,10 @@ alpha_emit_setcc (enum rtx_code code)
case GE: case GT: case GEU: case GTU:
/* These normally need swapping, but for integer zero we have
special patterns that recognize swapped operands. */
- if (!fp_p && op1 == const0_rtx)
+ if (cmp_mode == DImode && op1 == const0_rtx)
break;
code = swap_condition (code);
- if (fp_p)
+ if (cmp_mode == DFmode)
cmp_code = code, code = NE;
tmp = op0, op0 = op1, op1 = tmp;
break;
@@ -2613,7 +2608,7 @@ alpha_emit_setcc (enum rtx_code code)
gcc_unreachable ();
}
- if (!fp_p)
+ if (cmp_mode == DImode)
{
if (!register_operand (op0, DImode))
op0 = force_reg (DImode, op0);
@@ -2624,18 +2619,18 @@ alpha_emit_setcc (enum rtx_code code)
/* Emit an initial compare instruction, if necessary. */
if (cmp_code != UNKNOWN)
{
- enum machine_mode mode = fp_p ? DFmode : DImode;
-
- tmp = gen_reg_rtx (mode);
+ tmp = gen_reg_rtx (cmp_mode);
emit_insn (gen_rtx_SET (VOIDmode, tmp,
- gen_rtx_fmt_ee (cmp_code, mode, op0, op1)));
+ gen_rtx_fmt_ee (cmp_code, cmp_mode, op0, op1)));
- op0 = fp_p ? gen_lowpart (DImode, tmp) : tmp;
+ op0 = cmp_mode != DImode ? gen_lowpart (DImode, tmp) : tmp;
op1 = const0_rtx;
}
- /* Return the setcc comparison. */
- return gen_rtx_fmt_ee (code, DImode, op0, op1);
+ /* Emit the setcc instruction. */
+ emit_insn (gen_rtx_SET (VOIDmode, operands[0],
+ gen_rtx_fmt_ee (code, DImode, op0, op1)));
+ return true;
}
@@ -2651,20 +2646,17 @@ alpha_emit_conditional_move (rtx cmp, enum machine_mode mode)
{
enum rtx_code code = GET_CODE (cmp);
enum rtx_code cmov_code = NE;
- rtx op0 = alpha_compare.op0;
- rtx op1 = alpha_compare.op1;
- int fp_p = alpha_compare.fp_p;
+ rtx op0 = XEXP (cmp, 0);
+ rtx op1 = XEXP (cmp, 1);
enum machine_mode cmp_mode
= (GET_MODE (op0) == VOIDmode ? DImode : GET_MODE (op0));
- enum machine_mode cmp_op_mode = fp_p ? DFmode : DImode;
enum machine_mode cmov_mode = VOIDmode;
int local_fast_math = flag_unsafe_math_optimizations;
rtx tem;
- /* Zero the operands. */
- memset (&alpha_compare, 0, sizeof (alpha_compare));
+ gcc_assert (cmp_mode == DFmode || cmp_mode == DImode);
- if (fp_p != FLOAT_MODE_P (mode))
+ if (FLOAT_MODE_P (cmp_mode) != FLOAT_MODE_P (mode))
{
enum rtx_code cmp_code;
@@ -2691,7 +2683,7 @@ alpha_emit_conditional_move (rtx cmp, enum machine_mode mode)
case GE: case GT: case GEU: case GTU:
/* These normally need swapping, but for integer zero we have
special patterns that recognize swapped operands. */
- if (!fp_p && op1 == const0_rtx)
+ if (cmp_mode == DImode && op1 == const0_rtx)
cmp_code = code, code = NE;
else
{
@@ -2705,22 +2697,21 @@ alpha_emit_conditional_move (rtx cmp, enum machine_mode mode)
gcc_unreachable ();
}
- tem = gen_reg_rtx (cmp_op_mode);
+ tem = gen_reg_rtx (cmp_mode);
emit_insn (gen_rtx_SET (VOIDmode, tem,
- gen_rtx_fmt_ee (cmp_code, cmp_op_mode,
+ gen_rtx_fmt_ee (cmp_code, cmp_mode,
op0, op1)));
- cmp_mode = cmp_op_mode = fp_p ? DImode : DFmode;
- op0 = gen_lowpart (cmp_op_mode, tem);
- op1 = CONST0_RTX (cmp_op_mode);
- fp_p = !fp_p;
+ cmp_mode = cmp_mode == DImode ? DFmode : DImode;
+ op0 = gen_lowpart (cmp_mode, tem);
+ op1 = CONST0_RTX (cmp_mode);
local_fast_math = 1;
}
/* We may be able to use a conditional move directly.
This avoids emitting spurious compares. */
if (signed_comparison_operator (cmp, VOIDmode)
- && (!fp_p || local_fast_math)
+ && (cmp_mode == DImode || local_fast_math)
&& (op0 == CONST0_RTX (cmp_mode) || op1 == CONST0_RTX (cmp_mode)))
return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
@@ -2757,7 +2748,7 @@ alpha_emit_conditional_move (rtx cmp, enum machine_mode mode)
gcc_unreachable ();
}
- if (!fp_p)
+ if (cmp_mode == DImode)
{
if (!reg_or_0_operand (op0, DImode))
op0 = force_reg (DImode, op0);
@@ -2768,12 +2759,12 @@ alpha_emit_conditional_move (rtx cmp, enum machine_mode mode)
/* ??? We mark the branch mode to be CCmode to prevent the compare
and cmov from being combined, since the compare insn follows IEEE
rules that the cmov does not. */
- if (fp_p && !local_fast_math)
+ if (cmp_mode == DFmode && !local_fast_math)
cmov_mode = CCmode;
- tem = gen_reg_rtx (cmp_op_mode);
- emit_move_insn (tem, gen_rtx_fmt_ee (code, cmp_op_mode, op0, op1));
- return gen_rtx_fmt_ee (cmov_code, cmov_mode, tem, CONST0_RTX (cmp_op_mode));
+ tem = gen_reg_rtx (cmp_mode);
+ emit_move_insn (tem, gen_rtx_fmt_ee (code, cmp_mode, op0, op1));
+ return gen_rtx_fmt_ee (cmov_code, cmov_mode, tem, CONST0_RTX (cmp_mode));
}
/* Simplify a conditional move of two constants into a setcc with
@@ -5497,7 +5488,7 @@ alpha_initialize_trampoline (rtx tramp, rtx fnaddr, rtx cxt,
#ifdef ENABLE_EXECUTE_STACK
emit_library_call (init_one_libfunc ("__enable_execute_stack"),
- 0, VOIDmode, 1, tramp, Pmode);
+ LCT_NORMAL, VOIDmode, 1, tramp, Pmode);
#endif
if (jmpofs >= 0)
@@ -5800,24 +5791,28 @@ alpha_build_builtin_va_list (void)
return ptr_type_node;
record = (*lang_hooks.types.make_type) (RECORD_TYPE);
- type_decl = build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
+ type_decl = build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier ("__va_list_tag"), record);
TREE_CHAIN (record) = type_decl;
TYPE_NAME (record) = type_decl;
/* C++? SET_IS_AGGR_TYPE (record, 1); */
/* Dummy field to prevent alignment warnings. */
- space = build_decl (FIELD_DECL, NULL_TREE, integer_type_node);
+ space = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, NULL_TREE, integer_type_node);
DECL_FIELD_CONTEXT (space) = record;
DECL_ARTIFICIAL (space) = 1;
DECL_IGNORED_P (space) = 1;
- ofs = build_decl (FIELD_DECL, get_identifier ("__offset"),
+ ofs = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, get_identifier ("__offset"),
integer_type_node);
DECL_FIELD_CONTEXT (ofs) = record;
TREE_CHAIN (ofs) = space;
- base = build_decl (FIELD_DECL, get_identifier ("__base"),
+ base = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, get_identifier ("__base"),
ptr_type_node);
DECL_FIELD_CONTEXT (base) = record;
TREE_CHAIN (base) = ofs;
@@ -7343,7 +7338,7 @@ alpha_using_fp (void)
#if TARGET_ABI_OPEN_VMS
-const struct attribute_spec vms_attribute_table[] =
+static const struct attribute_spec vms_attribute_table[] =
{
/* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
{ "overlaid", 0, 0, true, false, false, NULL },
@@ -7736,11 +7731,14 @@ alpha_expand_prologue (void)
if (TARGET_ABI_OPEN_VMS)
{
+ /* Register frame procedures save the fp. */
if (alpha_procedure_type == PT_REGISTER)
- /* Register frame procedures save the fp.
- ?? Ought to have a dwarf2 save for this. */
- emit_move_insn (gen_rtx_REG (DImode, vms_save_fp_regno),
- hard_frame_pointer_rtx);
+ {
+ rtx insn = emit_move_insn (gen_rtx_REG (DImode, vms_save_fp_regno),
+ hard_frame_pointer_rtx);
+ add_reg_note (insn, REG_CFA_REGISTER, NULL);
+ RTX_FRAME_RELATED_P (insn) = 1;
+ }
if (alpha_procedure_type != PT_NULL && vms_base_regno != REG_PV)
emit_insn (gen_force_movdi (gen_rtx_REG (DImode, vms_base_regno),
@@ -8015,12 +8013,6 @@ alpha_output_function_end_prologue (FILE *file)
/* Write function epilogue. */
-/* ??? At some point we will want to support full unwind, and so will
- need to mark the epilogue as well. At the moment, we just confuse
- dwarf2out. */
-#undef FRP
-#define FRP(exp) exp
-
void
alpha_expand_epilogue (void)
{
@@ -8035,8 +8027,9 @@ alpha_expand_epilogue (void)
HOST_WIDE_INT reg_offset;
int fp_is_frame_pointer, fp_offset;
rtx sa_reg, sa_reg_exp = NULL;
- rtx sp_adj1, sp_adj2, mem;
+ rtx sp_adj1, sp_adj2, mem, reg, insn;
rtx eh_ofs;
+ rtx cfa_restores = NULL_RTX;
int i;
sa_size = alpha_sa_size ();
@@ -8087,7 +8080,7 @@ alpha_expand_epilogue (void)
if ((TARGET_ABI_OPEN_VMS
&& vms_unwind_regno == HARD_FRAME_POINTER_REGNUM)
|| (!TARGET_ABI_OPEN_VMS && frame_pointer_needed))
- FRP (emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx));
+ emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx);
/* Cope with very large offsets to the register save area. */
if (reg_offset + sa_size > 0x8000)
@@ -8103,7 +8096,7 @@ alpha_expand_epilogue (void)
sa_reg = gen_rtx_REG (DImode, 22);
sa_reg_exp = plus_constant (stack_pointer_rtx, bias);
- FRP (emit_move_insn (sa_reg, sa_reg_exp));
+ emit_move_insn (sa_reg, sa_reg_exp);
}
/* Restore registers in order, excepting a true frame pointer. */
@@ -8111,7 +8104,9 @@ alpha_expand_epilogue (void)
mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset));
if (! eh_ofs)
set_mem_alias_set (mem, alpha_sr_alias_set);
- FRP (emit_move_insn (gen_rtx_REG (DImode, REG_RA), mem));
+ reg = gen_rtx_REG (DImode, REG_RA);
+ emit_move_insn (reg, mem);
+ cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, cfa_restores);
reg_offset += 8;
imask &= ~(1UL << REG_RA);
@@ -8125,7 +8120,10 @@ alpha_expand_epilogue (void)
{
mem = gen_rtx_MEM (DImode, plus_constant(sa_reg, reg_offset));
set_mem_alias_set (mem, alpha_sr_alias_set);
- FRP (emit_move_insn (gen_rtx_REG (DImode, i), mem));
+ reg = gen_rtx_REG (DImode, i);
+ emit_move_insn (reg, mem);
+ cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
+ cfa_restores);
}
reg_offset += 8;
}
@@ -8135,7 +8133,9 @@ alpha_expand_epilogue (void)
{
mem = gen_rtx_MEM (DFmode, plus_constant(sa_reg, reg_offset));
set_mem_alias_set (mem, alpha_sr_alias_set);
- FRP (emit_move_insn (gen_rtx_REG (DFmode, i+32), mem));
+ reg = gen_rtx_REG (DFmode, i+32);
+ emit_move_insn (reg, mem);
+ cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, cfa_restores);
reg_offset += 8;
}
}
@@ -8151,7 +8151,9 @@ alpha_expand_epilogue (void)
mem = gen_rtx_MEM (DImode, plus_constant(hard_frame_pointer_rtx,
reg_offset));
set_mem_alias_set (mem, alpha_sr_alias_set);
- FRP (emit_move_insn (gen_rtx_REG (DImode, i), mem));
+ reg = gen_rtx_REG (DImode, i);
+ emit_move_insn (reg, mem);
+ cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, cfa_restores);
reg_offset -= 8;
}
@@ -8161,15 +8163,18 @@ alpha_expand_epilogue (void)
mem = gen_rtx_MEM (DFmode, plus_constant(hard_frame_pointer_rtx,
reg_offset));
set_mem_alias_set (mem, alpha_sr_alias_set);
- FRP (emit_move_insn (gen_rtx_REG (DFmode, i+32), mem));
+ reg = gen_rtx_REG (DFmode, i+32);
+ emit_move_insn (reg, mem);
+ cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, cfa_restores);
reg_offset -= 8;
}
/* Restore the return address from the DSIB. */
-
- mem = gen_rtx_MEM (DImode, plus_constant(hard_frame_pointer_rtx, -8));
+ mem = gen_rtx_MEM (DImode, plus_constant (hard_frame_pointer_rtx, -8));
set_mem_alias_set (mem, alpha_sr_alias_set);
- FRP (emit_move_insn (gen_rtx_REG (DImode, REG_RA), mem));
+ reg = gen_rtx_REG (DImode, REG_RA);
+ emit_move_insn (reg, mem);
+ cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, cfa_restores);
}
if (frame_size || eh_ofs)
@@ -8192,7 +8197,7 @@ alpha_expand_epilogue (void)
else if (TARGET_ABI_UNICOSMK)
{
sp_adj1 = gen_rtx_REG (DImode, 23);
- FRP (emit_move_insn (sp_adj1, hard_frame_pointer_rtx));
+ emit_move_insn (sp_adj1, hard_frame_pointer_rtx);
sp_adj2 = const0_rtx;
}
else if (frame_size < 0x40007fffL)
@@ -8205,21 +8210,20 @@ alpha_expand_epilogue (void)
else
{
sp_adj1 = gen_rtx_REG (DImode, 23);
- FRP (emit_move_insn (sp_adj1, sp_adj2));
+ emit_move_insn (sp_adj1, sp_adj2);
}
sp_adj2 = GEN_INT (low);
}
else
{
rtx tmp = gen_rtx_REG (DImode, 23);
- FRP (sp_adj2 = alpha_emit_set_const (tmp, DImode, frame_size,
- 3, false));
+ sp_adj2 = alpha_emit_set_const (tmp, DImode, frame_size, 3, false);
if (!sp_adj2)
{
/* We can't drop new things to memory this late, afaik,
so build it up by pieces. */
- FRP (sp_adj2 = alpha_emit_set_long_const (tmp, frame_size,
- -(frame_size < 0)));
+ sp_adj2 = alpha_emit_set_long_const (tmp, frame_size,
+ -(frame_size < 0));
gcc_assert (sp_adj2);
}
}
@@ -8233,46 +8237,58 @@ alpha_expand_epilogue (void)
mem = gen_rtx_MEM (DImode,
plus_constant (hard_frame_pointer_rtx, -16));
set_mem_alias_set (mem, alpha_sr_alias_set);
- FRP (emit_move_insn (hard_frame_pointer_rtx, mem));
+ emit_move_insn (hard_frame_pointer_rtx, mem);
+ cfa_restores = alloc_reg_note (REG_CFA_RESTORE,
+ hard_frame_pointer_rtx, cfa_restores);
}
else if (fp_is_frame_pointer)
{
emit_insn (gen_blockage ());
mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, fp_offset));
set_mem_alias_set (mem, alpha_sr_alias_set);
- FRP (emit_move_insn (hard_frame_pointer_rtx, mem));
+ emit_move_insn (hard_frame_pointer_rtx, mem);
+ cfa_restores = alloc_reg_note (REG_CFA_RESTORE,
+ hard_frame_pointer_rtx, cfa_restores);
}
else if (TARGET_ABI_OPEN_VMS)
{
emit_insn (gen_blockage ());
- FRP (emit_move_insn (hard_frame_pointer_rtx,
- gen_rtx_REG (DImode, vms_save_fp_regno)));
+ emit_move_insn (hard_frame_pointer_rtx,
+ gen_rtx_REG (DImode, vms_save_fp_regno));
+ cfa_restores = alloc_reg_note (REG_CFA_RESTORE,
+ hard_frame_pointer_rtx, cfa_restores);
}
/* Restore the stack pointer. */
emit_insn (gen_blockage ());
if (sp_adj2 == const0_rtx)
- FRP (emit_move_insn (stack_pointer_rtx, sp_adj1));
+ insn = emit_move_insn (stack_pointer_rtx, sp_adj1);
else
- FRP (emit_move_insn (stack_pointer_rtx,
- gen_rtx_PLUS (DImode, sp_adj1, sp_adj2)));
+ insn = emit_move_insn (stack_pointer_rtx,
+ gen_rtx_PLUS (DImode, sp_adj1, sp_adj2));
+ REG_NOTES (insn) = cfa_restores;
+ add_reg_note (insn, REG_CFA_DEF_CFA, stack_pointer_rtx);
+ RTX_FRAME_RELATED_P (insn) = 1;
}
else
{
+ gcc_assert (cfa_restores == NULL);
+
if (TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_REGISTER)
{
emit_insn (gen_blockage ());
- FRP (emit_move_insn (hard_frame_pointer_rtx,
- gen_rtx_REG (DImode, vms_save_fp_regno)));
+ insn = emit_move_insn (hard_frame_pointer_rtx,
+ gen_rtx_REG (DImode, vms_save_fp_regno));
+ add_reg_note (insn, REG_CFA_RESTORE, hard_frame_pointer_rtx);
+ RTX_FRAME_RELATED_P (insn) = 1;
}
else if (TARGET_ABI_UNICOSMK && alpha_procedure_type != PT_STACK)
{
/* Decrement the frame pointer if the function does not have a
frame. */
-
emit_insn (gen_blockage ());
- FRP (emit_insn (gen_adddi3 (hard_frame_pointer_rtx,
- hard_frame_pointer_rtx, constm1_rtx)));
+ emit_insn (gen_adddi3 (hard_frame_pointer_rtx,
+ hard_frame_pointer_rtx, constm1_rtx));
}
}
}
@@ -10256,18 +10272,15 @@ unicosmk_gen_dsib (unsigned long *imaskP)
emit_insn (gen_blockage ());
/* Set the new frame pointer. */
-
FRP (emit_insn (gen_adddi3 (hard_frame_pointer_rtx,
stack_pointer_rtx, GEN_INT (64))));
-
}
else
{
/* Increment the frame pointer register to indicate that we do not
have a frame. */
-
- FRP (emit_insn (gen_adddi3 (hard_frame_pointer_rtx,
- hard_frame_pointer_rtx, const1_rtx)));
+ emit_insn (gen_adddi3 (hard_frame_pointer_rtx,
+ hard_frame_pointer_rtx, const1_rtx));
}
}
@@ -10848,6 +10861,9 @@ alpha_init_libfuncs (void)
#define TARGET_MANGLE_TYPE alpha_mangle_type
#endif
+#undef TARGET_LEGITIMATE_ADDRESS_P
+#define TARGET_LEGITIMATE_ADDRESS_P alpha_legitimate_address_p
+
struct gcc_target targetm = TARGET_INITIALIZER;
diff --git a/gcc/config/alpha/alpha.h b/gcc/config/alpha/alpha.h
index f33e8e63854..3bfbd50e89e 100644
--- a/gcc/config/alpha/alpha.h
+++ b/gcc/config/alpha/alpha.h
@@ -803,24 +803,6 @@ extern int alpha_memory_latency;
#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
function_arg((CUM), (MODE), (TYPE), (NAMED))
-/* Try to output insns to set TARGET equal to the constant C if it can be
- done in less than N insns. Do all computations in MODE. Returns the place
- where the output has been placed if it can be done and the insns have been
- emitted. If it would take more than N insns, zero is returned and no
- insns and emitted. */
-
-/* Define the information needed to generate branch and scc insns. This is
- stored from the compare operation. Note that we can't use "rtx" here
- since it hasn't been defined! */
-
-struct alpha_compare
-{
- struct rtx_def *op0, *op1;
- int fp_p;
-};
-
-extern struct alpha_compare alpha_compare;
-
/* Make (or fake) .linkage entry for function call.
IS_LOCAL is 0 if name is used in call, 1 if name is used in definition. */
@@ -992,23 +974,6 @@ do { \
#define REG_OK_FOR_BASE_P(X) NONSTRICT_REG_OK_FOR_BASE_P (X)
#endif
-/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression that is a
- valid memory address for an instruction. */
-
-#ifdef REG_OK_STRICT
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, WIN) \
-do { \
- if (alpha_legitimate_address_p (MODE, X, 1)) \
- goto WIN; \
-} while (0)
-#else
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, WIN) \
-do { \
- if (alpha_legitimate_address_p (MODE, X, 0)) \
- goto WIN; \
-} while (0)
-#endif
-
/* Try a machine-dependent way of reloading an illegitimate address
operand. If we find one, push the reload and jump to WIN. This
macro is used in only one place: `find_reloads_address' in reload.c. */
diff --git a/gcc/config/alpha/alpha.md b/gcc/config/alpha/alpha.md
index 543ed533080..e6a05780bba 100644
--- a/gcc/config/alpha/alpha.md
+++ b/gcc/config/alpha/alpha.md
@@ -3963,206 +3963,53 @@
;; These are the main define_expand's used to make conditional branches
;; and compares.
-(define_expand "cmpdf"
- [(set (cc0) (compare (match_operand:DF 0 "reg_or_0_operand" "")
- (match_operand:DF 1 "reg_or_0_operand" "")))]
+(define_expand "cbranchdf4"
+ [(use (match_operator 0 "alpha_cbranch_operator"
+ [(match_operand:DF 1 "reg_or_0_operand" "")
+ (match_operand:DF 2 "reg_or_0_operand" "")]))
+ (use (match_operand 3 ""))]
"TARGET_FP"
-{
- alpha_compare.op0 = operands[0];
- alpha_compare.op1 = operands[1];
- alpha_compare.fp_p = 1;
- DONE;
-})
+ { alpha_emit_conditional_branch (operands, DFmode); DONE; })
-(define_expand "cmptf"
- [(set (cc0) (compare (match_operand:TF 0 "general_operand" "")
- (match_operand:TF 1 "general_operand" "")))]
+(define_expand "cbranchtf4"
+ [(use (match_operator 0 "alpha_cbranch_operator"
+ [(match_operand:TF 1 "general_operand")
+ (match_operand:TF 2 "general_operand")]))
+ (use (match_operand 3 ""))]
"TARGET_HAS_XFLOATING_LIBS"
-{
- alpha_compare.op0 = operands[0];
- alpha_compare.op1 = operands[1];
- alpha_compare.fp_p = 1;
- DONE;
-})
-
-(define_expand "cmpdi"
- [(set (cc0) (compare (match_operand:DI 0 "some_operand" "")
- (match_operand:DI 1 "some_operand" "")))]
- ""
-{
- alpha_compare.op0 = operands[0];
- alpha_compare.op1 = operands[1];
- alpha_compare.fp_p = 0;
- DONE;
-})
-
-(define_expand "beq"
- [(set (pc)
- (if_then_else (match_dup 1)
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "{ operands[1] = alpha_emit_conditional_branch (EQ); }")
-
-(define_expand "bne"
- [(set (pc)
- (if_then_else (match_dup 1)
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "{ operands[1] = alpha_emit_conditional_branch (NE); }")
-
-(define_expand "blt"
- [(set (pc)
- (if_then_else (match_dup 1)
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "{ operands[1] = alpha_emit_conditional_branch (LT); }")
+ { alpha_emit_conditional_branch (operands, TFmode); DONE; })
-(define_expand "ble"
- [(set (pc)
- (if_then_else (match_dup 1)
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "{ operands[1] = alpha_emit_conditional_branch (LE); }")
-
-(define_expand "bgt"
- [(set (pc)
- (if_then_else (match_dup 1)
- (label_ref (match_operand 0 "" ""))
- (pc)))]
+(define_expand "cbranchdi4"
+ [(use (match_operator 0 "alpha_cbranch_operator"
+ [(match_operand:DI 1 "some_operand")
+ (match_operand:DI 2 "some_operand")]))
+ (use (match_operand 3 ""))]
""
- "{ operands[1] = alpha_emit_conditional_branch (GT); }")
+ { alpha_emit_conditional_branch (operands, DImode); DONE; })
-(define_expand "bge"
- [(set (pc)
- (if_then_else (match_dup 1)
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "{ operands[1] = alpha_emit_conditional_branch (GE); }")
-
-(define_expand "bltu"
- [(set (pc)
- (if_then_else (match_dup 1)
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "{ operands[1] = alpha_emit_conditional_branch (LTU); }")
-
-(define_expand "bleu"
- [(set (pc)
- (if_then_else (match_dup 1)
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "{ operands[1] = alpha_emit_conditional_branch (LEU); }")
-
-(define_expand "bgtu"
- [(set (pc)
- (if_then_else (match_dup 1)
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "{ operands[1] = alpha_emit_conditional_branch (GTU); }")
-
-(define_expand "bgeu"
- [(set (pc)
- (if_then_else (match_dup 1)
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "{ operands[1] = alpha_emit_conditional_branch (GEU); }")
-
-(define_expand "bunordered"
- [(set (pc)
- (if_then_else (match_dup 1)
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "{ operands[1] = alpha_emit_conditional_branch (UNORDERED); }")
-
-(define_expand "bordered"
- [(set (pc)
- (if_then_else (match_dup 1)
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "{ operands[1] = alpha_emit_conditional_branch (ORDERED); }")
-
-(define_expand "seq"
- [(set (match_operand:DI 0 "register_operand" "")
- (match_dup 1))]
- ""
- "{ if ((operands[1] = alpha_emit_setcc (EQ)) == NULL_RTX) FAIL; }")
-
-(define_expand "sne"
- [(set (match_operand:DI 0 "register_operand" "")
- (match_dup 1))]
- ""
- "{ if ((operands[1] = alpha_emit_setcc (NE)) == NULL_RTX) FAIL; }")
-
-(define_expand "slt"
- [(set (match_operand:DI 0 "register_operand" "")
- (match_dup 1))]
- ""
- "{ if ((operands[1] = alpha_emit_setcc (LT)) == NULL_RTX) FAIL; }")
-
-(define_expand "sle"
- [(set (match_operand:DI 0 "register_operand" "")
- (match_dup 1))]
- ""
- "{ if ((operands[1] = alpha_emit_setcc (LE)) == NULL_RTX) FAIL; }")
-
-(define_expand "sgt"
- [(set (match_operand:DI 0 "register_operand" "")
- (match_dup 1))]
- ""
- "{ if ((operands[1] = alpha_emit_setcc (GT)) == NULL_RTX) FAIL; }")
-
-(define_expand "sge"
- [(set (match_operand:DI 0 "register_operand" "")
- (match_dup 1))]
- ""
- "{ if ((operands[1] = alpha_emit_setcc (GE)) == NULL_RTX) FAIL; }")
-
-(define_expand "sltu"
- [(set (match_operand:DI 0 "register_operand" "")
- (match_dup 1))]
- ""
- "{ if ((operands[1] = alpha_emit_setcc (LTU)) == NULL_RTX) FAIL; }")
-
-(define_expand "sleu"
- [(set (match_operand:DI 0 "register_operand" "")
- (match_dup 1))]
- ""
- "{ if ((operands[1] = alpha_emit_setcc (LEU)) == NULL_RTX) FAIL; }")
-
-(define_expand "sgtu"
- [(set (match_operand:DI 0 "register_operand" "")
- (match_dup 1))]
- ""
- "{ if ((operands[1] = alpha_emit_setcc (GTU)) == NULL_RTX) FAIL; }")
-
-(define_expand "sgeu"
- [(set (match_operand:DI 0 "register_operand" "")
- (match_dup 1))]
- ""
- "{ if ((operands[1] = alpha_emit_setcc (GEU)) == NULL_RTX) FAIL; }")
+(define_expand "cstoredf4"
+ [(use (match_operator:DI 1 "alpha_cbranch_operator"
+ [(match_operand:DF 2 "reg_or_0_operand")
+ (match_operand:DF 3 "reg_or_0_operand")]))
+ (clobber (match_operand:DI 0 "register_operand"))]
+ "TARGET_FP"
+ { if (!alpha_emit_setcc (operands, DFmode)) FAIL; else DONE; })
-(define_expand "sunordered"
- [(set (match_operand:DI 0 "register_operand" "")
- (match_dup 1))]
- ""
- "{ if ((operands[1] = alpha_emit_setcc (UNORDERED)) == NULL_RTX) FAIL; }")
+(define_expand "cstoretf4"
+ [(use (match_operator:DI 1 "alpha_cbranch_operator"
+ [(match_operand:TF 2 "general_operand")
+ (match_operand:TF 3 "general_operand")]))
+ (clobber (match_operand:DI 0 "register_operand"))]
+ "TARGET_HAS_XFLOATING_LIBS"
+ { if (!alpha_emit_setcc (operands, TFmode)) FAIL; else DONE; })
-(define_expand "sordered"
- [(set (match_operand:DI 0 "register_operand" "")
- (match_dup 1))]
+(define_expand "cstoredi4"
+ [(use (match_operator:DI 1 "alpha_cbranch_operator"
+ [(match_operand:DI 2 "some_operand")
+ (match_operand:DI 3 "some_operand")]))
+ (clobber (match_operand:DI 0 "register_operand"))]
""
- "{ if ((operands[1] = alpha_emit_setcc (ORDERED)) == NULL_RTX) FAIL; }")
+ { if (!alpha_emit_setcc (operands, DImode)) FAIL; else DONE; })
;; These are the main define_expand's used to make conditional moves.
@@ -6766,7 +6613,7 @@
rtx loop_label = gen_label_rtx ();
rtx want = gen_reg_rtx (Pmode);
rtx tmp = gen_reg_rtx (Pmode);
- rtx memref;
+ rtx memref, test;
emit_insn (gen_subdi3 (want, stack_pointer_rtx,
force_reg (Pmode, operands[1])));
@@ -6775,8 +6622,8 @@
if (!CONST_INT_P (operands[1]))
{
out_label = gen_label_rtx ();
- emit_insn (gen_cmpdi (want, tmp));
- emit_jump_insn (gen_bgeu (out_label));
+ test = gen_rtx_GEU (VOIDmode, want, tmp);
+ emit_jump_insn (gen_cbranchdi4 (test, want, tmp, out_label));
}
emit_label (loop_label);
@@ -6784,8 +6631,8 @@
MEM_VOLATILE_P (memref) = 1;
emit_move_insn (memref, const0_rtx);
emit_insn (gen_adddi3 (tmp, tmp, GEN_INT(-8192)));
- emit_insn (gen_cmpdi (tmp, want));
- emit_jump_insn (gen_bgtu (loop_label));
+ test = gen_rtx_GTU (VOIDmode, tmp, want);
+ emit_jump_insn (gen_cbranchdi4 (test, tmp, want, loop_label));
memref = gen_rtx_MEM (DImode, want);
MEM_VOLATILE_P (memref) = 1;
diff --git a/gcc/config/alpha/predicates.md b/gcc/config/alpha/predicates.md
index 425134ac820..ec11eaa3d1f 100644
--- a/gcc/config/alpha/predicates.md
+++ b/gcc/config/alpha/predicates.md
@@ -543,6 +543,12 @@
(and (match_code "reg")
(match_operand 0 "register_operand")))
+;; Return 1 if OP is a valid Alpha comparison operator for "cbranch"
+;; instructions.
+(define_predicate "alpha_cbranch_operator"
+ (ior (match_operand 0 "ordered_comparison_operator")
+ (match_code "ordered,unordered")))
+
;; Return 1 if OP is a valid Alpha comparison operator for "cmp" style
;; instructions.
(define_predicate "alpha_comparison_operator"
diff --git a/gcc/config/alpha/x-alpha b/gcc/config/alpha/x-alpha
index 27b5f466903..ecca70424af 100644
--- a/gcc/config/alpha/x-alpha
+++ b/gcc/config/alpha/x-alpha
@@ -1,3 +1,3 @@
driver-alpha.o: $(srcdir)/config/alpha/driver-alpha.c \
$(CONFIG_H) $(SYSTEM_H)
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
index 3f81f611f80..221dea1ceac 100644
--- a/gcc/config/arc/arc.c
+++ b/gcc/config/arc/arc.c
@@ -49,10 +49,6 @@ int arc_cpu_type;
cpu (or NULL). */
const char *arc_mangle_cpu;
-/* Save the operands last given to a compare for use when we
- generate a scc or bcc insn. */
-rtx arc_compare_op0, arc_compare_op1;
-
/* Name of text, data, and rodata sections used in varasm.c. */
const char *arc_text_section;
const char *arc_data_section;
@@ -82,7 +78,7 @@ static bool arc_handle_option (size_t, const char *, int);
static void record_cc_ref (rtx);
static void arc_init_reg_tables (void);
static int get_arc_condition_code (rtx);
-const struct attribute_spec arc_attribute_table[];
+EXPORTED_CONST struct attribute_spec arc_attribute_table[];
static tree arc_handle_interrupt_attribute (tree *, tree, tree, int, bool *);
static bool arc_assemble_integer (rtx, unsigned int, int);
static void arc_output_function_prologue (FILE *, HOST_WIDE_INT);
@@ -729,21 +725,14 @@ proper_comparison_operator (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
/* Misc. utilities. */
-/* X and Y are two things to compare using CODE. Emit the compare insn and
- return the rtx for the cc reg in the proper mode. */
+/* X and Y are two things to compare using CODE. Return the rtx
+ for the cc reg in the proper mode. */
rtx
gen_compare_reg (enum rtx_code code, rtx x, rtx y)
{
enum machine_mode mode = SELECT_CC_MODE (code, x, y);
- rtx cc_reg;
-
- cc_reg = gen_rtx_REG (mode, 61);
-
- emit_insn (gen_rtx_SET (VOIDmode, cc_reg,
- gen_rtx_COMPARE (mode, x, y)));
-
- return cc_reg;
+ return gen_rtx_REG (mode, 61);
}
/* Return 1 if VALUE, a const_double, will fit in a limm (4 byte number).
diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h
index db6829bc560..4153ad6f6b6 100644
--- a/gcc/config/arc/arc.h
+++ b/gcc/config/arc/arc.h
@@ -1067,11 +1067,6 @@ do { if ((LOG) != 0) fprintf (FILE, "\t.align %d\n", 1 << (LOG)); } while (0)
/* ??? Not defined in tm.texi. */
#define SETJMP_VIA_SAVE_AREA
-/* Define the information needed to generate branch and scc insns. This is
- stored from the compare operation. Note that we can't use "rtx" here
- since it hasn't been defined! */
-extern struct rtx_def *arc_compare_op0, *arc_compare_op1;
-
/* ARC function types. */
enum arc_function_type {
ARC_FUNCTION_UNKNOWN, ARC_FUNCTION_NORMAL,
diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
index b67984babbb..09e47daf1d1 100644
--- a/gcc/config/arc/arc.md
+++ b/gcc/config/arc/arc.md
@@ -585,29 +585,11 @@
"
{
enum rtx_code code = GET_CODE (operands[1]);
- rtx ccreg
- = gen_rtx_REG (SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1),
- 61);
-
- operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
+ rtx cc_reg = gen_compare_reg (code, XEXP (operands[1], 0),
+ XEXP (operands[1], 1));
+ operands[1] = gen_rtx_fmt_ee (code, VOIDmode, cc_reg, const0_rtx);
}")
-;(define_expand "movdicc"
-; [(set (match_operand:DI 0 "register_operand" "")
-; (if_then_else:DI (match_operand 1 "comparison_operator" "")
-; (match_operand:DI 2 "nonmemory_operand" "")
-; (match_operand:DI 3 "register_operand" "")))]
-; "0 /* ??? this would work better if we had cmpdi */"
-; "
-;{
-; enum rtx_code code = GET_CODE (operands[1]);
-; rtx ccreg
-; = gen_rtx_REG (SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1),
-; 61);
-;
-; operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
-;}")
-
(define_expand "movsfcc"
[(set (match_operand:SF 0 "register_operand" "")
(if_then_else:SF (match_operand 1 "comparison_operator" "")
@@ -617,29 +599,11 @@
"
{
enum rtx_code code = GET_CODE (operands[1]);
- rtx ccreg
- = gen_rtx_REG (SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1),
- 61);
-
- operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
+ rtx cc_reg = gen_compare_reg (code, XEXP (operands[1], 0),
+ XEXP (operands[1], 1));
+ operands[1] = gen_rtx_fmt_ee (code, VOIDmode, cc_reg, const0_rtx);
}")
-;(define_expand "movdfcc"
-; [(set (match_operand:DF 0 "register_operand" "")
-; (if_then_else:DF (match_operand 1 "comparison_operator" "")
-; (match_operand:DF 2 "nonmemory_operand" "")
-; (match_operand:DF 3 "register_operand" "")))]
-; "0 /* ??? can generate less efficient code if constants involved */"
-; "
-;{
-; enum rtx_code code = GET_CODE (operands[1]);
-; rtx ccreg
-; = gen_rtx_REG (SELECT_CC_MODE (code, arc_compare_op0, arc_compare_op1),
-; 61);
-;
-; operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
-;}")
-
(define_insn "*movsicc_insn"
[(set (match_operand:SI 0 "register_operand" "=r")
(if_then_else:SI (match_operand 1 "comparison_operator" "")
@@ -649,32 +613,6 @@
"mov.%d1 %0,%S2"
[(set_attr "type" "cmove")])
-; ??? This doesn't properly handle constants.
-;(define_insn "*movdicc_insn"
-; [(set (match_operand:DI 0 "register_operand" "=r,r")
-; (if_then_else:DI (match_operand 1 "comparison_operator" "")
-; (match_operand:DI 2 "nonmemory_operand" "r,Ji")
-; (match_operand:DI 3 "register_operand" "0,0")))]
-; "0"
-; "*
-;{
-; switch (which_alternative)
-; {
-; case 0 :
-; /* We normally copy the low-numbered register first. However, if
-; the first register operand 0 is the same as the second register of
-; operand 1, we must copy in the opposite order. */
-; if (REGNO (operands[0]) == REGNO (operands[2]) + 1)
-; return \"mov.%d1 %R0,%R2\;mov.%d1 %0,%2\";
-; else
-; return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\";
-; case 1 :
-; return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\";
-; }
-;}"
-; [(set_attr "type" "cmove,cmove")
-; (set_attr "length" "2,4")])
-
(define_insn "*movsfcc_insn"
[(set (match_operand:SF 0 "register_operand" "=r,r")
(if_then_else:SF (match_operand 1 "comparison_operator" "")
@@ -686,30 +624,6 @@
mov.%d1 %0,%2 ; %A2"
[(set_attr "type" "cmove,cmove")])
-;(define_insn "*movdfcc_insn"
-; [(set (match_operand:DF 0 "register_operand" "=r,r")
-; (if_then_else:DF (match_operand 1 "comparison_operator" "")
-; (match_operand:DF 2 "nonmemory_operand" "r,E")
-; (match_operand:DF 3 "register_operand" "0,0")))]
-; "0"
-; "*
-;{
-; switch (which_alternative)
-; {
-; case 0 :
-; /* We normally copy the low-numbered register first. However, if
-; the first register operand 0 is the same as the second register of
-; operand 1, we must copy in the opposite order. */
-; if (REGNO (operands[0]) == REGNO (operands[2]) + 1)
-; return \"mov.%d1 %R0,%R2\;mov.%d1 %0,%2\";
-; else
-; return \"mov.%d1 %0,%2\;mov.%d1 %R0,%R2\";
-; case 1 :
-; return \"mov.%d1 %0,%L2\;mov.%d1 %R0,%H2 ; %A2\";
-; }
-;}"
-; [(set_attr "type" "cmove,cmove")
-; (set_attr "length" "2,4")])
;; Zero extension instructions.
;; ??? We don't support volatile memrefs here, but I'm not sure why.
@@ -1156,22 +1070,6 @@
;; Compare instructions.
;; This controls RTL generation and register allocation.
-;; We generate RTL for comparisons and branches by having the cmpxx
-;; patterns store away the operands. Then, the scc and bcc patterns
-;; emit RTL for both the compare and the branch.
-
-(define_expand "cmpsi"
- [(set (reg:CC 61)
- (compare:CC (match_operand:SI 0 "register_operand" "")
- (match_operand:SI 1 "nonmemory_operand" "")))]
- ""
- "
-{
- arc_compare_op0 = operands[0];
- arc_compare_op1 = operands[1];
- DONE;
-}")
-
;; ??? We may be able to relax this a bit by adding a new constant 'K' for 0.
;; This assumes sub.f 0,symbol,0 is a valid insn.
;; Note that "sub.f 0,r0,1" is an 8 byte insn. To avoid unnecessarily
@@ -1211,96 +1109,25 @@
sub.f 0,%0,%1"
[(set_attr "type" "compare,compare,compare")])
-;; Next come the scc insns.
-
-(define_expand "seq"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (eq:SI (match_dup 1) (const_int 0)))]
- ""
- "
-{
- operands[1] = gen_compare_reg (EQ, arc_compare_op0, arc_compare_op1);
-}")
+;; Next come the scc insn and its expander.
-(define_expand "sne"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (ne:SI (match_dup 1) (const_int 0)))]
- ""
- "
-{
- operands[1] = gen_compare_reg (NE, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "sgt"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (gt:SI (match_dup 1) (const_int 0)))]
- ""
- "
-{
- operands[1] = gen_compare_reg (GT, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "sle"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (le:SI (match_dup 1) (const_int 0)))]
- ""
- "
-{
- operands[1] = gen_compare_reg (LE, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "sge"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (ge:SI (match_dup 1) (const_int 0)))]
- ""
- "
-{
- operands[1] = gen_compare_reg (GE, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "slt"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (lt:SI (match_dup 1) (const_int 0)))]
- ""
- "
-{
- operands[1] = gen_compare_reg (LT, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "sgtu"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (gtu:SI (match_dup 1) (const_int 0)))]
- ""
- "
-{
- operands[1] = gen_compare_reg (GTU, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "sleu"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (leu:SI (match_dup 1) (const_int 0)))]
- ""
- "
-{
- operands[1] = gen_compare_reg (LEU, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "sgeu"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (geu:SI (match_dup 1) (const_int 0)))]
- ""
- "
-{
- operands[1] = gen_compare_reg (GEU, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "sltu"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (ltu:SI (match_dup 1) (const_int 0)))]
+(define_expand "cstoresi4"
+ [(set (match_dup 4)
+ (match_op_dup 5
+ [(match_operand:SI 2 "register_operand" "")
+ (match_operand:SI 3 "nonmemory_operand" "")]))
+ (set (match_operand:SI 0 "register_operand")
+ (match_operator:SI 1 "ordered_comparison_operator"
+ [(match_dup 4)
+ (const_int 0)]))]
""
"
{
- operands[1] = gen_compare_reg (LTU, arc_compare_op0, arc_compare_op1);
+ operands[4] = gen_compare_reg (GET_CODE (operands[1]),
+ operands[2], operands[3]);
+ operands[5] = gen_rtx_fmt_ee (COMPARE,
+ GET_MODE (operands[4]),
+ operands[2], operands[3]);
}")
(define_insn "*scc_insn"
@@ -1332,114 +1159,26 @@
;; These control RTL generation for conditional jump insns
-(define_expand "beq"
- [(set (pc)
- (if_then_else (eq (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- operands[1] = gen_compare_reg (EQ, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "bne"
- [(set (pc)
- (if_then_else (ne (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- operands[1] = gen_compare_reg (NE, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "bgt"
- [(set (pc)
- (if_then_else (gt (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- operands[1] = gen_compare_reg (GT, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "ble"
- [(set (pc)
- (if_then_else (le (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- operands[1] = gen_compare_reg (LE, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "bge"
- [(set (pc)
- (if_then_else (ge (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- operands[1] = gen_compare_reg (GE, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "blt"
- [(set (pc)
- (if_then_else (lt (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- operands[1] = gen_compare_reg (LT, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "bgtu"
- [(set (pc)
- (if_then_else (gtu (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- operands[1] = gen_compare_reg (GTU, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "bleu"
- [(set (pc)
- (if_then_else (leu (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- operands[1] = gen_compare_reg (LEU, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "bgeu"
- [(set (pc)
- (if_then_else (geu (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- operands[1] = gen_compare_reg (GEU, arc_compare_op0, arc_compare_op1);
-}")
-
-(define_expand "bltu"
- [(set (pc)
- (if_then_else (ltu (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
+(define_expand "cbranchsi4"
+ [(set (match_dup 4)
+ (match_op_dup 5
+ [(match_operand:SI 1 "register_operand" "")
+ (match_operand:SI 2 "nonmemory_operand" "")]))
+ (set (pc)
+ (if_then_else
+ (match_operator 0 "ordered_comparison_operator"
+ [(match_dup 4)
+ (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
""
"
{
- operands[1] = gen_compare_reg (LTU, arc_compare_op0, arc_compare_op1);
+ operands[4] = gen_compare_reg (GET_CODE (operands[0]),
+ operands[1], operands[2]);
+ operands[5] = gen_rtx_fmt_ee (COMPARE,
+ GET_MODE (operands[4]),
+ operands[1], operands[2]);
}")
;; Now match both normal and inverted jump.
diff --git a/gcc/config/arm/arm-modes.def b/gcc/config/arm/arm-modes.def
index 0ff876f62df..73b5b4d3d0d 100644
--- a/gcc/config/arm/arm-modes.def
+++ b/gcc/config/arm/arm-modes.def
@@ -62,6 +62,4 @@ VECTOR_MODES (FLOAT, 16); /* V8HF V4SF V2DF */
INT_MODE (EI, 24);
INT_MODE (OI, 32);
INT_MODE (CI, 48);
-/* ??? This should actually have 512 bits but the precision only has 9
- bits. */
-FRACTIONAL_INT_MODE (XI, 511, 64);
+INT_MODE (XI, 64);
diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
index 34d266b139b..857d575e5d3 100644
--- a/gcc/config/arm/arm-protos.h
+++ b/gcc/config/arm/arm-protos.h
@@ -54,9 +54,7 @@ extern RTX_CODE arm_canonicalize_comparison (RTX_CODE, enum machine_mode,
extern int legitimate_pic_operand_p (rtx);
extern rtx legitimize_pic_address (rtx, enum machine_mode, rtx);
extern rtx legitimize_tls_address (rtx, rtx);
-extern int arm_legitimate_address_p (enum machine_mode, rtx, RTX_CODE, int);
-extern int thumb1_legitimate_address_p (enum machine_mode, rtx, int);
-extern int thumb2_legitimate_address_p (enum machine_mode, rtx, int);
+extern int arm_legitimate_address_outer_p (enum machine_mode, rtx, RTX_CODE, int);
extern int thumb_legitimate_offset_p (enum machine_mode, HOST_WIDE_INT);
extern rtx thumb_legitimize_reload_address (rtx *, enum machine_mode, int, int,
int);
@@ -86,7 +84,7 @@ extern bool arm_cannot_force_const_mem (rtx);
extern int cirrus_memory_offset (rtx);
extern int arm_coproc_mem_operand (rtx, bool);
-extern int neon_vector_mem_operand (rtx, bool);
+extern int neon_vector_mem_operand (rtx, int);
extern int neon_struct_mem_operand (rtx);
extern int arm_no_early_store_addr_dep (rtx, rtx);
extern int arm_no_early_alu_shift_dep (rtx, rtx);
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 1d9b4265843..3809270b2c5 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -58,7 +58,7 @@
typedef struct minipool_node Mnode;
typedef struct minipool_fixup Mfix;
-const struct attribute_spec arm_attribute_table[];
+EXPORTED_CONST struct attribute_spec arm_attribute_table[];
void (*arm_lang_output_object_attributes_hook)(void);
@@ -76,6 +76,7 @@ static int thumb1_base_register_rtx_p (rtx, enum machine_mode, int);
static rtx arm_legitimize_address (rtx, rtx, enum machine_mode);
static rtx thumb_legitimize_address (rtx, rtx, enum machine_mode);
inline static int thumb1_index_register_rtx_p (rtx, int);
+static bool arm_legitimate_address_p (enum machine_mode, rtx, bool);
static int thumb_far_jump_used_p (void);
static bool thumb_force_lr_save (void);
static int const_ok_for_op (HOST_WIDE_INT, enum rtx_code);
@@ -403,6 +404,9 @@ static bool arm_allocate_stack_slots_for_args (void);
#define TARGET_ASM_OUTPUT_DWARF_DTPREL arm_output_dwarf_dtprel
#endif
+#undef TARGET_LEGITIMATE_ADDRESS_P
+#define TARGET_LEGITIMATE_ADDRESS_P arm_legitimate_address_p
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* Obstack for minipool constant handling. */
@@ -418,10 +422,6 @@ extern FILE * asm_out_file;
/* True if we are currently building a constant table. */
int making_const_table;
-/* Define the information needed to generate branch insns. This is
- stored from the compare operation. */
-rtx arm_compare_op0, arm_compare_op1;
-
/* The processor for which instructions should be scheduled. */
enum processor_type arm_tune = arm_none;
@@ -956,13 +956,15 @@ arm_build_builtin_va_list (void)
/* Create the type. */
va_list_type = lang_hooks.types.make_type (RECORD_TYPE);
/* Give it the required name. */
- va_list_name = build_decl (TYPE_DECL,
+ va_list_name = build_decl (BUILTINS_LOCATION,
+ TYPE_DECL,
get_identifier ("__va_list"),
va_list_type);
DECL_ARTIFICIAL (va_list_name) = 1;
TYPE_NAME (va_list_type) = va_list_name;
/* Create the __ap field. */
- ap_field = build_decl (FIELD_DECL,
+ ap_field = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL,
get_identifier ("__ap"),
ptr_type_node);
DECL_ARTIFICIAL (ap_field) = 1;
@@ -2008,7 +2010,11 @@ const_ok_for_op (HOST_WIDE_INT i, enum rtx_code code)
case MINUS: /* Should only occur with (MINUS I reg) => rsb */
case XOR:
+ return 0;
+
case IOR:
+ if (TARGET_THUMB2)
+ return const_ok_for_arm (ARM_SIGN_EXTEND (~i));
return 0;
case AND:
@@ -2185,15 +2191,20 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode, rtx cond,
GEN_INT (ARM_SIGN_EXTEND (val))));
return 1;
}
+
if (remainder == 0)
{
if (reload_completed && rtx_equal_p (target, source))
return 0;
+
if (generate)
emit_constant_insn (cond,
gen_rtx_SET (VOIDmode, target, source));
return 1;
}
+
+ if (TARGET_THUMB2)
+ can_invert = 1;
break;
case AND:
@@ -2281,6 +2292,7 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode, rtx cond,
/* Calculate a few attributes that may be useful for specific
optimizations. */
+ /* Count number of leading zeros. */
for (i = 31; i >= 0; i--)
{
if ((remainder & (1 << i)) == 0)
@@ -2289,6 +2301,7 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode, rtx cond,
break;
}
+ /* Count number of leading 1's. */
for (i = 31; i >= 0; i--)
{
if ((remainder & (1 << i)) != 0)
@@ -2297,6 +2310,7 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode, rtx cond,
break;
}
+ /* Count number of trailing zero's. */
for (i = 0; i <= 31; i++)
{
if ((remainder & (1 << i)) == 0)
@@ -2305,6 +2319,7 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode, rtx cond,
break;
}
+ /* Count number of trailing 1's. */
for (i = 0; i <= 31; i++)
{
if ((remainder & (1 << i)) != 0)
@@ -2492,6 +2507,17 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode, rtx cond,
if (code == XOR)
break;
+ /* Convert.
+ x = y | constant ( which is composed of set_sign_bit_copies of leading 1s
+ and the remainder 0s for e.g. 0xfff00000)
+ x = ~(~(y ashift set_sign_bit_copies) lshiftrt set_sign_bit_copies)
+
+ This can be done in 2 instructions by using shifts with mov or mvn.
+ e.g. for
+ x = x | 0xfff00000;
+ we generate.
+ mvn r0, r0, asl #12
+ mvn r0, r0, lsr #12 */
if (set_sign_bit_copies > 8
&& (val & (-1 << (32 - set_sign_bit_copies))) == val)
{
@@ -2517,6 +2543,16 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode, rtx cond,
return 2;
}
+ /* Convert
+ x = y | constant (which has set_zero_bit_copies number of trailing ones).
+ to
+ x = ~((~y lshiftrt set_zero_bit_copies) ashift set_zero_bit_copies).
+
+ For eg. r0 = r0 | 0xfff
+ mvn r0, r0, lsr #12
+ mvn r0, r0, asl #12
+
+ */
if (set_zero_bit_copies > 8
&& (remainder & ((1 << set_zero_bit_copies) - 1)) == remainder)
{
@@ -2542,6 +2578,13 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode, rtx cond,
return 2;
}
+ /* This will never be reached for Thumb2 because orn is a valid
+ instruction. This is for Thumb1 and the ARM 32 bit cases.
+
+ x = y | constant (such that ~constant is a valid constant)
+ Transform this to
+ x = ~(~y & ~constant).
+ */
if (const_ok_for_arm (temp1 = ARM_SIGN_EXTEND (~val)))
{
if (generate)
@@ -2651,7 +2694,8 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode, rtx cond,
if (remainder & (1 << i))
num_bits_set++;
- if (code == AND || (can_invert && num_bits_set > 16))
+ if ((code == AND)
+ || (code != IOR && can_invert && num_bits_set > 16))
remainder = (~remainder) & 0xffffffff;
else if (code == PLUS && num_bits_set > 16)
remainder = (-remainder) & 0xffffffff;
@@ -3918,8 +3962,8 @@ pcrel_constant_p (rtx x)
/* Return nonzero if X is a valid ARM state address operand. */
int
-arm_legitimate_address_p (enum machine_mode mode, rtx x, RTX_CODE outer,
- int strict_p)
+arm_legitimate_address_outer_p (enum machine_mode mode, rtx x, RTX_CODE outer,
+ int strict_p)
{
bool use_ldrd;
enum rtx_code code = GET_CODE (x);
@@ -4003,7 +4047,7 @@ arm_legitimate_address_p (enum machine_mode mode, rtx x, RTX_CODE outer,
}
/* Return nonzero if X is a valid Thumb-2 address operand. */
-int
+static int
thumb2_legitimate_address_p (enum machine_mode mode, rtx x, int strict_p)
{
bool use_ldrd;
@@ -4224,15 +4268,17 @@ thumb2_legitimate_index_p (enum machine_mode mode, rtx index, int strict_p)
if (mode == DImode || mode == DFmode)
{
- HOST_WIDE_INT val = INTVAL (index);
- /* ??? Can we assume ldrd for thumb2? */
- /* Thumb-2 ldrd only has reg+const addressing modes. */
- if (code != CONST_INT)
+ if (code == CONST_INT)
+ {
+ HOST_WIDE_INT val = INTVAL (index);
+ /* ??? Can we assume ldrd for thumb2? */
+ /* Thumb-2 ldrd only has reg+const addressing modes. */
+ /* ldrd supports offsets of +-1020.
+ However the ldr fallback does not. */
+ return val > -256 && val < 256 && (val & 3) == 0;
+ }
+ else
return 0;
-
- /* ldrd supports offsets of +-1020.
- However the ldr fallback does not. */
- return val > -256 && val < 256 && (val & 3) == 0;
}
if (code == MULT)
@@ -4309,7 +4355,7 @@ thumb1_index_register_rtx_p (rtx x, int strict_p)
addresses based on the frame pointer or arg pointer until the
reload pass starts. This is so that eliminating such addresses
into stack based ones won't produce impossible code. */
-int
+static int
thumb1_legitimate_address_p (enum machine_mode mode, rtx x, int strict_p)
{
/* ??? Not clear if this is right. Experiment. */
@@ -4423,6 +4469,17 @@ thumb_legitimate_offset_p (enum machine_mode mode, HOST_WIDE_INT val)
}
}
+bool
+arm_legitimate_address_p (enum machine_mode mode, rtx x, bool strict_p)
+{
+ if (TARGET_ARM)
+ return arm_legitimate_address_outer_p (mode, x, SET, strict_p);
+ else if (TARGET_THUMB2)
+ return thumb2_legitimate_address_p (mode, x, strict_p);
+ else /* if (TARGET_THUMB1) */
+ return thumb1_legitimate_address_p (mode, x, strict_p);
+}
+
/* Build the SYMBOL_REF for __tls_get_addr. */
static GTY(()) rtx tls_get_addr_libfunc;
@@ -4658,7 +4715,7 @@ arm_legitimize_address (rtx x, rtx orig_x, enum machine_mode mode)
}
/* XXX We don't allow MINUS any more -- see comment in
- arm_legitimate_address_p (). */
+ arm_legitimate_address_outer_p (). */
else if (GET_CODE (x) == MINUS)
{
rtx xop0 = XEXP (x, 0);
@@ -6950,10 +7007,13 @@ arm_coproc_mem_operand (rtx op, bool wb)
}
/* Return TRUE if OP is a memory operand which we can load or store a vector
- to/from. If CORE is true, we're moving from ARM registers not Neon
- registers. */
+ to/from. TYPE is one of the following values:
+ 0 - Vector load/stor (vldr)
+ 1 - Core registers (ldm)
+ 2 - Element/structure loads (vld1)
+ */
int
-neon_vector_mem_operand (rtx op, bool core)
+neon_vector_mem_operand (rtx op, int type)
{
rtx ind;
@@ -6986,23 +7046,15 @@ neon_vector_mem_operand (rtx op, bool core)
return arm_address_register_rtx_p (ind, 0);
/* Allow post-increment with Neon registers. */
- if (!core && GET_CODE (ind) == POST_INC)
+ if (type != 1 && (GET_CODE (ind) == POST_INC || GET_CODE (ind) == PRE_DEC))
return arm_address_register_rtx_p (XEXP (ind, 0), 0);
-#if 0
- /* FIXME: We can support this too if we use VLD1/VST1. */
- if (!core
- && GET_CODE (ind) == POST_MODIFY
- && arm_address_register_rtx_p (XEXP (ind, 0), 0)
- && GET_CODE (XEXP (ind, 1)) == PLUS
- && rtx_equal_p (XEXP (XEXP (ind, 1), 0), XEXP (ind, 0)))
- ind = XEXP (ind, 1);
-#endif
+ /* FIXME: vld1 allows register post-modify. */
/* Match:
(plus (reg)
(const)). */
- if (!core
+ if (type == 0
&& GET_CODE (ind) == PLUS
&& GET_CODE (XEXP (ind, 0)) == REG
&& REG_MODE_OK_FOR_BASE_P (XEXP (ind, 0), VOIDmode)
@@ -7072,7 +7124,7 @@ coproc_secondary_reload_class (enum machine_mode mode, rtx x, bool wb)
if (TARGET_NEON
&& (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
|| GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT)
- && neon_vector_mem_operand (x, FALSE))
+ && neon_vector_mem_operand (x, 0))
return NO_REGS;
if (arm_coproc_mem_operand (x, wb) || s_register_operand (x, mode))
@@ -10788,7 +10840,7 @@ output_move_double (rtx *operands)
}
/* Output a move, load or store for quad-word vectors in ARM registers. Only
- handles MEMs accepted by neon_vector_mem_operand with CORE=true. */
+ handles MEMs accepted by neon_vector_mem_operand with TYPE=1. */
const char *
output_move_quad (rtx *operands)
@@ -10984,6 +11036,13 @@ output_move_neon (rtx *operands)
ops[1] = reg;
break;
+ case PRE_DEC:
+ /* FIXME: We should be using vld1/vst1 here in BE mode? */
+ templ = "v%smdb%%?\t%%0!, %%h1";
+ ops[0] = XEXP (addr, 0);
+ ops[1] = reg;
+ break;
+
case POST_MODIFY:
/* FIXME: Not currently enabled in neon_vector_mem_operand. */
gcc_unreachable ();
@@ -12767,22 +12826,23 @@ arm_get_frame_offsets (void)
{
int reg = -1;
- for (i = 4; i <= (TARGET_THUMB1 ? LAST_LO_REGNUM : 11); i++)
+ /* If it is safe to use r3, then do so. This sometimes
+ generates better code on Thumb-2 by avoiding the need to
+ use 32-bit push/pop instructions. */
+ if (!crtl->tail_call_emit
+ && arm_size_return_regs () <= 12)
{
- if ((offsets->saved_regs_mask & (1 << i)) == 0)
- {
- reg = i;
- break;
- }
- }
-
- if (reg == -1 && arm_size_return_regs () <= 12
- && !crtl->tail_call_emit)
- {
- /* Push/pop an argument register (r3) if all callee saved
- registers are already being pushed. */
reg = 3;
}
+ else
+ for (i = 4; i <= (TARGET_THUMB1 ? LAST_LO_REGNUM : 11); i++)
+ {
+ if ((offsets->saved_regs_mask & (1 << i)) == 0)
+ {
+ reg = i;
+ break;
+ }
+ }
if (reg != -1)
{
@@ -13848,6 +13908,24 @@ arm_print_operand (FILE *stream, rtx x, int code)
}
return;
+ /* Memory operand for vld1/vst1 instruction. */
+ case 'A':
+ {
+ rtx addr;
+ bool postinc = FALSE;
+ gcc_assert (GET_CODE (x) == MEM);
+ addr = XEXP (x, 0);
+ if (GET_CODE (addr) == POST_INC)
+ {
+ postinc = 1;
+ addr = XEXP (addr, 0);
+ }
+ asm_fprintf (stream, "[%r]", REGNO (addr));
+ if (postinc)
+ fputs("!", stream);
+ }
+ return;
+
default:
if (x == 0)
{
@@ -14667,13 +14745,13 @@ arm_hard_regno_mode_ok (unsigned int regno, enum machine_mode mode)
return VALID_IWMMXT_REG_MODE (mode);
}
- /* We allow any value to be stored in the general registers.
+ /* We allow almost any value to be stored in the general registers.
Restrict doubleword quantities to even register pairs so that we can
- use ldrd. Do not allow Neon structure opaque modes in general registers;
- they would use too many. */
+ use ldrd. Do not allow very large Neon structure opaque modes in
+ general registers; they would use too many. */
if (regno <= LAST_ARM_REGNUM)
return !(TARGET_LDRD && GET_MODE_SIZE (mode) > 4 && (regno & 1) != 0)
- && !VALID_NEON_STRUCT_MODE (mode);
+ && ARM_NUM_REGS (mode) <= 4;
if (regno == FRAME_POINTER_REGNUM
|| regno == ARG_POINTER_REGNUM)
@@ -16911,7 +16989,7 @@ thumb_pushpop (FILE *f, unsigned long mask, int push, int *cfa_offset,
if (push && pushed_words && dwarf2out_do_frame ())
{
- char *l = dwarf2out_cfi_label ();
+ char *l = dwarf2out_cfi_label (false);
int pushed_mask = real_regs;
*cfa_offset += pushed_words * 4;
@@ -17807,7 +17885,7 @@ thumb1_output_function_prologue (FILE *f, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
the stack pointer. */
if (dwarf2out_do_frame ())
{
- char *l = dwarf2out_cfi_label ();
+ char *l = dwarf2out_cfi_label (false);
cfa_offset = cfa_offset + crtl->args.pretend_args_size;
dwarf2out_def_cfa (l, SP_REGNUM, cfa_offset);
@@ -17856,7 +17934,7 @@ thumb1_output_function_prologue (FILE *f, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
if (dwarf2out_do_frame ())
{
- char *l = dwarf2out_cfi_label ();
+ char *l = dwarf2out_cfi_label (false);
cfa_offset = cfa_offset + 16;
dwarf2out_def_cfa (l, SP_REGNUM, cfa_offset);
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index e7bc7a7a2d5..ee0eee694d2 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -124,10 +124,6 @@ extern arm_cc arm_current_cc;
extern int arm_target_label;
extern int arm_ccfsm_state;
extern GTY(()) rtx arm_target_insn;
-/* Define the information needed to generate branch insns. This is
- stored from the compare operation. */
-extern GTY(()) rtx arm_compare_op0;
-extern GTY(()) rtx arm_compare_op1;
/* The label of the current constant pool. */
extern rtx pool_vector_label;
/* Set to 1 when a return insn is output, this means that the epilogue
@@ -484,10 +480,9 @@ extern int arm_arch_hwdiv;
}
#define PROMOTE_FUNCTION_MODE(MODE, UNSIGNEDP, TYPE) \
- if ((GET_MODE_CLASS (MODE) == MODE_INT \
- || GET_MODE_CLASS (MODE) == MODE_COMPLEX_INT) \
+ if (GET_MODE_CLASS (MODE) == MODE_INT \
&& GET_MODE_SIZE (MODE) < 4) \
- (MODE) = SImode; \
+ (MODE) = SImode;
/* Define this if most significant bit is lowest numbered
in instructions that operate on numbered bit-fields. */
@@ -2166,43 +2161,11 @@ typedef struct
#define REG_MODE_OK_FOR_REG_BASE_P(X, MODE) \
REG_OK_FOR_INDEX_P (X)
-/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
- that is a valid memory address for an instruction.
- The MODE argument is the machine mode for the MEM expression
- that wants to use this address. */
-
#define ARM_BASE_REGISTER_RTX_P(X) \
(GET_CODE (X) == REG && ARM_REG_OK_FOR_BASE_P (X))
#define ARM_INDEX_REGISTER_RTX_P(X) \
(GET_CODE (X) == REG && ARM_REG_OK_FOR_INDEX_P (X))
-
-#define ARM_GO_IF_LEGITIMATE_ADDRESS(MODE,X,WIN) \
- { \
- if (arm_legitimate_address_p (MODE, X, SET, REG_STRICT_P)) \
- goto WIN; \
- }
-
-#define THUMB2_GO_IF_LEGITIMATE_ADDRESS(MODE,X,WIN) \
- { \
- if (thumb2_legitimate_address_p (MODE, X, REG_STRICT_P)) \
- goto WIN; \
- }
-
-#define THUMB1_GO_IF_LEGITIMATE_ADDRESS(MODE,X,WIN) \
- { \
- if (thumb1_legitimate_address_p (MODE, X, REG_STRICT_P)) \
- goto WIN; \
- }
-
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, WIN) \
- if (TARGET_ARM) \
- ARM_GO_IF_LEGITIMATE_ADDRESS (MODE, X, WIN) \
- else if (TARGET_THUMB2) \
- THUMB2_GO_IF_LEGITIMATE_ADDRESS (MODE, X, WIN) \
- else /* if (TARGET_THUMB1) */ \
- THUMB1_GO_IF_LEGITIMATE_ADDRESS (MODE, X, WIN)
-
/* Define this for compatibility reasons. */
#define HANDLE_PRAGMA_PACK_PUSH_POP
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 801865287b7..40e41c56021 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -472,9 +472,9 @@
if (TARGET_THUMB1)
{
if (GET_CODE (operands[1]) != REG)
- operands[1] = force_reg (SImode, operands[1]);
+ operands[1] = force_reg (DImode, operands[1]);
if (GET_CODE (operands[2]) != REG)
- operands[2] = force_reg (SImode, operands[2]);
+ operands[2] = force_reg (DImode, operands[2]);
}
"
)
@@ -620,10 +620,11 @@
sub%?\\t%0, %1, #%n2
sub%?\\t%0, %1, #%n2
#"
- "TARGET_32BIT &&
- GET_CODE (operands[2]) == CONST_INT
+ "TARGET_32BIT
+ && GET_CODE (operands[2]) == CONST_INT
&& !(const_ok_for_arm (INTVAL (operands[2]))
- || const_ok_for_arm (-INTVAL (operands[2])))"
+ || const_ok_for_arm (-INTVAL (operands[2])))
+ && (reload_completed || !arm_eliminable_register (operands[1]))"
[(clobber (const_int 0))]
"
arm_split_constant (PLUS, SImode, curr_insn,
@@ -639,10 +640,10 @@
;; register. Trying to reload it will always fail catastrophically,
;; so never allow those alternatives to match if reloading is needed.
-(define_insn "*thumb1_addsi3"
- [(set (match_operand:SI 0 "register_operand" "=l,l,l,*rk,*hk,l,!k")
- (plus:SI (match_operand:SI 1 "register_operand" "%0,0,l,*0,*0,!k,!k")
- (match_operand:SI 2 "nonmemory_operand" "I,J,lL,*hk,*rk,!M,!O")))]
+(define_insn_and_split "*thumb1_addsi3"
+ [(set (match_operand:SI 0 "register_operand" "=l,l,l,*rk,*hk,l,!k,l,l")
+ (plus:SI (match_operand:SI 1 "register_operand" "%0,0,l,*0,*0,!k,!k,0,l")
+ (match_operand:SI 2 "nonmemory_operand" "I,J,lL,*hk,*rk,!M,!O,Pa,Pb")))]
"TARGET_THUMB1"
"*
static const char * const asms[] =
@@ -653,7 +654,9 @@
\"add\\t%0, %0, %2\",
\"add\\t%0, %0, %2\",
\"add\\t%0, %1, %2\",
- \"add\\t%0, %1, %2\"
+ \"add\\t%0, %1, %2\",
+ \"#\",
+ \"#\"
};
if ((which_alternative == 2 || which_alternative == 6)
&& GET_CODE (operands[2]) == CONST_INT
@@ -661,7 +664,22 @@
return \"sub\\t%0, %1, #%n2\";
return asms[which_alternative];
"
- [(set_attr "length" "2")]
+ "&& reload_completed && CONST_INT_P (operands[2])
+ && operands[1] != stack_pointer_rtx
+ && (INTVAL (operands[2]) > 255 || INTVAL (operands[2]) < -255)"
+ [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
+ (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
+ {
+ HOST_WIDE_INT offset = INTVAL (operands[2]);
+ if (offset > 255)
+ offset = 255;
+ else if (offset < -255)
+ offset = -255;
+
+ operands[3] = GEN_INT (offset);
+ operands[2] = GEN_INT (INTVAL (operands[2]) - offset);
+ }
+ [(set_attr "length" "2,2,2,2,2,2,2,4,4")]
)
;; Reloading and elimination of the frame pointer can
@@ -2615,11 +2633,11 @@
[(set (match_operand:SI 0 "s_register_operand" "=r,r")
(ior:SI (match_operand:SI 1 "s_register_operand" "r,r")
(match_operand:SI 2 "reg_or_int_operand" "rI,?n")))]
- "TARGET_32BIT"
+ "TARGET_ARM"
"@
orr%?\\t%0, %1, %2
#"
- "TARGET_32BIT
+ "TARGET_ARM
&& GET_CODE (operands[2]) == CONST_INT
&& !const_ok_for_arm (INTVAL (operands[2]))"
[(clobber (const_int 0))]
@@ -2646,7 +2664,7 @@
(set (match_operand:SI 0 "arm_general_register_operand" "")
(ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
(match_operand:SI 2 "const_int_operand" "")))]
- "TARGET_32BIT
+ "TARGET_ARM
&& !const_ok_for_arm (INTVAL (operands[2]))
&& const_ok_for_arm (~INTVAL (operands[2]))"
[(set (match_dup 3) (match_dup 2))
@@ -5476,8 +5494,8 @@
/* ??? We shouldn't really get invalid addresses here, but this can
happen if we are passed a SP (never OK for HImode/QImode) or
- virtual register (rejected by GO_IF_LEGITIMATE_ADDRESS for
- HImode/QImode) relative address. */
+ virtual register (also rejected as illegitimate for HImode/QImode)
+ relative address. */
/* ??? This should perhaps be fixed elsewhere, for instance, in
fixup_stack_1, by checking for other kinds of invalid addresses,
e.g. a bare reference to a virtual register. This may confuse the
@@ -5708,8 +5726,8 @@
{
/* ??? We shouldn't really get invalid addresses here, but this can
happen if we are passed a SP (never OK for HImode/QImode) or
- virtual register (rejected by GO_IF_LEGITIMATE_ADDRESS for
- HImode/QImode) relative address. */
+ virtual register (also rejected as illegitimate for HImode/QImode)
+ relative address. */
/* ??? This should perhaps be fixed elsewhere, for instance, in
fixup_stack_1, by checking for other kinds of invalid addresses,
e.g. a bare reference to a virtual register. This may confuse the
@@ -6386,8 +6404,16 @@
(match_operand:SI 2 "nonmemory_operand" "")])
(label_ref (match_operand 3 "" ""))
(pc)))]
- "TARGET_THUMB1"
+ "TARGET_THUMB1 || TARGET_32BIT"
"
+ if (!TARGET_THUMB1)
+ {
+ if (!arm_add_operand (operands[2], SImode))
+ operands[2] = force_reg (SImode, operands[2]);
+ emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
+ operands[3]));
+ DONE;
+ }
if (thumb1_cmpneg_operand (operands[2], SImode))
{
emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
@@ -6398,6 +6424,43 @@
operands[2] = force_reg (SImode, operands[2]);
")
+(define_expand "cbranchsf4"
+ [(set (pc) (if_then_else
+ (match_operator 0 "arm_comparison_operator"
+ [(match_operand:SF 1 "s_register_operand" "")
+ (match_operand:SF 2 "arm_float_compare_operand" "")])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
+ "TARGET_32BIT && TARGET_HARD_FLOAT"
+ "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
+ operands[3])); DONE;"
+)
+
+(define_expand "cbranchdf4"
+ [(set (pc) (if_then_else
+ (match_operator 0 "arm_comparison_operator"
+ [(match_operand:DF 1 "s_register_operand" "")
+ (match_operand:DF 2 "arm_float_compare_operand" "")])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
+ "TARGET_32BIT && TARGET_HARD_FLOAT"
+ "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
+ operands[3])); DONE;"
+)
+
+;; this uses the Cirrus DI compare instruction
+(define_expand "cbranchdi4"
+ [(set (pc) (if_then_else
+ (match_operator 0 "arm_comparison_operator"
+ [(match_operand:DI 1 "cirrus_fp_register" "")
+ (match_operand:DI 2 "cirrus_fp_register" "")])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
+ "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2],
+ operands[3])); DONE;"
+)
+
(define_insn "*cbranchsi4_insn"
[(set (pc) (if_then_else
(match_operator 0 "arm_comparison_operator"
@@ -7451,39 +7514,6 @@
;; Comparison and test insns
-(define_expand "cmpsi"
- [(match_operand:SI 0 "s_register_operand" "")
- (match_operand:SI 1 "arm_add_operand" "")]
- "TARGET_32BIT"
- "{
- arm_compare_op0 = operands[0];
- arm_compare_op1 = operands[1];
- DONE;
- }"
-)
-
-(define_expand "cmpsf"
- [(match_operand:SF 0 "s_register_operand" "")
- (match_operand:SF 1 "arm_float_compare_operand" "")]
- "TARGET_32BIT && TARGET_HARD_FLOAT"
- "
- arm_compare_op0 = operands[0];
- arm_compare_op1 = operands[1];
- DONE;
- "
-)
-
-(define_expand "cmpdf"
- [(match_operand:DF 0 "s_register_operand" "")
- (match_operand:DF 1 "arm_float_compare_operand" "")]
- "TARGET_32BIT && TARGET_HARD_FLOAT"
- "
- arm_compare_op0 = operands[0];
- arm_compare_op1 = operands[1];
- DONE;
- "
-)
-
(define_insn "*arm_cmpsi_insn"
[(set (reg:CC CC_REGNUM)
(compare:CC (match_operand:SI 0 "s_register_operand" "r,r")
@@ -7562,17 +7592,6 @@
(set_attr "cirrus" "compare")]
)
-;; Cirrus DI compare instruction
-(define_expand "cmpdi"
- [(match_operand:DI 0 "cirrus_fp_register" "")
- (match_operand:DI 1 "cirrus_fp_register" "")]
- "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
- "{
- arm_compare_op0 = operands[0];
- arm_compare_op1 = operands[1];
- DONE;
- }")
-
(define_insn "*cirrus_cmpdi"
[(set (reg:CC CC_REGNUM)
(compare:CC (match_operand:DI 0 "cirrus_fp_register" "v")
@@ -7600,170 +7619,16 @@
;; Conditional branch insns
-(define_expand "beq"
+(define_expand "cbranch_cc"
[(set (pc)
- (if_then_else (eq (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- "TARGET_32BIT"
- "operands[1] = arm_gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1);"
-)
-
-(define_expand "bne"
- [(set (pc)
- (if_then_else (ne (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- "TARGET_32BIT"
- "operands[1] = arm_gen_compare_reg (NE, arm_compare_op0, arm_compare_op1);"
-)
-
-(define_expand "bgt"
- [(set (pc)
- (if_then_else (gt (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- "TARGET_32BIT"
- "operands[1] = arm_gen_compare_reg (GT, arm_compare_op0, arm_compare_op1);"
-)
-
-(define_expand "ble"
- [(set (pc)
- (if_then_else (le (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- "TARGET_32BIT"
- "operands[1] = arm_gen_compare_reg (LE, arm_compare_op0, arm_compare_op1);"
-)
-
-(define_expand "bge"
- [(set (pc)
- (if_then_else (ge (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- "TARGET_32BIT"
- "operands[1] = arm_gen_compare_reg (GE, arm_compare_op0, arm_compare_op1);"
-)
-
-(define_expand "blt"
- [(set (pc)
- (if_then_else (lt (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
+ (if_then_else (match_operator 0 "" [(match_operand 1 "" "")
+ (match_operand 2 "" "")])
+ (label_ref (match_operand 3 "" ""))
(pc)))]
"TARGET_32BIT"
- "operands[1] = arm_gen_compare_reg (LT, arm_compare_op0, arm_compare_op1);"
-)
-
-(define_expand "bgtu"
- [(set (pc)
- (if_then_else (gtu (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- "TARGET_32BIT"
- "operands[1] = arm_gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1);"
-)
-
-(define_expand "bleu"
- [(set (pc)
- (if_then_else (leu (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- "TARGET_32BIT"
- "operands[1] = arm_gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1);"
-)
-
-(define_expand "bgeu"
- [(set (pc)
- (if_then_else (geu (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- "TARGET_32BIT"
- "operands[1] = arm_gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1);"
-)
-
-(define_expand "bltu"
- [(set (pc)
- (if_then_else (ltu (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- "TARGET_32BIT"
- "operands[1] = arm_gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1);"
-)
-
-(define_expand "bunordered"
- [(set (pc)
- (if_then_else (unordered (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
- "operands[1] = arm_gen_compare_reg (UNORDERED, arm_compare_op0,
- arm_compare_op1);"
-)
-
-(define_expand "bordered"
- [(set (pc)
- (if_then_else (ordered (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
- "operands[1] = arm_gen_compare_reg (ORDERED, arm_compare_op0,
- arm_compare_op1);"
-)
-
-(define_expand "bungt"
- [(set (pc)
- (if_then_else (ungt (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
- "operands[1] = arm_gen_compare_reg (UNGT, arm_compare_op0, arm_compare_op1);"
-)
-
-(define_expand "bunlt"
- [(set (pc)
- (if_then_else (unlt (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
- "operands[1] = arm_gen_compare_reg (UNLT, arm_compare_op0, arm_compare_op1);"
-)
-
-(define_expand "bunge"
- [(set (pc)
- (if_then_else (unge (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
- "operands[1] = arm_gen_compare_reg (UNGE, arm_compare_op0, arm_compare_op1);"
-)
-
-(define_expand "bunle"
- [(set (pc)
- (if_then_else (unle (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
- "operands[1] = arm_gen_compare_reg (UNLE, arm_compare_op0, arm_compare_op1);"
-)
-
-;; The following two patterns need two branch instructions, since there is
-;; no single instruction that will handle all cases.
-(define_expand "buneq"
- [(set (pc)
- (if_then_else (uneq (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
- "operands[1] = arm_gen_compare_reg (UNEQ, arm_compare_op0, arm_compare_op1);"
-)
-
-(define_expand "bltgt"
- [(set (pc)
- (if_then_else (ltgt (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
- "operands[1] = arm_gen_compare_reg (LTGT, arm_compare_op0, arm_compare_op1);"
+ "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]),
+ operands[1], operands[2]);
+ operands[2] = const0_rtx;"
)
;;
@@ -7876,141 +7741,16 @@
; scc insns
-(define_expand "seq"
- [(set (match_operand:SI 0 "s_register_operand" "")
- (eq:SI (match_dup 1) (const_int 0)))]
- "TARGET_32BIT"
- "operands[1] = arm_gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1);"
-)
-
-(define_expand "sne"
+(define_expand "cstore_cc"
[(set (match_operand:SI 0 "s_register_operand" "")
- (ne:SI (match_dup 1) (const_int 0)))]
+ (match_operator:SI 1 "" [(match_operand 2 "" "")
+ (match_operand 3 "" "")]))]
"TARGET_32BIT"
- "operands[1] = arm_gen_compare_reg (NE, arm_compare_op0, arm_compare_op1);"
+ "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]),
+ operands[2], operands[3]);
+ operands[3] = const0_rtx;"
)
-(define_expand "sgt"
- [(set (match_operand:SI 0 "s_register_operand" "")
- (gt:SI (match_dup 1) (const_int 0)))]
- "TARGET_32BIT"
- "operands[1] = arm_gen_compare_reg (GT, arm_compare_op0, arm_compare_op1);"
-)
-
-(define_expand "sle"
- [(set (match_operand:SI 0 "s_register_operand" "")
- (le:SI (match_dup 1) (const_int 0)))]
- "TARGET_32BIT"
- "operands[1] = arm_gen_compare_reg (LE, arm_compare_op0, arm_compare_op1);"
-)
-
-(define_expand "sge"
- [(set (match_operand:SI 0 "s_register_operand" "")
- (ge:SI (match_dup 1) (const_int 0)))]
- "TARGET_32BIT"
- "operands[1] = arm_gen_compare_reg (GE, arm_compare_op0, arm_compare_op1);"
-)
-
-(define_expand "slt"
- [(set (match_operand:SI 0 "s_register_operand" "")
- (lt:SI (match_dup 1) (const_int 0)))]
- "TARGET_32BIT"
- "operands[1] = arm_gen_compare_reg (LT, arm_compare_op0, arm_compare_op1);"
-)
-
-(define_expand "sgtu"
- [(set (match_operand:SI 0 "s_register_operand" "")
- (gtu:SI (match_dup 1) (const_int 0)))]
- "TARGET_32BIT"
- "operands[1] = arm_gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1);"
-)
-
-(define_expand "sleu"
- [(set (match_operand:SI 0 "s_register_operand" "")
- (leu:SI (match_dup 1) (const_int 0)))]
- "TARGET_32BIT"
- "operands[1] = arm_gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1);"
-)
-
-(define_expand "sgeu"
- [(set (match_operand:SI 0 "s_register_operand" "")
- (geu:SI (match_dup 1) (const_int 0)))]
- "TARGET_32BIT"
- "operands[1] = arm_gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1);"
-)
-
-(define_expand "sltu"
- [(set (match_operand:SI 0 "s_register_operand" "")
- (ltu:SI (match_dup 1) (const_int 0)))]
- "TARGET_32BIT"
- "operands[1] = arm_gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1);"
-)
-
-(define_expand "sunordered"
- [(set (match_operand:SI 0 "s_register_operand" "")
- (unordered:SI (match_dup 1) (const_int 0)))]
- "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
- "operands[1] = arm_gen_compare_reg (UNORDERED, arm_compare_op0,
- arm_compare_op1);"
-)
-
-(define_expand "sordered"
- [(set (match_operand:SI 0 "s_register_operand" "")
- (ordered:SI (match_dup 1) (const_int 0)))]
- "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
- "operands[1] = arm_gen_compare_reg (ORDERED, arm_compare_op0,
- arm_compare_op1);"
-)
-
-(define_expand "sungt"
- [(set (match_operand:SI 0 "s_register_operand" "")
- (ungt:SI (match_dup 1) (const_int 0)))]
- "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
- "operands[1] = arm_gen_compare_reg (UNGT, arm_compare_op0,
- arm_compare_op1);"
-)
-
-(define_expand "sunge"
- [(set (match_operand:SI 0 "s_register_operand" "")
- (unge:SI (match_dup 1) (const_int 0)))]
- "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
- "operands[1] = arm_gen_compare_reg (UNGE, arm_compare_op0,
- arm_compare_op1);"
-)
-
-(define_expand "sunlt"
- [(set (match_operand:SI 0 "s_register_operand" "")
- (unlt:SI (match_dup 1) (const_int 0)))]
- "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
- "operands[1] = arm_gen_compare_reg (UNLT, arm_compare_op0,
- arm_compare_op1);"
-)
-
-(define_expand "sunle"
- [(set (match_operand:SI 0 "s_register_operand" "")
- (unle:SI (match_dup 1) (const_int 0)))]
- "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
- "operands[1] = arm_gen_compare_reg (UNLE, arm_compare_op0,
- arm_compare_op1);"
-)
-
-;;; DO NOT add patterns for SUNEQ or SLTGT, these can't be represented with
-;;; simple ARM instructions.
-;
-; (define_expand "suneq"
-; [(set (match_operand:SI 0 "s_register_operand" "")
-; (uneq:SI (match_dup 1) (const_int 0)))]
-; "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
-; "gcc_unreachable ();"
-; )
-;
-; (define_expand "sltgt"
-; [(set (match_operand:SI 0 "s_register_operand" "")
-; (ltgt:SI (match_dup 1) (const_int 0)))]
-; "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
-; "gcc_unreachable ();"
-; )
-
(define_insn "*mov_scc"
[(set (match_operand:SI 0 "s_register_operand" "=r")
(match_operator:SI 1 "arm_comparison_operator"
@@ -8046,10 +7786,19 @@
(match_operator:SI 1 "arm_comparison_operator"
[(match_operand:SI 2 "s_register_operand" "")
(match_operand:SI 3 "reg_or_int_operand" "")]))]
- "TARGET_THUMB1"
+ "TARGET_32BIT || TARGET_THUMB1"
"{
rtx op3, scratch, scratch2;
+ if (!TARGET_THUMB1)
+ {
+ if (!arm_add_operand (operands[3], SImode))
+ operands[3] = force_reg (SImode, operands[3]);
+ emit_insn (gen_cstore_cc (operands[0], operands[1],
+ operands[2], operands[3]));
+ DONE;
+ }
+
if (operands[3] == const0_rtx)
{
switch (GET_CODE (operands[1]))
@@ -8170,6 +7919,38 @@
DONE;
}")
+(define_expand "cstoresf4"
+ [(set (match_operand:SI 0 "s_register_operand" "")
+ (match_operator:SI 1 "arm_comparison_operator"
+ [(match_operand:SF 2 "s_register_operand" "")
+ (match_operand:SF 3 "arm_float_compare_operand" "")]))]
+ "TARGET_32BIT && TARGET_HARD_FLOAT"
+ "emit_insn (gen_cstore_cc (operands[0], operands[1],
+ operands[2], operands[3])); DONE;"
+)
+
+(define_expand "cstoredf4"
+ [(set (match_operand:SI 0 "s_register_operand" "")
+ (match_operator:SI 1 "arm_comparison_operator"
+ [(match_operand:DF 2 "s_register_operand" "")
+ (match_operand:DF 3 "arm_float_compare_operand" "")]))]
+ "TARGET_32BIT && TARGET_HARD_FLOAT"
+ "emit_insn (gen_cstore_cc (operands[0], operands[1],
+ operands[2], operands[3])); DONE;"
+)
+
+;; this uses the Cirrus DI compare instruction
+(define_expand "cstoredi4"
+ [(set (match_operand:SI 0 "s_register_operand" "")
+ (match_operator:SI 1 "arm_comparison_operator"
+ [(match_operand:DI 2 "cirrus_fp_register" "")
+ (match_operand:DI 3 "cirrus_fp_register" "")]))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_MAVERICK"
+ "emit_insn (gen_cstore_cc (operands[0], operands[1],
+ operands[2], operands[3])); DONE;"
+)
+
+
(define_expand "cstoresi_eq0_thumb1"
[(parallel
[(set (match_operand:SI 0 "s_register_operand" "")
@@ -8214,7 +7995,7 @@
(define_insn "cstoresi_nltu_thumb1"
[(set (match_operand:SI 0 "s_register_operand" "=l,l")
- (neg:SI (gtu:SI (match_operand:SI 1 "s_register_operand" "l,*h")
+ (neg:SI (ltu:SI (match_operand:SI 1 "s_register_operand" "l,*h")
(match_operand:SI 2 "thumb1_cmp_operand" "lI*h,*r"))))]
"TARGET_THUMB1"
"cmp\\t%1, %2\;sbc\\t%0, %0, %0"
@@ -8250,7 +8031,8 @@
if (code == UNEQ || code == LTGT)
FAIL;
- ccreg = arm_gen_compare_reg (code, arm_compare_op0, arm_compare_op1);
+ ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
+ XEXP (operands[1], 1));
operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
}"
)
@@ -8275,7 +8057,8 @@
|| (!arm_float_add_operand (operands[3], SFmode)))
operands[3] = force_reg (SFmode, operands[3]);
- ccreg = arm_gen_compare_reg (code, arm_compare_op0, arm_compare_op1);
+ ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
+ XEXP (operands[1], 1));
operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
}"
)
@@ -8294,7 +8077,8 @@
if (code == UNEQ || code == LTGT)
FAIL;
- ccreg = arm_gen_compare_reg (code, arm_compare_op0, arm_compare_op1);
+ ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0),
+ XEXP (operands[1], 1));
operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx);
}"
)
diff --git a/gcc/config/arm/constraints.md b/gcc/config/arm/constraints.md
index 0c8fa733f75..f71599edbd4 100644
--- a/gcc/config/arm/constraints.md
+++ b/gcc/config/arm/constraints.md
@@ -30,9 +30,10 @@
;; The following multi-letter normal constraints have been used:
;; in ARM/Thumb-2 state: Da, Db, Dc, Dn, Dl, DL, Dv
+;; in Thumb-1 state: Pa, Pb
;; The following memory constraints have been used:
-;; in ARM/Thumb-2 state: Q, Ut, Uv, Uy, Un, Us
+;; in ARM/Thumb-2 state: Q, Ut, Uv, Uy, Un, Um, Us
;; in ARM state: Uq
@@ -129,6 +130,18 @@
(match_test "TARGET_THUMB1 && ival >= -508 && ival <= 508
&& ((ival & 3) == 0)")))
+(define_constraint "Pa"
+ "@internal In Thumb-1 state a constant in the range -510 to +510"
+ (and (match_code "const_int")
+ (match_test "TARGET_THUMB1 && ival >= -510 && ival <= 510
+ && (ival > 255 || ival < -255)")))
+
+(define_constraint "Pb"
+ "@internal In Thumb-1 state a constant in the range -262 to +262"
+ (and (match_code "const_int")
+ (match_test "TARGET_THUMB1 && ival >= -262 && ival <= 262
+ && (ival > 255 || ival < -255)")))
+
(define_constraint "G"
"In ARM/Thumb-2 state a valid FPA immediate constant."
(and (match_code "const_double")
@@ -214,25 +227,32 @@
(define_memory_constraint "Un"
"@internal
+ In ARM/Thumb-2 state a valid address for Neon doubleword vector
+ load/store instructions."
+ (and (match_code "mem")
+ (match_test "TARGET_32BIT && neon_vector_mem_operand (op, 0)")))
+
+(define_memory_constraint "Um"
+ "@internal
In ARM/Thumb-2 state a valid address for Neon element and structure
load/store instructions."
(and (match_code "mem")
- (match_test "TARGET_32BIT && neon_vector_mem_operand (op, FALSE)")))
+ (match_test "TARGET_32BIT && neon_vector_mem_operand (op, 2)")))
(define_memory_constraint "Us"
"@internal
In ARM/Thumb-2 state a valid address for non-offset loads/stores of
quad-word values in four ARM registers."
(and (match_code "mem")
- (match_test "TARGET_32BIT && neon_vector_mem_operand (op, TRUE)")))
+ (match_test "TARGET_32BIT && neon_vector_mem_operand (op, 1)")))
(define_memory_constraint "Uq"
"@internal
In ARM state an address valid in ldrsb instructions."
(and (match_code "mem")
(match_test "TARGET_ARM
- && arm_legitimate_address_p (GET_MODE (op), XEXP (op, 0),
- SIGN_EXTEND, 0)")))
+ && arm_legitimate_address_outer_p (GET_MODE (op), XEXP (op, 0),
+ SIGN_EXTEND, 0)")))
(define_memory_constraint "Q"
"@internal
diff --git a/gcc/config/arm/ieee754-df.S b/gcc/config/arm/ieee754-df.S
index 19a6f2c6fac..eb0c38632d0 100644
--- a/gcc/config/arm/ieee754-df.S
+++ b/gcc/config/arm/ieee754-df.S
@@ -1117,7 +1117,7 @@ ARM_FUNC_ALIAS nedf2 cmpdf2
ARM_FUNC_ALIAS eqdf2 cmpdf2
mov ip, #1 @ how should we specify unordered here?
-1: str ip, [sp, #-4]
+1: str ip, [sp, #-4]!
@ Trap any INF/NAN first.
mov ip, xh, lsl #1
@@ -1129,7 +1129,8 @@ ARM_FUNC_ALIAS eqdf2 cmpdf2
@ Test for equality.
@ Note that 0.0 is equal to -0.0.
-2: orrs ip, xl, xh, lsl #1 @ if x == 0.0 or -0.0
+2: add sp, sp, #4
+ orrs ip, xl, xh, lsl #1 @ if x == 0.0 or -0.0
do_it eq, e
COND(orr,s,eq) ip, yl, yh, lsl #1 @ and y == 0.0 or -0.0
teqne xh, yh @ or xh == yh
@@ -1168,7 +1169,7 @@ ARM_FUNC_ALIAS eqdf2 cmpdf2
bne 2b
orrs ip, yl, yh, lsl #12
beq 2b @ y is not NAN
-5: ldr r0, [sp, #-4] @ unordered return code
+5: ldr r0, [sp], #4 @ unordered return code
RET
FUNC_END gedf2
diff --git a/gcc/config/arm/ieee754-sf.S b/gcc/config/arm/ieee754-sf.S
index 38df203afbc..c93f66d8ff8 100644
--- a/gcc/config/arm/ieee754-sf.S
+++ b/gcc/config/arm/ieee754-sf.S
@@ -822,7 +822,7 @@ ARM_FUNC_ALIAS nesf2 cmpsf2
ARM_FUNC_ALIAS eqsf2 cmpsf2
mov ip, #1 @ how should we specify unordered here?
-1: str ip, [sp, #-4]
+1: str ip, [sp, #-4]!
@ Trap any INF/NAN first.
mov r2, r0, lsl #1
@@ -834,7 +834,8 @@ ARM_FUNC_ALIAS eqsf2 cmpsf2
@ Compare values.
@ Note that 0.0 is equal to -0.0.
-2: orrs ip, r2, r3, lsr #1 @ test if both are 0, clear C flag
+2: add sp, sp, #4
+ orrs ip, r2, r3, lsr #1 @ test if both are 0, clear C flag
do_it ne
teqne r0, r1 @ if not 0 compare sign
do_it pl
@@ -858,7 +859,7 @@ ARM_FUNC_ALIAS eqsf2 cmpsf2
bne 2b
movs ip, r1, lsl #9
beq 2b @ r1 is not NAN
-5: ldr r0, [sp, #-4] @ return unordered code.
+5: ldr r0, [sp], #4 @ return unordered code.
RET
FUNC_END gesf2
diff --git a/gcc/config/arm/lib1funcs.asm b/gcc/config/arm/lib1funcs.asm
index b1f2bcc74b9..cc5b94e91fe 100644
--- a/gcc/config/arm/lib1funcs.asm
+++ b/gcc/config/arm/lib1funcs.asm
@@ -1096,6 +1096,27 @@ LSYM(Lover12):
FUNC_END div0
#endif /* L_dvmd_lnx */
+#ifdef L_clear_cache
+#if defined __ARM_EABI__ && defined __linux__
+@ EABI GNU/Linux call to cacheflush syscall.
+ FUNC_START clear_cache
+ push {r7}
+#if __ARM_ARCH__ >= 7 || defined(__ARM_ARCH_6T2__)
+ movw r7, #2
+ movt r7, #0xf
+#else
+ mov r7, #0xf0000
+ add r7, r7, #2
+#endif
+ mov r2, #0
+ swi 0
+ pop {r7}
+ RET
+ FUNC_END clear_cache
+#else
+#error "This is only for ARM EABI GNU/Linux"
+#endif
+#endif /* L_clear_cache */
/* ------------------------------------------------------------------------ */
/* Dword shift operations. */
/* All the following Dword shift variants rely on the fact that
diff --git a/gcc/config/arm/linux-eabi.h b/gcc/config/arm/linux-eabi.h
index 4174d70db4d..85410c09fa4 100644
--- a/gcc/config/arm/linux-eabi.h
+++ b/gcc/config/arm/linux-eabi.h
@@ -72,16 +72,8 @@
do not use -lfloat. */
#undef LIBGCC_SPEC
-/* Clear the instruction cache from `beg' to `end'. This makes an
- inline system call to SYS_cacheflush. */
+/* Clear the instruction cache from `beg' to `end'. This is
+ implemented in lib1funcs.asm, so ensure an error if this definition
+ is used. */
#undef CLEAR_INSN_CACHE
-#define CLEAR_INSN_CACHE(BEG, END) \
-{ \
- register unsigned long _beg __asm ("a1") = (unsigned long) (BEG); \
- register unsigned long _end __asm ("a2") = (unsigned long) (END); \
- register unsigned long _flg __asm ("a3") = 0; \
- register unsigned long _scno __asm ("r7") = 0xf0002; \
- __asm __volatile ("swi 0 @ sys_cacheflush" \
- : "=r" (_beg) \
- : "0" (_beg), "r" (_end), "r" (_flg), "r" (_scno)); \
-}
+#define CLEAR_INSN_CACHE(BEG, END) not used
diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md
index ab69ab08035..ebd2a45156f 100644
--- a/gcc/config/arm/neon.md
+++ b/gcc/config/arm/neon.md
@@ -481,7 +481,7 @@
/* FIXME: If the memory layout is changed in big-endian mode, output_move_vfp
below must be changed to output_move_neon (which will use the
- element/structure loads/stores), and the constraint changed to 'Un' instead
+ element/structure loads/stores), and the constraint changed to 'Um' instead
of 'Uv'. */
switch (which_alternative)
@@ -862,6 +862,50 @@
(const_string "neon_mul_qqq_8_16_32_ddd_32")))))]
)
+(define_insn "*mul<mode>3add<mode>_neon"
+ [(set (match_operand:VDQ 0 "s_register_operand" "=w")
+ (plus:VDQ (mult:VDQ (match_operand:VDQ 2 "s_register_operand" "w")
+ (match_operand:VDQ 3 "s_register_operand" "w"))
+ (match_operand:VDQ 1 "s_register_operand" "0")))]
+ "TARGET_NEON"
+ "vmla.<V_if_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
+ [(set (attr "neon_type")
+ (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
+ (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
+ (const_string "neon_fp_vmla_ddd")
+ (const_string "neon_fp_vmla_qqq"))
+ (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
+ (if_then_else
+ (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
+ (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
+ (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))
+ (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
+ (const_string "neon_mla_qqq_8_16")
+ (const_string "neon_mla_qqq_32_qqd_32_scalar")))))]
+)
+
+(define_insn "*mul<mode>3neg<mode>add<mode>_neon"
+ [(set (match_operand:VDQ 0 "s_register_operand" "=w")
+ (minus:VDQ (match_operand:VDQ 1 "s_register_operand" "0")
+ (mult:VDQ (match_operand:VDQ 2 "s_register_operand" "w")
+ (match_operand:VDQ 3 "s_register_operand" "w"))))]
+ "TARGET_NEON"
+ "vmls.<V_if_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
+ [(set (attr "neon_type")
+ (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
+ (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
+ (const_string "neon_fp_vmla_ddd")
+ (const_string "neon_fp_vmla_qqq"))
+ (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
+ (if_then_else
+ (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
+ (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
+ (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))
+ (if_then_else (ne (symbol_ref "<Scalar_mul_8_16>") (const_int 0))
+ (const_string "neon_mla_qqq_8_16")
+ (const_string "neon_mla_qqq_32_qqd_32_scalar")))))]
+)
+
(define_insn "ior<mode>3"
[(set (match_operand:VDQ 0 "s_register_operand" "=w,w")
(ior:VDQ (match_operand:VDQ 1 "s_register_operand" "w,0")
diff --git a/gcc/config/arm/predicates.md b/gcc/config/arm/predicates.md
index c7d63355d34..7997cc94cf5 100644
--- a/gcc/config/arm/predicates.md
+++ b/gcc/config/arm/predicates.md
@@ -191,9 +191,13 @@
(define_special_predicate "equality_operator"
(match_code "eq,ne"))
-;; True for comparisons other than LTGT or UNEQ.
+;; True for integer comparisons and, if FP is active, for comparisons
+;; other than LTGT or UNEQ.
(define_special_predicate "arm_comparison_operator"
- (match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu,unordered,ordered,unlt,unle,unge,ungt"))
+ (ior (match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu")
+ (and (match_test "TARGET_32BIT && TARGET_HARD_FLOAT
+ && (TARGET_FPA || TARGET_VFP)")
+ (match_code "unordered,ordered,unlt,unle,unge,ungt"))))
(define_special_predicate "minmax_operator"
(and (match_code "smin,smax,umin,umax")
@@ -231,8 +235,8 @@
(define_special_predicate "arm_extendqisi_mem_op"
(and (match_operand 0 "memory_operand")
- (match_test "arm_legitimate_address_p (mode, XEXP (op, 0), SIGN_EXTEND,
- 0)")))
+ (match_test "arm_legitimate_address_outer_p (mode, XEXP (op, 0),
+ SIGN_EXTEND, 0)")))
(define_special_predicate "arm_reg_or_extendqisi_mem_op"
(ior (match_operand 0 "arm_extendqisi_mem_op")
diff --git a/gcc/config/arm/t-arm b/gcc/config/arm/t-arm
index 83b874c040e..c47297f828b 100644
--- a/gcc/config/arm/t-arm
+++ b/gcc/config/arm/t-arm
@@ -1,6 +1,6 @@
# Rules common to all arm targets
#
-# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
+# Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
#
# This file is part of GCC.
#
@@ -44,5 +44,5 @@ $(srcdir)/config/arm/arm-tune.md: $(srcdir)/config/arm/gentune.sh \
arm-c.o: $(srcdir)/config/arm/arm-c.c $(CONFIG_H) $(SYSTEM_H) \
coretypes.h $(TM_H) $(TREE_H) output.h $(C_COMMON_H)
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/config/arm/arm-c.c
-
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $(srcdir)/config/arm/arm-c.c
diff --git a/gcc/config/arm/t-linux-eabi b/gcc/config/arm/t-linux-eabi
index ebd177bf7f5..b8a5ce04e65 100644
--- a/gcc/config/arm/t-linux-eabi
+++ b/gcc/config/arm/t-linux-eabi
@@ -24,8 +24,8 @@ TARGET_LIBGCC2_CFLAGS = -fPIC
MULTILIB_OPTIONS =
MULTILIB_DIRNAMES =
-# Use a version of div0 which raises SIGFPE.
-LIB1ASMFUNCS := $(filter-out _dvmd_tls,$(LIB1ASMFUNCS)) _dvmd_lnx
+# Use a version of div0 which raises SIGFPE, and a special __clear_cache.
+LIB1ASMFUNCS := $(filter-out _dvmd_tls,$(LIB1ASMFUNCS)) _dvmd_lnx _clear_cache
# Multilib the standard Linux files. Don't include crti.o or crtn.o,
# which are provided by glibc.
diff --git a/gcc/config/arm/t-pe b/gcc/config/arm/t-pe
index 9b8f4a6160b..e965a1c61c2 100644
--- a/gcc/config/arm/t-pe
+++ b/gcc/config/arm/t-pe
@@ -1,5 +1,5 @@
-# Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006,
-# 2008 Free Software Foundation, Inc.
+# Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006, 2008, 2009
+# Free Software Foundation, Inc.
#
# This file is part of GCC.
#
@@ -41,7 +41,8 @@ dp-bit.c: $(srcdir)/config/fp-bit.c
pe.o: $(srcdir)/config/arm/pe.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_H) output.h flags.h $(TREE_H) expr.h toplev.h $(TM_P_H)
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/config/arm/pe.c
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $(srcdir)/config/arm/pe.c
MULTILIB_OPTIONS = mhard-float mthumb
MULTILIB_DIRNAMES = fpu thumb
diff --git a/gcc/config/arm/t-wince-pe b/gcc/config/arm/t-wince-pe
index d41ff14e4f3..4fcb48376bd 100644
--- a/gcc/config/arm/t-wince-pe
+++ b/gcc/config/arm/t-wince-pe
@@ -1,4 +1,4 @@
-# Copyright (C) 2003, 2004, 2006, 2008 Free Software Foundation, Inc.
+# Copyright (C) 2003, 2004, 2006, 2008, 2009 Free Software Foundation, Inc.
#
# This file is part of GCC.
#
@@ -40,7 +40,8 @@ dp-bit.c: $(srcdir)/config/fp-bit.c
pe.o: $(srcdir)/config/arm/pe.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_H) output.h flags.h $(TREE_H) expr.h toplev.h $(TM_P_H)
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/config/arm/pe.c
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $(srcdir)/config/arm/pe.c
MULTILIB_OPTIONS = mhard-float
MULTILIB_DIRNAMES = fpu
diff --git a/gcc/config/arm/thumb2.md b/gcc/config/arm/thumb2.md
index 14b52d0af84..6ed6fb36cf4 100644
--- a/gcc/config/arm/thumb2.md
+++ b/gcc/config/arm/thumb2.md
@@ -57,7 +57,7 @@
[(match_operand:SI 2 "s_register_operand" "r")
(match_operand:SI 3 "const_int_operand" "M")]))
(match_operand:SI 1 "s_register_operand" "r")))]
- "TARGET_ARM"
+ "TARGET_THUMB2"
"bic%?\\t%0, %1, %2%S4"
[(set_attr "predicable" "yes")
(set_attr "shift" "2")
@@ -849,30 +849,69 @@
;; Zero and sign extension instructions.
-(define_insn "*thumb2_zero_extendsidi2"
+(define_insn_and_split "*thumb2_zero_extendsidi2"
[(set (match_operand:DI 0 "s_register_operand" "=r")
(zero_extend:DI (match_operand:SI 1 "s_register_operand" "r")))]
"TARGET_THUMB2"
- "*
- /* ??? Output both instructions unconditionally, otherwise the conditional
- execution insn counter gets confused.
- if (REGNO (operands[1])
- != REGNO (operands[0]) + (WORDS_BIG_ENDIAN ? 1 : 0)) */
- output_asm_insn (\"mov%?\\t%Q0, %1\", operands);
- return \"mov%?\\t%R0, #0\";
+ "mov%?\\t%Q0, %1\;mov%?\\t%R0, #0"
+ "&& reload_completed"
+ [(set (match_dup 0) (match_dup 1))]
+ "
+ {
+ rtx lo_part = gen_lowpart (SImode, operands[0]);
+ if (!REG_P (lo_part) || REGNO (lo_part) != REGNO (operands[1]))
+ emit_move_insn (lo_part, operands[1]);
+ operands[0] = gen_highpart (SImode, operands[0]);
+ operands[1] = const0_rtx;
+ }
"
[(set_attr "length" "8")
(set_attr "ce_count" "2")
(set_attr "predicable" "yes")]
)
-(define_insn "*thumb2_zero_extendqidi2"
+(define_insn_and_split "*thumb2_zero_extendhidi2"
+ [(set (match_operand:DI 0 "s_register_operand" "=r,r")
+ (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
+ "TARGET_THUMB2"
+ "@
+ uxth%?\\t%Q0, %1\;mov%?\\t%R0, #0
+ ldr%(h%)\\t%Q0, %1\;mov%?\\t%R0, #0"
+ "&& reload_completed"
+ [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
+ (set (match_dup 2) (match_dup 3))]
+ "
+ {
+ operands[2] = gen_highpart (SImode, operands[0]);
+ operands[0] = gen_lowpart (SImode, operands[0]);
+ operands[3] = const0_rtx;
+ }
+ "
+ [(set_attr "length" "8")
+ (set_attr "ce_count" "2")
+ (set_attr "predicable" "yes")
+ (set_attr "type" "*,load_byte")
+ (set_attr "pool_range" "*,4092")
+ (set_attr "neg_pool_range" "*,250")]
+)
+
+(define_insn_and_split "*thumb2_zero_extendqidi2"
[(set (match_operand:DI 0 "s_register_operand" "=r,r")
(zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
"TARGET_THUMB2"
"@
- and%?\\t%Q0, %1, #255\;mov%?\\t%R0, #0
+ uxtb%?\\t%Q0, %1\;mov%?\\t%R0, #0
ldr%(b%)\\t%Q0, %1\;mov%?\\t%R0, #0"
+ "&& reload_completed"
+ [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
+ (set (match_dup 2) (match_dup 3))]
+ "
+ {
+ operands[2] = gen_highpart (SImode, operands[0]);
+ operands[0] = gen_lowpart (SImode, operands[0]);
+ operands[3] = const0_rtx;
+ }
+ "
[(set_attr "length" "8")
(set_attr "ce_count" "2")
(set_attr "predicable" "yes")
@@ -881,24 +920,74 @@
(set_attr "neg_pool_range" "*,250")]
)
-(define_insn "*thumb2_extendsidi2"
+(define_insn_and_split "*thumb2_extendsidi2"
[(set (match_operand:DI 0 "s_register_operand" "=r")
(sign_extend:DI (match_operand:SI 1 "s_register_operand" "r")))]
"TARGET_THUMB2"
- "*
- /* ??? Output both instructions unconditionally, otherwise the conditional
- execution insn counter gets confused.
- if (REGNO (operands[1])
- != REGNO (operands[0]) + (WORDS_BIG_ENDIAN ? 1 : 0)) */
- output_asm_insn (\"mov%?\\t%Q0, %1\", operands);
- return \"asr%?\\t%R0, %Q0, #31\";
- "
+ "mov%?\\t%Q0, %1\;asr?\\t%R0, %1, #31"
+ "&& reload_completed"
+ [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
+ {
+ rtx lo_part = gen_lowpart (SImode, operands[0]);
+
+ if (!REG_P (lo_part) || REGNO (lo_part) != REGNO (operands[1]))
+ emit_move_insn (lo_part, operands[1]);
+ operands[0] = gen_highpart (SImode, operands[0]);
+ }
[(set_attr "length" "8")
(set_attr "ce_count" "2")
(set_attr "shift" "1")
(set_attr "predicable" "yes")]
)
+(define_insn_and_split "*thumb2_extendhidi2"
+ [(set (match_operand:DI 0 "s_register_operand" "=r,r")
+ (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
+ "TARGET_THUMB2"
+ "@
+ sxth%?\\t%Q0, %1\;asr%?\\t%R0, %Q0, #31
+ ldrsh%?\\t%Q0, %1\;asr%?\\t%R0, %Q0, #31"
+ "&& reload_completed"
+ [(set (match_dup 0) (sign_extend:SI (match_dup 1)))
+ (set (match_dup 2) (ashiftrt:SI (match_dup 0) (const_int 31)))]
+ "
+ {
+ operands[2] = gen_highpart (SImode, operands[0]);
+ operands[0] = gen_lowpart (SImode, operands[0]);
+ }
+ "
+ [(set_attr "length" "8")
+ (set_attr "ce_count" "2")
+ (set_attr "predicable" "yes")
+ (set_attr "type" "*,load_byte")
+ (set_attr "pool_range" "*,4092")
+ (set_attr "neg_pool_range" "*,250")]
+)
+
+(define_insn_and_split "*thumb2_extendqidi2"
+ [(set (match_operand:DI 0 "s_register_operand" "=r,r")
+ (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
+ "TARGET_THUMB2"
+ "@
+ sxtb%?\\t%Q0, %1\;asr%?\\t%R0, %Q0, #31
+ ldrsb%?\\t%Q0, %1\;asr%?\\t%R0, %Q0, #31"
+ "&& reload_completed"
+ [(set (match_dup 0) (sign_extend:SI (match_dup 1)))
+ (set (match_dup 2) (ashiftrt:SI (match_dup 0) (const_int 31)))]
+ "
+ {
+ operands[2] = gen_highpart (SImode, operands[0]);
+ operands[0] = gen_lowpart (SImode, operands[0]);
+ }
+ "
+ [(set_attr "length" "8")
+ (set_attr "ce_count" "2")
+ (set_attr "predicable" "yes")
+ (set_attr "type" "*,load_byte")
+ (set_attr "pool_range" "*,4092")
+ (set_attr "neg_pool_range" "*,250")]
+)
+
;; All supported Thumb2 implementations are armv6, so only that case is
;; provided.
(define_insn "*thumb2_extendqisi_v6"
@@ -1162,6 +1251,71 @@
(set_attr "length" "2")]
)
+;; 16-bit encodings of "muls" and "mul<c>". We only use these when
+;; optimizing for size since "muls" is slow on all known
+;; implementations and since "mul<c>" will be generated by
+;; "*arm_mulsi3_v6" anyhow. The assembler will use a 16-bit encoding
+;; for "mul<c>" whenever possible anyhow.
+(define_peephole2
+ [(set (match_operand:SI 0 "low_register_operand" "")
+ (mult:SI (match_operand:SI 1 "low_register_operand" "")
+ (match_dup 0)))]
+ "TARGET_THUMB2 && optimize_size && peep2_regno_dead_p (0, CC_REGNUM)"
+ [(parallel
+ [(set (match_dup 0)
+ (mult:SI (match_dup 0) (match_dup 1)))
+ (clobber (reg:CC CC_REGNUM))])]
+ ""
+)
+
+(define_peephole2
+ [(set (match_operand:SI 0 "low_register_operand" "")
+ (mult:SI (match_dup 0)
+ (match_operand:SI 1 "low_register_operand" "")))]
+ "TARGET_THUMB2 && optimize_size && peep2_regno_dead_p (0, CC_REGNUM)"
+ [(parallel
+ [(set (match_dup 0)
+ (mult:SI (match_dup 0) (match_dup 1)))
+ (clobber (reg:CC CC_REGNUM))])]
+ ""
+)
+
+(define_insn "*thumb2_mulsi_short"
+ [(set (match_operand:SI 0 "low_register_operand" "=l")
+ (mult:SI (match_operand:SI 1 "low_register_operand" "%0")
+ (match_operand:SI 2 "low_register_operand" "l")))
+ (clobber (reg:CC CC_REGNUM))]
+ "TARGET_THUMB2 && optimize_size && reload_completed"
+ "mul%!\\t%0, %2, %0"
+ [(set_attr "predicable" "yes")
+ (set_attr "length" "2")
+ (set_attr "insn" "muls")])
+
+(define_insn "*thumb2_mulsi_short_compare0"
+ [(set (reg:CC_NOOV CC_REGNUM)
+ (compare:CC_NOOV
+ (mult:SI (match_operand:SI 1 "register_operand" "%0")
+ (match_operand:SI 2 "register_operand" "l"))
+ (const_int 0)))
+ (set (match_operand:SI 0 "register_operand" "=l")
+ (mult:SI (match_dup 1) (match_dup 2)))]
+ "TARGET_THUMB2 && optimize_size"
+ "muls\\t%0, %2, %0"
+ [(set_attr "length" "2")
+ (set_attr "insn" "muls")])
+
+(define_insn "*thumb2_mulsi_short_compare0_scratch"
+ [(set (reg:CC_NOOV CC_REGNUM)
+ (compare:CC_NOOV
+ (mult:SI (match_operand:SI 1 "register_operand" "%0")
+ (match_operand:SI 2 "register_operand" "l"))
+ (const_int 0)))
+ (clobber (match_scratch:SI 0 "=r"))]
+ "TARGET_THUMB2 && optimize_size"
+ "muls\\t%0, %2, %0"
+ [(set_attr "length" "2")
+ (set_attr "insn" "muls")])
+
(define_insn "*thumb2_cbz"
[(set (pc) (if_then_else
(eq (match_operand:SI 0 "s_register_operand" "l,?r")
@@ -1252,3 +1406,47 @@
(set_attr "length" "2")]
)
+(define_insn "orsi_notsi_si"
+ [(set (match_operand:SI 0 "s_register_operand" "=r")
+ (ior:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
+ (match_operand:SI 1 "s_register_operand" "r")))]
+ "TARGET_THUMB2"
+ "orn%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")]
+)
+
+(define_insn "*thumb_orsi_not_shiftsi_si"
+ [(set (match_operand:SI 0 "s_register_operand" "=r")
+ (ior:SI (not:SI (match_operator:SI 4 "shift_operator"
+ [(match_operand:SI 2 "s_register_operand" "r")
+ (match_operand:SI 3 "const_int_operand" "M")]))
+ (match_operand:SI 1 "s_register_operand" "r")))]
+ "TARGET_THUMB2"
+ "orn%?\\t%0, %1, %2%S4"
+ [(set_attr "predicable" "yes")
+ (set_attr "shift" "2")
+ (set_attr "type" "alu_shift")]
+)
+
+(define_insn_and_split "*thumb2_iorsi3"
+ [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
+ (ior:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
+ (match_operand:SI 2 "reg_or_int_operand" "rI,K,?n")))]
+ "TARGET_THUMB2"
+ "@
+ orr%?\\t%0, %1, %2
+ orn%?\\t%0, %1, #%B2
+ #"
+ "TARGET_THUMB2
+ && GET_CODE (operands[2]) == CONST_INT
+ && !(const_ok_for_arm (INTVAL (operands[2]))
+ || const_ok_for_arm (~INTVAL (operands[2])))"
+ [(clobber (const_int 0))]
+ "
+ arm_split_constant (IOR, SImode, curr_insn,
+ INTVAL (operands[2]), operands[0], operands[1], 0);
+ DONE;
+ "
+ [(set_attr "length" "4,4,16")
+ (set_attr "predicable" "yes")]
+)
diff --git a/gcc/config/avr/avr-protos.h b/gcc/config/avr/avr-protos.h
index 44246901b32..82ef981e49d 100644
--- a/gcc/config/avr/avr-protos.h
+++ b/gcc/config/avr/avr-protos.h
@@ -2,7 +2,7 @@
Copyright (C) 2000, 2001, 2002, 2003, 2004, 2006, 2007, 2008, 2009
Free Software Foundation, Inc.
- Contributed by Denis Chertykov (denisc@overta.ru)
+ Contributed by Denis Chertykov (chertykov@gmail.com)
This file is part of GCC.
@@ -61,7 +61,6 @@ extern void function_arg_advance (CUMULATIVE_ARGS *cum,
#ifdef RTX_CODE
extern void asm_output_external_libcall (FILE *file, rtx symref);
-extern int legitimate_address_p (enum machine_mode mode, rtx x, int strict);
extern int compare_diff_p (rtx insn);
extern const char *output_movqi (rtx insn, rtx operands[], int *l);
extern const char *output_movhi (rtx insn, rtx operands[], int *l);
@@ -72,8 +71,8 @@ extern const char *out_movhi_mr_r (rtx insn, rtx op[], int *l);
extern const char *out_movsi_r_mr (rtx insn, rtx op[], int *l);
extern const char *out_movsi_mr_r (rtx insn, rtx op[], int *l);
extern const char *output_movsisf (rtx insn, rtx operands[], int *l);
-extern const char *out_tstsi (rtx insn, int *l);
-extern const char *out_tsthi (rtx insn, int *l);
+extern const char *out_tstsi (rtx insn, rtx src, int *l);
+extern const char *out_tsthi (rtx insn, rtx src, int *l);
extern const char *ret_cond_branch (rtx x, int len, int reverse);
extern const char *ashlqi3_out (rtx insn, rtx operands[], int *len);
diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c
index 6bcc8e80372..1e79644fc2e 100644
--- a/gcc/config/avr/avr.c
+++ b/gcc/config/avr/avr.c
@@ -1,7 +1,7 @@
/* Subroutines for insn-output.c for ATMEL AVR micro controllers
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008,
2009 Free Software Foundation, Inc.
- Contributed by Denis Chertykov (denisc@overta.ru)
+ Contributed by Denis Chertykov (chertykov@gmail.com)
This file is part of GCC.
@@ -67,10 +67,11 @@ static int compare_sign_p (rtx insn);
static tree avr_handle_progmem_attribute (tree *, tree, tree, int, bool *);
static tree avr_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
static tree avr_handle_fntype_attribute (tree *, tree, tree, int, bool *);
-const struct attribute_spec avr_attribute_table[];
+EXPORTED_CONST struct attribute_spec avr_attribute_table[];
static bool avr_assemble_integer (rtx, unsigned int, int);
static void avr_file_start (void);
static void avr_file_end (void);
+static bool avr_legitimate_address_p (enum machine_mode, rtx, bool);
static void avr_asm_function_end_prologue (FILE *);
static void avr_asm_function_begin_epilogue (FILE *);
static rtx avr_function_value (const_tree, const_tree, bool);
@@ -367,6 +368,9 @@ static const struct mcu_type_s avr_mcu_types[] = {
#undef TARGET_CASE_VALUES_THRESHOLD
#define TARGET_CASE_VALUES_THRESHOLD avr_case_values_threshold
+#undef TARGET_LEGITIMATE_ADDRESS_P
+#define TARGET_LEGITIMATE_ADDRESS_P avr_legitimate_address_p
+
struct gcc_target targetm = TARGET_INITIALIZER;
void
@@ -1099,8 +1103,8 @@ avr_asm_function_begin_epilogue (FILE *file)
/* Return nonzero if X (an RTX) is a legitimate memory address on the target
machine for a memory operand of mode MODE. */
-int
-legitimate_address_p (enum machine_mode mode, rtx x, int strict)
+bool
+avr_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
{
enum reg_class r = NO_REGS;
@@ -2915,21 +2919,21 @@ compare_eq_p (rtx insn)
/* Output test instruction for HImode. */
const char *
-out_tsthi (rtx insn, int *l)
+out_tsthi (rtx insn, rtx op, int *l)
{
if (compare_sign_p (insn))
{
if (l) *l = 1;
return AS1 (tst,%B0);
}
- if (reg_unused_after (insn, SET_SRC (PATTERN (insn)))
+ if (reg_unused_after (insn, op)
&& compare_eq_p (insn))
{
/* Faster than sbiw if we can clobber the operand. */
if (l) *l = 1;
return AS2 (or,%A0,%B0);
}
- if (test_hard_reg_class (ADDW_REGS, SET_SRC (PATTERN (insn))))
+ if (test_hard_reg_class (ADDW_REGS, op))
{
if (l) *l = 1;
return AS2 (sbiw,%0,0);
@@ -2943,14 +2947,14 @@ out_tsthi (rtx insn, int *l)
/* Output test instruction for SImode. */
const char *
-out_tstsi (rtx insn, int *l)
+out_tstsi (rtx insn, rtx op, int *l)
{
if (compare_sign_p (insn))
{
if (l) *l = 1;
return AS1 (tst,%D0);
}
- if (test_hard_reg_class (ADDW_REGS, SET_SRC (PATTERN (insn))))
+ if (test_hard_reg_class (ADDW_REGS, op))
{
if (l) *l = 3;
return (AS2 (sbiw,%A0,0) CR_TAB
@@ -4367,8 +4371,8 @@ adjust_insn_length (rtx insn, int len)
{
switch (GET_MODE (op[1]))
{
- case HImode: out_tsthi (insn,&len); break;
- case SImode: out_tstsi (insn,&len); break;
+ case HImode: out_tsthi (insn, op[1], &len); break;
+ case SImode: out_tstsi (insn, op[1], &len); break;
default: break;
}
}
@@ -5734,6 +5738,21 @@ avr_reorg (void)
XEXP (pattern,1) = x;
INSN_CODE (next) = -1;
}
+ else if (true_regnum (XEXP (pattern, 0)) >= 0
+ && XEXP (pattern, 1) == const0_rtx)
+ {
+ /* This is a tst insn, we can reverse it. */
+ rtx next = next_real_insn (insn);
+ rtx pat = PATTERN (next);
+ rtx src = SET_SRC (pat);
+ rtx t = XEXP (src,0);
+
+ PUT_CODE (t, swap_condition (GET_CODE (t)));
+ XEXP (pattern, 1) = XEXP (pattern, 0);
+ XEXP (pattern, 0) = const0_rtx;
+ INSN_CODE (next) = -1;
+ INSN_CODE (insn) = -1;
+ }
else if (true_regnum (XEXP (pattern,0)) >= 0
&& GET_CODE (XEXP (pattern,1)) == CONST_INT)
{
@@ -5753,20 +5772,6 @@ avr_reorg (void)
}
}
}
- else if (true_regnum (SET_SRC (pattern)) >= 0)
- {
- /* This is a tst insn */
- rtx next = next_real_insn (insn);
- rtx pat = PATTERN (next);
- rtx src = SET_SRC (pat);
- rtx t = XEXP (src,0);
-
- PUT_CODE (t, swap_condition (GET_CODE (t)));
- SET_SRC (pattern) = gen_rtx_COMPARE (GET_MODE (SET_SRC (pattern)), const0_rtx,
- SET_SRC (pattern));
- INSN_CODE (next) = -1;
- INSN_CODE (insn) = -1;
- }
}
}
}
diff --git a/gcc/config/avr/avr.h b/gcc/config/avr/avr.h
index 79d81b94923..6e85bba7f6c 100644
--- a/gcc/config/avr/avr.h
+++ b/gcc/config/avr/avr.h
@@ -2,7 +2,7 @@
for ATMEL AVR at90s8515, ATmega103/103L, ATmega603/603L microcontrollers.
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
2008, 2009 Free Software Foundation, Inc.
- Contributed by Denis Chertykov (denisc@overta.ru)
+ Contributed by Denis Chertykov (chertykov@gmail.com)
This file is part of GCC.
@@ -408,20 +408,6 @@ extern int avr_reg_order[];
#define MAX_REGS_PER_ADDRESS 1
-#ifdef REG_OK_STRICT
-# define GO_IF_LEGITIMATE_ADDRESS(mode, operand, ADDR) \
-{ \
- if (legitimate_address_p (mode, operand, 1)) \
- goto ADDR; \
-}
-# else
-# define GO_IF_LEGITIMATE_ADDRESS(mode, operand, ADDR) \
-{ \
- if (legitimate_address_p (mode, operand, 0)) \
- goto ADDR; \
-}
-#endif
-
#define REG_OK_FOR_BASE_NOSTRICT_P(X) \
(REGNO (X) >= FIRST_PSEUDO_REGISTER || REG_OK_FOR_BASE_STRICT_P(X))
diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md
index 269e2c5ddb5..b861730287a 100644
--- a/gcc/config/avr/avr.md
+++ b/gcc/config/avr/avr.md
@@ -3,7 +3,7 @@
;; for ATMEL AVR micro controllers.
;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008
;; Free Software Foundation, Inc.
-;; Contributed by Denis Chertykov (denisc@overta.ru)
+;; Contributed by Denis Chertykov (chertykov@gmail.com)
;; This file is part of GCC.
@@ -2202,53 +2202,65 @@
;;<=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=>
;; compare
-(define_insn "tstqi"
+; Optimize negated tests into reverse compare if overflow is undefined.
+(define_insn "*negated_tstqi"
[(set (cc0)
- (match_operand:QI 0 "register_operand" "r"))]
- ""
- "tst %0"
+ (compare (neg:QI (match_operand:QI 0 "register_operand" "r"))
+ (const_int 0)))]
+ "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
+ "cp __zero_reg__,%0"
[(set_attr "cc" "compare")
(set_attr "length" "1")])
(define_insn "*reversed_tstqi"
[(set (cc0)
- (compare (const_int 0)
+ (compare (const_int 0)
(match_operand:QI 0 "register_operand" "r")))]
""
"cp __zero_reg__,%0"
- [(set_attr "cc" "compare")
- (set_attr "length" "1")])
+[(set_attr "cc" "compare")
+ (set_attr "length" "2")])
-(define_insn "tsthi"
+(define_insn "*negated_tsthi"
[(set (cc0)
- (match_operand:HI 0 "register_operand" "!w,r"))]
- ""
- "* return out_tsthi (insn,NULL);"
-[(set_attr "cc" "compare,compare")
- (set_attr "length" "1,2")])
+ (compare (neg:HI (match_operand:HI 0 "register_operand" "r"))
+ (const_int 0)))]
+ "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
+ "cp __zero_reg__,%A0
+ cpc __zero_reg__,%B0"
+[(set_attr "cc" "compare")
+ (set_attr "length" "2")])
+;; Leave here the clobber used by the cmphi pattern for simplicity, even
+;; though it is unused, because this pattern is synthesized by avr_reorg.
(define_insn "*reversed_tsthi"
[(set (cc0)
(compare (const_int 0)
- (match_operand:HI 0 "register_operand" "r")))]
+ (match_operand:HI 0 "register_operand" "r")))
+ (clobber (match_scratch:QI 1 "=X"))]
""
"cp __zero_reg__,%A0
cpc __zero_reg__,%B0"
[(set_attr "cc" "compare")
(set_attr "length" "2")])
-(define_insn "tstsi"
+(define_insn "*negated_tstsi"
[(set (cc0)
- (match_operand:SI 0 "register_operand" "r"))]
- ""
- "* return out_tstsi (insn,NULL);"
+ (compare (neg:SI (match_operand:SI 0 "register_operand" "r"))
+ (const_int 0)))]
+ "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
+ "cp __zero_reg__,%A0
+ cpc __zero_reg__,%B0
+ cpc __zero_reg__,%C0
+ cpc __zero_reg__,%D0"
[(set_attr "cc" "compare")
(set_attr "length" "4")])
(define_insn "*reversed_tstsi"
[(set (cc0)
- (compare (const_int 0)
- (match_operand:SI 0 "register_operand" "r")))]
+ (compare (const_int 0)
+ (match_operand:SI 0 "register_operand" "r")))
+ (clobber (match_scratch:QI 1 "=X"))]
""
"cp __zero_reg__,%A0
cpc __zero_reg__,%B0
@@ -2258,16 +2270,17 @@
(set_attr "length" "4")])
-(define_insn "cmpqi"
+(define_insn "*cmpqi"
[(set (cc0)
- (compare (match_operand:QI 0 "register_operand" "r,d")
- (match_operand:QI 1 "nonmemory_operand" "r,i")))]
+ (compare (match_operand:QI 0 "register_operand" "r,r,d")
+ (match_operand:QI 1 "nonmemory_operand" "L,r,i")))]
""
"@
+ tst %0
cp %0,%1
cpi %0,lo8(%1)"
- [(set_attr "cc" "compare,compare")
- (set_attr "length" "1,1")])
+ [(set_attr "cc" "compare,compare,compare")
+ (set_attr "length" "1,1,1")])
(define_insn "*cmpqi_sign_extend"
[(set (cc0)
@@ -2279,19 +2292,22 @@
[(set_attr "cc" "compare")
(set_attr "length" "1")])
-(define_insn "cmphi"
+(define_insn "*cmphi"
[(set (cc0)
- (compare (match_operand:HI 0 "register_operand" "r,d,d,r,r")
- (match_operand:HI 1 "nonmemory_operand" "r,M,i,M,i")))
- (clobber (match_scratch:QI 2 "=X,X,&d,&d,&d"))]
+ (compare (match_operand:HI 0 "register_operand" "!w,r,r,d,d,r,r")
+ (match_operand:HI 1 "nonmemory_operand" "L,L,r,M,i,M,i")))
+ (clobber (match_scratch:QI 2 "=X,X,X,X,&d,&d,&d"))]
""
"*{
switch (which_alternative)
{
- case 0:
+ case 0: case 1:
+ return out_tsthi (insn, operands[0], NULL);
+
+ case 2:
return (AS2 (cp,%A0,%A1) CR_TAB
AS2 (cpc,%B0,%B1));
- case 1:
+ case 3:
if (reg_unused_after (insn, operands[0])
&& INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 63
&& test_hard_reg_class (ADDW_REGS, operands[0]))
@@ -2299,7 +2315,7 @@
else
return (AS2 (cpi,%0,%1) CR_TAB
AS2 (cpc,%B0,__zero_reg__));
- case 2:
+ case 4:
if (reg_unused_after (insn, operands[0]))
return (AS2 (subi,%0,lo8(%1)) CR_TAB
AS2 (sbci,%B0,hi8(%1)));
@@ -2307,12 +2323,12 @@
return (AS2 (ldi, %2,hi8(%1)) CR_TAB
AS2 (cpi, %A0,lo8(%1)) CR_TAB
AS2 (cpc, %B0,%2));
- case 3:
+ case 5:
return (AS2 (ldi, %2,lo8(%1)) CR_TAB
AS2 (cp, %A0,%2) CR_TAB
AS2 (cpc, %B0,__zero_reg__));
- case 4:
+ case 6:
return (AS2 (ldi, %2,lo8(%1)) CR_TAB
AS2 (cp, %A0,%2) CR_TAB
AS2 (ldi, %2,hi8(%1)) CR_TAB
@@ -2320,25 +2336,28 @@
}
return \"bug\";
}"
- [(set_attr "cc" "compare,compare,compare,compare,compare")
- (set_attr "length" "2,2,3,3,4")])
+ [(set_attr "cc" "compare,compare,compare,compare,compare,compare,compare")
+ (set_attr "length" "1,2,2,2,3,3,4")])
-(define_insn "cmpsi"
+(define_insn "*cmpsi"
[(set (cc0)
- (compare (match_operand:SI 0 "register_operand" "r,d,d,r,r")
- (match_operand:SI 1 "nonmemory_operand" "r,M,i,M,i")))
- (clobber (match_scratch:QI 2 "=X,X,&d,&d,&d"))]
+ (compare (match_operand:SI 0 "register_operand" "r,r,d,d,r,r")
+ (match_operand:SI 1 "nonmemory_operand" "L,r,M,i,M,i")))
+ (clobber (match_scratch:QI 2 "=X,X,X,&d,&d,&d"))]
""
"*{
switch (which_alternative)
{
case 0:
+ return out_tstsi (insn, operands[0], NULL);
+
+ case 1:
return (AS2 (cp,%A0,%A1) CR_TAB
AS2 (cpc,%B0,%B1) CR_TAB
AS2 (cpc,%C0,%C1) CR_TAB
AS2 (cpc,%D0,%D1));
- case 1:
+ case 2:
if (reg_unused_after (insn, operands[0])
&& INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 63
&& test_hard_reg_class (ADDW_REGS, operands[0]))
@@ -2350,7 +2369,7 @@
AS2 (cpc,%B0,__zero_reg__) CR_TAB
AS2 (cpc,%C0,__zero_reg__) CR_TAB
AS2 (cpc,%D0,__zero_reg__));
- case 2:
+ case 3:
if (reg_unused_after (insn, operands[0]))
return (AS2 (subi,%A0,lo8(%1)) CR_TAB
AS2 (sbci,%B0,hi8(%1)) CR_TAB
@@ -2364,13 +2383,13 @@
AS2 (cpc, %C0,%2) CR_TAB
AS2 (ldi, %2,hhi8(%1)) CR_TAB
AS2 (cpc, %D0,%2));
- case 3:
+ case 4:
return (AS2 (ldi,%2,lo8(%1)) CR_TAB
AS2 (cp,%A0,%2) CR_TAB
AS2 (cpc,%B0,__zero_reg__) CR_TAB
AS2 (cpc,%C0,__zero_reg__) CR_TAB
AS2 (cpc,%D0,__zero_reg__));
- case 4:
+ case 5:
return (AS2 (ldi, %2,lo8(%1)) CR_TAB
AS2 (cp, %A0,%2) CR_TAB
AS2 (ldi, %2,hi8(%1)) CR_TAB
@@ -2382,113 +2401,53 @@
}
return \"bug\";
}"
- [(set_attr "cc" "compare,compare,compare,compare,compare")
- (set_attr "length" "4,4,7,5,8")])
-
-; Optimize negated tests into reverse compare if overflow is undefined.
-(define_insn_and_split "negated_tst<mode>"
- [(set (cc0)
- (neg:QISI (match_operand:QISI 0 "register_operand")))]
+ [(set_attr "cc" "compare,compare,compare,compare,compare,compare")
+ (set_attr "length" "4,4,4,7,5,8")])
- "(!flag_wrapv && !flag_trapv && flag_strict_overflow)"
- "#"
- ""
- [(set (cc0)
- (compare (const_int 0)
- (match_dup 0)))]
- "")
;; ----------------------------------------------------------------------
;; JUMP INSTRUCTIONS
;; ----------------------------------------------------------------------
;; Conditional jump instructions
-(define_expand "beq"
- [(set (pc)
- (if_then_else (eq (cc0) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "")
-
-(define_expand "bne"
- [(set (pc)
- (if_then_else (ne (cc0) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "")
-
-(define_expand "bge"
- [(set (pc)
- (if_then_else (ge (cc0) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "")
-
-(define_expand "bgeu"
- [(set (pc)
- (if_then_else (geu (cc0) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "")
-
-(define_expand "blt"
- [(set (pc)
- (if_then_else (lt (cc0) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "")
-
-(define_expand "bltu"
- [(set (pc)
- (if_then_else (ltu (cc0) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "")
-
-
-
-/****************************************************************
- AVR not have following conditional jumps: LE,LEU,GT,GTU.
- Convert them all to proper jumps.
-*****************************************************************/
-
-(define_expand "ble"
- [(set (pc)
- (if_then_else (le (cc0) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "")
-
-(define_expand "bleu"
- [(set (pc)
- (if_then_else (leu (cc0) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "")
+(define_expand "cbranchsi4"
+ [(parallel [(set (cc0)
+ (compare (match_operand:SI 1 "register_operand" "")
+ (match_operand:SI 2 "nonmemory_operand" "")))
+ (clobber (match_scratch:QI 4 ""))])
+ (set (pc)
+ (if_then_else
+ (match_operator 0 "ordered_comparison_operator" [(cc0)
+ (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
+ "")
+
+(define_expand "cbranchhi4"
+ [(parallel [(set (cc0)
+ (compare (match_operand:HI 1 "register_operand" "")
+ (match_operand:HI 2 "nonmemory_operand" "")))
+ (clobber (match_scratch:QI 4 ""))])
+ (set (pc)
+ (if_then_else
+ (match_operator 0 "ordered_comparison_operator" [(cc0)
+ (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
+ "")
-(define_expand "bgt"
- [(set (pc)
- (if_then_else (gt (cc0) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "")
+(define_expand "cbranchqi4"
+ [(set (cc0)
+ (compare (match_operand:QI 1 "register_operand" "")
+ (match_operand:QI 2 "nonmemory_operand" "")))
+ (set (pc)
+ (if_then_else
+ (match_operator 0 "ordered_comparison_operator" [(cc0)
+ (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
+ "")
-(define_expand "bgtu"
- [(set (pc)
- (if_then_else (gtu (cc0) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "")
;; Test a single bit in a QI/HI/SImode register.
(define_insn "*sbrx_branch"
@@ -2557,7 +2516,8 @@
;; Convert sign tests to bit 7/15/31 tests that match the above insns.
(define_peephole2
- [(set (cc0) (match_operand:QI 0 "register_operand" ""))
+ [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
+ (const_int 0)))
(set (pc) (if_then_else (ge (cc0) (const_int 0))
(label_ref (match_operand 1 "" ""))
(pc)))]
@@ -2571,7 +2531,8 @@
"")
(define_peephole2
- [(set (cc0) (match_operand:QI 0 "register_operand" ""))
+ [(set (cc0) (compare (match_operand:QI 0 "register_operand" "")
+ (const_int 0)))
(set (pc) (if_then_else (lt (cc0) (const_int 0))
(label_ref (match_operand 1 "" ""))
(pc)))]
@@ -2585,7 +2546,9 @@
"")
(define_peephole2
- [(set (cc0) (match_operand:HI 0 "register_operand" ""))
+ [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
+ (const_int 0)))
+ (clobber (match_operand:HI 2 ""))])
(set (pc) (if_then_else (ge (cc0) (const_int 0))
(label_ref (match_operand 1 "" ""))
(pc)))]
@@ -2597,7 +2560,9 @@
"")
(define_peephole2
- [(set (cc0) (match_operand:HI 0 "register_operand" ""))
+ [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "")
+ (const_int 0)))
+ (clobber (match_operand:HI 2 ""))])
(set (pc) (if_then_else (lt (cc0) (const_int 0))
(label_ref (match_operand 1 "" ""))
(pc)))]
@@ -2609,7 +2574,9 @@
"")
(define_peephole2
- [(set (cc0) (match_operand:SI 0 "register_operand" ""))
+ [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
+ (const_int 0)))
+ (clobber (match_operand:SI 2 ""))])
(set (pc) (if_then_else (ge (cc0) (const_int 0))
(label_ref (match_operand 1 "" ""))
(pc)))]
@@ -2621,7 +2588,9 @@
"operands[2] = GEN_INT (-2147483647 - 1);")
(define_peephole2
- [(set (cc0) (match_operand:SI 0 "register_operand" ""))
+ [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
+ (const_int 0)))
+ (clobber (match_operand:SI 2 ""))])
(set (pc) (if_then_else (lt (cc0) (const_int 0))
(label_ref (match_operand 1 "" ""))
(pc)))]
@@ -2650,6 +2619,11 @@
[(set_attr "type" "branch")
(set_attr "cc" "clobber")])
+;; ****************************************************************
+;; AVR does not have following conditional jumps: LE,LEU,GT,GTU.
+;; Convert them all to proper jumps.
+;; ****************************************************************/
+
(define_insn "difficult_branch"
[(set (pc)
(if_then_else (match_operator 1 "difficult_comparison_operator"
@@ -3150,7 +3124,9 @@
}")
(define_peephole
- [(set (cc0) (match_operand:QI 0 "register_operand" ""))
+ [(set (cc0)
+ (compare (match_operand:QI 0 "register_operand" "")
+ (const_int 0)))
(set (pc)
(if_then_else (eq (cc0) (const_int 0))
(label_ref (match_operand 1 "" ""))
diff --git a/gcc/config/avr/libgcc.S b/gcc/config/avr/libgcc.S
index b6262b338dd..07a50b20e31 100644
--- a/gcc/config/avr/libgcc.S
+++ b/gcc/config/avr/libgcc.S
@@ -1,7 +1,7 @@
/* -*- Mode: Asm -*- */
/* Copyright (C) 1998, 1999, 2000, 2007, 2008, 2009
Free Software Foundation, Inc.
- Contributed by Denis Chertykov <denisc@overta.ru>
+ Contributed by Denis Chertykov <chertykov@gmail.com>
This file is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
diff --git a/gcc/config/bfin/bfin-protos.h b/gcc/config/bfin/bfin-protos.h
index 33de846da95..13542411221 100644
--- a/gcc/config/bfin/bfin-protos.h
+++ b/gcc/config/bfin/bfin-protos.h
@@ -146,7 +146,6 @@ extern rtx bfin_gen_compare (rtx, Mmode);
extern int bfin_local_alignment (tree, int);
extern void initialize_trampoline (rtx, rtx, rtx);
-extern bool bfin_legitimate_address_p (Mmode, rtx, int);
extern rtx bfin_va_arg (tree, tree);
extern void bfin_expand_prologue (void);
diff --git a/gcc/config/bfin/bfin.c b/gcc/config/bfin/bfin.c
index 077d5c544a7..715ec818cf5 100644
--- a/gcc/config/bfin/bfin.c
+++ b/gcc/config/bfin/bfin.c
@@ -67,10 +67,6 @@ struct GTY(()) machine_function
int has_loopreg_clobber;
};
-/* Test and compare insns in bfin.md store the information needed to
- generate branch and scc insns here. */
-rtx bfin_compare_op0, bfin_compare_op1;
-
/* RTX for condition code flag register and RETS register */
extern GTY(()) rtx bfin_cc_rtx;
extern GTY(()) rtx bfin_rets_rtx;
@@ -2714,7 +2710,7 @@ rtx
bfin_gen_compare (rtx cmp, enum machine_mode mode ATTRIBUTE_UNUSED)
{
enum rtx_code code1, code2;
- rtx op0 = bfin_compare_op0, op1 = bfin_compare_op1;
+ rtx op0 = XEXP (cmp, 0), op1 = XEXP (cmp, 1);
rtx tem = bfin_cc_rtx;
enum rtx_code code = GET_CODE (cmp);
@@ -2742,7 +2738,7 @@ bfin_gen_compare (rtx cmp, enum machine_mode mode ATTRIBUTE_UNUSED)
code2 = EQ;
break;
}
- emit_insn (gen_rtx_SET (BImode, tem,
+ emit_insn (gen_rtx_SET (VOIDmode, tem,
gen_rtx_fmt_ee (code1, BImode, op0, op1)));
}
@@ -2899,8 +2895,26 @@ bfin_valid_reg_p (unsigned int regno, int strict, enum machine_mode mode,
return REGNO_OK_FOR_BASE_NONSTRICT_P (regno, mode, outer_code, SCRATCH);
}
-bool
-bfin_legitimate_address_p (enum machine_mode mode, rtx x, int strict)
+/* Recognize an RTL expression that is a valid memory address for an
+ instruction. The MODE argument is the machine mode for the MEM expression
+ that wants to use this address.
+
+ Blackfin addressing modes are as follows:
+
+ [preg]
+ [preg + imm16]
+
+ B [ Preg + uimm15 ]
+ W [ Preg + uimm16m2 ]
+ [ Preg + uimm17m4 ]
+
+ [preg++]
+ [preg--]
+ [--sp]
+*/
+
+static bool
+bfin_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
{
switch (GET_CODE (x)) {
case REG:
@@ -4219,17 +4233,17 @@ bfin_optimize_loop (loop_info loop)
{
/* If loop->iter_reg is a DREG or PREG, we can split it here
without scratch register. */
- rtx insn;
+ rtx insn, test;
emit_insn_before (gen_addsi3 (loop->iter_reg,
loop->iter_reg,
constm1_rtx),
loop->loop_end);
- emit_insn_before (gen_cmpsi (loop->iter_reg, const0_rtx),
- loop->loop_end);
-
- insn = emit_jump_insn_before (gen_bne (loop->start_label),
+ test = gen_rtx_NE (VOIDmode, loop->iter_reg, const0_rtx);
+ insn = emit_jump_insn_before (gen_cbranchsi4 (test,
+ loop->iter_reg, const0_rtx,
+ loop->start_label),
loop->loop_end);
JUMP_LABEL (insn) = loop->start_label;
@@ -5432,7 +5446,7 @@ bfin_handle_l1_data_attribute (tree *node, tree name, tree ARG_UNUSED (args),
}
/* Table of valid machine attributes. */
-const struct attribute_spec bfin_attribute_table[] =
+static const struct attribute_spec bfin_attribute_table[] =
{
/* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
{ "interrupt_handler", 0, 0, false, true, true, handle_int_attribute },
@@ -6322,4 +6336,7 @@ bfin_expand_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
#undef TARGET_RETURN_IN_MEMORY
#define TARGET_RETURN_IN_MEMORY bfin_return_in_memory
+#undef TARGET_LEGITIMATE_ADDRESS_P
+#define TARGET_LEGITIMATE_ADDRESS_P bfin_legitimate_address_p
+
struct gcc_target targetm = TARGET_INITIALIZER;
diff --git a/gcc/config/bfin/bfin.h b/gcc/config/bfin/bfin.h
index d97fe8faaf4..29e4f910842 100644
--- a/gcc/config/bfin/bfin.h
+++ b/gcc/config/bfin/bfin.h
@@ -908,46 +908,13 @@ typedef struct {
/* A number, the maximum number of registers that can appear in a
valid memory address. Note that it is up to you to specify a
- value equal to the maximum number that `GO_IF_LEGITIMATE_ADDRESS'
+ value equal to the maximum number that `TARGET_LEGITIMATE_ADDRESS_P'
would ever accept. */
#define MAX_REGS_PER_ADDRESS 1
-/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
- that is a valid memory address for an instruction.
- The MODE argument is the machine mode for the MEM expression
- that wants to use this address.
-
- Blackfin addressing modes are as follows:
-
- [preg]
- [preg + imm16]
-
- B [ Preg + uimm15 ]
- W [ Preg + uimm16m2 ]
- [ Preg + uimm17m4 ]
-
- [preg++]
- [preg--]
- [--sp]
-*/
-
#define LEGITIMATE_MODE_FOR_AUTOINC_P(MODE) \
(GET_MODE_SIZE (MODE) <= 4 || (MODE) == PDImode)
-#ifdef REG_OK_STRICT
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, WIN) \
- do { \
- if (bfin_legitimate_address_p (MODE, X, 1)) \
- goto WIN; \
- } while (0);
-#else
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, WIN) \
- do { \
- if (bfin_legitimate_address_p (MODE, X, 0)) \
- goto WIN; \
- } while (0);
-#endif
-
#define HAVE_POST_INCREMENT 1
#define HAVE_POST_DECREMENT 1
#define HAVE_PRE_DECREMENT 1
@@ -1292,7 +1259,6 @@ do { \
#define ASM_OUTPUT_REG_PUSH(FILE, REGNO) fprintf (FILE, "[SP--] = %s;\n", reg_names[REGNO])
#define ASM_OUTPUT_REG_POP(FILE, REGNO) fprintf (FILE, "%s = [SP++];\n", reg_names[REGNO])
-extern struct rtx_def *bfin_compare_op0, *bfin_compare_op1;
extern struct rtx_def *bfin_cc_rtx, *bfin_rets_rtx;
/* This works for GAS and some other assemblers. */
diff --git a/gcc/config/bfin/bfin.md b/gcc/config/bfin/bfin.md
index 4397b7a139a..a3638700a53 100644
--- a/gcc/config/bfin/bfin.md
+++ b/gcc/config/bfin/bfin.md
@@ -141,8 +141,7 @@
(UNSPEC_ONES 12)])
(define_constants
- [(UNSPEC_VOLATILE_EH_RETURN 0)
- (UNSPEC_VOLATILE_CSYNC 1)
+ [(UNSPEC_VOLATILE_CSYNC 1)
(UNSPEC_VOLATILE_SSYNC 2)
(UNSPEC_VOLATILE_LOAD_FUNCDESC 3)
(UNSPEC_VOLATILE_STORE_EH_HANDLER 4)
@@ -2255,29 +2254,6 @@
;; Conditional branch patterns
;; The Blackfin has only few condition codes: eq, lt, lte, ltu, leu
-;; The only outcome of this pattern is that global variables
-;; bfin_compare_op[01] are set for use in bcond patterns.
-
-(define_expand "cmpbi"
- [(set (cc0) (compare (match_operand:BI 0 "register_operand" "")
- (match_operand:BI 1 "immediate_operand" "")))]
- ""
-{
- bfin_compare_op0 = operands[0];
- bfin_compare_op1 = operands[1];
- DONE;
-})
-
-(define_expand "cmpsi"
- [(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
- (match_operand:SI 1 "reg_or_const_int_operand" "")))]
- ""
-{
- bfin_compare_op0 = operands[0];
- bfin_compare_op1 = operands[1];
- DONE;
-})
-
(define_insn "compare_eq"
[(set (match_operand:BI 0 "register_operand" "=C,C")
(eq:BI (match_operand:SI 1 "register_operand" "d,a")
@@ -2326,106 +2302,6 @@
"cc =%1<%2 (iu);"
[(set_attr "type" "compare")])
-(define_expand "beq"
- [(set (match_dup 1) (match_dup 2))
- (set (pc)
- (if_then_else (match_dup 3)
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
-{
- rtx op0 = bfin_compare_op0, op1 = bfin_compare_op1;
- operands[1] = bfin_cc_rtx; /* hard register: CC */
- operands[2] = gen_rtx_EQ (BImode, op0, op1);
- /* If we have a BImode input, then we already have a compare result, and
- do not need to emit another comparison. */
- if (GET_MODE (bfin_compare_op0) == BImode)
- {
- gcc_assert (bfin_compare_op1 == const0_rtx);
- emit_insn (gen_cbranchbi4 (operands[2], op0, op1, operands[0]));
- DONE;
- }
-
- operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
-})
-
-(define_expand "bne"
- [(set (match_dup 1) (match_dup 2))
- (set (pc)
- (if_then_else (match_dup 3)
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
-{
- rtx op0 = bfin_compare_op0, op1 = bfin_compare_op1;
- /* If we have a BImode input, then we already have a compare result, and
- do not need to emit another comparison. */
- if (GET_MODE (bfin_compare_op0) == BImode)
- {
- rtx cmp = gen_rtx_NE (BImode, op0, op1);
-
- gcc_assert (bfin_compare_op1 == const0_rtx);
- emit_insn (gen_cbranchbi4 (cmp, op0, op1, operands[0]));
- DONE;
- }
-
- operands[1] = bfin_cc_rtx; /* hard register: CC */
- operands[2] = gen_rtx_EQ (BImode, op0, op1);
- operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
-})
-
-(define_expand "bgt"
- [(set (match_dup 1) (match_dup 2))
- (set (pc)
- (if_then_else (match_dup 3)
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
-{
- operands[1] = bfin_cc_rtx;
- operands[2] = gen_rtx_LE (BImode, bfin_compare_op0, bfin_compare_op1);
- operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
-})
-
-(define_expand "bgtu"
- [(set (match_dup 1) (match_dup 2))
- (set (pc)
- (if_then_else (match_dup 3)
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
-{
- operands[1] = bfin_cc_rtx;
- operands[2] = gen_rtx_LEU (BImode, bfin_compare_op0, bfin_compare_op1);
- operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
-})
-
-(define_expand "blt"
- [(set (match_dup 1) (match_dup 2))
- (set (pc)
- (if_then_else (match_dup 3)
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
-{
- operands[1] = bfin_cc_rtx;
- operands[2] = gen_rtx_LT (BImode, bfin_compare_op0, bfin_compare_op1);
- operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
-})
-
-(define_expand "bltu"
- [(set (match_dup 1) (match_dup 2))
- (set (pc)
- (if_then_else (match_dup 3)
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
-{
- operands[1] = bfin_cc_rtx;
- operands[2] = gen_rtx_LTU (BImode, bfin_compare_op0, bfin_compare_op1);
- operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
-})
-
;; Same as above, but and CC with the overflow bit generated by the first
;; multiplication.
(define_insn "flag_mul_macv2hi_parts_acconly_andcc0"
@@ -2490,63 +2366,25 @@
(set_attr "length" "6")
(set_attr "seq_insns" "multi")])
-(define_expand "bge"
- [(set (match_dup 1) (match_dup 2))
- (set (pc)
- (if_then_else (match_dup 3)
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
-{
- operands[1] = bfin_cc_rtx;
- operands[2] = gen_rtx_LT (BImode, bfin_compare_op0, bfin_compare_op1);
- operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
-})
-
-(define_expand "bgeu"
- [(set (match_dup 1) (match_dup 2))
- (set (pc)
- (if_then_else (match_dup 3)
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
-{
- operands[1] = bfin_cc_rtx;
- operands[2] = gen_rtx_LTU (BImode, bfin_compare_op0, bfin_compare_op1);
- operands[3] = gen_rtx_EQ (BImode, operands[1], const0_rtx);
-})
-
-(define_expand "ble"
- [(set (match_dup 1) (match_dup 2))
- (set (pc)
- (if_then_else (match_dup 3)
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
-{
- operands[1] = bfin_cc_rtx;
- operands[2] = gen_rtx_LE (BImode, bfin_compare_op0, bfin_compare_op1);
- operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
-})
-
-(define_expand "bleu"
- [(set (match_dup 1) (match_dup 2))
- (set (pc)
- (if_then_else (match_dup 3)
- (label_ref (match_operand 0 "" ""))
- (pc)))
- ]
+(define_expand "cbranchsi4"
+ [(set (pc)
+ (if_then_else (match_operator 0 "ordered_comparison_operator"
+ [(match_operand:SI 1 "register_operand" "")
+ (match_operand:SI 2 "reg_or_const_int_operand" "")])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
""
{
- operands[1] = bfin_cc_rtx;
- operands[2] = gen_rtx_LEU (BImode, bfin_compare_op0, bfin_compare_op1);
- operands[3] = gen_rtx_NE (BImode, operands[1], const0_rtx);
+ rtx bi_compare = bfin_gen_compare (operands[0], SImode);
+ emit_jump_insn (gen_cbranchbi4 (bi_compare, bfin_cc_rtx, CONST0_RTX (BImode),
+ operands[3]));
+ DONE;
})
(define_insn "cbranchbi4"
[(set (pc)
(if_then_else
- (match_operator 0 "bfin_cbranch_operator"
+ (match_operator 0 "bfin_bimode_comparison_operator"
[(match_operand:BI 1 "register_operand" "C")
(match_operand:BI 2 "immediate_operand" "P0")])
(label_ref (match_operand 3 "" ""))
@@ -2564,7 +2402,7 @@
(define_insn "cbranch_predicted_taken"
[(set (pc)
(if_then_else
- (match_operator 0 "bfin_cbranch_operator"
+ (match_operator 0 "bfin_bimode_comparison_operator"
[(match_operand:BI 1 "register_operand" "C")
(match_operand:BI 2 "immediate_operand" "P0")])
(label_ref (match_operand 3 "" ""))
@@ -2580,7 +2418,7 @@
(define_insn "cbranch_with_nops"
[(set (pc)
(if_then_else
- (match_operator 0 "bfin_cbranch_operator"
+ (match_operator 0 "bfin_bimode_comparison_operator"
[(match_operand:BI 1 "register_operand" "C")
(match_operand:BI 2 "immediate_operand" "P0")])
(label_ref (match_operand 3 "" ""))
@@ -2594,60 +2432,49 @@
[(set_attr "type" "brcc")
(set_attr "length" "8")])
-;; setcc insns. */
-(define_expand "seq"
- [(set (match_dup 1) (eq:BI (match_dup 2) (match_dup 3)))
- (set (match_operand:SI 0 "register_operand" "")
- (ne:SI (match_dup 1) (const_int 0)))]
- ""
-{
- operands[2] = bfin_compare_op0;
- operands[3] = bfin_compare_op1;
- operands[1] = bfin_cc_rtx;
-})
+;; setcc insns.
-(define_expand "slt"
- [(set (match_dup 1) (lt:BI (match_dup 2) (match_dup 3)))
+(define_expand "cstorebi4"
+ [(set (match_dup 4)
+ (match_operator:BI 1 "bfin_bimode_comparison_operator"
+ [(match_operand:BI 2 "register_operand" "")
+ (match_operand:BI 3 "reg_or_const_int_operand" "")]))
(set (match_operand:SI 0 "register_operand" "")
- (ne:SI (match_dup 1) (const_int 0)))]
+ (ne:SI (match_dup 4) (const_int 0)))]
""
{
- operands[2] = bfin_compare_op0;
- operands[3] = bfin_compare_op1;
- operands[1] = bfin_cc_rtx;
-})
+ /* It could be expanded as a movbisi instruction, but the portable
+ alternative produces better code. */
+ if (GET_CODE (operands[1]) == NE)
+ FAIL;
-(define_expand "sle"
- [(set (match_dup 1) (le:BI (match_dup 2) (match_dup 3)))
- (set (match_operand:SI 0 "register_operand" "")
- (ne:SI (match_dup 1) (const_int 0)))]
- ""
-{
- operands[2] = bfin_compare_op0;
- operands[3] = bfin_compare_op1;
- operands[1] = bfin_cc_rtx;
+ operands[4] = bfin_cc_rtx;
})
-(define_expand "sltu"
- [(set (match_dup 1) (ltu:BI (match_dup 2) (match_dup 3)))
- (set (match_operand:SI 0 "register_operand" "")
- (ne:SI (match_dup 1) (const_int 0)))]
+(define_expand "cstoresi4"
+ [(set (match_operand:SI 0 "register_operand")
+ (match_operator:SI 1 "ordered_comparison_operator"
+ [(match_operand:SI 2 "register_operand" "")
+ (match_operand:SI 3 "reg_or_const_int_operand" "")]))]
""
{
- operands[2] = bfin_compare_op0;
- operands[3] = bfin_compare_op1;
- operands[1] = bfin_cc_rtx;
-})
+ rtx bi_compare, test;
-(define_expand "sleu"
- [(set (match_dup 1) (leu:BI (match_dup 2) (match_dup 3)))
- (set (match_operand:SI 0 "register_operand" "")
- (ne:SI (match_dup 1) (const_int 0)))]
- ""
-{
- operands[2] = bfin_compare_op0;
- operands[3] = bfin_compare_op1;
- operands[1] = bfin_cc_rtx;
+ if (!bfin_direct_comparison_operator (operands[1], SImode))
+ {
+ if (!register_operand (operands[3], SImode)
+ || GET_CODE (operands[1]) == NE)
+ FAIL;
+ test = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
+ SImode, operands[3], operands[2]);
+ }
+ else
+ test = operands[1];
+
+ bi_compare = bfin_gen_compare (test, SImode);
+ gcc_assert (GET_CODE (bi_compare) == NE);
+ emit_insn (gen_movbisi (operands[0], bfin_cc_rtx));
+ DONE;
})
(define_insn "nop"
@@ -2676,13 +2503,16 @@
"CC = %1;"
[(set_attr "length" "2")])
-(define_insn "movbisi"
+(define_insn_and_split "movbisi"
[(set (match_operand:SI 0 "register_operand" "=d")
(ne:SI (match_operand:BI 1 "register_operand" "C")
(const_int 0)))]
""
- "%0 = CC;"
- [(set_attr "length" "2")])
+ "#"
+ ""
+ [(set (match_operand:SI 0 "register_operand" "")
+ (zero_extend:SI (match_operand:BI 1 "register_operand" "")))]
+ "")
(define_insn "notbi"
[(set (match_operand:BI 0 "register_operand" "=C")
@@ -2742,8 +2572,7 @@
"bfin_expand_epilogue (0, 0, 1); DONE;")
(define_expand "eh_return"
- [(unspec_volatile [(match_operand:SI 0 "register_operand" "")]
- UNSPEC_VOLATILE_EH_RETURN)]
+ [(use (match_operand:SI 0 "register_operand" ""))]
""
{
emit_insn (gen_eh_store_handler (EH_RETURN_HANDLER_RTX, operands[0]));
@@ -2761,11 +2590,10 @@
[(set_attr "type" "mcst")])
(define_insn_and_split "eh_return_internal"
- [(set (pc)
- (unspec_volatile [(reg:SI REG_P2)] UNSPEC_VOLATILE_EH_RETURN))]
+ [(eh_return)]
""
"#"
- "reload_completed"
+ "epilogue_completed"
[(const_int 1)]
"bfin_expand_epilogue (1, 1, 0); DONE;")
diff --git a/gcc/config/bfin/predicates.md b/gcc/config/bfin/predicates.md
index 7aac5b0534c..bce725a7009 100644
--- a/gcc/config/bfin/predicates.md
+++ b/gcc/config/bfin/predicates.md
@@ -172,10 +172,14 @@
&& REGNO (op) <= LAST_VIRTUAL_REGISTER));
})
-;; Test for an operator valid in a conditional branch
-(define_predicate "bfin_cbranch_operator"
+;; Test for an operator valid in a BImode conditional branch
+(define_predicate "bfin_bimode_comparison_operator"
(match_code "eq,ne"))
+;; Test for an operator whose result is accessible with movbisi.
+(define_predicate "bfin_direct_comparison_operator"
+ (match_code "eq,lt,le,leu,ltu"))
+
;; The following two are used to compute the addrtype attribute. They return
;; true if passed a memory address usable for a 16-bit load or store using a
;; P or I register, respectively. If neither matches, we know we have a
diff --git a/gcc/config/cris/cris.c b/gcc/config/cris/cris.c
index 2112670de6c..bc634ddbf3e 100644
--- a/gcc/config/cris/cris.c
+++ b/gcc/config/cris/cris.c
@@ -1431,13 +1431,18 @@ cris_normal_notice_update_cc (rtx exp, rtx insn)
if (SET_DEST (exp) == cc0_rtx)
{
CC_STATUS_INIT;
- cc_status.value1 = SET_SRC (exp);
- /* Handle flags for the special btstq on one bit. */
- if (GET_CODE (SET_SRC (exp)) == ZERO_EXTRACT
- && XEXP (SET_SRC (exp), 1) == const1_rtx)
+ if (GET_CODE (SET_SRC (exp)) == COMPARE
+ && XEXP (SET_SRC (exp), 1) == const0_rtx)
+ cc_status.value1 = XEXP (SET_SRC (exp), 0);
+ else
+ cc_status.value1 = SET_SRC (exp);
+
+ /* Handle flags for the special btstq on one bit. */
+ if (GET_CODE (cc_status.value1) == ZERO_EXTRACT
+ && XEXP (cc_status.value1, 1) == const1_rtx)
{
- if (CONST_INT_P (XEXP (SET_SRC (exp), 0)))
+ if (CONST_INT_P (XEXP (cc_status.value1, 0)))
/* Using cmpq. */
cc_status.flags = CC_INVERTED;
else
@@ -1445,7 +1450,7 @@ cris_normal_notice_update_cc (rtx exp, rtx insn)
cc_status.flags = CC_Z_IN_NOT_N;
}
- if (GET_CODE (SET_SRC (exp)) == COMPARE)
+ else if (GET_CODE (SET_SRC (exp)) == COMPARE)
{
if (!REG_P (XEXP (SET_SRC (exp), 0))
&& XEXP (SET_SRC (exp), 1) != const0_rtx)
@@ -1855,6 +1860,11 @@ cris_rtx_costs (rtx x, int code, int outer_code, int *total,
}
return false;
+ case ZERO_EXTRACT:
+ if (outer_code != COMPARE)
+ return false;
+ /* fall through */
+
case ZERO_EXTEND: case SIGN_EXTEND:
*total = rtx_cost (XEXP (x, 0), outer_code, speed);
return true;
diff --git a/gcc/config/cris/cris.md b/gcc/config/cris/cris.md
index f4b2128ea19..79eb8da3b0d 100644
--- a/gcc/config/cris/cris.md
+++ b/gcc/config/cris/cris.md
@@ -248,40 +248,16 @@
;; Test insns.
-;; DImode
-;;
-;; Allow register and offsettable mem operands only; post-increment is
-;; not worth the trouble.
-
-(define_expand "tstdi"
- [(set (cc0) (match_operand:DI 0 "nonimmediate_operand"))]
- ""
-{
- if (TARGET_V32 && MEM_P (operands[0]))
- operands[0] = force_reg (DImode, operands[0]);
-})
-
-(define_insn "*tstdi_non_v32"
- [(set (cc0)
- (match_operand:DI 0 "nonimmediate_operand" "r,o"))]
- "!TARGET_V32"
- "test.d %M0\;ax\;test.d %H0")
-
-(define_insn "*tstdi_v32"
- [(set (cc0)
- (match_operand:DI 0 "register_operand" "r"))]
- "TARGET_V32"
- "cmpq 0,%M0\;ax\;cmpq 0,%H0")
-
;; No test insns with side-effect on the mem addressing.
;;
;; See note on cmp-insns with side-effects (or lack of them)
;; Normal named test patterns from SI on.
-(define_insn "tstsi"
+(define_insn "*tstsi"
[(set (cc0)
- (match_operand:SI 0 "nonimmediate_operand" "r,Q>,m"))]
+ (compare (match_operand:SI 0 "nonimmediate_operand" "r,Q>,m")
+ (const_int 0)))]
""
{
if (which_alternative == 0 && TARGET_V32)
@@ -290,15 +266,10 @@
}
[(set_attr "slottable" "yes,yes,no")])
-(define_expand "tst<mode>"
- [(set (cc0)
- (match_operand:BW 0 "nonimmediate_operand"))]
- ""
- "")
-
(define_insn "*tst<mode>_cmp"
[(set (cc0)
- (match_operand:BW 0 "nonimmediate_operand" "r,Q>,m"))]
+ (compare (match_operand:BW 0 "nonimmediate_operand" "r,Q>,m")
+ (const_int 0)))]
"cris_cc0_user_requires_cmp (insn)"
"@
cmp<m> 0,%0
@@ -308,7 +279,8 @@
(define_insn "*tst<mode>_non_cmp"
[(set (cc0)
- (match_operand:BW 0 "nonimmediate_operand" "r,Q>,m"))]
+ (compare (match_operand:BW 0 "nonimmediate_operand" "r,Q>,m")
+ (const_int 0)))]
"!cris_cc0_user_requires_cmp (insn)"
"@
move<m> %0,%0
@@ -332,24 +304,13 @@
;; DImode for anything else but a structure/block-mode. Just do the
;; obvious stuff for the straight-forward constraint letters.
-(define_expand "cmpdi"
- [(set (cc0)
- (compare (match_operand:DI 0 "nonimmediate_operand" "")
- (match_operand:DI 1 "general_operand" "")))]
- ""
-{
- if (TARGET_V32 && !REG_P (operands[0]))
- operands[0] = force_reg (DImode, operands[0]);
- if (TARGET_V32 && MEM_P (operands[1]))
- operands[1] = force_reg (DImode, operands[1]);
-})
-
(define_insn "*cmpdi_non_v32"
[(set (cc0)
- (compare (match_operand:DI 0 "nonimmediate_operand" "r,r,r,r,r,r,o")
- (match_operand:DI 1 "general_operand" "Kc,I,P,n,r,o,r")))]
+ (compare (match_operand:DI 0 "nonimmediate_operand" "rm,r,r,r,r,r,r,o")
+ (match_operand:DI 1 "general_operand" "M,Kc,I,P,n,r,o,r")))]
"!TARGET_V32"
"@
+ test.d %M0\;ax\;test.d %H0
cmpq %1,%M0\;ax\;cmpq 0,%H0
cmpq %1,%M0\;ax\;cmpq -1,%H0
cmp%e1.%z1 %1,%M0\;ax\;cmpq %H1,%H0
@@ -415,9 +376,9 @@
(set_attr "cc" "rev")])
;; The "normal" compare patterns, from SI on. Special-cases with zero
-;; should not happen.
+;; are covered above.
-(define_insn "cmpsi"
+(define_insn "*cmpsi"
[(set (cc0)
(compare
(match_operand:SI 0 "nonimmediate_operand" "r,r,r, Q>,r,r,m")
@@ -434,7 +395,7 @@
[(set_attr "slottable" "yes,yes,yes,yes,no,no,no")
(set_attr "cc" "normal,normal,normal,rev,normal,normal,rev")])
-(define_insn "cmp<mode>"
+(define_insn "*cmp<mode>"
[(set (cc0)
(compare (match_operand:BW 0 "nonimmediate_operand" "r,r, Q>,r,m")
(match_operand:BW 1 "general_operand" "r,Q>,r, g,r")))]
@@ -457,10 +418,12 @@
;; extends subregs for lower-size modes. FIXME: Add testcase.
(define_insn "*btst"
[(set (cc0)
- (zero_extract
- (match_operand:SI 0 "nonmemory_operand" "r, r,r, r,r, r,Kp")
- (match_operand:SI 1 "const_int_operand" "Kc,n,Kc,n,Kc,n,n")
- (match_operand:SI 2 "nonmemory_operand" "M, M,Kc,n,r, r,r")))]
+ (compare
+ (zero_extract:SI
+ (match_operand:SI 0 "nonmemory_operand" "r, r,r, r,r, r,Kp")
+ (match_operand:SI 1 "const_int_operand" "Kc,n,Kc,n,Kc,n,n")
+ (match_operand:SI 2 "nonmemory_operand" "M, M,Kc,n,r, r,r"))
+ (const_int 0)))]
;; Either it is a single bit, or consecutive ones starting at 0.
;; The btst ones depend on stuff in NOTICE_UPDATE_CC.
"CONST_INT_P (operands[1])
@@ -3550,6 +3513,36 @@
;; Conditional branches.
+(define_expand "cbranch<mode>4"
+ [(set (cc0) (compare
+ (match_operand:BWD 1 "nonimmediate_operand")
+ (match_operand:BWD 2 "general_operand")))
+ (set (pc)
+ (if_then_else (match_operator 0 "ordered_comparison_operator"
+ [(cc0) (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
+ ""
+ "")
+
+(define_expand "cbranchdi4"
+ [(set (cc0)
+ (compare (match_operand:DI 1 "nonimmediate_operand" "")
+ (match_operand:DI 2 "general_operand" "")))
+ (set (pc)
+ (if_then_else (match_operator 0 "ordered_comparison_operator"
+ [(cc0) (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
+ ""
+{
+ if (TARGET_V32 && !REG_P (operands[1]))
+ operands[1] = force_reg (DImode, operands[1]);
+ if (TARGET_V32 && MEM_P (operands[2]))
+ operands[2] = force_reg (DImode, operands[2]);
+})
+
+
;; We suffer from the same overflow-bit-gets-in-the-way problem as
;; e.g. m68k, so we have to check if overflow bit is set on all "signed"
;; conditions.
@@ -3634,6 +3627,31 @@
;; Set on condition: sCC.
+(define_expand "cstoredi4"
+ [(set (cc0) (compare
+ (match_operand:DI 2 "nonimmediate_operand")
+ (match_operand:DI 3 "general_operand")))
+ (set (match_operand:SI 0 "register_operand")
+ (match_operator:SI 1 "ordered_comparison_operator"
+ [(cc0) (const_int 0)]))]
+ ""
+{
+ if (TARGET_V32 && !REG_P (operands[2]))
+ operands[2] = force_reg (DImode, operands[2]);
+ if (TARGET_V32 && MEM_P (operands[3]))
+ operands[3] = force_reg (DImode, operands[3]);
+})
+
+(define_expand "cstore<mode>4"
+ [(set (cc0) (compare
+ (match_operand:BWD 2 "nonimmediate_operand")
+ (match_operand:BWD 3 "general_operand")))
+ (set (match_operand:SI 0 "register_operand")
+ (match_operator:SI 1 "ordered_comparison_operator"
+ [(cc0) (const_int 0)]))]
+ ""
+ "")
+
;; Like bCC, we have to check the overflow bit for
;; signed conditions.
diff --git a/gcc/config/crx/crx-protos.h b/gcc/config/crx/crx-protos.h
index 0be641dd89e..b35051d99f5 100644
--- a/gcc/config/crx/crx-protos.h
+++ b/gcc/config/crx/crx-protos.h
@@ -53,7 +53,6 @@ enum crx_addrtype
};
extern enum crx_addrtype crx_decompose_address (rtx addr, struct crx_address *out);
-extern int crx_legitimate_address_p (enum machine_mode, rtx, int);
extern int crx_const_double_ok (rtx op);
@@ -62,10 +61,6 @@ extern void crx_print_operand (FILE *, rtx, int);
extern void crx_print_operand_address (FILE *, rtx);
/* Misc functions called from crx.md. */
-extern rtx crx_expand_compare (enum rtx_code, enum machine_mode);
-extern void crx_expand_branch (enum rtx_code, rtx);
-extern void crx_expand_scond (enum rtx_code, rtx);
-
extern void crx_expand_movmem_single (rtx, rtx, rtx, rtx, rtx, unsigned HOST_WIDE_INT *);
extern int crx_expand_movmem (rtx, rtx, rtx, rtx);
#endif /* RTX_CODE */
diff --git a/gcc/config/crx/crx.c b/gcc/config/crx/crx.c
index 6f10afd2e5f..28446259044 100644
--- a/gcc/config/crx/crx.c
+++ b/gcc/config/crx/crx.c
@@ -1,6 +1,7 @@
/* Output routines for GCC for CRX.
Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
- 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+ 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+ Free Software Foundation, Inc.
This file is part of GCC.
@@ -122,11 +123,7 @@ static enum machine_mode output_memory_reference_mode;
/*****************************************************************************/
/* Table of machine attributes. */
-const struct attribute_spec crx_attribute_table[];
-
-/* Test and compare insns use these globals to generate branch insns. */
-rtx crx_compare_op0 = NULL_RTX;
-rtx crx_compare_op1 = NULL_RTX;
+EXPORTED_CONST struct attribute_spec crx_attribute_table[];
/*****************************************************************************/
/* TARGETM FUNCTION PROTOTYPES */
@@ -137,6 +134,14 @@ static rtx crx_struct_value_rtx (tree fntype ATTRIBUTE_UNUSED,
int incoming ATTRIBUTE_UNUSED);
static bool crx_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED);
static int crx_address_cost (rtx, bool);
+static bool crx_legitimate_address_p (enum machine_mode, rtx, bool);
+
+/*****************************************************************************/
+/* RTL VALIDITY */
+/*****************************************************************************/
+
+#undef TARGET_LEGITIMATE_ADDRESS_P
+#define TARGET_LEGITIMATE_ADDRESS_P crx_legitimate_address_p
/*****************************************************************************/
/* STACK LAYOUT AND CALLING CONVENTIONS */
@@ -541,7 +546,7 @@ crx_function_arg_regno_p (int n)
/* ADDRESSING MODES */
/* ---------------- */
-/* Implements the macro GO_IF_LEGITIMATE_ADDRESS defined in crx.h.
+/* Implements the hook for TARGET_LEGITIMATE_ADDRESS_P defined in crx.h.
* The following addressing modes are supported on CRX:
*
* Relocations --> const | symbol_ref | label_ref
@@ -726,9 +731,9 @@ crx_decompose_address (rtx addr, struct crx_address *out)
return retval;
}
-int
+bool
crx_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED,
- rtx addr, int strict)
+ rtx addr, bool strict)
{
enum crx_addrtype addrtype;
struct crx_address address;
@@ -1217,43 +1222,6 @@ crx_expand_movmem (rtx dstbase, rtx srcbase, rtx count_exp, rtx align_exp)
return 1;
}
-rtx
-crx_expand_compare (enum rtx_code code, enum machine_mode mode)
-{
- rtx op0, op1, cc_reg, ret;
-
- op0 = crx_compare_op0;
- op1 = crx_compare_op1;
-
- /* Emit the compare that writes into CC_REGNUM) */
- cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
- ret = gen_rtx_COMPARE (CCmode, op0, op1);
- emit_insn (gen_rtx_SET (VOIDmode, cc_reg, ret));
- /* debug_rtx (get_last_insn ()); */
-
- /* Return the rtx for using the result in CC_REGNUM */
- return gen_rtx_fmt_ee (code, mode, cc_reg, const0_rtx);
-}
-
-void
-crx_expand_branch (enum rtx_code code, rtx label)
-{
- rtx tmp = crx_expand_compare (code, VOIDmode);
- tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
- gen_rtx_LABEL_REF (VOIDmode, label),
- pc_rtx);
- emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
- /* debug_rtx (get_last_insn ()); */
-}
-
-void
-crx_expand_scond (enum rtx_code code, rtx dest)
-{
- rtx tmp = crx_expand_compare (code, GET_MODE (dest));
- emit_move_insn (dest, tmp);
- /* debug_rtx (get_last_insn ()); */
-}
-
static void
mpushpop_str (char *stringbuffer, const char *mnemonic, char *mask)
{
@@ -1468,4 +1436,3 @@ crx_expand_epilogue (void)
else
emit_jump_insn (gen_pop_and_popret_return (GEN_INT (sum_regs)));
}
-
diff --git a/gcc/config/crx/crx.h b/gcc/config/crx/crx.h
index 69065f3795b..d22db7da903 100644
--- a/gcc/config/crx/crx.h
+++ b/gcc/config/crx/crx.h
@@ -404,20 +404,6 @@ struct cumulative_args
#define REG_OK_FOR_INDEX_P(X) 1
#endif /* REG_OK_STRICT */
-#ifdef REG_OK_STRICT
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, LABEL) \
-{ \
- if (crx_legitimate_address_p (MODE, X, 1)) \
- goto LABEL; \
-}
-#else
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, LABEL) \
-{ \
- if (crx_legitimate_address_p (MODE, X, 0)) \
- goto LABEL; \
-}
-#endif /* REG_OK_STRICT */
-
#define LEGITIMATE_CONSTANT_P(X) 1
/*****************************************************************************/
@@ -520,11 +506,4 @@ struct cumulative_args
#define FUNCTION_MODE QImode
-/*****************************************************************************/
-/* EXTERNAL DECLARATIONS FOR VARIABLES DEFINED IN CRX.C */
-/*****************************************************************************/
-
-extern rtx crx_compare_op0; /* operand 0 for comparisons */
-extern rtx crx_compare_op1; /* operand 1 for comparisons */
-
#endif /* ! GCC_CRX_H */
diff --git a/gcc/config/crx/crx.md b/gcc/config/crx/crx.md
index b9655544ffc..229e345d32f 100644
--- a/gcc/config/crx/crx.md
+++ b/gcc/config/crx/crx.md
@@ -63,6 +63,10 @@
(ior (match_code "symbol_ref")
(match_operand 0 "register_operand")))
+(define_predicate "cc_reg_operand"
+ (and (match_code "reg")
+ (match_test "REGNO (op) == CC_REGNUM")))
+
(define_predicate "nosp_reg_operand"
(and (match_operand 0 "register_operand")
(match_test "REGNO (op) != SP_REGNUM")))
@@ -107,8 +111,6 @@
(define_code_iterator mima_oprnd [smax umax smin umin])
(define_code_attr mimaIsa [(smax "maxs") (umax "maxu") (smin "mins") (umin "minu")])
-(define_code_iterator any_cond [eq ne gt gtu lt ltu ge geu le leu])
-
;; Addition Instructions
(define_insn "adddi3"
@@ -522,9 +524,21 @@
;; Compare and Branch Instructions
+(define_insn "cbranchcc4"
+ [(set (pc)
+ (if_then_else (match_operator 0 "ordered_comparison_operator"
+ [(match_operand:CC 1 "cc_reg_operand" "r")
+ (match_operand 2 "cst4_operand" "L")])
+ (label_ref (match_operand 3 ""))
+ (pc)))]
+ ""
+ "b%d0\t%l3"
+ [(set_attr "length" "6")]
+)
+
(define_insn "cbranch<mode>4"
[(set (pc)
- (if_then_else (match_operator 0 "comparison_operator"
+ (if_then_else (match_operator 0 "ordered_comparison_operator"
[(match_operand:CRXIM 1 "register_operand" "r")
(match_operand:CRXIM 2 "reg_or_cst4_operand" "rL")])
(label_ref (match_operand 3 "" ""))
@@ -535,18 +549,18 @@
[(set_attr "length" "6")]
)
-;; Compare Instructions
-(define_expand "cmp<mode>"
+;; Scond Instructions
+
+(define_expand "cstore<mode>4"
[(set (reg:CC CC_REGNUM)
- (compare:CC (match_operand:CRXIM 0 "register_operand" "")
- (match_operand:CRXIM 1 "nonmemory_operand" "")))]
+ (compare:CC (match_operand:CRXIM 2 "register_operand" "")
+ (match_operand:CRXIM 3 "nonmemory_operand" "")))
+ (set (match_operand:SI 0 "register_operand")
+ (match_operator:SI 1 "ordered_comparison_operator"
+ [(reg:CC CC_REGNUM) (const_int 0)]))]
+ ""
""
- {
- crx_compare_op0 = operands[0];
- crx_compare_op1 = operands[1];
- DONE;
- }
)
(define_insn "cmp<mode>_internal"
@@ -558,48 +572,9 @@
[(set_attr "length" "2,<lImmArith>")]
)
-;; Conditional Branch Instructions
-
-(define_expand "b<code>"
- [(set (pc)
- (if_then_else (any_cond (reg:CC CC_REGNUM)
- (const_int 0))
- (label_ref (match_operand 0 ""))
- (pc)))]
- ""
- {
- crx_expand_branch (<CODE>, operands[0]);
- DONE;
- }
-)
-
-(define_insn "bCOND_internal"
- [(set (pc)
- (if_then_else (match_operator 0 "comparison_operator"
- [(reg:CC CC_REGNUM)
- (const_int 0)])
- (label_ref (match_operand 1 ""))
- (pc)))]
- ""
- "b%d0\t%l1"
- [(set_attr "length" "6")]
-)
-
-;; Scond Instructions
-
-(define_expand "s<code>"
- [(set (match_operand:SI 0 "register_operand")
- (any_cond:SI (reg:CC CC_REGNUM) (const_int 0)))]
- ""
- {
- crx_expand_scond (<CODE>, operands[0]);
- DONE;
- }
-)
-
(define_insn "sCOND_internal"
[(set (match_operand:SI 0 "register_operand" "=r")
- (match_operator:SI 1 "comparison_operator"
+ (match_operator:SI 1 "ordered_comparison_operator"
[(reg:CC CC_REGNUM) (const_int 0)]))]
""
"s%d1\t%0"
diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h
index 050773fb130..6fb1ec0c176 100644
--- a/gcc/config/darwin.h
+++ b/gcc/config/darwin.h
@@ -76,6 +76,38 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#undef WCHAR_TYPE_SIZE
#define WCHAR_TYPE_SIZE 32
+#define INT8_TYPE "signed char"
+#define INT16_TYPE "short int"
+#define INT32_TYPE "int"
+#define INT64_TYPE "long long int"
+#define UINT8_TYPE "unsigned char"
+#define UINT16_TYPE "short unsigned int"
+#define UINT32_TYPE "unsigned int"
+#define UINT64_TYPE "long long unsigned int"
+
+#define INT_LEAST8_TYPE "signed char"
+#define INT_LEAST16_TYPE "short int"
+#define INT_LEAST32_TYPE "int"
+#define INT_LEAST64_TYPE "long long int"
+#define UINT_LEAST8_TYPE "unsigned char"
+#define UINT_LEAST16_TYPE "short unsigned int"
+#define UINT_LEAST32_TYPE "unsigned int"
+#define UINT_LEAST64_TYPE "long long unsigned int"
+
+#define INT_FAST8_TYPE "signed char"
+#define INT_FAST16_TYPE "short int"
+#define INT_FAST32_TYPE "int"
+#define INT_FAST64_TYPE "long long int"
+#define UINT_FAST8_TYPE "unsigned char"
+#define UINT_FAST16_TYPE "short unsigned int"
+#define UINT_FAST32_TYPE "unsigned int"
+#define UINT_FAST64_TYPE "long long unsigned int"
+
+#define INTPTR_TYPE "long int"
+#define UINTPTR_TYPE "long unsigned int"
+
+#define SIG_ATOMIC_TYPE "int"
+
/* Default to using the NeXT-style runtime, since that's what is
pre-installed on Darwin systems. */
@@ -241,7 +273,7 @@ extern GTY(()) int darwin_ms_struct;
%{o*}%{!o:-o a.out} \
%{!A:%{!nostdlib:%{!nostartfiles:%S}}} \
%{L*} %{fopenmp:%:include(libgomp.spec)%(link_gomp)} \
- %(link_libgcc) %o %{fprofile-arcs|fprofile-generate|coverage:-lgcov} \
+ %(link_libgcc) %o %{fprofile-arcs|fprofile-generate*|coverage:-lgcov} \
%{!nostdlib:%{!nodefaultlibs:%(link_ssp) %G %L}} \
%{!A:%{!nostdlib:%{!nostartfiles:%E}}} %{T*} %{F*} }}}}}}}\n\
%{!fdump=*:%{!fsyntax-only:%{!c:%{!M:%{!MM:%{!E:%{!S:\
diff --git a/gcc/config/darwin9.h b/gcc/config/darwin9.h
index 390f8e577fe..8c6f671b03b 100644
--- a/gcc/config/darwin9.h
+++ b/gcc/config/darwin9.h
@@ -32,7 +32,7 @@ along with GCC; see the file COPYING3. If not see
%{o*}%{!o:-o a.out} \
%{!A:%{!nostdlib:%{!nostartfiles:%S}}} \
%{L*} %{fopenmp:%:include(libgomp.spec)%(link_gomp)} \
- %(link_libgcc) %o %{fprofile-arcs|fprofile-generate|coverage:-lgcov} \
+ %(link_libgcc) %o %{fprofile-arcs|fprofile-generate*|coverage:-lgcov} \
%{!nostdlib:%{!nodefaultlibs:%(link_ssp) %G %L}} \
%{!A:%{!nostdlib:%{!nostartfiles:%E}}} %{T*} %{F*} }}}}}}}\n\
%{!fdump=*:%{!fsyntax-only:%{!c:%{!M:%{!MM:%{!E:%{!S:\
diff --git a/gcc/config/fr30/fr30.c b/gcc/config/fr30/fr30.c
index e7f2e3cfd86..5642c548a29 100644
--- a/gcc/config/fr30/fr30.c
+++ b/gcc/config/fr30/fr30.c
@@ -48,12 +48,6 @@
/*}}}*/
/*{{{ Function Prologues & Epilogues */
-/* Define the information needed to generate branch and scc insns. This is
- stored from the compare operation. */
-
-struct rtx_def * fr30_compare_op0;
-struct rtx_def * fr30_compare_op1;
-
/* The FR30 stack looks like this:
Before call After call
diff --git a/gcc/config/fr30/fr30.h b/gcc/config/fr30/fr30.h
index c1e8e0a9723..b958a678db4 100644
--- a/gcc/config/fr30/fr30.h
+++ b/gcc/config/fr30/fr30.h
@@ -1106,16 +1106,6 @@ fprintf (STREAM, "\t.word .L%d\n", VALUE)
#endif
/*}}}*/
-/*{{{ Exported variables */
-
-/* Define the information needed to generate branch and scc insns. This is
- stored from the compare operation. Note that we can't use "rtx" here
- since it hasn't been defined! */
-
-extern struct rtx_def * fr30_compare_op0;
-extern struct rtx_def * fr30_compare_op1;
-
-/*}}}*/
/* Local Variables: */
/* folded-file: t */
diff --git a/gcc/config/fr30/fr30.md b/gcc/config/fr30/fr30.md
index a198ea3544d..fa115c4cfa1 100644
--- a/gcc/config/fr30/fr30.md
+++ b/gcc/config/fr30/fr30.md
@@ -916,23 +916,7 @@
;;}}}
;;{{{ Comparisons
-;; Note, we store the operands in the comparison insns, and use them later
-;; when generating the branch or scc operation.
-
-;; First the routines called by the machine independent part of the compiler
-(define_expand "cmpsi"
- [(set (reg:CC 16)
- (compare:CC (match_operand:SI 0 "register_operand" "")
- (match_operand:SI 1 "nonmemory_operand" "")))]
- ""
- "{
- fr30_compare_op0 = operands[0];
- fr30_compare_op1 = operands[1];
- DONE;
- }"
-)
-
-;; Now, the actual comparisons, generated by the branch and/or scc operations
+;; The actual comparisons, generated by the cbranch and/or cstore expanders
(define_insn "*cmpsi_internal"
[(set (reg:CC 16)
@@ -951,165 +935,19 @@
;; Define_expands called by the machine independent part of the compiler
;; to allocate a new comparison register
-(define_expand "beq"
- [(set (reg:CC 16)
- (compare:CC (match_dup 1)
- (match_dup 2)))
- (set (pc)
- (if_then_else (eq:CC (reg:CC 16)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "{
- operands[1] = fr30_compare_op0;
- operands[2] = fr30_compare_op1;
- }"
-)
-
-(define_expand "bne"
- [(set (reg:CC 16)
- (compare:CC (match_dup 1)
- (match_dup 2)))
- (set (pc)
- (if_then_else (ne:CC (reg:CC 16)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "{
- operands[1] = fr30_compare_op0;
- operands[2] = fr30_compare_op1;
- }"
-)
-
-(define_expand "blt"
- [(set (reg:CC 16)
- (compare:CC (match_dup 1)
- (match_dup 2)))
- (set (pc)
- (if_then_else (lt:CC (reg:CC 16)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "{
- operands[1] = fr30_compare_op0;
- operands[2] = fr30_compare_op1;
- }"
-)
-
-(define_expand "ble"
- [(set (reg:CC 16)
- (compare:CC (match_dup 1)
- (match_dup 2)))
- (set (pc)
- (if_then_else (le:CC (reg:CC 16)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "{
- operands[1] = fr30_compare_op0;
- operands[2] = fr30_compare_op1;
- }"
-)
-
-(define_expand "bgt"
+(define_expand "cbranchsi4"
[(set (reg:CC 16)
- (compare:CC (match_dup 1)
- (match_dup 2)))
+ (compare:CC (match_operand:SI 1 "register_operand" "")
+ (match_operand:SI 2 "nonmemory_operand" "")))
(set (pc)
- (if_then_else (gt:CC (reg:CC 16)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
+ (if_then_else (match_operator:CC 0 "ordered_comparison_operator"
+ [(reg:CC 16) (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
(pc)))]
""
- "{
- operands[1] = fr30_compare_op0;
- operands[2] = fr30_compare_op1;
- }"
-)
-
-(define_expand "bge"
- [(set (reg:CC 16)
- (compare:CC (match_dup 1)
- (match_dup 2)))
- (set (pc)
- (if_then_else (ge:CC (reg:CC 16)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "{
- operands[1] = fr30_compare_op0;
- operands[2] = fr30_compare_op1;
- }"
-)
-
-(define_expand "bltu"
- [(set (reg:CC 16)
- (compare:CC (match_dup 1)
- (match_dup 2)))
- (set (pc)
- (if_then_else (ltu:CC (reg:CC 16)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "{
- operands[1] = fr30_compare_op0;
- operands[2] = fr30_compare_op1;
- }"
-)
-
-(define_expand "bleu"
- [(set (reg:CC 16)
- (compare:CC (match_dup 1)
- (match_dup 2)))
- (set (pc)
- (if_then_else (leu:CC (reg:CC 16)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "{
- operands[1] = fr30_compare_op0;
- operands[2] = fr30_compare_op1;
- }"
-)
-
-(define_expand "bgtu"
- [(set (reg:CC 16)
- (compare:CC (match_dup 1)
- (match_dup 2)))
- (set (pc)
- (if_then_else (gtu:CC (reg:CC 16)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
""
- "{
- operands[1] = fr30_compare_op0;
- operands[2] = fr30_compare_op1;
- }"
)
-(define_expand "bgeu"
- [(set (reg:CC 16)
- (compare:CC (match_dup 1)
- (match_dup 2)))
- (set (pc)
- (if_then_else (geu:CC (reg:CC 16)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "{
- operands[1] = fr30_compare_op0;
- operands[2] = fr30_compare_op1;
- }"
-)
;; Actual branches. We must allow for the (label_ref) and the (pc) to be
;; swapped. If they are swapped, it reverses the sense of the branch.
diff --git a/gcc/config/freebsd-stdint.h b/gcc/config/freebsd-stdint.h
new file mode 100644
index 00000000000..2719e41b310
--- /dev/null
+++ b/gcc/config/freebsd-stdint.h
@@ -0,0 +1,56 @@
+/* Definitions for <stdint.h> types for FreeBSD systems.
+ Copyright (C) 2009 Free Software Foundation, Inc.
+ Contributed by Gerald Pfeifer <gerald@pfeifer.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.
+
+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/>. */
+
+#define SIG_ATOMIC_TYPE "int"
+
+#define INT8_TYPE "signed char"
+#define INT16_TYPE "short int"
+#define INT32_TYPE "int"
+#define INT64_TYPE (LONG_TYPE_SIZE == 64 ? "long int" : "long long int")
+#define UINT8_TYPE "unsigned char"
+#define UINT16_TYPE "short unsigned int"
+#define UINT32_TYPE "unsigned int"
+#define UINT64_TYPE (LONG_TYPE_SIZE == 64 ? "long unsigned int" : "long long unsigned int")
+
+#define INT_LEAST8_TYPE "signed char"
+#define INT_LEAST16_TYPE "short int"
+#define INT_LEAST32_TYPE "int"
+#define INT_LEAST64_TYPE (LONG_TYPE_SIZE == 64 ? "long int" : "long long int")
+#define UINT_LEAST8_TYPE "unsigned char"
+#define UINT_LEAST16_TYPE "short unsigned int"
+#define UINT_LEAST32_TYPE "unsigned int"
+#define UINT_LEAST64_TYPE (LONG_TYPE_SIZE == 64 ? "long unsigned int" : "long long unsigned int")
+
+#define INT_FAST8_TYPE "int"
+#define INT_FAST16_TYPE "int"
+#define INT_FAST32_TYPE "int"
+#define INT_FAST64_TYPE (LONG_TYPE_SIZE == 64 ? "long int" : "long long int")
+#define UINT_FAST8_TYPE "unsigned int"
+#define UINT_FAST16_TYPE "unsigned int"
+#define UINT_FAST32_TYPE "unsigned int"
+#define UINT_FAST64_TYPE (LONG_TYPE_SIZE == 64 ? "long unsigned int" : "long long unsigned int")
+
+#define INTPTR_TYPE (LONG_TYPE_SIZE == 64 ? "long int" : "int")
+#define UINTPTR_TYPE (LONG_TYPE_SIZE == 64 ? "long unsigned int" : "unsigned int")
diff --git a/gcc/config/frv/frv-protos.h b/gcc/config/frv/frv-protos.h
index c34d02cf96f..56f42439640 100644
--- a/gcc/config/frv/frv-protos.h
+++ b/gcc/config/frv/frv-protos.h
@@ -47,7 +47,7 @@ extern int frv_frame_pointer_required (void);
extern int frv_initial_elimination_offset (int, int);
#ifdef RTX_CODE
-extern int frv_legitimate_address_p (enum machine_mode, rtx,
+extern int frv_legitimate_address_p_1 (enum machine_mode, rtx,
int, int, int);
extern rtx frv_find_base_term (rtx);
@@ -81,8 +81,8 @@ extern const char *output_move_single (rtx *, rtx);
extern const char *output_move_double (rtx *, rtx);
extern const char *output_condmove_single
(rtx *, rtx);
-extern int frv_emit_cond_branch (enum rtx_code, rtx);
-extern int frv_emit_scc (enum rtx_code, rtx);
+extern int frv_emit_cond_branch (rtx *);
+extern int frv_emit_scc (rtx *);
extern rtx frv_split_scc (rtx, rtx, rtx, rtx, HOST_WIDE_INT);
extern int frv_emit_cond_move (rtx, rtx, rtx, rtx);
extern rtx frv_split_cond_move (rtx *);
diff --git a/gcc/config/frv/frv.c b/gcc/config/frv/frv.c
index 4e8c1b24cf8..c7e717e05ae 100644
--- a/gcc/config/frv/frv.c
+++ b/gcc/config/frv/frv.c
@@ -193,11 +193,6 @@ typedef struct
int base_offset;
} frv_frame_accessor_t;
-/* Define the information needed to generate branch and scc insns. This is
- stored from the compare operation. */
-rtx frv_compare_op0;
-rtx frv_compare_op1;
-
/* Conditional execution support gathered together in one structure. */
typedef struct
{
@@ -269,6 +264,7 @@ frv_cpu_t frv_cpu_type = CPU_TYPE; /* value of -mcpu= */
/* Forward references */
static bool frv_handle_option (size_t, const char *, int);
+static bool frv_legitimate_address_p (enum machine_mode, rtx, bool);
static int frv_default_flags_for_cpu (void);
static int frv_string_begins_with (const_tree, const char *);
static FRV_INLINE bool frv_small_data_reloc_p (rtx, int);
@@ -472,6 +468,9 @@ static bool frv_secondary_reload (bool, rtx, enum reg_class,
#undef TARGET_SECONDARY_RELOAD
#define TARGET_SECONDARY_RELOAD frv_secondary_reload
+#undef TARGET_LEGITIMATE_ADDRESS_P
+#define TARGET_LEGITIMATE_ADDRESS_P frv_legitimate_address_p
+
struct gcc_target targetm = TARGET_INITIALIZER;
#define FRV_SYMBOL_REF_TLS_P(RTX) \
@@ -2537,7 +2536,7 @@ frv_return_addr_rtx (int count, rtx frame)
MEMREF has already happened.
MEMREF must be a legitimate operand for modes larger than SImode.
- GO_IF_LEGITIMATE_ADDRESS forbids register+register addresses, which
+ frv_legitimate_address_p forbids register+register addresses, which
this function cannot handle. */
rtx
frv_index_memory (rtx memref, enum machine_mode mode, int index)
@@ -3328,12 +3327,6 @@ frv_regno_ok_for_base_p (int regno, int strict_p)
conditional to define the strict variant in that case and the non-strict
variant otherwise.
- Subroutines to check for acceptable registers for various purposes (one for
- base registers, one for index registers, and so on) are typically among the
- subroutines used to define `GO_IF_LEGITIMATE_ADDRESS'. Then only these
- subroutine macros need have two variants; the higher levels of macros may be
- the same whether strict or not.
-
Normally, constant addresses which are the sum of a `symbol_ref' and an
integer are stored inside a `const' RTX to mark them as constant.
Therefore, there is no need to recognize such sums specifically as
@@ -3344,30 +3337,14 @@ frv_regno_ok_for_base_p (int regno, int strict_p)
are not marked with `const'. It assumes that a naked `plus' indicates
indexing. If so, then you *must* reject such naked constant sums as
illegitimate addresses, so that none of them will be given to
- `PRINT_OPERAND_ADDRESS'.
-
- On some machines, whether a symbolic address is legitimate depends on the
- section that the address refers to. On these machines, define the macro
- `ENCODE_SECTION_INFO' to store the information into the `symbol_ref', and
- then check for it here. When you see a `const', you will have to look
- inside it to find the `symbol_ref' in order to determine the section.
-
- The best way to modify the name string is by adding text to the beginning,
- with suitable punctuation to prevent any ambiguity. Allocate the new name
- in `saveable_obstack'. You will have to modify `ASM_OUTPUT_LABELREF' to
- remove and decode the added text and output the name accordingly, and define
- `(* targetm.strip_name_encoding)' to access the original name string.
-
- You can check the information stored here into the `symbol_ref' in the
- definitions of the macros `GO_IF_LEGITIMATE_ADDRESS' and
`PRINT_OPERAND_ADDRESS'. */
int
-frv_legitimate_address_p (enum machine_mode mode,
- rtx x,
- int strict_p,
- int condexec_p,
- int allow_double_reg_p)
+frv_legitimate_address_p_1 (enum machine_mode mode,
+ rtx x,
+ int strict_p,
+ int condexec_p,
+ int allow_double_reg_p)
{
rtx x0, x1;
int ret = 0;
@@ -3485,7 +3462,7 @@ frv_legitimate_address_p (enum machine_mode mode,
if (TARGET_DEBUG_ADDR)
{
- fprintf (stderr, "\n========== GO_IF_LEGITIMATE_ADDRESS, mode = %s, result = %d, addresses are %sstrict%s\n",
+ fprintf (stderr, "\n========== legitimate_address_p, mode = %s, result = %d, addresses are %sstrict%s\n",
GET_MODE_NAME (mode), ret, (strict_p) ? "" : "not ",
(condexec_p) ? ", inside conditional code" : "");
debug_rtx (x);
@@ -3494,6 +3471,12 @@ frv_legitimate_address_p (enum machine_mode mode,
return ret;
}
+bool
+frv_legitimate_address_p (enum machine_mode mode, rtx x, bool strict_p)
+{
+ return frv_legitimate_address_p_1 (mode, x, strict_p, FALSE, FALSE);
+}
+
/* Given an ADDR, generate code to inline the PLT. */
static rtx
gen_inlined_tls_plt (rtx addr)
@@ -3788,8 +3771,8 @@ frv_legitimate_memory_operand (rtx op, enum machine_mode mode, int condexec_p)
{
return ((GET_MODE (op) == mode || mode == VOIDmode)
&& GET_CODE (op) == MEM
- && frv_legitimate_address_p (mode, XEXP (op, 0),
- reload_completed, condexec_p, FALSE));
+ && frv_legitimate_address_p_1 (mode, XEXP (op, 0),
+ reload_completed, condexec_p, FALSE));
}
void
@@ -3949,7 +3932,7 @@ condexec_memory_operand (rtx op, enum machine_mode mode)
return FALSE;
addr = XEXP (op, 0);
- return frv_legitimate_address_p (mode, addr, reload_completed, TRUE, FALSE);
+ return frv_legitimate_address_p_1 (mode, addr, reload_completed, TRUE, FALSE);
}
/* Return true if the bare return instruction can be used outside of the
@@ -4768,19 +4751,18 @@ frv_emit_comparison (enum rtx_code test, rtx op0, rtx op1)
}
-/* Emit code for a conditional branch. The comparison operands were previously
- stored in frv_compare_op0 and frv_compare_op1.
-
+/* Emit code for a conditional branch.
XXX: I originally wanted to add a clobber of a CCR register to use in
conditional execution, but that confuses the rest of the compiler. */
int
-frv_emit_cond_branch (enum rtx_code test, rtx label)
+frv_emit_cond_branch (rtx operands[])
{
rtx test_rtx;
rtx label_ref;
rtx if_else;
- rtx cc_reg = frv_emit_comparison (test, frv_compare_op0, frv_compare_op1);
+ enum rtx_code test = GET_CODE (operands[0]);
+ rtx cc_reg = frv_emit_comparison (test, operands[1], operands[2]);
enum machine_mode cc_mode = GET_MODE (cc_reg);
/* Branches generate:
@@ -4788,7 +4770,7 @@ frv_emit_cond_branch (enum rtx_code test, rtx label)
(if_then_else (<test>, <cc_reg>, (const_int 0))
(label_ref <branch_label>)
(pc))) */
- label_ref = gen_rtx_LABEL_REF (VOIDmode, label);
+ label_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
test_rtx = gen_rtx_fmt_ee (test, cc_mode, cc_reg, const0_rtx);
if_else = gen_rtx_IF_THEN_ELSE (cc_mode, test_rtx, label_ref, pc_rtx);
emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, if_else));
@@ -4796,23 +4778,23 @@ frv_emit_cond_branch (enum rtx_code test, rtx label)
}
-/* Emit code to set a gpr to 1/0 based on a comparison. The comparison
- operands were previously stored in frv_compare_op0 and frv_compare_op1. */
+/* Emit code to set a gpr to 1/0 based on a comparison. */
int
-frv_emit_scc (enum rtx_code test, rtx target)
+frv_emit_scc (rtx operands[])
{
rtx set;
rtx test_rtx;
rtx clobber;
rtx cr_reg;
- rtx cc_reg = frv_emit_comparison (test, frv_compare_op0, frv_compare_op1);
+ enum rtx_code test = GET_CODE (operands[1]);
+ rtx cc_reg = frv_emit_comparison (test, operands[2], operands[3]);
/* SCC instructions generate:
(parallel [(set <target> (<test>, <cc_reg>, (const_int 0))
(clobber (<ccr_reg>))]) */
test_rtx = gen_rtx_fmt_ee (test, SImode, cc_reg, const0_rtx);
- set = gen_rtx_SET (VOIDmode, target, test_rtx);
+ set = gen_rtx_SET (VOIDmode, operands[0], test_rtx);
cr_reg = ((TARGET_ALLOC_CC)
? gen_reg_rtx (CC_CCRmode)
@@ -4874,7 +4856,8 @@ frv_emit_cond_move (rtx dest, rtx test_rtx, rtx src1, rtx src2)
rtx cr_reg;
rtx if_rtx;
enum rtx_code test = GET_CODE (test_rtx);
- rtx cc_reg = frv_emit_comparison (test, frv_compare_op0, frv_compare_op1);
+ rtx cc_reg = frv_emit_comparison (test,
+ XEXP (test_rtx, 0), XEXP (test_rtx, 1));
enum machine_mode cc_mode = GET_MODE (cc_reg);
/* Conditional move instructions generate:
@@ -5851,7 +5834,7 @@ frv_ifcvt_rewrite_mem (rtx mem, enum machine_mode mode, rtx insn)
{
rtx addr = XEXP (mem, 0);
- if (!frv_legitimate_address_p (mode, addr, reload_completed, TRUE, FALSE))
+ if (!frv_legitimate_address_p_1 (mode, addr, reload_completed, TRUE, FALSE))
{
if (GET_CODE (addr) == PLUS)
{
diff --git a/gcc/config/frv/frv.h b/gcc/config/frv/frv.h
index b6fdca4aa0a..15047e3c7ed 100644
--- a/gcc/config/frv/frv.h
+++ b/gcc/config/frv/frv.h
@@ -2022,80 +2022,9 @@ __asm__("\n" \
/* A number, the maximum number of registers that can appear in a valid memory
address. Note that it is up to you to specify a value equal to the maximum
- number that `GO_IF_LEGITIMATE_ADDRESS' would ever accept. */
+ number that `TARGET_LEGITIMATE_ADDRESS_P' would ever accept. */
#define MAX_REGS_PER_ADDRESS 2
-/* A C compound statement with a conditional `goto LABEL;' executed if X (an
- RTX) is a legitimate memory address on the target machine for a memory
- operand of mode MODE.
-
- It usually pays to define several simpler macros to serve as subroutines for
- this one. Otherwise it may be too complicated to understand.
-
- This macro must exist in two variants: a strict variant and a non-strict
- one. The strict variant is used in the reload pass. It must be defined so
- that any pseudo-register that has not been allocated a hard register is
- considered a memory reference. In contexts where some kind of register is
- required, a pseudo-register with no hard register must be rejected.
-
- The non-strict variant is used in other passes. It must be defined to
- accept all pseudo-registers in every context where some kind of register is
- required.
-
- Compiler source files that want to use the strict variant of this macro
- define the macro `REG_OK_STRICT'. You should use an `#ifdef REG_OK_STRICT'
- conditional to define the strict variant in that case and the non-strict
- variant otherwise.
-
- Subroutines to check for acceptable registers for various purposes (one for
- base registers, one for index registers, and so on) are typically among the
- subroutines used to define `GO_IF_LEGITIMATE_ADDRESS'. Then only these
- subroutine macros need have two variants; the higher levels of macros may be
- the same whether strict or not.
-
- Normally, constant addresses which are the sum of a `symbol_ref' and an
- integer are stored inside a `const' RTX to mark them as constant.
- Therefore, there is no need to recognize such sums specifically as
- legitimate addresses. Normally you would simply recognize any `const' as
- legitimate.
-
- Usually `PRINT_OPERAND_ADDRESS' is not prepared to handle constant sums that
- are not marked with `const'. It assumes that a naked `plus' indicates
- indexing. If so, then you *must* reject such naked constant sums as
- illegitimate addresses, so that none of them will be given to
- `PRINT_OPERAND_ADDRESS'.
-
- On some machines, whether a symbolic address is legitimate depends on the
- section that the address refers to. On these machines, define the macro
- `ENCODE_SECTION_INFO' to store the information into the `symbol_ref', and
- then check for it here. When you see a `const', you will have to look
- inside it to find the `symbol_ref' in order to determine the section.
-
- The best way to modify the name string is by adding text to the beginning,
- with suitable punctuation to prevent any ambiguity. Allocate the new name
- in `saveable_obstack'. You will have to modify `ASM_OUTPUT_LABELREF' to
- remove and decode the added text and output the name accordingly, and define
- `(* targetm.strip_name_encoding)' to access the original name string.
-
- You can check the information stored here into the `symbol_ref' in the
- definitions of the macros `GO_IF_LEGITIMATE_ADDRESS' and
- `PRINT_OPERAND_ADDRESS'. */
-
-#ifdef REG_OK_STRICT
-#define REG_OK_STRICT_P 1
-#else
-#define REG_OK_STRICT_P 0
-#endif
-
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, LABEL) \
- do \
- { \
- if (frv_legitimate_address_p (MODE, X, REG_OK_STRICT_P, \
- FALSE, FALSE)) \
- goto LABEL; \
- } \
- while (0)
-
/* A C expression that is nonzero if X (assumed to be a `reg' RTX) is valid for
use as a base register. For hard registers, it should always accept those
which the hardware permits and reject the others. Whether the macro accepts
@@ -2913,9 +2842,6 @@ enum frv_builtins
/* Enable prototypes on the call rtl functions. */
#define MD_CALL_PROTOTYPES 1
-extern GTY(()) rtx frv_compare_op0; /* operand save for */
-extern GTY(()) rtx frv_compare_op1; /* comparison generation */
-
#define CPU_UNITS_QUERY 1
#ifdef __FRV_FDPIC__
diff --git a/gcc/config/frv/frv.md b/gcc/config/frv/frv.md
index aadf02c4fbd..9315f9b623c 100644
--- a/gcc/config/frv/frv.md
+++ b/gcc/config/frv/frv.md
@@ -3734,59 +3734,7 @@
;; ::
;; ::::::::::::::::::::
-;; Note, we store the operands in the comparison insns, and use them later
-;; when generating the branch or scc operation.
-
-;; First the routines called by the machine independent part of the compiler
-(define_expand "cmpsi"
- [(set (cc0)
- (compare (match_operand:SI 0 "integer_register_operand" "")
- (match_operand:SI 1 "gpr_or_int10_operand" "")))]
- ""
- "
-{
- frv_compare_op0 = operands[0];
- frv_compare_op1 = operands[1];
- DONE;
-}")
-
-;(define_expand "cmpdi"
-; [(set (cc0)
-; (compare (match_operand:DI 0 "register_operand" "")
-; (match_operand:DI 1 "nonmemory_operand" "")))]
-; ""
-; "
-;{
-; frv_compare_op0 = operands[0];
-; frv_compare_op1 = operands[1];
-; DONE;
-;}")
-
-(define_expand "cmpsf"
- [(set (cc0)
- (compare (match_operand:SF 0 "fpr_operand" "")
- (match_operand:SF 1 "fpr_operand" "")))]
- "TARGET_HARD_FLOAT"
- "
-{
- frv_compare_op0 = operands[0];
- frv_compare_op1 = operands[1];
- DONE;
-}")
-
-(define_expand "cmpdf"
- [(set (cc0)
- (compare (match_operand:DF 0 "fpr_operand" "")
- (match_operand:DF 1 "fpr_operand" "")))]
- "TARGET_HARD_FLOAT && TARGET_DOUBLE"
- "
-{
- frv_compare_op0 = operands[0];
- frv_compare_op1 = operands[1];
- DONE;
-}")
-
-;; Now, the actual comparisons, generated by the branch and/or scc operations
+;; The comparisons are generated by the branch and/or scc operations
(define_insn "cmpsi_cc"
[(set (match_operand:CC 0 "icc_operand" "=t,t")
@@ -3847,137 +3795,31 @@
;; ::::::::::::::::::::
;; Define_expands called by the machine independent part of the compiler
-;; to allocate a new comparison register. Each of these named patterns
-;; must be present, and they cannot be amalgamated into one pattern.
-;;
-;; If a fixed condition code register is being used, (as opposed to, say,
-;; using cc0), then the expands should look like this:
-;;
-;; (define_expand "<name_of_test>"
-;; [(set (reg:CC <number_of_CC_register>)
-;; (compare:CC (match_dup 1)
-;; (match_dup 2)))
-;; (set (pc)
-;; (if_then_else (eq:CC (reg:CC <number_of_CC_register>)
-;; (const_int 0))
-;; (label_ref (match_operand 0 "" ""))
-;; (pc)))]
-;; ""
-;; "{
-;; operands[1] = frv_compare_op0;
-;; operands[2] = frv_compare_op1;
-;; }"
-;; )
-
-(define_expand "beq"
- [(use (match_operand 0 "" ""))]
- ""
- "
-{
- if (! frv_emit_cond_branch (EQ, operands[0]))
- FAIL;
-
- DONE;
-}")
-
-(define_expand "bne"
- [(use (match_operand 0 "" ""))]
- ""
- "
-{
- if (! frv_emit_cond_branch (NE, operands[0]))
- FAIL;
-
- DONE;
-}")
-
-(define_expand "blt"
- [(use (match_operand 0 "" ""))]
- ""
- "
-{
- if (! frv_emit_cond_branch (LT, operands[0]))
- FAIL;
-
- DONE;
-}")
-
-(define_expand "ble"
- [(use (match_operand 0 "" ""))]
- ""
- "
-{
- if (! frv_emit_cond_branch (LE, operands[0]))
- FAIL;
-
- DONE;
-}")
-
-(define_expand "bgt"
- [(use (match_operand 0 "" ""))]
- ""
- "
-{
- if (! frv_emit_cond_branch (GT, operands[0]))
- FAIL;
-
- DONE;
-}")
-
-(define_expand "bge"
- [(use (match_operand 0 "" ""))]
- ""
- "
-{
- if (! frv_emit_cond_branch (GE, operands[0]))
- FAIL;
-
- DONE;
-}")
-
-(define_expand "bltu"
- [(use (match_operand 0 "" ""))]
- ""
- "
-{
- if (! frv_emit_cond_branch (LTU, operands[0]))
- FAIL;
-
- DONE;
-}")
-
-(define_expand "bleu"
- [(use (match_operand 0 "" ""))]
- ""
- "
-{
- if (! frv_emit_cond_branch (LEU, operands[0]))
- FAIL;
-
- DONE;
-}")
+;; to allocate a new comparison register.
-(define_expand "bgtu"
- [(use (match_operand 0 "" ""))]
- ""
- "
-{
- if (! frv_emit_cond_branch (GTU, operands[0]))
- FAIL;
+(define_expand "cbranchdf4"
+ [(use (match_operator 0 "ordered_comparison_operator"
+ [(match_operand:DF 1 "fpr_operand" "")
+ (match_operand:DF 2 "fpr_operand" "")]))
+ (use (match_operand 3 ""))]
+ "TARGET_HARD_FLOAT && TARGET_DOUBLE"
+ { if (frv_emit_cond_branch (operands)) DONE; gcc_unreachable (); })
- DONE;
-}")
+(define_expand "cbranchsf4"
+ [(use (match_operator 0 "ordered_comparison_operator"
+ [(match_operand:SF 1 "fpr_operand" "")
+ (match_operand:SF 2 "fpr_operand" "")]))
+ (use (match_operand 3 ""))]
+ "TARGET_HARD_FLOAT"
+ { if (frv_emit_cond_branch (operands)) DONE; gcc_unreachable (); })
-(define_expand "bgeu"
- [(use (match_operand 0 "" ""))]
+(define_expand "cbranchsi4"
+ [(use (match_operator 0 "ordered_comparison_operator"
+ [(match_operand:SI 1 "integer_register_operand" "")
+ (match_operand:SI 2 "gpr_or_int10_operand" "")]))
+ (use (match_operand 3 ""))]
""
- "
-{
- if (! frv_emit_cond_branch (GEU, operands[0]))
- FAIL;
-
- DONE;
-}")
+ { if (frv_emit_cond_branch (operands)) DONE; gcc_unreachable (); })
;; Actual branches. We must allow for the (label_ref) and the (pc) to be
;; swapped. If they are swapped, it reverses the sense of the branch.
@@ -4142,115 +3984,29 @@
;; Define_expands called by the machine independent part of the compiler
;; to allocate a new comparison register
-(define_expand "seq"
- [(match_operand:SI 0 "integer_register_operand" "")]
- "TARGET_SCC"
- "
-{
- if (! frv_emit_scc (EQ, operands[0]))
- FAIL;
-
- DONE;
-}")
-
-(define_expand "sne"
- [(match_operand:SI 0 "integer_register_operand" "")]
- "TARGET_SCC"
- "
-{
- if (! frv_emit_scc (NE, operands[0]))
- FAIL;
-
- DONE;
-}")
-
-(define_expand "slt"
- [(match_operand:SI 0 "integer_register_operand" "")]
- "TARGET_SCC"
- "
-{
- if (! frv_emit_scc (LT, operands[0]))
- FAIL;
-
- DONE;
-}")
-
-(define_expand "sle"
- [(match_operand:SI 0 "integer_register_operand" "")]
- "TARGET_SCC"
- "
-{
- if (! frv_emit_scc (LE, operands[0]))
- FAIL;
-
- DONE;
-}")
-
-(define_expand "sgt"
- [(match_operand:SI 0 "integer_register_operand" "")]
- "TARGET_SCC"
- "
-{
- if (! frv_emit_scc (GT, operands[0]))
- FAIL;
-
- DONE;
-}")
-
-(define_expand "sge"
- [(match_operand:SI 0 "integer_register_operand" "")]
- "TARGET_SCC"
- "
-{
- if (! frv_emit_scc (GE, operands[0]))
- FAIL;
-
- DONE;
-}")
-
-(define_expand "sltu"
- [(match_operand:SI 0 "integer_register_operand" "")]
- "TARGET_SCC"
- "
-{
- if (! frv_emit_scc (LTU, operands[0]))
- FAIL;
-
- DONE;
-}")
-
-(define_expand "sleu"
- [(match_operand:SI 0 "integer_register_operand" "")]
- "TARGET_SCC"
- "
-{
- if (! frv_emit_scc (LEU, operands[0]))
- FAIL;
-
- DONE;
-}")
-
-(define_expand "sgtu"
- [(match_operand:SI 0 "integer_register_operand" "")]
- "TARGET_SCC"
- "
-{
- if (! frv_emit_scc (GTU, operands[0]))
- FAIL;
-
- DONE;
-}")
+(define_expand "cstoredf4"
+ [(use (match_operator:SI 1 "ordered_comparison_operator"
+ [(match_operand:DF 2 "fpr_operand")
+ (match_operand:DF 3 "fpr_operand")]))
+ (clobber (match_operand:SI 0 "register_operand"))]
+ "TARGET_HARD_FLOAT && TARGET_DOUBLE"
+ { if (frv_emit_scc (operands)) DONE; else FAIL; })
-(define_expand "sgeu"
- [(match_operand:SI 0 "integer_register_operand" "")]
- "TARGET_SCC"
- "
-{
- if (! frv_emit_scc (GEU, operands[0]))
- FAIL;
+(define_expand "cstoresf4"
+ [(use (match_operator:SI 1 "ordered_comparison_operator"
+ [(match_operand:SF 2 "fpr_operand")
+ (match_operand:SF 3 "fpr_operand")]))
+ (clobber (match_operand:SI 0 "register_operand"))]
+ "TARGET_HARD_FLOAT"
+ { if (frv_emit_scc (operands)) DONE; else FAIL; })
- DONE;
-}")
+(define_expand "cstoresi4"
+ [(use (match_operator:SI 1 "ordered_comparison_operator"
+ [(match_operand:SI 2 "integer_register_operand")
+ (match_operand:SI 3 "gpr_or_int10_operand")]))
+ (clobber (match_operand:SI 0 "register_operand"))]
+ ""
+ { if (frv_emit_scc (operands)) DONE; else FAIL; })
(define_insn "*scc_int"
[(set (match_operand:SI 0 "integer_register_operand" "=d")
diff --git a/gcc/config/frv/predicates.md b/gcc/config/frv/predicates.md
index 5f7ef4edac9..4ecfa9aed45 100644
--- a/gcc/config/frv/predicates.md
+++ b/gcc/config/frv/predicates.md
@@ -239,8 +239,8 @@
subreg = SUBREG_REG (op);
code = GET_CODE (subreg);
if (code == MEM)
- return frv_legitimate_address_p (mode, XEXP (subreg, 0),
- reload_completed, FALSE, FALSE);
+ return frv_legitimate_address_p_1 (mode, XEXP (subreg, 0),
+ reload_completed, FALSE, FALSE);
return (code == REG);
@@ -278,8 +278,8 @@
subreg = SUBREG_REG (op);
code = GET_CODE (subreg);
if (code == MEM)
- return frv_legitimate_address_p (mode, XEXP (subreg, 0),
- reload_completed, FALSE, FALSE);
+ return frv_legitimate_address_p_1 (mode, XEXP (subreg, 0),
+ reload_completed, FALSE, FALSE);
return (code == REG);
@@ -334,8 +334,8 @@
subreg = SUBREG_REG (op);
code = GET_CODE (subreg);
if (code == MEM)
- return frv_legitimate_address_p (mode, XEXP (subreg, 0),
- reload_completed, TRUE, FALSE);
+ return frv_legitimate_address_p_1 (mode, XEXP (subreg, 0),
+ reload_completed, TRUE, FALSE);
return (code == REG);
@@ -373,8 +373,8 @@
subreg = SUBREG_REG (op);
code = GET_CODE (subreg);
if (code == MEM)
- return frv_legitimate_address_p (mode, XEXP (subreg, 0),
- reload_completed, TRUE, FALSE);
+ return frv_legitimate_address_p_1 (mode, XEXP (subreg, 0),
+ reload_completed, TRUE, FALSE);
return (code == REG);
@@ -599,7 +599,7 @@
if (GET_MODE (op) != mode && GET_MODE (op) != VOIDmode)
return FALSE;
- return frv_legitimate_address_p (DImode, op, reload_completed, FALSE, TRUE);
+ return frv_legitimate_address_p_1 (DImode, op, reload_completed, FALSE, TRUE);
})
;; TODO: Add a comment here.
diff --git a/gcc/config/h8300/h8300-protos.h b/gcc/config/h8300/h8300-protos.h
index 2e7b72fe6c4..35023c6236d 100644
--- a/gcc/config/h8300/h8300-protos.h
+++ b/gcc/config/h8300/h8300-protos.h
@@ -44,7 +44,8 @@ extern const char *output_logical_op (enum machine_mode, rtx *);
extern unsigned int compute_logical_op_length (enum machine_mode,
rtx *);
extern int compute_logical_op_cc (enum machine_mode, rtx *);
-extern void h8300_expand_branch (enum rtx_code, rtx);
+extern void h8300_expand_branch (rtx[]);
+extern void h8300_expand_store (rtx[]);
extern bool expand_a_shift (enum machine_mode, int, rtx[]);
extern int h8300_shift_needs_scratch_p (int, enum machine_mode);
extern int expand_a_rotate (rtx[]);
@@ -59,7 +60,6 @@ extern int same_cmp_preceding_p (rtx);
extern int same_cmp_following_p (rtx);
extern int h8300_legitimate_constant_p (rtx);
-extern int h8300_legitimate_address_p (enum machine_mode, rtx, int);
/* Used in builtins.c */
extern rtx h8300_return_addr_rtx (int, rtx);
diff --git a/gcc/config/h8300/h8300.c b/gcc/config/h8300/h8300.c
index 34d1f82687c..c3dd29723fe 100644
--- a/gcc/config/h8300/h8300.c
+++ b/gcc/config/h8300/h8300.c
@@ -1226,6 +1226,11 @@ h8300_rtx_costs (rtx x, int code, int outer_code, int *total, bool speed)
*total = 20;
return true;
+ case COMPARE:
+ if (XEXP (x, 1) == const0_rtx)
+ *total = 0;
+ return false;
+
case AND:
if (!h8300_dst_operand (XEXP (x, 0), VOIDmode)
|| !h8300_src_operand (XEXP (x, 1), VOIDmode))
@@ -3503,16 +3508,42 @@ compute_logical_op_cc (enum machine_mode mode, rtx *operands)
/* Expand a conditional branch. */
void
-h8300_expand_branch (enum rtx_code code, rtx label)
+h8300_expand_branch (rtx operands[])
{
+ enum rtx_code code = GET_CODE (operands[0]);
+ rtx op0 = operands[1];
+ rtx op1 = operands[2];
+ rtx label = operands[3];
rtx tmp;
+ tmp = gen_rtx_COMPARE (VOIDmode, op0, op1);
+ emit_insn (gen_rtx_SET (VOIDmode, cc0_rtx, tmp));
+
tmp = gen_rtx_fmt_ee (code, VOIDmode, cc0_rtx, const0_rtx);
tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
gen_rtx_LABEL_REF (VOIDmode, label),
pc_rtx);
emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
}
+
+
+/* Expand a conditional store. */
+
+void
+h8300_expand_store (rtx operands[])
+{
+ rtx dest = operands[0];
+ enum rtx_code code = GET_CODE (operands[1]);
+ rtx op0 = operands[2];
+ rtx op1 = operands[3];
+ rtx tmp;
+
+ tmp = gen_rtx_COMPARE (VOIDmode, op0, op1);
+ emit_insn (gen_rtx_SET (VOIDmode, cc0_rtx, tmp));
+
+ tmp = gen_rtx_fmt_ee (code, GET_MODE (dest), cc0_rtx, const0_rtx);
+ emit_insn (gen_rtx_SET (VOIDmode, dest, tmp));
+}
/* Shifts.
@@ -5232,7 +5263,7 @@ h8300_insert_attributes (tree node, tree *attributes)
tiny_data: This variable lives in the tiny data area and can be
referenced with 16-bit absolute memory references. */
-const struct attribute_spec h8300_attribute_table[] =
+static const struct attribute_spec h8300_attribute_table[] =
{
/* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
{ "interrupt_handler", 0, 0, true, false, false, h8300_handle_fndecl_attribute },
@@ -5655,8 +5686,8 @@ h8300_rtx_ok_for_base_p (rtx x, int strict)
legitimate address has the form REG, REG+CONSTANT_ADDRESS or
CONSTANT_ADDRESS. */
-int
-h8300_legitimate_address_p (enum machine_mode mode, rtx x, int strict)
+static bool
+h8300_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
{
/* The register indirect addresses like @er0 is always valid. */
if (h8300_rtx_ok_for_base_p (x, strict))
@@ -5764,6 +5795,9 @@ h8300_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
#undef TARGET_HARD_REGNO_SCRATCH_OK
#define TARGET_HARD_REGNO_SCRATCH_OK h8300_hard_regno_scratch_ok
+#undef TARGET_LEGITIMATE_ADDRESS_P
+#define TARGET_LEGITIMATE_ADDRESS_P h8300_legitimate_address_p
+
#undef TARGET_DEFAULT_TARGET_FLAGS
#define TARGET_DEFAULT_TARGET_FLAGS TARGET_DEFAULT
diff --git a/gcc/config/h8300/h8300.h b/gcc/config/h8300/h8300.h
index 7e3711323aa..dd95ed7253d 100644
--- a/gcc/config/h8300/h8300.h
+++ b/gcc/config/h8300/h8300.h
@@ -921,24 +921,6 @@ struct cum_arg
((C) == 'W')
-#ifndef REG_OK_STRICT
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
- do \
- { \
- if (h8300_legitimate_address_p ((MODE), (X), 0)) \
- goto ADDR; \
- } \
- while (0)
-#else
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
- do \
- { \
- if (h8300_legitimate_address_p ((MODE), (X), 1)) \
- goto ADDR; \
- } \
- while (0)
-#endif
-
/* Go to LABEL if ADDR (a legitimate address expression)
has an effect that depends on the machine mode it is used for.
diff --git a/gcc/config/h8300/h8300.md b/gcc/config/h8300/h8300.md
index 61f876c8399..c05e8c6966f 100644
--- a/gcc/config/h8300/h8300.md
+++ b/gcc/config/h8300/h8300.md
@@ -961,28 +961,33 @@
;; ----------------------------------------------------------------------
(define_insn ""
- [(set (cc0) (zero_extract:HI (match_operand:QI 0 "bit_memory_operand" "r,U")
- (const_int 1)
- (match_operand 1 "const_int_operand" "n,n")))]
+ [(set (cc0) (compare
+ (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "r,U")
+ (const_int 1)
+ (match_operand 1 "const_int_operand" "n,n"))
+ (const_int 0)))]
"TARGET_H8300"
"btst %Z1,%Y0"
[(set_attr "length" "2,4")
(set_attr "cc" "set_zn,set_zn")])
(define_insn ""
- [(set (cc0) (zero_extract:HI (match_operand:HI 0 "register_operand" "r")
- (const_int 1)
- (match_operand 1 "const_int_operand" "n")))]
+ [(set (cc0) (compare
+ (zero_extract:HI (match_operand:HI 0 "register_operand" "r")
+ (const_int 1)
+ (match_operand 1 "const_int_operand" "n"))
+ (const_int 0)))]
"TARGET_H8300"
"btst %Z1,%Y0"
[(set_attr "length" "2")
(set_attr "cc" "set_zn")])
(define_insn_and_split "*tst_extzv_1_n"
- [(set (cc0)
- (zero_extract:SI (match_operand:QI 0 "general_operand_src" "r,U,mn>")
- (const_int 1)
- (match_operand 1 "const_int_operand" "n,n,n")))
+ [(set (cc0) (compare
+ (zero_extract:SI (match_operand:QI 0 "general_operand_src" "r,U,mn>")
+ (const_int 1)
+ (match_operand 1 "const_int_operand" "n,n,n"))
+ (const_int 0)))
(clobber (match_scratch:QI 2 "=X,X,&r"))]
"(TARGET_H8300H || TARGET_H8300S)"
"@
@@ -993,18 +998,20 @@
&& !OK_FOR_U (operands[0])"
[(set (match_dup 2)
(match_dup 0))
- (parallel [(set (cc0) (zero_extract:SI (match_dup 2)
- (const_int 1)
- (match_dup 1)))
+ (parallel [(set (cc0) (compare (zero_extract:SI (match_dup 2)
+ (const_int 1)
+ (match_dup 1))
+ (const_int 0)))
(clobber (scratch:QI))])]
""
[(set_attr "length" "2,8,10")
(set_attr "cc" "set_zn,set_zn,set_zn")])
(define_insn ""
- [(set (cc0) (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
- (const_int 1)
- (match_operand 1 "const_int_operand" "n")))]
+ [(set (cc0) (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
+ (const_int 1)
+ (match_operand 1 "const_int_operand" "n"))
+ (const_int 0)))]
"(TARGET_H8300H || TARGET_H8300S)
&& INTVAL (operands[1]) <= 15"
"btst %Z1,%Y0"
@@ -1012,10 +1019,10 @@
(set_attr "cc" "set_zn")])
(define_insn_and_split "*tstsi_upper_bit"
- [(set (cc0)
- (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
- (const_int 1)
- (match_operand 1 "const_int_operand" "n")))
+ [(set (cc0) (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
+ (const_int 1)
+ (match_operand 1 "const_int_operand" "n"))
+ (const_int 0)))
(clobber (match_scratch:SI 2 "=&r"))]
"(TARGET_H8300H || TARGET_H8300S)
&& INTVAL (operands[1]) >= 16"
@@ -1026,18 +1033,18 @@
(const_int -65536))
(lshiftrt:SI (match_dup 0)
(const_int 16))))
- (set (cc0)
- (zero_extract:SI (match_dup 2)
- (const_int 1)
- (match_dup 3)))]
+ (set (cc0) (compare (zero_extract:SI (match_dup 2)
+ (const_int 1)
+ (match_dup 3))
+ (const_int 0)))]
"operands[3] = GEN_INT (INTVAL (operands[1]) - 16);")
(define_insn "*tstsi_variable_bit"
- [(set (cc0)
- (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
- (const_int 1)
- (and:SI (match_operand:SI 1 "register_operand" "r")
- (const_int 7))))]
+ [(set (cc0) (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
+ (const_int 1)
+ (and:SI (match_operand:SI 1 "register_operand" "r")
+ (const_int 7)))
+ (const_int 0)))]
"TARGET_H8300H || TARGET_H8300S"
"btst %w1,%w0"
[(set_attr "length" "2")
@@ -1045,10 +1052,12 @@
(define_insn_and_split "*tstsi_variable_bit_qi"
[(set (cc0)
- (zero_extract:SI (zero_extend:SI (match_operand:QI 0 "general_operand_src" "r,U,mn>"))
- (const_int 1)
- (and:SI (match_operand:SI 1 "register_operand" "r,r,r")
- (const_int 7))))
+ (compare
+ (zero_extract:SI (zero_extend:SI (match_operand:QI 0 "general_operand_src" "r,U,mn>"))
+ (const_int 1)
+ (and:SI (match_operand:SI 1 "register_operand" "r,r,r")
+ (const_int 7)))
+ (const_int 0)))
(clobber (match_scratch:QI 2 "=X,X,&r"))]
"(TARGET_H8300H || TARGET_H8300S)"
"@
@@ -1059,55 +1068,59 @@
&& !OK_FOR_U (operands[0])"
[(set (match_dup 2)
(match_dup 0))
- (parallel [(set (cc0) (zero_extract:SI (zero_extend:SI (match_dup 2))
- (const_int 1)
- (and:SI (match_dup 1)
- (const_int 7))))
+ (parallel [(set (cc0) (compare (zero_extract:SI (zero_extend:SI (match_dup 2))
+ (const_int 1)
+ (and:SI (match_dup 1)
+ (const_int 7)))
+ (const_int 0)))
(clobber (scratch:QI))])]
""
[(set_attr "length" "2,8,10")
(set_attr "cc" "set_zn,set_zn,set_zn")])
-(define_insn "tstqi"
- [(set (cc0) (match_operand:QI 0 "register_operand" "r"))]
+(define_insn "*tstqi"
+ [(set (cc0) (compare (match_operand:QI 0 "register_operand" "r")
+ (const_int 0)))]
""
"mov.b %X0,%X0"
[(set_attr "length" "2")
(set_attr "cc" "set_znv")])
-(define_insn "tsthi"
- [(set (cc0) (match_operand:HI 0 "register_operand" "r"))]
+(define_insn "*tsthi"
+ [(set (cc0) (compare (match_operand:HI 0 "register_operand" "r")
+ (const_int 0)))]
""
"mov.w %T0,%T0"
[(set_attr "length" "2")
(set_attr "cc" "set_znv")])
(define_insn "*tsthi_upper"
- [(set (cc0)
- (and:HI (match_operand:HI 0 "register_operand" "r")
- (const_int -256)))]
+ [(set (cc0) (compare (and:HI (match_operand:HI 0 "register_operand" "r")
+ (const_int -256))
+ (const_int 0)))]
""
"mov.b %t0,%t0"
[(set_attr "length" "2")
(set_attr "cc" "set_znv")])
-(define_insn "tstsi"
- [(set (cc0) (match_operand:SI 0 "register_operand" "r"))]
+(define_insn "*tstsi"
+ [(set (cc0) (compare (match_operand:SI 0 "register_operand" "r")
+ (const_int 0)))]
"TARGET_H8300H || TARGET_H8300S"
"mov.l %S0,%S0"
[(set_attr "length" "2")
(set_attr "cc" "set_znv")])
(define_insn "*tstsi_upper"
- [(set (cc0)
- (and:SI (match_operand:SI 0 "register_operand" "r")
- (const_int -65536)))]
+ [(set (cc0) (compare (and:SI (match_operand:SI 0 "register_operand" "r")
+ (const_int -65536))
+ (const_int 0)))]
""
"mov.w %e0,%e0"
[(set_attr "length" "2")
(set_attr "cc" "set_znv")])
-(define_insn "cmpqi"
+(define_insn "*cmpqi"
[(set (cc0)
(compare (match_operand:QI 0 "h8300_dst_operand" "rQ")
(match_operand:QI 1 "h8300_src_operand" "rQi")))]
@@ -1116,19 +1129,6 @@
[(set_attr "length_table" "addb")
(set_attr "cc" "compare")])
-(define_expand "cmphi"
- [(set (cc0)
- (compare (match_operand:HI 0 "h8300_dst_operand" "")
- (match_operand:HI 1 "h8300_src_operand" "")))]
- ""
- "
-{
- /* Force operand1 into a register if we're compiling
- for the H8/300. */
- if (GET_CODE (operands[1]) != REG && TARGET_H8300)
- operands[1] = force_reg (HImode, operands[1]);
-}")
-
(define_insn "*cmphi_h8300_znvc"
[(set (cc0)
(compare (match_operand:HI 0 "register_operand" "r")
@@ -2155,55 +2155,37 @@
;; Conditional jump instructions
-(define_expand "ble"
- [(match_operand 0 "" "")]
- ""
- "h8300_expand_branch (LE, operands[0]); DONE;")
-
-(define_expand "bleu"
- [(match_operand 0 "" "")]
+(define_expand "cbranchqi4"
+ [(use (match_operator 0 "ordered_comparison_operator"
+ [(match_operand:QI 1 "h8300_dst_operand" "")
+ (match_operand:QI 2 "h8300_src_operand" "")]))
+ (use (match_operand 3 ""))]
""
- "h8300_expand_branch (LEU, operands[0]); DONE;")
+ "h8300_expand_branch (operands); DONE;")
-(define_expand "bge"
- [(match_operand 0 "" "")]
+(define_expand "cbranchhi4"
+ [(use (match_operator 0 "ordered_comparison_operator"
+ [(match_operand:HI 1 "h8300_dst_operand" "")
+ (match_operand:HI 2 "h8300_src_operand" "")]))
+ (use (match_operand 3 ""))]
""
- "h8300_expand_branch (GE, operands[0]); DONE;")
-
-(define_expand "bgeu"
- [(match_operand 0 "" "")]
- ""
- "h8300_expand_branch (GEU, operands[0]); DONE;")
-
-(define_expand "blt"
- [(match_operand 0 "" "")]
- ""
- "h8300_expand_branch (LT, operands[0]); DONE;")
-
-(define_expand "bltu"
- [(match_operand 0 "" "")]
- ""
- "h8300_expand_branch (LTU, operands[0]); DONE;")
-
-(define_expand "bgt"
- [(match_operand 0 "" "")]
- ""
- "h8300_expand_branch (GT, operands[0]); DONE;")
-
-(define_expand "bgtu"
- [(match_operand 0 "" "")]
- ""
- "h8300_expand_branch (GTU, operands[0]); DONE;")
-
-(define_expand "beq"
- [(match_operand 0 "" "")]
- ""
- "h8300_expand_branch (EQ, operands[0]); DONE;")
+ "
+{
+ /* Force operand1 into a register if we're compiling
+ for the H8/300. */
+ if ((GET_CODE (operands[2]) != REG && operands[2] != const0_rtx)
+ && TARGET_H8300)
+ operands[2] = force_reg (HImode, operands[2]);
+ h8300_expand_branch (operands); DONE;
+}")
-(define_expand "bne"
- [(match_operand 0 "" "")]
- ""
- "h8300_expand_branch (NE, operands[0]); DONE;")
+(define_expand "cbranchsi4"
+ [(use (match_operator 0 "ordered_comparison_operator"
+ [(match_operand:SI 1 "h8300_dst_operand" "")
+ (match_operand:SI 2 "h8300_src_operand" "")]))
+ (use (match_operand 3 ""))]
+ "TARGET_H8300H || TARGET_H8300S"
+ "h8300_expand_branch (operands); DONE;")
(define_insn "branch_true"
[(set (pc)
@@ -3019,8 +3001,8 @@
(clobber (match_operand:QI 3 "register_operand" ""))]
"epilogue_completed
&& find_regno_note (insn, REG_DEAD, REGNO (operands[1]))"
- [(set (cc0)
- (match_dup 1))
+ [(set (cc0) (compare (match_dup 1)
+ (const_int 0)))
(set (pc)
(if_then_else (le (cc0) (const_int 0))
(label_ref (match_dup 5))
@@ -3032,8 +3014,8 @@
(clobber (scratch:QI))])
(set (match_dup 1)
(plus:QI (match_dup 1) (const_int -1)))
- (set (cc0)
- (match_dup 1))
+ (set (cc0) (compare (match_dup 1)
+ (const_int 0)))
(set (pc)
(if_then_else (ne (cc0) (const_int 0))
(label_ref (match_dup 4))
@@ -3052,8 +3034,8 @@
&& !find_regno_note (insn, REG_DEAD, REGNO (operands[1]))"
[(set (match_dup 3)
(match_dup 1))
- (set (cc0)
- (match_dup 3))
+ (set (cc0) (compare (match_dup 3)
+ (const_int 0)))
(set (pc)
(if_then_else (le (cc0) (const_int 0))
(label_ref (match_dup 5))
@@ -3065,8 +3047,8 @@
(clobber (scratch:QI))])
(set (match_dup 3)
(plus:QI (match_dup 3) (const_int -1)))
- (set (cc0)
- (match_dup 3))
+ (set (cc0) (compare (match_dup 3)
+ (const_int 0)))
(set (pc)
(if_then_else (ne (cc0) (const_int 0))
(label_ref (match_dup 4))
@@ -3413,17 +3395,29 @@
[(set_attr "cc" "none_0hit")
(set_attr "length_table" "bitfield")])
-(define_expand "seq"
- [(set (match_operand:HI 0 "register_operand" "")
- (eq:HI (cc0) (const_int 0)))]
+(define_expand "cstoreqi4"
+ [(use (match_operator 1 "eqne_operator"
+ [(match_operand:QI 2 "h8300_dst_operand" "")
+ (match_operand:QI 3 "h8300_src_operand" "")]))
+ (clobber (match_operand:HI 0 "register_operand"))]
"TARGET_H8300SX"
- "")
+ "h8300_expand_store (operands); DONE;")
-(define_expand "sne"
- [(set (match_operand:HI 0 "register_operand" "")
- (ne:HI (cc0) (const_int 0)))]
+(define_expand "cstorehi4"
+ [(use (match_operator 1 "eqne_operator"
+ [(match_operand:HI 2 "h8300_dst_operand" "")
+ (match_operand:HI 3 "h8300_src_operand" "")]))
+ (clobber (match_operand:HI 0 "register_operand"))]
"TARGET_H8300SX"
- "")
+ "h8300_expand_store (operands); DONE;")
+
+(define_expand "cstoresi4"
+ [(use (match_operator 1 "eqne_operator"
+ [(match_operand:SI 2 "h8300_dst_operand" "")
+ (match_operand:SI 3 "h8300_src_operand" "")]))
+ (clobber (match_operand:HI 0 "register_operand"))]
+ "TARGET_H8300SX"
+ "h8300_expand_store (operands); DONE;")
(define_insn "*bstzhireg"
[(set (match_operand:HI 0 "register_operand" "=r")
@@ -3451,13 +3445,7 @@
[(set (cc0) (match_dup 5))
(set (zero_extract:QI (match_dup 0) (const_int 1) (match_dup 1))
(match_op_dup:QI 2 [(cc0) (const_int 0)]))]
- "
-{
- if (operands[4] == const0_rtx && GET_CODE (operands[3]) == REG)
- operands[5] = operands[3];
- else
- operands[5] = gen_rtx_COMPARE (VOIDmode, operands[3], operands[4]);
-}"
+ "operands[5] = gen_rtx_COMPARE (VOIDmode, operands[3], operands[4]);"
[(set_attr "cc" "set_znv,compare")])
(define_insn "*bstz"
@@ -3499,13 +3487,7 @@
(if_then_else:QI
(match_op_dup 1 [(cc0) (const_int 0)])
(ior:QI (match_dup 4) (match_dup 5)) (match_dup 4)))]
- "
-{
- if (operands[3] == const0_rtx && GET_CODE (operands[2]) == REG)
- operands[6] = operands[2];
- else
- operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
-}"
+ "operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);"
[(set_attr "cc" "set_znv,compare")])
(define_insn "*condbset"
@@ -3541,13 +3523,7 @@
(if_then_else:QI
(match_op_dup 1 [(cc0) (const_int 0)])
(and:QI (match_dup 4) (match_dup 5)) (match_dup 4)))]
- "
-{
- if (operands[3] == const0_rtx && GET_CODE (operands[2]) == REG)
- operands[6] = operands[2];
- else
- operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
-}"
+ "operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);"
[(set_attr "cc" "set_znv,compare")])
(define_insn "*condbclr"
@@ -3587,13 +3563,7 @@
(ashift:QI (const_int 1)
(match_operand:QI 5 "register_operand" "r,r")))
(match_dup 4)))]
- "
-{
- if (operands[3] == const0_rtx && GET_CODE (operands[2]) == REG)
- operands[6] = operands[2];
- else
- operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
-}"
+ "operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);"
[(set_attr "cc" "set_znv,compare")])
(define_insn "*condbsetreg"
@@ -3634,13 +3604,7 @@
(ashift:QI (const_int 1)
(match_operand:QI 5 "register_operand" "r,r")))
(match_dup 4)))]
- "
-{
- if (operands[3] == const0_rtx && GET_CODE (operands[2]) == REG)
- operands[6] = operands[2];
- else
- operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
-}"
+ "operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);"
[(set_attr "cc" "set_znv,compare")])
(define_insn "*condbclrreg"
@@ -3878,10 +3842,10 @@
"(TARGET_H8300H || TARGET_H8300S)"
"#"
"&& reload_completed"
- [(set (cc0)
- (zero_extract:SI (match_dup 1)
- (const_int 1)
- (const_int 0)))
+ [(set (cc0) (compare (zero_extract:SI (match_dup 1)
+ (const_int 1)
+ (const_int 0))
+ (const_int 0)))
(set (pc)
(if_then_else (eq (cc0)
(const_int 0))
@@ -3901,10 +3865,10 @@
"(TARGET_H8300H || TARGET_H8300S)"
"#"
"&& reload_completed"
- [(set (cc0)
- (zero_extract:SI (match_dup 1)
- (const_int 1)
- (const_int 0)))
+ [(set (cc0) (compare (zero_extract:SI (match_dup 1)
+ (const_int 1)
+ (const_int 0))
+ (const_int 0)))
(set (pc)
(if_then_else (ne (cc0)
(const_int 0))
@@ -4398,8 +4362,8 @@
""
"#"
""
- [(set (cc0)
- (match_dup 0))
+ [(set (cc0) (compare (match_dup 0)
+ (const_int 0)))
(set (pc)
(if_then_else (ge (cc0)
(const_int 0))
@@ -4418,8 +4382,8 @@
""
"#"
""
- [(set (cc0)
- (match_dup 0))
+ [(set (cc0) (compare (match_dup 0)
+ (const_int 0)))
(set (pc)
(if_then_else (lt (cc0)
(const_int 0))
@@ -4852,8 +4816,8 @@
[(set (match_operand:HI 0 "register_operand" "")
(plus:HI (match_dup 0)
(match_operand 1 "incdec_operand" "")))
- (set (cc0)
- (match_dup 0))
+ (set (cc0) (compare (match_dup 0)
+ (const_int 0)))
(set (pc)
(if_then_else (match_operator 3 "eqne_operator"
[(cc0) (const_int 0)])
@@ -4864,8 +4828,8 @@
(unspec:HI [(match_dup 0)
(match_dup 1)]
UNSPEC_INCDEC))
- (set (cc0)
- (match_dup 0))
+ (set (cc0) (compare (match_dup 0)
+ (const_int 0)))
(set (pc)
(if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
(label_ref (match_dup 2))
@@ -4878,8 +4842,8 @@
[(set (match_operand:SI 0 "register_operand" "")
(plus:SI (match_dup 0)
(match_operand 1 "incdec_operand" "")))
- (set (cc0)
- (match_dup 0))
+ (set (cc0) (compare (match_dup 0)
+ (const_int 0)))
(set (pc)
(if_then_else (match_operator 3 "eqne_operator"
[(cc0) (const_int 0)])
@@ -4890,8 +4854,8 @@
(unspec:SI [(match_dup 0)
(match_dup 1)]
UNSPEC_INCDEC))
- (set (cc0)
- (match_dup 0))
+ (set (cc0) (compare (match_dup 0)
+ (const_int 0)))
(set (pc)
(if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
(label_ref (match_dup 2))
@@ -4900,9 +4864,10 @@
(define_peephole2
[(parallel [(set (cc0)
- (zero_extract:SI (match_operand:QI 0 "register_operand" "")
- (const_int 1)
- (const_int 7)))
+ (compare (zero_extract:SI (match_operand:QI 0 "register_operand" "")
+ (const_int 1)
+ (const_int 7))
+ (const_int 0)))
(clobber (scratch:QI))])
(set (pc)
(if_then_else (match_operator 1 "eqne_operator"
@@ -4910,8 +4875,8 @@
(label_ref (match_operand 2 "" ""))
(pc)))]
"(TARGET_H8300H || TARGET_H8300S)"
- [(set (cc0)
- (match_dup 0))
+ [(set (cc0) (compare (match_dup 0)
+ (const_int 0)))
(set (pc)
(if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
(label_ref (match_dup 2))
@@ -5032,6 +4997,45 @@
"operands[3] = gen_lowpart (HImode, operands[0]);
operands[4] = gen_lowpart (HImode, operands[1]);")
+;; Convert a memory comparison to a move if there is a scratch register.
+
+(define_peephole2
+ [(match_scratch:QI 1 "r")
+ (set (cc0)
+ (compare (match_operand:QI 0 "memory_operand" "")
+ (const_int 0)))]
+ ""
+ [(set (match_dup 1)
+ (match_dup 0))
+ (set (cc0) (compare (match_dup 1)
+ (const_int 0)))]
+ "")
+
+(define_peephole2
+ [(match_scratch:HI 1 "r")
+ (set (cc0)
+ (compare (match_operand:HI 0 "memory_operand" "")
+ (const_int 0)))]
+ "(TARGET_H8300H || TARGET_H8300S)"
+ [(set (match_dup 1)
+ (match_dup 0))
+ (set (cc0) (compare (match_dup 1)
+ (const_int 0)))]
+ "")
+
+(define_peephole2
+ [(match_scratch:SI 1 "r")
+ (set (cc0)
+ (compare (match_operand:SI 0 "memory_operand" "")
+ (const_int 0)))]
+ "(TARGET_H8300H || TARGET_H8300S)"
+ [(set (match_dup 1)
+ (match_dup 0))
+ (set (cc0) (compare (match_dup 1)
+ (const_int 0)))]
+ "")
+
+
;; (compare (reg:HI) (const_int)) takes 4 bytes, so we try to achieve
;; the equivalent with shorter sequences. Here is the summary. Cases
;; are grouped for each define_peephole2.
@@ -5073,13 +5077,14 @@
(label_ref (match_operand 2 "" ""))
(pc)))]
"(TARGET_H8300H || TARGET_H8300S)
+ && INTVAL (operands[1]) != 0
&& peep2_reg_dead_p (1, operands[0])"
[(set (match_dup 0)
(unspec:HI [(match_dup 0)
(match_dup 4)]
UNSPEC_INCDEC))
- (set (cc0)
- (match_dup 0))
+ (set (cc0) (compare (match_dup 0)
+ (const_int 0)))
(set (pc)
(if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
(label_ref (match_dup 2))
@@ -5113,8 +5118,8 @@
(ashiftrt:HI (match_dup 0)
(match_dup 4)))
(clobber (scratch:QI))])
- (set (cc0)
- (match_dup 0))
+ (set (cc0) (compare (match_dup 0)
+ (const_int 0)))
(set (pc)
(if_then_else (match_dup 2)
(label_ref (match_dup 3))
@@ -5148,8 +5153,8 @@
(ashiftrt:HI (match_dup 0)
(match_dup 4)))
(clobber (scratch:QI))])
- (set (cc0)
- (match_dup 0))
+ (set (cc0) (compare (match_dup 0)
+ (const_int 0)))
(set (pc)
(if_then_else (match_dup 5)
(label_ref (match_dup 3))
@@ -5182,9 +5187,9 @@
(label_ref (match_operand 2 "" ""))
(pc)))]
"TARGET_H8300H || TARGET_H8300S"
- [(set (cc0)
- (and:HI (match_dup 0)
- (const_int -256)))
+ [(set (cc0) (compare (and:HI (match_dup 0)
+ (const_int -256))
+ (const_int 0)))
(set (pc)
(if_then_else (match_dup 1)
(label_ref (match_dup 2))
@@ -5211,9 +5216,9 @@
(label_ref (match_operand 2 "" ""))
(pc)))]
"TARGET_H8300H || TARGET_H8300S"
- [(set (cc0)
- (and:HI (match_dup 0)
- (const_int -256)))
+ [(set (cc0) (compare (and:HI (match_dup 0)
+ (const_int -256))
+ (const_int 0)))
(set (pc)
(if_then_else (match_dup 3)
(label_ref (match_dup 2))
@@ -5307,13 +5312,14 @@
(label_ref (match_operand 2 "" ""))
(pc)))]
"(TARGET_H8300H || TARGET_H8300S)
+ && INTVAL (operands[1]) != 0
&& peep2_reg_dead_p (1, operands[0])"
[(set (match_dup 0)
(unspec:SI [(match_dup 0)
(match_dup 4)]
UNSPEC_INCDEC))
- (set (cc0)
- (match_dup 0))
+ (set (cc0) (compare (match_dup 0)
+ (const_int 0)))
(set (pc)
(if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
(label_ref (match_dup 2))
@@ -5348,8 +5354,8 @@
[(set (match_dup 0)
(plus:SI (match_dup 0)
(match_dup 4)))
- (set (cc0)
- (match_dup 0))
+ (set (cc0) (compare (match_dup 0)
+ (const_int 0)))
(set (pc)
(if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
(label_ref (match_dup 2))
@@ -5381,13 +5387,14 @@
&& ((INTVAL (operands[1]) & 0x00ff) == INTVAL (operands[1])
|| (INTVAL (operands[1]) & 0xff00) == INTVAL (operands[1])
|| INTVAL (operands[1]) == 0x0000ffff)
+ && INTVAL (operands[1]) != 0
&& INTVAL (operands[1]) != 1
&& INTVAL (operands[1]) != 2"
[(set (match_dup 0)
(xor:SI (match_dup 0)
(match_dup 1)))
- (set (cc0)
- (match_dup 0))
+ (set (cc0) (compare (match_dup 0)
+ (const_int 0)))
(set (pc)
(if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
(label_ref (match_dup 2))
@@ -5425,8 +5432,8 @@
(match_dup 4)))
(set (match_dup 0)
(not:SI (match_dup 0)))
- (set (cc0)
- (match_dup 0))
+ (set (cc0) (compare (match_dup 0)
+ (const_int 0)))
(set (pc)
(if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
(label_ref (match_dup 2))
@@ -5464,8 +5471,8 @@
(unspec:SI [(match_dup 0)
(const_int -1)]
UNSPEC_INCDEC))
- (set (cc0)
- (match_dup 0))
+ (set (cc0) (compare (match_dup 0)
+ (const_int 0)))
(set (pc)
(if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
(label_ref (match_dup 2))
@@ -5507,8 +5514,8 @@
(ashiftrt:SI (match_dup 4)
(match_dup 5)))
(clobber (scratch:QI))])
- (set (cc0)
- (match_dup 4))
+ (set (cc0) (compare (match_dup 4)
+ (const_int 0)))
(set (pc)
(if_then_else (match_dup 2)
(label_ref (match_dup 3))
@@ -5550,8 +5557,8 @@
(ashiftrt:SI (match_dup 4)
(match_dup 5)))
(clobber (scratch:QI))])
- (set (cc0)
- (match_dup 4))
+ (set (cc0) (compare (match_dup 4)
+ (const_int 0)))
(set (pc)
(if_then_else (match_dup 6)
(label_ref (match_dup 3))
@@ -5591,8 +5598,8 @@
(ashiftrt:SI (match_dup 0)
(match_dup 4)))
(clobber (scratch:QI))])
- (set (cc0)
- (match_dup 0))
+ (set (cc0) (compare (match_dup 0)
+ (const_int 0)))
(set (pc)
(if_then_else (match_dup 2)
(label_ref (match_dup 3))
@@ -5626,8 +5633,8 @@
(ashiftrt:SI (match_dup 0)
(match_dup 4)))
(clobber (scratch:QI))])
- (set (cc0)
- (match_dup 0))
+ (set (cc0) (compare (match_dup 0)
+ (const_int 0)))
(set (pc)
(if_then_else (match_dup 5)
(label_ref (match_dup 3))
@@ -5672,8 +5679,8 @@
[(set (match_dup 0)
(and:SI (match_dup 0)
(match_dup 4)))
- (set (cc0)
- (match_dup 0))
+ (set (cc0) (compare (match_dup 0)
+ (const_int 0)))
(set (pc)
(if_then_else (match_dup 2)
(label_ref (match_dup 3))
@@ -5712,8 +5719,8 @@
[(set (match_dup 0)
(and:SI (match_dup 0)
(match_dup 4)))
- (set (cc0)
- (match_dup 0))
+ (set (cc0) (compare (match_dup 0)
+ (const_int 0)))
(set (pc)
(if_then_else (match_dup 5)
(label_ref (match_dup 3))
@@ -5746,9 +5753,9 @@
(label_ref (match_operand 2 "" ""))
(pc)))]
"TARGET_H8300H || TARGET_H8300S"
- [(set (cc0)
- (and:SI (match_dup 0)
- (const_int -65536)))
+ [(set (cc0) (compare (and:SI (match_dup 0)
+ (const_int -65536))
+ (const_int 0)))
(set (pc)
(if_then_else (match_dup 1)
(label_ref (match_dup 2))
@@ -5775,9 +5782,9 @@
(label_ref (match_operand 2 "" ""))
(pc)))]
"TARGET_H8300H || TARGET_H8300S"
- [(set (cc0)
- (and:SI (match_dup 0)
- (const_int -65536)))
+ [(set (cc0) (compare (and:SI (match_dup 0)
+ (const_int -65536))
+ (const_int 0)))
(set (pc)
(if_then_else (match_dup 3)
(label_ref (match_dup 2))
@@ -5814,6 +5821,7 @@
(label_ref (match_operand 2 "" ""))
(pc)))]
"(TARGET_H8300H || TARGET_H8300S)
+ && INTVAL (operands[1]) != 0
&& !peep2_reg_dead_p (1, operands[0])
&& !same_cmp_following_p (insn)"
[(set (match_dup 4)
@@ -5822,8 +5830,8 @@
(unspec:SI [(match_dup 4)
(match_dup 5)]
UNSPEC_INCDEC))
- (set (cc0)
- (match_dup 4))
+ (set (cc0) (compare (match_dup 4)
+ (const_int 0)))
(set (pc)
(if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
(label_ref (match_dup 2))
@@ -5836,8 +5844,8 @@
[(set (match_operand:HI 0 "register_operand" "")
(and:HI (match_dup 0)
(match_operand:HI 1 "const_int_qi_operand" "")))
- (set (cc0)
- (match_dup 0))
+ (set (cc0) (compare (match_dup 0)
+ (const_int 0)))
(set (pc)
(if_then_else (match_operator 3 "eqne_operator"
[(cc0) (const_int 0)])
@@ -5847,8 +5855,8 @@
[(set (match_dup 4)
(and:QI (match_dup 4)
(match_dup 5)))
- (set (cc0)
- (match_dup 4))
+ (set (cc0) (compare (match_dup 4)
+ (const_int 0)))
(set (pc)
(if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
(label_ref (match_dup 2))
@@ -5860,8 +5868,8 @@
[(set (match_operand:SI 0 "register_operand" "")
(and:SI (match_dup 0)
(match_operand:SI 1 "const_int_qi_operand" "")))
- (set (cc0)
- (match_dup 0))
+ (set (cc0) (compare (match_dup 0)
+ (const_int 0)))
(set (pc)
(if_then_else (match_operator 3 "eqne_operator"
[(cc0) (const_int 0)])
@@ -5871,8 +5879,8 @@
[(set (match_dup 4)
(and:QI (match_dup 4)
(match_dup 5)))
- (set (cc0)
- (match_dup 4))
+ (set (cc0) (compare (match_dup 4)
+ (const_int 0)))
(set (pc)
(if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
(label_ref (match_dup 2))
@@ -5884,8 +5892,8 @@
[(set (match_operand:SI 0 "register_operand" "")
(and:SI (match_dup 0)
(match_operand:SI 1 "const_int_hi_operand" "")))
- (set (cc0)
- (match_dup 0))
+ (set (cc0) (compare (match_dup 0)
+ (const_int 0)))
(set (pc)
(if_then_else (match_operator 3 "eqne_operator"
[(cc0) (const_int 0)])
@@ -5895,8 +5903,8 @@
[(set (match_dup 4)
(and:HI (match_dup 4)
(match_dup 5)))
- (set (cc0)
- (match_dup 4))
+ (set (cc0) (compare (match_dup 4)
+ (const_int 0)))
(set (pc)
(if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
(label_ref (match_dup 2))
@@ -5911,8 +5919,8 @@
(set (match_dup 0)
(xor:SI (match_dup 0)
(match_operand:SI 2 "const_int_qi_operand" "")))
- (set (cc0)
- (match_dup 0))
+ (set (cc0) (compare (match_dup 0)
+ (const_int 0)))
(set (pc)
(if_then_else (match_operator 4 "eqne_operator"
[(cc0) (const_int 0)])
@@ -5926,8 +5934,8 @@
(set (match_dup 5)
(xor:QI (match_dup 5)
(match_dup 7)))
- (set (cc0)
- (match_dup 5))
+ (set (cc0) (compare (match_dup 5)
+ (const_int 0)))
(set (pc)
(if_then_else (match_op_dup 4 [(cc0) (const_int 0)])
(label_ref (match_dup 3))
@@ -6088,7 +6096,8 @@
(match_operand 2 "h8300_src_operand" "")))]
"TARGET_H8300SX
&& peep2_reg_dead_p (2, operands[0])
- && !reg_overlap_mentioned_p (operands[0], operands[2])"
+ && !reg_overlap_mentioned_p (operands[0], operands[2])
+ && operands[2] != const0_rtx"
[(set (cc0)
(compare (match_dup 1)
(match_dup 2)))])
diff --git a/gcc/config/i386/biarch32.h b/gcc/config/i386/biarch32.h
new file mode 100644
index 00000000000..d4f186d6cb7
--- /dev/null
+++ b/gcc/config/i386/biarch32.h
@@ -0,0 +1,29 @@
+/* Make configure files to produce biarch compiler defaulting to 32bit mode.
+ This file must be included very first, while the OS specific file later
+ to overwrite otherwise wrong defaults.
+ Copyright (C) 2009 Free Software Foundation, Inc.
+ Contributed by Kai Tietz <kai.tietz@onevision.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.
+
+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/>. */
+
+#define TARGET_64BIT_DEFAULT 0
+#define TARGET_BI_ARCH 1
diff --git a/gcc/config/i386/cpuid.h b/gcc/config/i386/cpuid.h
index b5258652ed2..2d0916fb36a 100644
--- a/gcc/config/i386/cpuid.h
+++ b/gcc/config/i386/cpuid.h
@@ -29,6 +29,7 @@
#define bit_CMPXCHG16B (1 << 13)
#define bit_SSE4_1 (1 << 19)
#define bit_SSE4_2 (1 << 20)
+#define bit_MOVBE (1 << 22)
#define bit_POPCNT (1 << 23)
#define bit_AES (1 << 25)
#define bit_XSAVE (1 << 26)
diff --git a/gcc/config/i386/cygming.opt b/gcc/config/i386/cygming.opt
index 7c29eb89b9f..e845a0d5827 100644
--- a/gcc/config/i386/cygming.opt
+++ b/gcc/config/i386/cygming.opt
@@ -45,3 +45,7 @@ Set Windows defines
mwindows
Target
Create GUI application
+
+mpe-aligned-commons
+Target Var(use_pe_aligned_common) Init(HAVE_GAS_ALIGNED_COMM)
+Use the GNU extension to the PE format for aligned common data
diff --git a/gcc/config/i386/driver-i386.c b/gcc/config/i386/driver-i386.c
index 69c6c0c7f3b..df0689db149 100644
--- a/gcc/config/i386/driver-i386.c
+++ b/gcc/config/i386/driver-i386.c
@@ -46,12 +46,15 @@ describe_cache (struct cache_desc level1, struct cache_desc level2)
/* At the moment, gcc does not use the information
about the associativity of the cache. */
- sprintf (size, "--param l1-cache-size=%u", level1.sizekb);
- sprintf (line, "--param l1-cache-line-size=%u", level1.line);
+ snprintf (size, sizeof (size),
+ "--param l1-cache-size=%u ", level1.sizekb);
+ snprintf (line, sizeof (line),
+ "--param l1-cache-line-size=%u ", level1.line);
- sprintf (size2, "--param l2-cache-size=%u", level2.sizekb);
+ snprintf (size2, sizeof (size2),
+ "--param l2-cache-size=%u ", level2.sizekb);
- return concat (size, " ", line, " ", size2, " ", NULL);
+ return concat (size, line, size2, NULL);
}
/* Detect L2 cache parameters using CPUID extended function 0x80000006. */
@@ -336,7 +339,11 @@ detect_caches_intel (bool xeon_mp, unsigned max_level, unsigned max_ext_level)
enum vendor_signatures
{
SIG_INTEL = 0x756e6547 /* Genu */,
- SIG_AMD = 0x68747541 /* Auth */,
+ SIG_AMD = 0x68747541 /* Auth */
+};
+
+enum processor_signatures
+{
SIG_GEODE = 0x646f6547 /* Geod */
};
@@ -374,6 +381,9 @@ const char *host_detect_local_cpu (int argc, const char **argv)
/* Extended features */
unsigned int has_lahf_lm = 0, has_sse4a = 0;
unsigned int has_longmode = 0, has_3dnowp = 0, has_3dnow = 0;
+ unsigned int has_movbe = 0, has_sse4_1 = 0, has_sse4_2 = 0;
+ unsigned int has_popcnt = 0, has_aes = 0, has_avx = 0;
+ unsigned int has_pclmul = 0;
bool arch;
@@ -391,13 +401,33 @@ const char *host_detect_local_cpu (int argc, const char **argv)
__cpuid (1, eax, ebx, ecx, edx);
- /* We don't care for extended family. */
model = (eax >> 4) & 0x0f;
family = (eax >> 8) & 0x0f;
+ if (vendor == SIG_INTEL)
+ {
+ unsigned int extended_model, extended_family;
+
+ extended_model = (eax >> 12) & 0xf0;
+ extended_family = (eax >> 20) & 0xff;
+ if (family == 0x0f)
+ {
+ family += extended_family;
+ model += extended_model;
+ }
+ else if (family == 0x06)
+ model += extended_model;
+ }
has_sse3 = ecx & bit_SSE3;
has_ssse3 = ecx & bit_SSSE3;
+ has_sse4_1 = ecx & bit_SSE4_1;
+ has_sse4_2 = ecx & bit_SSE4_2;
+ has_avx = ecx & bit_AVX;
has_cmpxchg16b = ecx & bit_CMPXCHG16B;
+ has_movbe = ecx & bit_MOVBE;
+ has_popcnt = ecx & bit_POPCNT;
+ has_aes = ecx & bit_AES;
+ has_pclmul = ecx & bit_PCLMUL;
has_cmpxchg8b = edx & bit_CMPXCHG8B;
has_cmov = edx & bit_CMOV;
@@ -433,19 +463,27 @@ const char *host_detect_local_cpu (int argc, const char **argv)
if (vendor == SIG_AMD)
{
- processor = PROCESSOR_PENTIUM;
+ unsigned int name;
- if (has_mmx)
- processor = PROCESSOR_K6;
- if (has_3dnowp)
- processor = PROCESSOR_ATHLON;
- if (has_sse2 || has_longmode)
- processor = PROCESSOR_K8;
- if (has_sse4a)
+ /* Detect geode processor by its processor signature. */
+ if (ext_level > 0x80000001)
+ __cpuid (0x80000002, name, ebx, ecx, edx);
+ else
+ name = 0;
+
+ if (name == SIG_GEODE)
+ processor = PROCESSOR_GEODE;
+ else if (has_sse4a)
processor = PROCESSOR_AMDFAM10;
+ else if (has_sse2 || has_longmode)
+ processor = PROCESSOR_K8;
+ else if (has_3dnowp)
+ processor = PROCESSOR_ATHLON;
+ else if (has_mmx)
+ processor = PROCESSOR_K6;
+ else
+ processor = PROCESSOR_PENTIUM;
}
- else if (vendor == SIG_GEODE)
- processor = PROCESSOR_GEODE;
else
{
switch (family)
@@ -484,8 +522,8 @@ const char *host_detect_local_cpu (int argc, const char **argv)
break;
case PROCESSOR_PENTIUMPRO:
if (has_longmode)
- /* It is Core 2 Duo. */
- cpu = "core2";
+ /* It is Core 2 or Atom. */
+ cpu = (model == 28) ? "atom" : "core2";
else if (arch)
{
if (has_sse3)
@@ -573,41 +611,38 @@ const char *host_detect_local_cpu (int argc, const char **argv)
if (arch)
{
if (has_cmpxchg16b)
- options = concat (options, "-mcx16 ", NULL);
+ options = concat (options, " -mcx16", NULL);
if (has_lahf_lm)
- options = concat (options, "-msahf ", NULL);
+ options = concat (options, " -msahf", NULL);
+ if (has_movbe)
+ options = concat (options, " -mmovbe", NULL);
+ if (has_aes)
+ options = concat (options, " -maes", NULL);
+ if (has_pclmul)
+ options = concat (options, " -mpclmul", NULL);
+ if (has_popcnt)
+ options = concat (options, " -mpopcnt", NULL);
+
+ if (has_avx)
+ options = concat (options, " -mavx", NULL);
+ else if (has_sse4_2)
+ options = concat (options, " -msse4.2", NULL);
+ else if (has_sse4_1)
+ options = concat (options, " -msse4.1", NULL);
}
done:
- return concat (cache, "-m", argv[0], "=", cpu, " ", options, NULL);
+ return concat (cache, "-m", argv[0], "=", cpu, options, NULL);
}
#else
-/* If we aren't compiling with GCC we just provide a minimal
- default value. */
+/* If we aren't compiling with GCC then the driver will just ignore
+ -march and -mtune "native" target and will leave to the newly
+ built compiler to generate code for its default target. */
-const char *host_detect_local_cpu (int argc, const char **argv)
+const char *host_detect_local_cpu (int argc ATTRIBUTE_UNUSED,
+ const char **argv ATTRIBUTE_UNUSED)
{
- const char *cpu;
- bool arch;
-
- if (argc < 1)
- return NULL;
-
- arch = !strcmp (argv[0], "arch");
-
- if (!arch && strcmp (argv[0], "tune"))
- return NULL;
-
- if (arch)
- {
- /* FIXME: i386 is wrong for 64bit compiler. How can we tell if
- we are generating 64bit or 32bit code? */
- cpu = "i386";
- }
- else
- cpu = "generic";
-
- return concat ("-m", argv[0], "=", cpu, NULL);
+ return NULL;
}
#endif /* __GNUC__ */
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index 803a9da7ca3..8ae5bd66b26 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -56,7 +56,6 @@ extern bool legitimate_constant_p (rtx);
extern bool constant_address_p (rtx);
extern bool legitimate_pic_operand_p (rtx);
extern int legitimate_pic_address_disp_p (rtx);
-extern int legitimate_address_p (enum machine_mode, rtx, int);
extern void print_reg (rtx, int, FILE*);
extern void print_operand (FILE*, rtx, int);
@@ -106,7 +105,7 @@ extern int ix86_match_ccmode (rtx, enum machine_mode);
extern rtx ix86_expand_compare (enum rtx_code, rtx *, rtx *);
extern int ix86_use_fcomi_compare (enum rtx_code);
extern void ix86_expand_branch (enum rtx_code, rtx);
-extern int ix86_expand_setcc (enum rtx_code, rtx);
+extern void ix86_expand_setcc (enum rtx_code, rtx);
extern int ix86_expand_int_movcc (rtx[]);
extern int ix86_expand_fp_movcc (rtx[]);
extern bool ix86_expand_fp_vcond (rtx[]);
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 073c24fb719..3e7199e83f7 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -1965,9 +1965,12 @@ static int ix86_isa_flags_explicit;
#define OPTION_MASK_ISA_ABM_SET \
(OPTION_MASK_ISA_ABM | OPTION_MASK_ISA_POPCNT)
+
#define OPTION_MASK_ISA_POPCNT_SET OPTION_MASK_ISA_POPCNT
#define OPTION_MASK_ISA_CX16_SET OPTION_MASK_ISA_CX16
#define OPTION_MASK_ISA_SAHF_SET OPTION_MASK_ISA_SAHF
+#define OPTION_MASK_ISA_MOVBE_SET OPTION_MASK_ISA_MOVBE
+#define OPTION_MASK_ISA_CRC32_SET OPTION_MASK_ISA_CRC32
/* Define a set of ISAs which aren't available when a given ISA is
disabled. MMX and SSE ISAs are handled separately. */
@@ -2009,6 +2012,8 @@ static int ix86_isa_flags_explicit;
#define OPTION_MASK_ISA_POPCNT_UNSET OPTION_MASK_ISA_POPCNT
#define OPTION_MASK_ISA_CX16_UNSET OPTION_MASK_ISA_CX16
#define OPTION_MASK_ISA_SAHF_UNSET OPTION_MASK_ISA_SAHF
+#define OPTION_MASK_ISA_MOVBE_UNSET OPTION_MASK_ISA_MOVBE
+#define OPTION_MASK_ISA_CRC32_UNSET OPTION_MASK_ISA_CRC32
/* Vectorization library interface and handlers. */
tree (*ix86_veclib_handler)(enum built_in_function, tree, tree) = NULL;
@@ -2299,6 +2304,32 @@ ix86_handle_option (size_t code, const char *arg ATTRIBUTE_UNUSED, int value)
}
return true;
+ case OPT_mmovbe:
+ if (value)
+ {
+ ix86_isa_flags |= OPTION_MASK_ISA_MOVBE_SET;
+ ix86_isa_flags_explicit |= OPTION_MASK_ISA_MOVBE_SET;
+ }
+ else
+ {
+ ix86_isa_flags &= ~OPTION_MASK_ISA_MOVBE_UNSET;
+ ix86_isa_flags_explicit |= OPTION_MASK_ISA_MOVBE_UNSET;
+ }
+ return true;
+
+ case OPT_mcrc32:
+ if (value)
+ {
+ ix86_isa_flags |= OPTION_MASK_ISA_CRC32_SET;
+ ix86_isa_flags_explicit |= OPTION_MASK_ISA_CRC32_SET;
+ }
+ else
+ {
+ ix86_isa_flags &= ~OPTION_MASK_ISA_CRC32_UNSET;
+ ix86_isa_flags_explicit |= OPTION_MASK_ISA_CRC32_UNSET;
+ }
+ return true;
+
case OPT_maes:
if (value)
{
@@ -2361,6 +2392,8 @@ ix86_target_string (int isa, int flags, const char *arch, const char *tune,
{ "-mmmx", OPTION_MASK_ISA_MMX },
{ "-mabm", OPTION_MASK_ISA_ABM },
{ "-mpopcnt", OPTION_MASK_ISA_POPCNT },
+ { "-mmovbe", OPTION_MASK_ISA_MOVBE },
+ { "-mcrc32", OPTION_MASK_ISA_CRC32 },
{ "-maes", OPTION_MASK_ISA_AES },
{ "-mpclmul", OPTION_MASK_ISA_PCLMUL },
};
@@ -2577,7 +2610,8 @@ override_options (bool main_args_p)
PTA_AES = 1 << 17,
PTA_PCLMUL = 1 << 18,
PTA_AVX = 1 << 19,
- PTA_FMA = 1 << 20
+ PTA_FMA = 1 << 20,
+ PTA_MOVBE = 1 << 21
};
static struct pta
@@ -2621,7 +2655,7 @@ override_options (bool main_args_p)
| PTA_SSSE3 | PTA_CX16},
{"atom", PROCESSOR_ATOM, CPU_ATOM,
PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3
- | PTA_SSSE3 | PTA_CX16},
+ | PTA_SSSE3 | PTA_CX16 | PTA_MOVBE},
{"geode", PROCESSOR_GEODE, CPU_GEODE,
PTA_MMX | PTA_3DNOW | PTA_3DNOW_A |PTA_PREFETCH_SSE},
{"k6", PROCESSOR_K6, CPU_K6, PTA_MMX},
@@ -2935,6 +2969,9 @@ override_options (bool main_args_p)
if (!(TARGET_64BIT && (processor_alias_table[i].flags & PTA_NO_SAHF))
&& !(ix86_isa_flags_explicit & OPTION_MASK_ISA_SAHF))
ix86_isa_flags |= OPTION_MASK_ISA_SAHF;
+ if (processor_alias_table[i].flags & PTA_MOVBE
+ && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_MOVBE))
+ ix86_isa_flags |= OPTION_MASK_ISA_MOVBE;
if (processor_alias_table[i].flags & PTA_AES
&& !(ix86_isa_flags_explicit & OPTION_MASK_ISA_AES))
ix86_isa_flags |= OPTION_MASK_ISA_AES;
@@ -4386,7 +4423,7 @@ ix86_function_regparm (const_tree type, const_tree decl)
if (TARGET_64BIT)
return (ix86_function_type_abi (type) == SYSV_ABI
- ? X86_64_REGPARM_MAX : X64_REGPARM_MAX);
+ ? X86_64_REGPARM_MAX : X86_64_MS_REGPARM_MAX);
regparm = ix86_regparm;
attr = lookup_attribute ("regparm", TYPE_ATTRIBUTES (type));
@@ -4629,8 +4666,8 @@ ix86_function_arg_regno_p (int regno)
parm_regs = x86_64_ms_abi_int_parameter_registers;
else
parm_regs = x86_64_int_parameter_registers;
- for (i = 0; i < (ix86_abi == MS_ABI ? X64_REGPARM_MAX
- : X86_64_REGPARM_MAX); i++)
+ for (i = 0; i < (ix86_abi == MS_ABI
+ ? X86_64_MS_REGPARM_MAX : X86_64_REGPARM_MAX); i++)
if (regno == parm_regs[i])
return true;
return false;
@@ -4756,8 +4793,8 @@ init_cumulative_args (CUMULATIVE_ARGS *cum, /* Argument info to initialize */
if (TARGET_64BIT)
{
if (cum->call_abi != ix86_abi)
- cum->nregs = ix86_abi != SYSV_ABI ? X86_64_REGPARM_MAX
- : X64_REGPARM_MAX;
+ cum->nregs = (ix86_abi != SYSV_ABI
+ ? X86_64_REGPARM_MAX : X86_64_MS_REGPARM_MAX);
}
if (TARGET_SSE)
{
@@ -4765,8 +4802,9 @@ init_cumulative_args (CUMULATIVE_ARGS *cum, /* Argument info to initialize */
if (TARGET_64BIT)
{
if (cum->call_abi != ix86_abi)
- cum->sse_nregs = ix86_abi != SYSV_ABI ? X86_64_SSE_REGPARM_MAX
- : X64_SSE_REGPARM_MAX;
+ cum->sse_nregs = (ix86_abi != SYSV_ABI
+ ? X86_64_SSE_REGPARM_MAX
+ : X86_64_MS_SSE_REGPARM_MAX);
}
}
if (TARGET_MMX)
@@ -5877,10 +5915,11 @@ function_arg_64 (CUMULATIVE_ARGS *cum, enum machine_mode mode,
return GEN_INT (cum->maybe_vaarg
? (cum->sse_nregs < 0
? (cum->call_abi == ix86_abi
- ? SSE_REGPARM_MAX
- : (ix86_abi != SYSV_ABI ? X86_64_SSE_REGPARM_MAX
- : X64_SSE_REGPARM_MAX))
- : cum->sse_regno)
+ ? SSE_REGPARM_MAX
+ : (ix86_abi != SYSV_ABI
+ ? X86_64_SSE_REGPARM_MAX
+ : X86_64_MS_SSE_REGPARM_MAX))
+ : cum->sse_regno)
: -1);
switch (mode)
@@ -6490,15 +6529,20 @@ ix86_build_builtin_va_list_abi (enum calling_abi abi)
return build_pointer_type (char_type_node);
record = (*lang_hooks.types.make_type) (RECORD_TYPE);
- type_decl = build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
+ type_decl = build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier ("__va_list_tag"), record);
- f_gpr = build_decl (FIELD_DECL, get_identifier ("gp_offset"),
+ f_gpr = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, get_identifier ("gp_offset"),
unsigned_type_node);
- f_fpr = build_decl (FIELD_DECL, get_identifier ("fp_offset"),
+ f_fpr = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, get_identifier ("fp_offset"),
unsigned_type_node);
- f_ovf = build_decl (FIELD_DECL, get_identifier ("overflow_arg_area"),
+ f_ovf = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, get_identifier ("overflow_arg_area"),
ptr_type_node);
- f_sav = build_decl (FIELD_DECL, get_identifier ("reg_save_area"),
+ f_sav = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, get_identifier ("reg_save_area"),
ptr_type_node);
va_list_gpr_counter_field = f_gpr;
@@ -6582,7 +6626,8 @@ setup_incoming_varargs_64 (CUMULATIVE_ARGS *cum)
int regparm = ix86_regparm;
if (cum->call_abi != ix86_abi)
- regparm = ix86_abi != SYSV_ABI ? X86_64_REGPARM_MAX : X64_REGPARM_MAX;
+ regparm = (ix86_abi != SYSV_ABI
+ ? X86_64_REGPARM_MAX : X86_64_MS_REGPARM_MAX);
/* GPR size of varargs save area. */
if (cfun->va_list_gpr_size)
@@ -6679,7 +6724,7 @@ setup_incoming_varargs_ms_64 (CUMULATIVE_ARGS *cum)
alias_set_type set = get_varargs_alias_set ();
int i;
- for (i = cum->regno; i < X64_REGPARM_MAX; i++)
+ for (i = cum->regno; i < X86_64_MS_REGPARM_MAX; i++)
{
rtx reg, mem;
@@ -6889,8 +6934,8 @@ ix86_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
bool need_temp;
tree int_addr, sse_addr;
- lab_false = create_artificial_label ();
- lab_over = create_artificial_label ();
+ lab_false = create_artificial_label (UNKNOWN_LOCATION);
+ lab_over = create_artificial_label (UNKNOWN_LOCATION);
examine_argument (nat_mode, type, 0, &needed_intregs, &needed_sseregs);
@@ -7412,10 +7457,12 @@ ix86_setup_frame_addresses (void)
cfun->machine->accesses_prev_frame = 1;
}
-#if (defined(HAVE_GAS_HIDDEN) && (SUPPORTS_ONE_ONLY - 0)) || TARGET_MACHO
-# define USE_HIDDEN_LINKONCE 1
-#else
-# define USE_HIDDEN_LINKONCE 0
+#ifndef USE_HIDDEN_LINKONCE
+# if (defined(HAVE_GAS_HIDDEN) && (SUPPORTS_ONE_ONLY - 0)) || TARGET_MACHO
+# define USE_HIDDEN_LINKONCE 1
+# else
+# define USE_HIDDEN_LINKONCE 0
+# endif
#endif
static int pic_labels_used;
@@ -7470,11 +7517,12 @@ ix86_file_end (void)
{
tree decl;
- decl = build_decl (FUNCTION_DECL, get_identifier (name),
+ decl = build_decl (BUILTINS_LOCATION,
+ FUNCTION_DECL, get_identifier (name),
error_mark_node);
TREE_PUBLIC (decl) = 1;
TREE_STATIC (decl) = 1;
- DECL_ONE_ONLY (decl) = 1;
+ DECL_COMDAT_GROUP (decl) = DECL_ASSEMBLER_NAME (decl);
(*targetm.asm_out.unique_section) (decl, 0);
switch_to_section (get_named_section (decl, NULL, 0));
@@ -7586,6 +7634,9 @@ output_set_got (rtx dest, rtx label ATTRIBUTE_UNUSED)
static rtx
gen_push (rtx arg)
{
+ if (ix86_cfa_state->reg == stack_pointer_rtx)
+ ix86_cfa_state->offset += UNITS_PER_WORD;
+
return gen_rtx_SET (VOIDmode,
gen_rtx_MEM (Pmode,
gen_rtx_PRE_DEC (Pmode,
@@ -7645,8 +7696,7 @@ ix86_save_reg (unsigned int regno, int maybe_eh_return)
}
}
- if (crtl->drap_reg
- && regno == REGNO (crtl->drap_reg))
+ if (crtl->drap_reg && regno == REGNO (crtl->drap_reg))
return 1;
return (df_regs_ever_live_p (regno)
@@ -7975,6 +8025,49 @@ ix86_emit_save_sse_regs_using_mov (rtx pointer, HOST_WIDE_INT offset)
}
}
+static GTY(()) rtx queued_cfa_restores;
+
+/* Add a REG_CFA_RESTORE REG note to INSN or queue them until next stack
+ manipulation insn. Don't add it if the previously
+ saved value will be left untouched within stack red-zone till return,
+ as unwinders can find the same value in the register and
+ on the stack. */
+
+static void
+ix86_add_cfa_restore_note (rtx insn, rtx reg, HOST_WIDE_INT red_offset)
+{
+ if (TARGET_RED_ZONE
+ && !TARGET_64BIT_MS_ABI
+ && red_offset + RED_ZONE_SIZE >= 0
+ && crtl->args.pops_args < 65536)
+ return;
+
+ if (insn)
+ {
+ add_reg_note (insn, REG_CFA_RESTORE, reg);
+ RTX_FRAME_RELATED_P (insn) = 1;
+ }
+ else
+ queued_cfa_restores
+ = alloc_reg_note (REG_CFA_RESTORE, reg, queued_cfa_restores);
+}
+
+/* Add queued REG_CFA_RESTORE notes if any to INSN. */
+
+static void
+ix86_add_queued_cfa_restore_notes (rtx insn)
+{
+ rtx last;
+ if (!queued_cfa_restores)
+ return;
+ for (last = queued_cfa_restores; XEXP (last, 1); last = XEXP (last, 1))
+ ;
+ XEXP (last, 1) = REG_NOTES (insn);
+ REG_NOTES (insn) = queued_cfa_restores;
+ queued_cfa_restores = NULL_RTX;
+ RTX_FRAME_RELATED_P (insn) = 1;
+}
+
/* Expand prologue or epilogue stack adjustment.
The pattern exist to put a dependency on all ebp-based memory accesses.
STYLE should be negative if instructions should be marked as frame related,
@@ -7982,7 +8075,8 @@ ix86_emit_save_sse_regs_using_mov (rtx pointer, HOST_WIDE_INT offset)
otherwise. */
static void
-pro_epilogue_adjust_stack (rtx dest, rtx src, rtx offset, int style)
+pro_epilogue_adjust_stack (rtx dest, rtx src, rtx offset,
+ int style, bool set_cfa)
{
rtx insn;
@@ -8005,7 +8099,24 @@ pro_epilogue_adjust_stack (rtx dest, rtx src, rtx offset, int style)
insn = emit_insn (gen_pro_epilogue_adjust_stack_rex64_2 (dest, src, r11,
offset));
}
- if (style < 0)
+
+ if (style >= 0)
+ ix86_add_queued_cfa_restore_notes (insn);
+
+ if (set_cfa)
+ {
+ rtx r;
+
+ gcc_assert (ix86_cfa_state->reg == src);
+ ix86_cfa_state->offset += INTVAL (offset);
+ ix86_cfa_state->reg = dest;
+
+ r = gen_rtx_PLUS (Pmode, src, offset);
+ r = gen_rtx_SET (VOIDmode, dest, r);
+ add_reg_note (insn, REG_CFA_ADJUST_CFA, r);
+ RTX_FRAME_RELATED_P (insn) = 1;
+ }
+ else if (style < 0)
RTX_FRAME_RELATED_P (insn) = 1;
}
@@ -8141,30 +8252,6 @@ ix86_internal_arg_pointer (void)
return virtual_incoming_args_rtx;
}
-/* Handle the TARGET_DWARF_HANDLE_FRAME_UNSPEC hook.
- This is called from dwarf2out.c to emit call frame instructions
- for frame-related insns containing UNSPECs and UNSPEC_VOLATILEs. */
-static void
-ix86_dwarf_handle_frame_unspec (const char *label, rtx pattern, int index)
-{
- rtx unspec = SET_SRC (pattern);
- gcc_assert (GET_CODE (unspec) == UNSPEC);
-
- switch (index)
- {
- case UNSPEC_REG_SAVE:
- dwarf2out_reg_save_reg (label, XVECEXP (unspec, 0, 0),
- SET_DEST (pattern));
- break;
- case UNSPEC_DEF_CFA:
- dwarf2out_def_cfa (label, REGNO (SET_DEST (pattern)),
- INTVAL (XVECEXP (unspec, 0, 0)));
- break;
- default:
- gcc_unreachable ();
- }
-}
-
/* Finalize stack_realign_needed flag, which will guide prologue/epilogue
to be generated in correct form. */
static void
@@ -8208,6 +8295,10 @@ ix86_expand_prologue (void)
/* DRAP should not coexist with stack_realign_fp */
gcc_assert (!(crtl->drap_reg && stack_realign_fp));
+ /* Initialize CFA state for before the prologue. */
+ ix86_cfa_state->reg = stack_pointer_rtx;
+ ix86_cfa_state->offset = INCOMING_FRAME_SP_OFFSET;
+
ix86_compute_frame_layout (&frame);
/* Emit prologue code to adjust stack alignment and setup DRAP, in case
@@ -8237,6 +8328,7 @@ ix86_expand_prologue (void)
insn = emit_insn (gen_rtx_SET (VOIDmode, y, x));
RTX_FRAME_RELATED_P (insn) = 1;
+ ix86_cfa_state->reg = crtl->drap_reg;
/* Align the stack. */
insn = emit_insn ((*ix86_gen_andsp) (stack_pointer_rtx,
@@ -8265,6 +8357,9 @@ ix86_expand_prologue (void)
insn = emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
RTX_FRAME_RELATED_P (insn) = 1;
+
+ if (ix86_cfa_state->reg == stack_pointer_rtx)
+ ix86_cfa_state->reg = hard_frame_pointer_rtx;
}
if (stack_realign_fp)
@@ -8303,7 +8398,8 @@ ix86_expand_prologue (void)
;
else if (! TARGET_STACK_PROBE || allocate < CHECK_STACK_LIMIT)
pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
- GEN_INT (-allocate), -1);
+ GEN_INT (-allocate), -1,
+ ix86_cfa_state->reg == stack_pointer_rtx);
else
{
/* Only valid for Win32. */
@@ -8331,10 +8427,15 @@ ix86_expand_prologue (void)
else
insn = gen_allocate_stack_worker_32 (eax, eax);
insn = emit_insn (insn);
- RTX_FRAME_RELATED_P (insn) = 1;
- t = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (-allocate));
- t = gen_rtx_SET (VOIDmode, stack_pointer_rtx, t);
- add_reg_note (insn, REG_FRAME_RELATED_EXPR, t);
+
+ if (ix86_cfa_state->reg == stack_pointer_rtx)
+ {
+ ix86_cfa_state->offset += allocate;
+ t = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (-allocate));
+ t = gen_rtx_SET (VOIDmode, stack_pointer_rtx, t);
+ add_reg_note (insn, REG_CFA_ADJUST_CFA, t);
+ RTX_FRAME_RELATED_P (insn) = 1;
+ }
if (eax_live)
{
@@ -8441,18 +8542,104 @@ ix86_expand_prologue (void)
emit_insn (gen_cld ());
}
+/* Emit code to restore REG using a POP insn. */
+
+static void
+ix86_emit_restore_reg_using_pop (rtx reg, HOST_WIDE_INT red_offset)
+{
+ rtx insn = emit_insn (ix86_gen_pop1 (reg));
+
+ if (ix86_cfa_state->reg == crtl->drap_reg
+ && REGNO (reg) == REGNO (crtl->drap_reg))
+ {
+ /* Previously we'd represented the CFA as an expression
+ like *(%ebp - 8). We've just popped that value from
+ the stack, which means we need to reset the CFA to
+ the drap register. This will remain until we restore
+ the stack pointer. */
+ add_reg_note (insn, REG_CFA_DEF_CFA, reg);
+ RTX_FRAME_RELATED_P (insn) = 1;
+ return;
+ }
+
+ if (ix86_cfa_state->reg == stack_pointer_rtx)
+ {
+ ix86_cfa_state->offset -= UNITS_PER_WORD;
+ add_reg_note (insn, REG_CFA_ADJUST_CFA,
+ copy_rtx (XVECEXP (PATTERN (insn), 0, 1)));
+ RTX_FRAME_RELATED_P (insn) = 1;
+ }
+
+ /* When the frame pointer is the CFA, and we pop it, we are
+ swapping back to the stack pointer as the CFA. This happens
+ for stack frames that don't allocate other data, so we assume
+ the stack pointer is now pointing at the return address, i.e.
+ the function entry state, which makes the offset be 1 word. */
+ else if (ix86_cfa_state->reg == hard_frame_pointer_rtx
+ && reg == hard_frame_pointer_rtx)
+ {
+ ix86_cfa_state->reg = stack_pointer_rtx;
+ ix86_cfa_state->offset = UNITS_PER_WORD;
+
+ add_reg_note (insn, REG_CFA_DEF_CFA,
+ gen_rtx_PLUS (Pmode, stack_pointer_rtx,
+ GEN_INT (UNITS_PER_WORD)));
+ RTX_FRAME_RELATED_P (insn) = 1;
+ }
+
+ ix86_add_cfa_restore_note (insn, reg, red_offset);
+}
+
+/* Emit code to restore saved registers using POP insns. */
+
+static void
+ix86_emit_restore_regs_using_pop (HOST_WIDE_INT red_offset)
+{
+ int regno;
+
+ for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
+ if (!SSE_REGNO_P (regno) && ix86_save_reg (regno, false))
+ {
+ ix86_emit_restore_reg_using_pop (gen_rtx_REG (Pmode, regno),
+ red_offset);
+ red_offset += UNITS_PER_WORD;
+ }
+}
+
+/* Emit code and notes for the LEAVE instruction. */
+
+static void
+ix86_emit_leave (HOST_WIDE_INT red_offset)
+{
+ rtx insn = emit_insn (ix86_gen_leave ());
+
+ ix86_add_queued_cfa_restore_notes (insn);
+
+ if (ix86_cfa_state->reg == hard_frame_pointer_rtx)
+ {
+ add_reg_note (insn, REG_CFA_ADJUST_CFA,
+ copy_rtx (XVECEXP (PATTERN (insn), 0, 0)));
+ RTX_FRAME_RELATED_P (insn) = 1;
+ ix86_add_cfa_restore_note (insn, hard_frame_pointer_rtx, red_offset);
+ }
+}
+
/* Emit code to restore saved registers using MOV insns. First register
is restored from POINTER + OFFSET. */
static void
ix86_emit_restore_regs_using_mov (rtx pointer, HOST_WIDE_INT offset,
+ HOST_WIDE_INT red_offset,
int maybe_eh_return)
{
- int regno;
+ unsigned int regno;
rtx base_address = gen_rtx_MEM (Pmode, pointer);
+ rtx insn;
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
if (!SSE_REGNO_P (regno) && ix86_save_reg (regno, maybe_eh_return))
{
+ rtx reg = gen_rtx_REG (Pmode, regno);
+
/* Ensure that adjust_address won't be forced to produce pointer
out of range allowed by x86-64 instruction set. */
if (TARGET_64BIT && offset != trunc_int_for_mode (offset, SImode))
@@ -8465,9 +8652,25 @@ ix86_emit_restore_regs_using_mov (rtx pointer, HOST_WIDE_INT offset,
base_address = gen_rtx_MEM (Pmode, r11);
offset = 0;
}
- emit_move_insn (gen_rtx_REG (Pmode, regno),
- adjust_address (base_address, Pmode, offset));
+ insn = emit_move_insn (reg,
+ adjust_address (base_address, Pmode, offset));
offset += UNITS_PER_WORD;
+
+ if (ix86_cfa_state->reg == crtl->drap_reg
+ && regno == REGNO (crtl->drap_reg))
+ {
+ /* Previously we'd represented the CFA as an expression
+ like *(%ebp - 8). We've just popped that value from
+ the stack, which means we need to reset the CFA to
+ the drap register. This will remain until we restore
+ the stack pointer. */
+ add_reg_note (insn, REG_CFA_DEF_CFA, reg);
+ RTX_FRAME_RELATED_P (insn) = 1;
+ }
+ else
+ ix86_add_cfa_restore_note (NULL_RTX, reg, red_offset);
+
+ red_offset += UNITS_PER_WORD;
}
}
@@ -8475,15 +8678,18 @@ ix86_emit_restore_regs_using_mov (rtx pointer, HOST_WIDE_INT offset,
is restored from POINTER + OFFSET. */
static void
ix86_emit_restore_sse_regs_using_mov (rtx pointer, HOST_WIDE_INT offset,
+ HOST_WIDE_INT red_offset,
int maybe_eh_return)
{
int regno;
rtx base_address = gen_rtx_MEM (TImode, pointer);
- rtx mem;
+ rtx mem, insn;
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
if (SSE_REGNO_P (regno) && ix86_save_reg (regno, maybe_eh_return))
{
+ rtx reg = gen_rtx_REG (TImode, regno);
+
/* Ensure that adjust_address won't be forced to produce pointer
out of range allowed by x86-64 instruction set. */
if (TARGET_64BIT && offset != trunc_int_for_mode (offset, SImode))
@@ -8498,8 +8704,12 @@ ix86_emit_restore_sse_regs_using_mov (rtx pointer, HOST_WIDE_INT offset,
}
mem = adjust_address (base_address, TImode, offset);
set_mem_align (mem, 128);
- emit_move_insn (gen_rtx_REG (TImode, regno), mem);
+ insn = emit_move_insn (reg, mem);
offset += 16;
+
+ ix86_add_cfa_restore_note (NULL_RTX, reg, red_offset);
+
+ red_offset += 16;
}
}
@@ -8508,10 +8718,11 @@ ix86_emit_restore_sse_regs_using_mov (rtx pointer, HOST_WIDE_INT offset,
void
ix86_expand_epilogue (int style)
{
- int regno;
int sp_valid;
struct ix86_frame frame;
- HOST_WIDE_INT offset;
+ HOST_WIDE_INT offset, red_offset;
+ struct machine_cfa_state cfa_state_save = *ix86_cfa_state;
+ bool using_drap;
ix86_finalize_stack_realign_flags ();
@@ -8527,6 +8738,9 @@ ix86_expand_epilogue (int style)
if (frame_pointer_needed && frame.red_zone_size)
emit_insn (gen_memory_blockage ());
+ using_drap = crtl->drap_reg && crtl->stack_realign_needed;
+ gcc_assert (!using_drap || ix86_cfa_state->reg == crtl->drap_reg);
+
/* Calculate start of saved registers relative to ebp. Special care
must be taken for the normal return case of a function using
eh_return: the eax and edx registers are marked as saved, but not
@@ -8537,6 +8751,19 @@ ix86_expand_epilogue (int style)
offset *= -UNITS_PER_WORD;
offset -= frame.nsseregs * 16 + frame.padding0;
+ /* Calculate start of saved registers relative to esp on entry of the
+ function. When realigning stack, this needs to be the most negative
+ value possible at runtime. */
+ red_offset = offset;
+ if (using_drap)
+ red_offset -= crtl->stack_alignment_needed / BITS_PER_UNIT
+ + UNITS_PER_WORD;
+ else if (stack_realign_fp)
+ red_offset -= crtl->stack_alignment_needed / BITS_PER_UNIT
+ - UNITS_PER_WORD;
+ if (frame_pointer_needed)
+ red_offset -= UNITS_PER_WORD;
+
/* If we're only restoring one register and sp is not valid then
using a move instruction to restore the register since it's
less work than reloading sp and popping the register.
@@ -8551,7 +8778,8 @@ ix86_expand_epilogue (int style)
|| (TARGET_EPILOGUE_USING_MOVE
&& cfun->machine->use_fast_prologue_epilogue
&& ((frame.nregs + frame.nsseregs) > 1 || frame.to_allocate))
- || (frame_pointer_needed && !(frame.nregs + frame.nsseregs) && frame.to_allocate)
+ || (frame_pointer_needed && !(frame.nregs + frame.nsseregs)
+ && frame.to_allocate)
|| (frame_pointer_needed && TARGET_USE_LEAVE
&& cfun->machine->use_fast_prologue_epilogue
&& (frame.nregs + frame.nsseregs) == 1)
@@ -8571,22 +8799,32 @@ ix86_expand_epilogue (int style)
|| stack_realign_fp)
{
ix86_emit_restore_sse_regs_using_mov (stack_pointer_rtx,
- frame.to_allocate, style == 2);
+ frame.to_allocate, red_offset,
+ style == 2);
ix86_emit_restore_regs_using_mov (stack_pointer_rtx,
frame.to_allocate
+ frame.nsseregs * 16
+ + frame.padding0,
+ red_offset
+ + frame.nsseregs * 16
+ frame.padding0, style == 2);
}
else
{
ix86_emit_restore_sse_regs_using_mov (hard_frame_pointer_rtx,
- offset, style == 2);
+ offset, red_offset,
+ style == 2);
ix86_emit_restore_regs_using_mov (hard_frame_pointer_rtx,
offset
+ frame.nsseregs * 16
+ + frame.padding0,
+ red_offset
+ + frame.nsseregs * 16
+ frame.padding0, style == 2);
}
+ red_offset -= offset;
+
/* eh_return epilogues need %ecx added to the stack pointer. */
if (style == 2)
{
@@ -8599,13 +8837,29 @@ ix86_expand_epilogue (int style)
{
tmp = gen_rtx_PLUS (Pmode, hard_frame_pointer_rtx, sa);
tmp = plus_constant (tmp, UNITS_PER_WORD);
- emit_insn (gen_rtx_SET (VOIDmode, sa, tmp));
+ tmp = emit_insn (gen_rtx_SET (VOIDmode, sa, tmp));
tmp = gen_rtx_MEM (Pmode, hard_frame_pointer_rtx);
- emit_move_insn (hard_frame_pointer_rtx, tmp);
+ tmp = emit_move_insn (hard_frame_pointer_rtx, tmp);
+
+ /* Note that we use SA as a temporary CFA, as the return
+ address is at the proper place relative to it. We
+ pretend this happens at the FP restore insn because
+ prior to this insn the FP would be stored at the wrong
+ offset relative to SA, and after this insn we have no
+ other reasonable register to use for the CFA. We don't
+ bother resetting the CFA to the SP for the duration of
+ the return insn. */
+ add_reg_note (tmp, REG_CFA_DEF_CFA,
+ plus_constant (sa, UNITS_PER_WORD));
+ ix86_add_queued_cfa_restore_notes (tmp);
+ add_reg_note (tmp, REG_CFA_RESTORE, hard_frame_pointer_rtx);
+ RTX_FRAME_RELATED_P (tmp) = 1;
+ ix86_cfa_state->reg = sa;
+ ix86_cfa_state->offset = UNITS_PER_WORD;
pro_epilogue_adjust_stack (stack_pointer_rtx, sa,
- const0_rtx, style);
+ const0_rtx, style, false);
}
else
{
@@ -8614,7 +8868,18 @@ ix86_expand_epilogue (int style)
+ frame.nregs * UNITS_PER_WORD
+ frame.nsseregs * 16
+ frame.padding0));
- emit_insn (gen_rtx_SET (VOIDmode, stack_pointer_rtx, tmp));
+ tmp = emit_insn (gen_rtx_SET (VOIDmode, stack_pointer_rtx, tmp));
+ ix86_add_queued_cfa_restore_notes (tmp);
+
+ gcc_assert (ix86_cfa_state->reg == stack_pointer_rtx);
+ if (ix86_cfa_state->offset != UNITS_PER_WORD)
+ {
+ ix86_cfa_state->offset = UNITS_PER_WORD;
+ add_reg_note (tmp, REG_CFA_DEF_CFA,
+ plus_constant (stack_pointer_rtx,
+ UNITS_PER_WORD));
+ RTX_FRAME_RELATED_P (tmp) = 1;
+ }
}
}
else if (!frame_pointer_needed)
@@ -8623,18 +8888,18 @@ ix86_expand_epilogue (int style)
+ frame.nregs * UNITS_PER_WORD
+ frame.nsseregs * 16
+ frame.padding0),
- style);
+ style, !using_drap);
/* If not an i386, mov & pop is faster than "leave". */
else if (TARGET_USE_LEAVE || optimize_function_for_size_p (cfun)
|| !cfun->machine->use_fast_prologue_epilogue)
- emit_insn ((*ix86_gen_leave) ());
+ ix86_emit_leave (red_offset);
else
{
pro_epilogue_adjust_stack (stack_pointer_rtx,
hard_frame_pointer_rtx,
- const0_rtx, style);
+ const0_rtx, style, !using_drap);
- emit_insn ((*ix86_gen_pop1) (hard_frame_pointer_rtx));
+ ix86_emit_restore_reg_using_pop (hard_frame_pointer_rtx, red_offset);
}
}
else
@@ -8652,32 +8917,36 @@ ix86_expand_epilogue (int style)
gcc_assert (!stack_realign_fp);
pro_epilogue_adjust_stack (stack_pointer_rtx,
hard_frame_pointer_rtx,
- GEN_INT (offset), style);
+ GEN_INT (offset), style, false);
ix86_emit_restore_sse_regs_using_mov (stack_pointer_rtx,
- frame.to_allocate, style == 2);
+ frame.to_allocate, red_offset,
+ style == 2);
pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
- GEN_INT (frame.nsseregs * 16), style);
+ GEN_INT (frame.nsseregs * 16),
+ style, false);
}
else if (frame.to_allocate || frame.nsseregs)
{
ix86_emit_restore_sse_regs_using_mov (stack_pointer_rtx,
- frame.to_allocate,
+ frame.to_allocate, red_offset,
style == 2);
pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
GEN_INT (frame.to_allocate
+ frame.nsseregs * 16
- + frame.padding0), style);
+ + frame.padding0), style,
+ !using_drap && !frame_pointer_needed);
}
- for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
- if (!SSE_REGNO_P (regno) && ix86_save_reg (regno, false))
- emit_insn ((*ix86_gen_pop1) (gen_rtx_REG (Pmode, regno)));
+ ix86_emit_restore_regs_using_pop (red_offset + frame.nsseregs * 16
+ + frame.padding0);
+ red_offset -= offset;
+
if (frame_pointer_needed)
{
/* Leave results in shorter dependency chains on CPUs that are
able to grok it fast. */
if (TARGET_USE_LEAVE)
- emit_insn ((*ix86_gen_leave) ());
+ ix86_emit_leave (red_offset);
else
{
/* For stack realigned really happens, recover stack
@@ -8686,47 +8955,71 @@ ix86_expand_epilogue (int style)
if (stack_realign_fp)
pro_epilogue_adjust_stack (stack_pointer_rtx,
hard_frame_pointer_rtx,
- const0_rtx, style);
- emit_insn ((*ix86_gen_pop1) (hard_frame_pointer_rtx));
+ const0_rtx, style, !using_drap);
+ ix86_emit_restore_reg_using_pop (hard_frame_pointer_rtx,
+ red_offset);
}
}
}
- if (crtl->drap_reg && crtl->stack_realign_needed)
+ if (using_drap)
{
int param_ptr_offset = (call_used_regs[REGNO (crtl->drap_reg)]
? 0 : UNITS_PER_WORD);
+ rtx insn;
+
gcc_assert (stack_realign_drap);
- emit_insn ((*ix86_gen_add3) (stack_pointer_rtx,
- crtl->drap_reg,
- GEN_INT (-(UNITS_PER_WORD
- + param_ptr_offset))));
- if (!call_used_regs[REGNO (crtl->drap_reg)])
- emit_insn ((*ix86_gen_pop1) (crtl->drap_reg));
-
+
+ insn = emit_insn ((*ix86_gen_add3) (stack_pointer_rtx,
+ crtl->drap_reg,
+ GEN_INT (-(UNITS_PER_WORD
+ + param_ptr_offset))));
+
+ ix86_cfa_state->reg = stack_pointer_rtx;
+ ix86_cfa_state->offset = UNITS_PER_WORD + param_ptr_offset;
+
+ add_reg_note (insn, REG_CFA_DEF_CFA,
+ gen_rtx_PLUS (Pmode, ix86_cfa_state->reg,
+ GEN_INT (ix86_cfa_state->offset)));
+ RTX_FRAME_RELATED_P (insn) = 1;
+
+ if (param_ptr_offset)
+ ix86_emit_restore_reg_using_pop (crtl->drap_reg, -UNITS_PER_WORD);
}
/* Sibcall epilogues don't want a return instruction. */
if (style == 0)
- return;
+ {
+ *ix86_cfa_state = cfa_state_save;
+ return;
+ }
if (crtl->args.pops_args && crtl->args.size)
{
rtx popc = GEN_INT (crtl->args.pops_args);
- /* i386 can only pop 64K bytes. If asked to pop more, pop
- return address, do explicit add, and jump indirectly to the
- caller. */
+ /* i386 can only pop 64K bytes. If asked to pop more, pop return
+ address, do explicit add, and jump indirectly to the caller. */
if (crtl->args.pops_args >= 65536)
{
rtx ecx = gen_rtx_REG (SImode, CX_REG);
+ rtx insn;
/* There is no "pascal" calling convention in any 64bit ABI. */
gcc_assert (!TARGET_64BIT);
- emit_insn (gen_popsi1 (ecx));
- emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, popc));
+ insn = emit_insn (gen_popsi1 (ecx));
+ ix86_cfa_state->offset -= UNITS_PER_WORD;
+
+ add_reg_note (insn, REG_CFA_ADJUST_CFA,
+ copy_rtx (XVECEXP (PATTERN (insn), 0, 1)));
+ add_reg_note (insn, REG_CFA_REGISTER,
+ gen_rtx_SET (VOIDmode, ecx, pc_rtx));
+ RTX_FRAME_RELATED_P (insn) = 1;
+
+ pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
+ popc, -1, true);
emit_jump_insn (gen_return_indirect_internal (ecx));
}
else
@@ -8734,6 +9027,10 @@ ix86_expand_epilogue (int style)
}
else
emit_jump_insn (gen_return_internal ());
+
+ /* Restore the state back to the state from the prologue,
+ so that it's correct for the next epilogue. */
+ *ix86_cfa_state = cfa_state_save;
}
/* Reset from the function's potential modifications. */
@@ -8877,6 +9174,10 @@ ix86_decompose_address (rtx addr, struct ix86_address *out)
base_reg = base && GET_CODE (base) == SUBREG ? SUBREG_REG (base) : base;
index_reg = index && GET_CODE (index) == SUBREG ? SUBREG_REG (index) : index;
+ /* Avoid useless 0 displacement. */
+ if (disp == const0_rtx && (base || index))
+ disp = NULL_RTX;
+
/* Allow arg pointer and stack pointer as index if there is not scaling. */
if (base_reg && index_reg && scale == 1
&& (index_reg == arg_pointer_rtx
@@ -8888,10 +9189,16 @@ ix86_decompose_address (rtx addr, struct ix86_address *out)
tmp = base_reg, base_reg = index_reg, index_reg = tmp;
}
- /* Special case: %ebp cannot be encoded as a base without a displacement. */
- if ((base_reg == hard_frame_pointer_rtx
- || base_reg == frame_pointer_rtx
- || base_reg == arg_pointer_rtx) && !disp)
+ /* Special case: %ebp cannot be encoded as a base without a displacement.
+ Similarly %r13. */
+ if (!disp
+ && base_reg
+ && (base_reg == hard_frame_pointer_rtx
+ || base_reg == frame_pointer_rtx
+ || base_reg == arg_pointer_rtx
+ || (REG_P (base_reg)
+ && (REGNO (base_reg) == HARD_FRAME_POINTER_REGNUM
+ || REGNO (base_reg) == R13_REG))))
disp = const0_rtx;
/* Special case: on K6, [%esi] makes the instruction vector decoded.
@@ -8905,7 +9212,7 @@ ix86_decompose_address (rtx addr, struct ix86_address *out)
disp = const0_rtx;
/* Special case: encode reg+reg instead of reg*2. */
- if (!base && index && scale && scale == 2)
+ if (!base && index && scale == 2)
base = index, base_reg = index_reg, scale = 1;
/* Special case: scaling cannot be encoded without base or displacement. */
@@ -9090,13 +9397,6 @@ ix86_cannot_force_const_mem (rtx x)
return !legitimate_constant_p (x);
}
-/* Determine if a given RTX is a valid constant address. */
-
-bool
-constant_address_p (rtx x)
-{
- return CONSTANT_P (x) && legitimate_address_p (Pmode, x, 1);
-}
/* Nonzero if the constant value X is a legitimate general operand
when generating PIC code. It is given that flag_pic is on and
@@ -9265,17 +9565,17 @@ legitimate_pic_address_disp_p (rtx disp)
return 0;
}
-/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression that is a valid
- memory address for an instruction. The MODE argument is the machine mode
- for the MEM expression that wants to use this address.
+/* Recognizes RTL expressions that are valid memory addresses for an
+ instruction. The MODE argument is the machine mode for the MEM
+ expression that wants to use this address.
It only recognizes address in canonical form. LEGITIMIZE_ADDRESS should
convert common non-canonical forms to canonical form so that they will
be recognized. */
-int
-legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED,
- rtx addr, int strict)
+static bool
+ix86_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED,
+ rtx addr, bool strict)
{
struct ix86_address parts;
rtx base, index, disp;
@@ -9499,6 +9799,14 @@ legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED,
report_error:
return FALSE;
}
+
+/* Determine if a given RTX is a valid constant address. */
+
+bool
+constant_address_p (rtx x)
+{
+ return CONSTANT_P (x) && ix86_legitimate_address_p (Pmode, x, 1);
+}
/* Return a unique alias set for the GOT. */
@@ -9526,7 +9834,7 @@ ix86_GOT_alias_set (void)
differentiate them from global data objects. The returned
address is the PIC reg + an unspec constant.
- GO_IF_LEGITIMATE_ADDRESS rejects symbolic references unless the PIC
+ TARGET_LEGITIMATE_ADDRESS_P rejects symbolic references unless the PIC
reg also appears in the address. */
static rtx
@@ -9955,7 +10263,8 @@ get_dllimport_decl (tree decl)
*loc = h = GGC_NEW (struct tree_map);
h->hash = in.hash;
h->base.from = decl;
- h->to = to = build_decl (VAR_DECL, NULL, ptr_type_node);
+ h->to = to = build_decl (DECL_SOURCE_LOCATION (decl),
+ VAR_DECL, NULL, ptr_type_node);
DECL_ARTIFICIAL (to) = 1;
DECL_IGNORED_P (to) = 1;
DECL_EXTERNAL (to) = 1;
@@ -10010,9 +10319,6 @@ legitimize_dllimport_symbol (rtx symbol, bool want_reg)
OLDX is the address as it was before break_out_memory_refs was called.
In some cases it is useful to look at this to decide what needs to be done.
- MODE and WIN are passed so that this macro can use
- GO_IF_LEGITIMATE_ADDRESS.
-
It is always safe for this macro to do nothing. It exists to recognize
opportunities to optimize the output.
@@ -10154,7 +10460,7 @@ ix86_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
}
}
- if (changed && legitimate_address_p (mode, x, FALSE))
+ if (changed && ix86_legitimate_address_p (mode, x, FALSE))
return x;
if (GET_CODE (XEXP (x, 0)) == MULT)
@@ -10180,7 +10486,7 @@ ix86_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
x = legitimize_pic_address (x, 0);
}
- if (changed && legitimate_address_p (mode, x, FALSE))
+ if (changed && ix86_legitimate_address_p (mode, x, FALSE))
return x;
if (REG_P (XEXP (x, 0)))
@@ -14949,15 +15255,12 @@ ix86_split_fp_branch (enum rtx_code code, rtx op1, rtx op2,
emit_label (label);
}
-int
+void
ix86_expand_setcc (enum rtx_code code, rtx dest)
{
rtx ret, tmp, tmpreg, equiv;
rtx second_test, bypass_test;
- if (GET_MODE (ix86_compare_op0) == (TARGET_64BIT ? TImode : DImode))
- return 0; /* FAIL */
-
gcc_assert (GET_MODE (dest) == QImode);
ret = ix86_expand_compare (code, &second_test, &bypass_test);
@@ -14996,8 +15299,6 @@ ix86_expand_setcc (enum rtx_code code, rtx dest)
ix86_compare_op0, ix86_compare_op1);
set_unique_reg_note (get_last_insn (), REG_EQUAL, equiv);
}
-
- return 1; /* DONE */
}
/* Expand comparison setting or clearing carry flag. Return true when
@@ -15145,6 +15446,8 @@ ix86_expand_int_movcc (rtx operands[])
bool sign_bit_compare_p = false;;
start_sequence ();
+ ix86_compare_op0 = XEXP (operands[1], 0);
+ ix86_compare_op1 = XEXP (operands[1], 1);
compare_op = ix86_expand_compare (code, &second_test, &bypass_test);
compare_seq = get_insns ();
end_sequence ();
@@ -15862,6 +16165,8 @@ ix86_expand_fp_movcc (rtx operands[])
enum rtx_code code = GET_CODE (operands[1]);
rtx tmp, compare_op, second_test, bypass_test;
+ ix86_compare_op0 = XEXP (operands[1], 0);
+ ix86_compare_op1 = XEXP (operands[1], 1);
if (TARGET_SSE_MATH && SSE_FLOAT_MODE_P (mode))
{
enum machine_mode cmode;
@@ -16389,6 +16694,8 @@ ix86_expand_int_addcc (rtx operands[])
bool fpcmp = false;
enum machine_mode mode = GET_MODE (operands[0]);
+ ix86_compare_op0 = XEXP (operands[1], 0);
+ ix86_compare_op1 = XEXP (operands[1], 1);
if (operands[3] != const1_rtx
&& operands[3] != constm1_rtx)
return 0;
@@ -17216,7 +17523,7 @@ counter_mode (rtx count_exp)
{
if (GET_MODE (count_exp) != VOIDmode)
return GET_MODE (count_exp);
- if (GET_CODE (count_exp) != CONST_INT)
+ if (!CONST_INT_P (count_exp))
return Pmode;
if (TARGET_64BIT && (INTVAL (count_exp) & ~0xffffffff))
return DImode;
@@ -19128,7 +19435,7 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1,
}
if (ix86_cmodel == CM_LARGE_PIC
- && GET_CODE (fnaddr) == MEM
+ && MEM_P (fnaddr)
&& GET_CODE (XEXP (fnaddr, 0)) == SYMBOL_REF
&& !local_symbolic_operand (XEXP (fnaddr, 0), VOIDmode))
fnaddr = gen_rtx_MEM (QImode, construct_plt_address (XEXP (fnaddr, 0)));
@@ -19311,23 +19618,53 @@ memory_address_length (rtx addr)
/* Rule of thumb:
- esp as the base always wants an index,
- - ebp as the base always wants a displacement. */
+ - ebp as the base always wants a displacement,
+ - r12 as the base always wants an index,
+ - r13 as the base always wants a displacement. */
/* Register Indirect. */
if (base && !index && !disp)
{
/* esp (for its index) and ebp (for its displacement) need
- the two-byte modrm form. */
- if (addr == stack_pointer_rtx
- || addr == arg_pointer_rtx
- || addr == frame_pointer_rtx
- || addr == hard_frame_pointer_rtx)
+ the two-byte modrm form. Similarly for r12 and r13 in 64-bit
+ code. */
+ if (REG_P (addr)
+ && (addr == arg_pointer_rtx
+ || addr == frame_pointer_rtx
+ || REGNO (addr) == SP_REG
+ || REGNO (addr) == BP_REG
+ || REGNO (addr) == R12_REG
+ || REGNO (addr) == R13_REG))
len = 1;
}
- /* Direct Addressing. */
+ /* Direct Addressing. In 64-bit mode mod 00 r/m 5
+ is not disp32, but disp32(%rip), so for disp32
+ SIB byte is needed, unless print_operand_address
+ optimizes it into disp32(%rip) or (%rip) is implied
+ by UNSPEC. */
else if (disp && !base && !index)
- len = 4;
+ {
+ len = 4;
+ if (TARGET_64BIT)
+ {
+ rtx symbol = disp;
+
+ if (GET_CODE (disp) == CONST)
+ symbol = XEXP (disp, 0);
+ if (GET_CODE (symbol) == PLUS
+ && CONST_INT_P (XEXP (symbol, 1)))
+ symbol = XEXP (symbol, 0);
+
+ if (GET_CODE (symbol) != LABEL_REF
+ && (GET_CODE (symbol) != SYMBOL_REF
+ || SYMBOL_REF_TLS_MODEL (symbol) != 0)
+ && (GET_CODE (symbol) != UNSPEC
+ || (XINT (symbol, 1) != UNSPEC_GOTPCREL
+ && XINT (symbol, 1) != UNSPEC_GOTNTPOFF)))
+ len += 1;
+ }
+ }
else
{
@@ -19339,19 +19676,31 @@ memory_address_length (rtx addr)
else
len = 4;
}
- /* ebp always wants a displacement. */
- else if (base == hard_frame_pointer_rtx)
- len = 1;
+ /* ebp always wants a displacement. Similarly r13. */
+ else if (REG_P (base)
+ && (REGNO (base) == BP_REG || REGNO (base) == R13_REG))
+ len = 1;
/* An index requires the two-byte modrm form.... */
if (index
- /* ...like esp, which always wants an index. */
- || base == stack_pointer_rtx
+ /* ...like esp (or r12), which always wants an index. */
|| base == arg_pointer_rtx
- || base == frame_pointer_rtx)
+ || base == frame_pointer_rtx
+ || (REG_P (base)
+ && (REGNO (base) == SP_REG || REGNO (base) == R12_REG)))
len += 1;
}
+ switch (parts.seg)
+ {
+ case SEG_FS:
+ case SEG_GS:
+ len += 1;
+ break;
+ default:
+ break;
+ }
+
return len;
}
@@ -19366,30 +19715,50 @@ ix86_attr_length_immediate_default (rtx insn, int shortform)
for (i = recog_data.n_operands - 1; i >= 0; --i)
if (CONSTANT_P (recog_data.operand[i]))
{
+ enum attr_mode mode = get_attr_mode (insn);
+
gcc_assert (!len);
- if (shortform && satisfies_constraint_K (recog_data.operand[i]))
- len = 1;
- else
+ if (shortform && CONST_INT_P (recog_data.operand[i]))
{
- switch (get_attr_mode (insn))
+ HOST_WIDE_INT ival = INTVAL (recog_data.operand[i]);
+ switch (mode)
{
- case MODE_QI:
- len+=1;
- break;
- case MODE_HI:
- len+=2;
- break;
- case MODE_SI:
- len+=4;
- break;
- /* Immediates for DImode instructions are encoded as 32bit sign extended values. */
- case MODE_DI:
- len+=4;
- break;
- default:
- fatal_insn ("unknown insn mode", insn);
+ case MODE_QI:
+ len = 1;
+ continue;
+ case MODE_HI:
+ ival = trunc_int_for_mode (ival, HImode);
+ break;
+ case MODE_SI:
+ ival = trunc_int_for_mode (ival, SImode);
+ break;
+ default:
+ break;
+ }
+ if (IN_RANGE (ival, -128, 127))
+ {
+ len = 1;
+ continue;
}
}
+ switch (mode)
+ {
+ case MODE_QI:
+ len = 1;
+ break;
+ case MODE_HI:
+ len = 2;
+ break;
+ case MODE_SI:
+ len = 4;
+ break;
+ /* Immediates for DImode instructions are encoded as 32bit sign extended values. */
+ case MODE_DI:
+ len = 4;
+ break;
+ default:
+ fatal_insn ("unknown insn mode", insn);
+ }
}
return len;
}
@@ -19401,22 +19770,45 @@ ix86_attr_length_address_default (rtx insn)
if (get_attr_type (insn) == TYPE_LEA)
{
- rtx set = PATTERN (insn);
+ rtx set = PATTERN (insn), addr;
if (GET_CODE (set) == PARALLEL)
set = XVECEXP (set, 0, 0);
gcc_assert (GET_CODE (set) == SET);
- return memory_address_length (SET_SRC (set));
+ addr = SET_SRC (set);
+ if (TARGET_64BIT && get_attr_mode (insn) == MODE_SI)
+ {
+ if (GET_CODE (addr) == ZERO_EXTEND)
+ addr = XEXP (addr, 0);
+ if (GET_CODE (addr) == SUBREG)
+ addr = SUBREG_REG (addr);
+ }
+
+ return memory_address_length (addr);
}
extract_insn_cached (insn);
for (i = recog_data.n_operands - 1; i >= 0; --i)
if (MEM_P (recog_data.operand[i]))
{
+ constrain_operands_cached (reload_completed);
+ if (which_alternative != -1)
+ {
+ const char *constraints = recog_data.constraints[i];
+ int alt = which_alternative;
+
+ while (*constraints == '=' || *constraints == '+')
+ constraints++;
+ while (alt-- > 0)
+ while (*constraints++ != ',')
+ ;
+ /* Skip ignored operands. */
+ if (*constraints == 'X')
+ continue;
+ }
return memory_address_length (XEXP (recog_data.operand[i], 0));
- break;
}
return 0;
}
@@ -19445,7 +19837,8 @@ ix86_attr_length_vex_default (rtx insn, int has_0f_opcode,
if (REG_P (recog_data.operand[i]))
{
/* REX.W bit uses 3 byte VEX prefix. */
- if (GET_MODE (recog_data.operand[i]) == DImode)
+ if (GET_MODE (recog_data.operand[i]) == DImode
+ && GENERAL_REG_P (recog_data.operand[i]))
return 3 + 1;
}
else
@@ -20378,6 +20771,16 @@ enum ix86_builtins
IX86_BUILTIN_MFENCE,
IX86_BUILTIN_LFENCE,
+ IX86_BUILTIN_BSRSI,
+ IX86_BUILTIN_BSRDI,
+ IX86_BUILTIN_RDPMC,
+ IX86_BUILTIN_RDTSC,
+ IX86_BUILTIN_RDTSCP,
+ IX86_BUILTIN_ROLQI,
+ IX86_BUILTIN_ROLHI,
+ IX86_BUILTIN_RORQI,
+ IX86_BUILTIN_RORHI,
+
/* SSE3. */
IX86_BUILTIN_ADDSUBPS,
IX86_BUILTIN_HADDPS,
@@ -21080,6 +21483,8 @@ enum ix86_special_builtin_type
{
SPECIAL_FTYPE_UNKNOWN,
VOID_FTYPE_VOID,
+ UINT64_FTYPE_VOID,
+ UINT64_FTYPE_PINT,
V32QI_FTYPE_PCCHAR,
V16QI_FTYPE_PCCHAR,
V8SF_FTYPE_PCV4SF,
@@ -21125,6 +21530,9 @@ enum ix86_builtin_type
INT_FTYPE_V4SF_V4SF_PTEST,
INT_FTYPE_V2DI_V2DI_PTEST,
INT_FTYPE_V2DF_V2DF_PTEST,
+ INT_FTYPE_INT,
+ UINT64_FTYPE_INT,
+ INT64_FTYPE_INT64,
INT64_FTYPE_V4SF,
INT64_FTYPE_V2DF,
INT_FTYPE_V16QI,
@@ -21235,6 +21643,8 @@ enum ix86_builtin_type
UINT_FTYPE_UINT_UINT,
UINT_FTYPE_UINT_USHORT,
UINT_FTYPE_UINT_UCHAR,
+ UINT16_FTYPE_UINT16_INT,
+ UINT8_FTYPE_UINT8_INT,
V8HI_FTYPE_V8HI_INT,
V4SI_FTYPE_V4SI_INT,
V4HI_FTYPE_V4HI_INT,
@@ -21273,6 +21683,9 @@ enum ix86_builtin_type
/* Special builtins with variable number of arguments. */
static const struct builtin_description bdesc_special_args[] =
{
+ { ~OPTION_MASK_ISA_64BIT, CODE_FOR_rdtsc, "__builtin_ia32_rdtsc", IX86_BUILTIN_RDTSC, UNKNOWN, (int) UINT64_FTYPE_VOID },
+ { ~OPTION_MASK_ISA_64BIT, CODE_FOR_rdtscp, "__builtin_ia32_rdtscp", IX86_BUILTIN_RDTSCP, UNKNOWN, (int) UINT64_FTYPE_PINT },
+
/* MMX */
{ OPTION_MASK_ISA_MMX, CODE_FOR_mmx_emms, "__builtin_ia32_emms", IX86_BUILTIN_EMMS, UNKNOWN, (int) VOID_FTYPE_VOID },
@@ -21353,6 +21766,14 @@ static const struct builtin_description bdesc_special_args[] =
/* Builtins with variable number of arguments. */
static const struct builtin_description bdesc_args[] =
{
+ { ~OPTION_MASK_ISA_64BIT, CODE_FOR_bsr, "__builtin_ia32_bsrsi", IX86_BUILTIN_BSRSI, UNKNOWN, (int) INT_FTYPE_INT },
+ { OPTION_MASK_ISA_64BIT, CODE_FOR_bsr_rex64, "__builtin_ia32_bsrdi", IX86_BUILTIN_BSRDI, UNKNOWN, (int) INT64_FTYPE_INT64 },
+ { ~OPTION_MASK_ISA_64BIT, CODE_FOR_rdpmc, "__builtin_ia32_rdpmc", IX86_BUILTIN_RDPMC, UNKNOWN, (int) UINT64_FTYPE_INT },
+ { ~OPTION_MASK_ISA_64BIT, CODE_FOR_rotlqi3, "__builtin_ia32_rolqi", IX86_BUILTIN_ROLQI, UNKNOWN, (int) UINT8_FTYPE_UINT8_INT },
+ { ~OPTION_MASK_ISA_64BIT, CODE_FOR_rotlhi3, "__builtin_ia32_rolhi", IX86_BUILTIN_ROLHI, UNKNOWN, (int) UINT16_FTYPE_UINT16_INT },
+ { ~OPTION_MASK_ISA_64BIT, CODE_FOR_rotrqi3, "__builtin_ia32_rorqi", IX86_BUILTIN_RORQI, UNKNOWN, (int) UINT8_FTYPE_UINT8_INT },
+ { ~OPTION_MASK_ISA_64BIT, CODE_FOR_rotrhi3, "__builtin_ia32_rorhi", IX86_BUILTIN_RORHI, UNKNOWN, (int) UINT16_FTYPE_UINT16_INT },
+
/* MMX */
{ OPTION_MASK_ISA_MMX, CODE_FOR_mmx_addv8qi3, "__builtin_ia32_paddb", IX86_BUILTIN_PADDB, UNKNOWN, (int) V8QI_FTYPE_V8QI_V8QI },
{ OPTION_MASK_ISA_MMX, CODE_FOR_mmx_addv4hi3, "__builtin_ia32_paddw", IX86_BUILTIN_PADDW, UNKNOWN, (int) V4HI_FTYPE_V4HI_V4HI },
@@ -21810,10 +22231,10 @@ static const struct builtin_description bdesc_args[] =
/* SSE4.2 */
{ OPTION_MASK_ISA_SSE4_2, CODE_FOR_sse4_2_gtv2di3, "__builtin_ia32_pcmpgtq", IX86_BUILTIN_PCMPGTQ, UNKNOWN, (int) V2DI_FTYPE_V2DI_V2DI },
- { OPTION_MASK_ISA_SSE4_2, CODE_FOR_sse4_2_crc32qi, "__builtin_ia32_crc32qi", IX86_BUILTIN_CRC32QI, UNKNOWN, (int) UINT_FTYPE_UINT_UCHAR },
- { OPTION_MASK_ISA_SSE4_2, CODE_FOR_sse4_2_crc32hi, "__builtin_ia32_crc32hi", IX86_BUILTIN_CRC32HI, UNKNOWN, (int) UINT_FTYPE_UINT_USHORT },
- { OPTION_MASK_ISA_SSE4_2, CODE_FOR_sse4_2_crc32si, "__builtin_ia32_crc32si", IX86_BUILTIN_CRC32SI, UNKNOWN, (int) UINT_FTYPE_UINT_UINT },
- { OPTION_MASK_ISA_SSE4_2 | OPTION_MASK_ISA_64BIT, CODE_FOR_sse4_2_crc32di, "__builtin_ia32_crc32di", IX86_BUILTIN_CRC32DI, UNKNOWN, (int) UINT64_FTYPE_UINT64_UINT64 },
+ { OPTION_MASK_ISA_SSE4_2 | OPTION_MASK_ISA_CRC32, CODE_FOR_sse4_2_crc32qi, "__builtin_ia32_crc32qi", IX86_BUILTIN_CRC32QI, UNKNOWN, (int) UINT_FTYPE_UINT_UCHAR },
+ { OPTION_MASK_ISA_SSE4_2 | OPTION_MASK_ISA_CRC32, CODE_FOR_sse4_2_crc32hi, "__builtin_ia32_crc32hi", IX86_BUILTIN_CRC32HI, UNKNOWN, (int) UINT_FTYPE_UINT_USHORT },
+ { OPTION_MASK_ISA_SSE4_2 | OPTION_MASK_ISA_CRC32, CODE_FOR_sse4_2_crc32si, "__builtin_ia32_crc32si", IX86_BUILTIN_CRC32SI, UNKNOWN, (int) UINT_FTYPE_UINT_UINT },
+ { OPTION_MASK_ISA_SSE4_2 | OPTION_MASK_ISA_CRC32 | OPTION_MASK_ISA_64BIT, CODE_FOR_sse4_2_crc32di, "__builtin_ia32_crc32di", IX86_BUILTIN_CRC32DI, UNKNOWN, (int) UINT64_FTYPE_UINT64_UINT64 },
/* SSE4A */
{ OPTION_MASK_ISA_SSE4A, CODE_FOR_sse4a_extrqi, "__builtin_ia32_extrqi", IX86_BUILTIN_EXTRQI, UNKNOWN, (int) V2DI_FTYPE_V2DI_UINT_UINT },
@@ -22997,6 +23418,34 @@ ix86_init_mmx_sse_builtins (void)
= build_function_type_list (V2DF_type_node,
V2DF_type_node, V2DI_type_node, NULL_TREE);
+ /* Integer intrinsics. */
+ tree uint64_ftype_void
+ = build_function_type (long_long_unsigned_type_node,
+ void_list_node);
+ tree int_ftype_int
+ = build_function_type_list (integer_type_node,
+ integer_type_node, NULL_TREE);
+ tree int64_ftype_int64
+ = build_function_type_list (long_long_integer_type_node,
+ long_long_integer_type_node,
+ NULL_TREE);
+ tree uint64_ftype_int
+ = build_function_type_list (long_long_unsigned_type_node,
+ integer_type_node, NULL_TREE);
+ tree uint64_ftype_pint
+ = build_function_type_list (long_long_unsigned_type_node,
+ pint_type_node, NULL_TREE);
+ tree ushort_ftype_ushort_int
+ = build_function_type_list (short_unsigned_type_node,
+ short_unsigned_type_node,
+ integer_type_node,
+ NULL_TREE);
+ tree uchar_ftype_uchar_int
+ = build_function_type_list (unsigned_char_type_node,
+ unsigned_char_type_node,
+ integer_type_node,
+ NULL_TREE);
+
tree ftype;
/* Add all special builtins with variable number of operands. */
@@ -23014,6 +23463,12 @@ ix86_init_mmx_sse_builtins (void)
case VOID_FTYPE_VOID:
type = void_ftype_void;
break;
+ case UINT64_FTYPE_VOID:
+ type = uint64_ftype_void;
+ break;
+ case UINT64_FTYPE_PINT:
+ type = uint64_ftype_pint;
+ break;
case V32QI_FTYPE_PCCHAR:
type = v32qi_ftype_pcchar;
break;
@@ -23144,6 +23599,15 @@ ix86_init_mmx_sse_builtins (void)
case INT_FTYPE_V2DF_V2DF_PTEST:
type = int_ftype_v2df_v2df;
break;
+ case INT_FTYPE_INT:
+ type = int_ftype_int;
+ break;
+ case UINT64_FTYPE_INT:
+ type = uint64_ftype_int;
+ break;
+ case INT64_FTYPE_INT64:
+ type = int64_ftype_int64;
+ break;
case INT64_FTYPE_V4SF:
type = int64_ftype_v4sf;
break;
@@ -23454,6 +23918,12 @@ ix86_init_mmx_sse_builtins (void)
case UINT_FTYPE_UINT_UCHAR:
type = unsigned_ftype_unsigned_uchar;
break;
+ case UINT16_FTYPE_UINT16_INT:
+ type = ushort_ftype_ushort_int;
+ break;
+ case UINT8_FTYPE_UINT8_INT:
+ type = uchar_ftype_uchar_int;
+ break;
case V8HI_FTYPE_V8HI_INT:
type = v8hi_ftype_v8hi_int;
break;
@@ -24049,7 +24519,7 @@ ix86_expand_multi_arg_builtin (enum insn_code icode, tree exp, rtx target,
if (last_arg_constant && i == nargs-1)
{
- if (GET_CODE (op) != CONST_INT)
+ if (!CONST_INT_P (op))
{
error ("last argument must be an immediate");
return gen_reg_rtx (tmode);
@@ -24533,6 +25003,9 @@ ix86_expand_args_builtin (const struct builtin_description *d,
return ix86_expand_sse_ptest (d, exp, target);
case FLOAT128_FTYPE_FLOAT128:
case FLOAT_FTYPE_FLOAT:
+ case INT_FTYPE_INT:
+ case UINT64_FTYPE_INT:
+ case INT64_FTYPE_INT64:
case INT64_FTYPE_V4SF:
case INT64_FTYPE_V2DF:
case INT_FTYPE_V16QI:
@@ -24658,6 +25131,8 @@ ix86_expand_args_builtin (const struct builtin_description *d,
case UINT_FTYPE_UINT_UINT:
case UINT_FTYPE_UINT_USHORT:
case UINT_FTYPE_UINT_UCHAR:
+ case UINT16_FTYPE_UINT16_INT:
+ case UINT8_FTYPE_UINT8_INT:
nargs = 2;
break;
case V2DI2TI_FTYPE_V2DI_INT:
@@ -24902,6 +25377,12 @@ ix86_expand_special_args_builtin (const struct builtin_description *d,
case VOID_FTYPE_VOID:
emit_insn (GEN_FCN (icode) (target));
return 0;
+ case UINT64_FTYPE_VOID:
+ nargs = 0;
+ klass = load;
+ memory = 0;
+ break;
+ case UINT64_FTYPE_PINT:
case V2DI_FTYPE_PV2DI:
case V32QI_FTYPE_PCCHAR:
case V16QI_FTYPE_PCCHAR:
@@ -25024,6 +25505,9 @@ ix86_expand_special_args_builtin (const struct builtin_description *d,
switch (nargs)
{
+ case 0:
+ pat = GEN_FCN (icode) (target);
+ break;
case 1:
pat = GEN_FCN (icode) (target, args[0].op);
break;
@@ -25539,7 +26023,8 @@ ix86_veclibabi_svml (enum built_in_function fn, tree type_out, tree type_in)
fntype = build_function_type_list (type_out, type_in, type_in, NULL);
/* Build a function declaration for the vectorized function. */
- new_fndecl = build_decl (FUNCTION_DECL, get_identifier (name), fntype);
+ new_fndecl = build_decl (BUILTINS_LOCATION,
+ FUNCTION_DECL, get_identifier (name), fntype);
TREE_PUBLIC (new_fndecl) = 1;
DECL_EXTERNAL (new_fndecl) = 1;
DECL_IS_NOVOPS (new_fndecl) = 1;
@@ -25623,7 +26108,8 @@ ix86_veclibabi_acml (enum built_in_function fn, tree type_out, tree type_in)
fntype = build_function_type_list (type_out, type_in, type_in, NULL);
/* Build a function declaration for the vectorized function. */
- new_fndecl = build_decl (FUNCTION_DECL, get_identifier (name), fntype);
+ new_fndecl = build_decl (BUILTINS_LOCATION,
+ FUNCTION_DECL, get_identifier (name), fntype);
TREE_PUBLIC (new_fndecl) = 1;
DECL_EXTERNAL (new_fndecl) = 1;
DECL_IS_NOVOPS (new_fndecl) = 1;
@@ -27194,6 +27680,7 @@ x86_function_profiler (FILE *file, int labelno ATTRIBUTE_UNUSED)
}
}
+#ifdef ASM_OUTPUT_MAX_SKIP_PAD
/* We don't have exact information about the insn sizes, but we may assume
quite safely that we are informed about all 1 byte insns and memory
address sizes. This is enough to eliminate unnecessary padding in
@@ -27202,7 +27689,7 @@ x86_function_profiler (FILE *file, int labelno ATTRIBUTE_UNUSED)
static int
min_insn_size (rtx insn)
{
- int l = 0;
+ int l = 0, len;
if (!INSN_P (insn) || !active_insn_p (insn))
return 0;
@@ -27211,9 +27698,7 @@ min_insn_size (rtx insn)
if (GET_CODE (PATTERN (insn)) == UNSPEC_VOLATILE
&& XINT (PATTERN (insn), 1) == UNSPECV_ALIGN)
return 0;
- if (JUMP_P (insn)
- && (GET_CODE (PATTERN (insn)) == ADDR_VEC
- || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC))
+ if (JUMP_TABLE_DATA_P (insn))
return 0;
/* Important case - calls are always 5 bytes.
@@ -27222,14 +27707,31 @@ min_insn_size (rtx insn)
&& symbolic_reference_mentioned_p (PATTERN (insn))
&& !SIBLING_CALL_P (insn))
return 5;
- if (get_attr_length (insn) <= 1)
+ len = get_attr_length (insn);
+ if (len <= 1)
return 1;
- /* For normal instructions we may rely on the sizes of addresses
- and the presence of symbol to require 4 bytes of encoding.
- This is not the case for jumps where references are PC relative. */
+ /* For normal instructions we rely on get_attr_length being exact,
+ with a few exceptions. */
if (!JUMP_P (insn))
{
+ enum attr_type type = get_attr_type (insn);
+
+ switch (type)
+ {
+ case TYPE_MULTI:
+ if (GET_CODE (PATTERN (insn)) == ASM_INPUT
+ || asm_noperands (PATTERN (insn)) >= 0)
+ return 0;
+ break;
+ case TYPE_OTHER:
+ case TYPE_FCMP:
+ break;
+ default:
+ /* Otherwise trust get_attr_length. */
+ return len;
+ }
+
l = get_attr_length_address (insn);
if (l < 4 && symbolic_reference_mentioned_p (PATTERN (insn)))
l = 4;
@@ -27244,7 +27746,7 @@ min_insn_size (rtx insn)
window. */
static void
-ix86_avoid_jump_misspredicts (void)
+ix86_avoid_jump_mispredicts (void)
{
rtx insn, start = get_insns ();
int nbytes = 0, njumps = 0;
@@ -27258,15 +27760,52 @@ ix86_avoid_jump_misspredicts (void)
The smallest offset in the page INSN can start is the case where START
ends on the offset 0. Offset of INSN is then NBYTES - sizeof (INSN).
- We add p2align to 16byte window with maxskip 17 - NBYTES + sizeof (INSN).
+ We add p2align to 16byte window with maxskip 15 - NBYTES + sizeof (INSN).
*/
- for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+ for (insn = start; insn; insn = NEXT_INSN (insn))
{
+ int min_size;
+
+ if (LABEL_P (insn))
+ {
+ int align = label_to_alignment (insn);
+ int max_skip = label_to_max_skip (insn);
+
+ if (max_skip > 15)
+ max_skip = 15;
+ /* If align > 3, only up to 16 - max_skip - 1 bytes can be
+ already in the current 16 byte page, because otherwise
+ ASM_OUTPUT_MAX_SKIP_ALIGN could skip max_skip or fewer
+ bytes to reach 16 byte boundary. */
+ if (align <= 0
+ || (align <= 3 && max_skip != (1 << align) - 1))
+ max_skip = 0;
+ if (dump_file)
+ fprintf (dump_file, "Label %i with max_skip %i\n",
+ INSN_UID (insn), max_skip);
+ if (max_skip)
+ {
+ while (nbytes + max_skip >= 16)
+ {
+ start = NEXT_INSN (start);
+ if ((JUMP_P (start)
+ && GET_CODE (PATTERN (start)) != ADDR_VEC
+ && GET_CODE (PATTERN (start)) != ADDR_DIFF_VEC)
+ || CALL_P (start))
+ njumps--, isjump = 1;
+ else
+ isjump = 0;
+ nbytes -= min_insn_size (start);
+ }
+ }
+ continue;
+ }
- nbytes += min_insn_size (insn);
+ min_size = min_insn_size (insn);
+ nbytes += min_size;
if (dump_file)
- fprintf(dump_file, "Insn %i estimated to %i bytes\n",
- INSN_UID (insn), min_insn_size (insn));
+ fprintf (dump_file, "Insn %i estimated to %i bytes\n",
+ INSN_UID (insn), min_size);
if ((JUMP_P (insn)
&& GET_CODE (PATTERN (insn)) != ADDR_VEC
&& GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC)
@@ -27290,7 +27829,7 @@ ix86_avoid_jump_misspredicts (void)
gcc_assert (njumps >= 0);
if (dump_file)
fprintf (dump_file, "Interval %i to %i has %i bytes\n",
- INSN_UID (start), INSN_UID (insn), nbytes);
+ INSN_UID (start), INSN_UID (insn), nbytes);
if (njumps == 3 && isjump && nbytes < 16)
{
@@ -27299,10 +27838,11 @@ ix86_avoid_jump_misspredicts (void)
if (dump_file)
fprintf (dump_file, "Padding insn %i by %i bytes!\n",
INSN_UID (insn), padsize);
- emit_insn_before (gen_align (GEN_INT (padsize)), insn);
+ emit_insn_before (gen_pad (GEN_INT (padsize)), insn);
}
}
}
+#endif
/* AMD Athlon works faster
when RET is not destination of conditional jump or directly preceded
@@ -27351,7 +27891,7 @@ ix86_pad_returns (void)
}
if (replace)
{
- emit_insn_before (gen_return_internal_long (), ret);
+ emit_jump_insn_before (gen_return_internal_long (), ret);
delete_insn (ret);
}
}
@@ -27362,12 +27902,15 @@ ix86_pad_returns (void)
static void
ix86_reorg (void)
{
- if (TARGET_PAD_RETURNS && optimize
- && optimize_function_for_speed_p (cfun))
- ix86_pad_returns ();
- if (TARGET_FOUR_JUMP_LIMIT && optimize
- && optimize_function_for_speed_p (cfun))
- ix86_avoid_jump_misspredicts ();
+ if (optimize && optimize_function_for_speed_p (cfun))
+ {
+ if (TARGET_PAD_RETURNS)
+ ix86_pad_returns ();
+#ifdef ASM_OUTPUT_MAX_SKIP_PAD
+ if (TARGET_FOUR_JUMP_LIMIT)
+ ix86_avoid_jump_mispredicts ();
+#endif
+ }
}
/* Return nonzero when QImode register that must be represented via REX prefix
@@ -28872,13 +29415,14 @@ void ix86_emit_i387_log1p (rtx op0, rtx op1)
rtx tmp = gen_reg_rtx (XFmode);
rtx tmp2 = gen_reg_rtx (XFmode);
+ rtx test;
emit_insn (gen_absxf2 (tmp, op1));
- emit_insn (gen_cmpxf (tmp,
+ test = gen_rtx_GE (VOIDmode, tmp,
CONST_DOUBLE_FROM_REAL_VALUE (
REAL_VALUE_ATOF ("0.29289321881345247561810596348408353", XFmode),
- XFmode)));
- emit_jump_insn (gen_bge (label1));
+ XFmode));
+ emit_jump_insn (gen_cbranchxf4 (test, XEXP (test, 0), XEXP (test, 1), label1));
emit_move_insn (tmp2, standard_80387_constant_rtx (4)); /* fldln2 */
emit_insn (gen_fyl2xp1xf3_i387 (op0, op1, tmp2));
@@ -30204,8 +30748,6 @@ ix86_enum_va_list (int idx, const char **pname, tree *ptree)
#define TARGET_UPDATE_STACK_BOUNDARY ix86_update_stack_boundary
#undef TARGET_GET_DRAP_RTX
#define TARGET_GET_DRAP_RTX ix86_get_drap_rtx
-#undef TARGET_DWARF_HANDLE_FRAME_UNSPEC
-#define TARGET_DWARF_HANDLE_FRAME_UNSPEC ix86_dwarf_handle_frame_unspec
#undef TARGET_STRICT_ARGUMENT_NAMING
#define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
@@ -30267,6 +30809,9 @@ ix86_enum_va_list (int idx, const char **pname, tree *ptree)
#undef TARGET_EXPAND_TO_RTL_HOOK
#define TARGET_EXPAND_TO_RTL_HOOK ix86_maybe_switch_abi
+#undef TARGET_LEGITIMATE_ADDRESS_P
+#define TARGET_LEGITIMATE_ADDRESS_P ix86_legitimate_address_p
+
struct gcc_target targetm = TARGET_INITIALIZER;
#include "gt-i386.h"
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 4aafd9c92fe..657c8ae3eef 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -59,6 +59,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#define TARGET_ABM OPTION_ISA_ABM
#define TARGET_POPCNT OPTION_ISA_POPCNT
#define TARGET_SAHF OPTION_ISA_SAHF
+#define TARGET_MOVBE OPTION_ISA_MOVBE
+#define TARGET_CRC32 OPTION_ISA_CRC32
#define TARGET_AES OPTION_ISA_AES
#define TARGET_PCLMUL OPTION_ISA_PCLMUL
#define TARGET_CMPXCHG16B OPTION_ISA_CX16
@@ -1803,12 +1805,12 @@ typedef struct ix86_args {
#define REG_OK_FOR_BASE_P(X) REG_OK_FOR_BASE_STRICT_P (X)
#endif
-/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
+/* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
that is a valid memory address for an instruction.
The MODE argument is the machine mode for the MEM expression
that wants to use this address.
- The other macros defined here are used only in GO_IF_LEGITIMATE_ADDRESS,
+ The other macros defined here are used only in TARGET_LEGITIMATE_ADDRESS_P,
except for CONSTANT_ADDRESS_P which is usually machine-independent.
See legitimize_pic_address in i386.c for details as to what
@@ -1823,22 +1825,6 @@ typedef struct ix86_args {
#define LEGITIMATE_CONSTANT_P(X) legitimate_constant_p (X)
-#ifdef REG_OK_STRICT
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
-do { \
- if (legitimate_address_p ((MODE), (X), 1)) \
- goto ADDR; \
-} while (0)
-
-#else
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
-do { \
- if (legitimate_address_p ((MODE), (X), 0)) \
- goto ADDR; \
-} while (0)
-
-#endif
-
/* If defined, a C expression to determine the base term of address X.
This macro is used in only one place: `find_base_term' in alias.c.
@@ -1868,20 +1854,22 @@ do { \
/* Abi specific values for REGPARM_MAX and SSE_REGPARM_MAX */
#define X86_64_REGPARM_MAX 6
-#define X64_REGPARM_MAX 4
-#define X86_32_REGPARM_MAX 3
+#define X86_64_MS_REGPARM_MAX 4
-#define X86_64_SSE_REGPARM_MAX 8
-#define X64_SSE_REGPARM_MAX 4
-#define X86_32_SSE_REGPARM_MAX (TARGET_SSE ? 3 : 0)
+#define X86_32_REGPARM_MAX 3
#define REGPARM_MAX \
- (TARGET_64BIT ? (TARGET_64BIT_MS_ABI ? X64_REGPARM_MAX \
+ (TARGET_64BIT ? (TARGET_64BIT_MS_ABI ? X86_64_MS_REGPARM_MAX \
: X86_64_REGPARM_MAX) \
: X86_32_REGPARM_MAX)
+#define X86_64_SSE_REGPARM_MAX 8
+#define X86_64_MS_SSE_REGPARM_MAX 4
+
+#define X86_32_SSE_REGPARM_MAX (TARGET_SSE ? 3 : 0)
+
#define SSE_REGPARM_MAX \
- (TARGET_64BIT ? (TARGET_64BIT_MS_ABI ? X64_SSE_REGPARM_MAX \
+ (TARGET_64BIT ? (TARGET_64BIT_MS_ABI ? X86_64_MS_SSE_REGPARM_MAX \
: X86_64_SSE_REGPARM_MAX) \
: X86_32_SSE_REGPARM_MAX)
@@ -2191,6 +2179,22 @@ do { \
#define ASM_OUTPUT_OPCODE(STREAM, PTR) \
ASM_OUTPUT_AVX_PREFIX ((STREAM), (PTR))
+/* A C statement to output to the stdio stream FILE an assembler
+ command to pad the location counter to a multiple of 1<<LOG
+ bytes if it is within MAX_SKIP bytes. */
+
+#ifdef HAVE_GAS_MAX_SKIP_P2ALIGN
+#undef ASM_OUTPUT_MAX_SKIP_PAD
+#define ASM_OUTPUT_MAX_SKIP_PAD(FILE, LOG, MAX_SKIP) \
+ if ((LOG) != 0) \
+ { \
+ if ((MAX_SKIP) == 0) \
+ fprintf ((FILE), "\t.p2align %d\n", (LOG)); \
+ else \
+ fprintf ((FILE), "\t.p2align %d,,%d\n", (LOG), (MAX_SKIP)); \
+ }
+#endif
+
/* Under some conditions we need jump tables in the text section,
because the assembler cannot handle label differences between
sections. This is the case for x86_64 on Mach-O for example. */
@@ -2392,6 +2396,15 @@ enum ix86_stack_slot
#define FASTCALL_PREFIX '@'
+/* Machine specific CFA tracking during prologue/epilogue generation. */
+
+#ifndef USED_FOR_TARGET
+struct GTY(()) machine_cfa_state
+{
+ rtx reg;
+ HOST_WIDE_INT offset;
+};
+
struct GTY(()) machine_function {
struct stack_local_entry *stack_locals;
const char *some_ld_name;
@@ -2418,8 +2431,10 @@ struct GTY(()) machine_function {
int tls_descriptor_call_expanded_p;
/* This value is used for amd64 targets and specifies the current abi
to be used. MS_ABI means ms abi. Otherwise SYSV_ABI means sysv abi. */
- enum calling_abi call_abi;
+ enum calling_abi call_abi;
+ struct machine_cfa_state cfa;
};
+#endif
#define ix86_stack_locals (cfun->machine->stack_locals)
#define ix86_varargs_gpr_size (cfun->machine->varargs_gpr_size)
@@ -2435,6 +2450,7 @@ struct GTY(()) machine_function {
REG_SP is live. */
#define ix86_current_function_calls_tls_descriptor \
(ix86_tls_descriptor_calls_expanded_in_cfun && df_regs_ever_live_p (SP_REG))
+#define ix86_cfa_state (&cfun->machine->cfa)
/* Control behavior of x86_file_start. */
#define X86_FILE_START_VERSION_DIRECTIVE false
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 1bb96fd07db..59d9e829ed0 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -101,7 +101,6 @@
(UNSPEC_ADD_CARRY 34)
(UNSPEC_FLDCW 35)
(UNSPEC_REP 36)
- (UNSPEC_EH_RETURN 37)
(UNSPEC_LD_MPIC 38) ; load_macho_picbase
(UNSPEC_TRUNC_NOOP 39)
@@ -245,6 +244,9 @@
(UNSPECV_CLD 15)
(UNSPECV_VZEROALL 16)
(UNSPECV_VZEROUPPER 17)
+ (UNSPECV_RDTSC 18)
+ (UNSPECV_RDTSCP 19)
+ (UNSPECV_RDPMC 20)
])
;; Constants to represent pcomtrue/pcomfalse variants
@@ -312,6 +314,7 @@
(R9_REG 38)
(R10_REG 39)
(R11_REG 40)
+ (R12_REG 41)
(R13_REG 42)
(XMM8_REG 45)
(XMM9_REG 46)
@@ -415,16 +418,23 @@
;; Set when length prefix is used.
(define_attr "prefix_data16" ""
- (if_then_else (ior (eq_attr "mode" "HI")
- (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
- (const_int 1)
- (const_int 0)))
+ (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
+ (const_int 0)
+ (eq_attr "mode" "HI")
+ (const_int 1)
+ (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
+ (const_int 1)
+ ]
+ (const_int 0)))
;; Set when string REP prefix is used.
(define_attr "prefix_rep" ""
- (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
- (const_int 1)
- (const_int 0)))
+ (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
+ (const_int 0)
+ (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
+ (const_int 1)
+ ]
+ (const_int 0)))
;; Set when 0f opcode prefix is used.
(define_attr "prefix_0f" ""
@@ -436,8 +446,11 @@
;; Set when REX opcode prefix is used.
(define_attr "prefix_rex" ""
- (cond [(and (eq_attr "mode" "DI")
- (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
+ (cond [(ne (symbol_ref "!TARGET_64BIT") (const_int 0))
+ (const_int 0)
+ (and (eq_attr "mode" "DI")
+ (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
+ (eq_attr "unit" "!mmx")))
(const_int 1)
(and (eq_attr "mode" "QI")
(ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
@@ -446,11 +459,23 @@
(ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
(const_int 0))
(const_int 1)
+ (and (eq_attr "type" "imovx")
+ (match_operand:QI 1 "ext_QIreg_operand" ""))
+ (const_int 1)
]
(const_int 0)))
-;; There are also additional prefixes in SSSE3.
-(define_attr "prefix_extra" "" (const_int 0))
+;; There are also additional prefixes in 3DNOW, SSSE3 or SSE5.
+;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
+;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
+;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
+(define_attr "prefix_extra" ""
+ (cond [(eq_attr "type" "ssemuladd,sse4arg")
+ (const_int 2)
+ (eq_attr "type" "sseiadd1,ssecvt1")
+ (const_int 1)
+ ]
+ (const_int 0)))
;; Prefix used: original, VEX or maybe VEX.
(define_attr "prefix" "orig,vex,maybe_vex"
@@ -458,15 +483,16 @@
(const_string "vex")
(const_string "orig")))
-;; There is a 8bit immediate for VEX.
-(define_attr "prefix_vex_imm8" "" (const_int 0))
-
;; VEX W bit is used.
(define_attr "prefix_vex_w" "" (const_int 0))
;; The length of VEX prefix
+;; Only instructions with 0f prefix can have 2 byte VEX prefix,
+;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
+;; still prefix_0f 1, with prefix_extra 1.
(define_attr "length_vex" ""
- (if_then_else (eq_attr "prefix_0f" "1")
+ (if_then_else (and (eq_attr "prefix_0f" "1")
+ (eq_attr "prefix_extra" "0"))
(if_then_else (eq_attr "prefix_vex_w" "1")
(symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
(symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
@@ -481,8 +507,9 @@
(eq_attr "unit" "i387")
(const_int 0)
(and (eq_attr "type" "incdec")
- (ior (match_operand:SI 1 "register_operand" "")
- (match_operand:HI 1 "register_operand" "")))
+ (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
+ (ior (match_operand:SI 1 "register_operand" "")
+ (match_operand:HI 1 "register_operand" ""))))
(const_int 0)
(and (eq_attr "type" "push")
(not (match_operand 1 "memory_operand" "")))
@@ -491,12 +518,13 @@
(not (match_operand 0 "memory_operand" "")))
(const_int 0)
(and (eq_attr "type" "imov")
- (ior (and (match_operand 0 "register_operand" "")
- (match_operand 1 "immediate_operand" ""))
- (ior (and (match_operand 0 "ax_reg_operand" "")
- (match_operand 1 "memory_displacement_only_operand" ""))
- (and (match_operand 0 "memory_displacement_only_operand" "")
- (match_operand 1 "ax_reg_operand" "")))))
+ (and (not (eq_attr "mode" "DI"))
+ (ior (and (match_operand 0 "register_operand" "")
+ (match_operand 1 "immediate_operand" ""))
+ (ior (and (match_operand 0 "ax_reg_operand" "")
+ (match_operand 1 "memory_displacement_only_operand" ""))
+ (and (match_operand 0 "memory_displacement_only_operand" "")
+ (match_operand 1 "ax_reg_operand" ""))))))
(const_int 0)
(and (eq_attr "type" "call")
(match_operand 0 "constant_call_address_operand" ""))
@@ -504,6 +532,9 @@
(and (eq_attr "type" "callv")
(match_operand 1 "constant_call_address_operand" ""))
(const_int 0)
+ (and (eq_attr "type" "alu,alu1,icmp,test")
+ (match_operand 0 "ax_reg_operand" ""))
+ (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
]
(const_int 1)))
@@ -524,7 +555,7 @@
(and (eq_attr "prefix" "maybe_vex")
(ne (symbol_ref "TARGET_AVX") (const_int 0))))
(plus (attr "length_vex")
- (plus (attr "prefix_vex_imm8")
+ (plus (attr "length_immediate")
(plus (attr "modrm")
(attr "length_address"))))]
(plus (plus (attr "modrm")
@@ -759,77 +790,183 @@
(include "constraints.md")
-;; Compare instructions.
+;; Compare and branch/compare and store instructions.
+
+(define_expand "cbranchti4"
+ [(set (reg:CC FLAGS_REG)
+ (compare:CC (match_operand:TI 1 "nonimmediate_operand" "")
+ (match_operand:TI 2 "x86_64_general_operand" "")))
+ (set (pc) (if_then_else
+ (match_operator 0 "comparison_operator"
+ [(reg:CC FLAGS_REG)
+ (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
+ "TARGET_64BIT"
+{
+ if (MEM_P (operands[1]) && MEM_P (operands[2]))
+ operands[1] = force_reg (TImode, operands[1]);
+ ix86_compare_op0 = operands[1];
+ ix86_compare_op1 = operands[2];
+ ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
+ DONE;
+})
-;; All compare insns have expanders that save the operands away without
-;; actually generating RTL. The bCOND or sCOND (emitted immediately
-;; after the cmp) will actually emit the cmpM.
+(define_expand "cbranchdi4"
+ [(set (reg:CC FLAGS_REG)
+ (compare:CC (match_operand:DI 1 "nonimmediate_operand" "")
+ (match_operand:DI 2 "x86_64_general_operand" "")))
+ (set (pc) (if_then_else
+ (match_operator 0 "comparison_operator"
+ [(reg:CC FLAGS_REG)
+ (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
+ ""
+{
+ if (MEM_P (operands[1]) && MEM_P (operands[2]))
+ operands[1] = force_reg (DImode, operands[1]);
+ ix86_compare_op0 = operands[1];
+ ix86_compare_op1 = operands[2];
+ ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
+ DONE;
+})
-(define_expand "cmpti"
+(define_expand "cstoredi4"
[(set (reg:CC FLAGS_REG)
- (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
- (match_operand:TI 1 "x86_64_general_operand" "")))]
+ (compare:CC (match_operand:DI 2 "nonimmediate_operand" "")
+ (match_operand:DI 3 "x86_64_general_operand" "")))
+ (set (match_operand:QI 0 "register_operand" "")
+ (match_operator 1 "comparison_operator"
+ [(reg:CC FLAGS_REG)
+ (const_int 0)]))]
"TARGET_64BIT"
{
- if (MEM_P (operands[0]) && MEM_P (operands[1]))
- operands[0] = force_reg (TImode, operands[0]);
- ix86_compare_op0 = operands[0];
- ix86_compare_op1 = operands[1];
+ if (MEM_P (operands[2]) && MEM_P (operands[3]))
+ operands[2] = force_reg (DImode, operands[2]);
+ ix86_compare_op0 = operands[2];
+ ix86_compare_op1 = operands[3];
+ ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
DONE;
})
-(define_expand "cmpdi"
+(define_expand "cbranchsi4"
[(set (reg:CC FLAGS_REG)
- (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
- (match_operand:DI 1 "x86_64_general_operand" "")))]
+ (compare:CC (match_operand:SI 1 "cmpsi_operand" "")
+ (match_operand:SI 2 "general_operand" "")))
+ (set (pc) (if_then_else
+ (match_operator 0 "comparison_operator"
+ [(reg:CC FLAGS_REG)
+ (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
""
{
- if (MEM_P (operands[0]) && MEM_P (operands[1]))
- operands[0] = force_reg (DImode, operands[0]);
- ix86_compare_op0 = operands[0];
- ix86_compare_op1 = operands[1];
+ if (MEM_P (operands[1]) && MEM_P (operands[2]))
+ operands[1] = force_reg (SImode, operands[1]);
+ ix86_compare_op0 = operands[1];
+ ix86_compare_op1 = operands[2];
+ ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
DONE;
})
-(define_expand "cmpsi"
+(define_expand "cstoresi4"
[(set (reg:CC FLAGS_REG)
- (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
- (match_operand:SI 1 "general_operand" "")))]
+ (compare:CC (match_operand:SI 2 "cmpsi_operand" "")
+ (match_operand:SI 3 "general_operand" "")))
+ (set (match_operand:QI 0 "register_operand" "")
+ (match_operator 1 "comparison_operator"
+ [(reg:CC FLAGS_REG)
+ (const_int 0)]))]
""
{
- if (MEM_P (operands[0]) && MEM_P (operands[1]))
- operands[0] = force_reg (SImode, operands[0]);
- ix86_compare_op0 = operands[0];
- ix86_compare_op1 = operands[1];
+ if (MEM_P (operands[2]) && MEM_P (operands[3]))
+ operands[2] = force_reg (SImode, operands[2]);
+ ix86_compare_op0 = operands[2];
+ ix86_compare_op1 = operands[3];
+ ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
DONE;
})
-(define_expand "cmphi"
+(define_expand "cbranchhi4"
[(set (reg:CC FLAGS_REG)
- (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
- (match_operand:HI 1 "general_operand" "")))]
+ (compare:CC (match_operand:HI 1 "nonimmediate_operand" "")
+ (match_operand:HI 2 "general_operand" "")))
+ (set (pc) (if_then_else
+ (match_operator 0 "comparison_operator"
+ [(reg:CC FLAGS_REG)
+ (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
""
{
- if (MEM_P (operands[0]) && MEM_P (operands[1]))
- operands[0] = force_reg (HImode, operands[0]);
- ix86_compare_op0 = operands[0];
- ix86_compare_op1 = operands[1];
+ if (MEM_P (operands[1]) && MEM_P (operands[2]))
+ operands[1] = force_reg (HImode, operands[1]);
+ ix86_compare_op0 = operands[1];
+ ix86_compare_op1 = operands[2];
+ ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
DONE;
})
-(define_expand "cmpqi"
+(define_expand "cstorehi4"
[(set (reg:CC FLAGS_REG)
- (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
- (match_operand:QI 1 "general_operand" "")))]
- "TARGET_QIMODE_MATH"
+ (compare:CC (match_operand:HI 2 "nonimmediate_operand" "")
+ (match_operand:HI 3 "general_operand" "")))
+ (set (match_operand:QI 0 "register_operand" "")
+ (match_operator 1 "comparison_operator"
+ [(reg:CC FLAGS_REG)
+ (const_int 0)]))]
+ ""
{
- if (MEM_P (operands[0]) && MEM_P (operands[1]))
- operands[0] = force_reg (QImode, operands[0]);
- ix86_compare_op0 = operands[0];
- ix86_compare_op1 = operands[1];
+ if (MEM_P (operands[2]) && MEM_P (operands[3]))
+ operands[2] = force_reg (HImode, operands[2]);
+ ix86_compare_op0 = operands[2];
+ ix86_compare_op1 = operands[3];
+ ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
+ DONE;
+})
+
+
+(define_expand "cbranchqi4"
+ [(set (reg:CC FLAGS_REG)
+ (compare:CC (match_operand:QI 1 "nonimmediate_operand" "")
+ (match_operand:QI 2 "general_operand" "")))
+ (set (pc) (if_then_else
+ (match_operator 0 "comparison_operator"
+ [(reg:CC FLAGS_REG)
+ (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
+ ""
+{
+ if (MEM_P (operands[1]) && MEM_P (operands[2]))
+ operands[1] = force_reg (QImode, operands[1]);
+ ix86_compare_op0 = operands[1];
+ ix86_compare_op1 = operands[2];
+ ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
DONE;
})
+
+(define_expand "cstoreqi4"
+ [(set (reg:CC FLAGS_REG)
+ (compare:CC (match_operand:QI 2 "nonimmediate_operand" "")
+ (match_operand:QI 3 "general_operand" "")))
+ (set (match_operand:QI 0 "register_operand" "")
+ (match_operator 1 "comparison_operator"
+ [(reg:CC FLAGS_REG)
+ (const_int 0)]))]
+ ""
+{
+ if (MEM_P (operands[2]) && MEM_P (operands[3]))
+ operands[2] = force_reg (QImode, operands[2]);
+ ix86_compare_op0 = operands[2];
+ ix86_compare_op1 = operands[3];
+ ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
+ DONE;
+})
+
+
(define_insn "cmpdi_ccno_1_rex64"
[(set (reg FLAGS_REG)
(compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
@@ -1039,6 +1176,7 @@
"!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
"cmp{b}\t{%1, %h0|%h0, %1}"
[(set_attr "type" "icmp")
+ (set_attr "modrm" "1")
(set_attr "mode" "QI")])
(define_insn "cmpqi_ext_3_insn_rex64"
@@ -1053,6 +1191,7 @@
"TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
"cmp{b}\t{%1, %h0|%h0, %1}"
[(set_attr "type" "icmp")
+ (set_attr "modrm" "1")
(set_attr "mode" "QI")])
(define_insn "*cmpqi_ext_4"
@@ -1078,39 +1217,103 @@
;; which would allow mix and match FP modes on the compares. Which is what
;; the old patterns did, but with many more of them.
-(define_expand "cmpxf"
+(define_expand "cbranchxf4"
+ [(set (reg:CC FLAGS_REG)
+ (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
+ (match_operand:XF 2 "nonmemory_operand" "")))
+ (set (pc) (if_then_else
+ (match_operator 0 "comparison_operator"
+ [(reg:CC FLAGS_REG)
+ (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
+ "TARGET_80387"
+{
+ ix86_compare_op0 = operands[1];
+ ix86_compare_op1 = operands[2];
+ ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
+ DONE;
+})
+
+(define_expand "cstorexf4"
[(set (reg:CC FLAGS_REG)
- (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
- (match_operand:XF 1 "nonmemory_operand" "")))]
+ (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
+ (match_operand:XF 3 "nonmemory_operand" "")))
+ (set (match_operand:QI 0 "register_operand" "")
+ (match_operator 1 "comparison_operator"
+ [(reg:CC FLAGS_REG)
+ (const_int 0)]))]
"TARGET_80387"
{
- ix86_compare_op0 = operands[0];
- ix86_compare_op1 = operands[1];
+ ix86_compare_op0 = operands[2];
+ ix86_compare_op1 = operands[3];
+ ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
DONE;
})
-(define_expand "cmp<mode>"
+(define_expand "cbranch<mode>4"
[(set (reg:CC FLAGS_REG)
- (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
- (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
+ (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
+ (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
+ (set (pc) (if_then_else
+ (match_operator 0 "comparison_operator"
+ [(reg:CC FLAGS_REG)
+ (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
"TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
{
- ix86_compare_op0 = operands[0];
- ix86_compare_op1 = operands[1];
+ ix86_compare_op0 = operands[1];
+ ix86_compare_op1 = operands[2];
+ ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
DONE;
})
-(define_expand "cmpcc"
+(define_expand "cstore<mode>4"
[(set (reg:CC FLAGS_REG)
- (compare:CC (match_operand 0 "flags_reg_operand" "")
- (match_operand 1 "general_operand" "")))]
+ (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
+ (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
+ (set (match_operand:QI 0 "register_operand" "")
+ (match_operator 1 "comparison_operator"
+ [(reg:CC FLAGS_REG)
+ (const_int 0)]))]
+ "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
+{
+ ix86_compare_op0 = operands[2];
+ ix86_compare_op1 = operands[3];
+ ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
+ DONE;
+})
+
+(define_expand "cbranchcc4"
+ [(set (pc) (if_then_else
+ (match_operator 0 "comparison_operator"
+ [(match_operand 1 "flags_reg_operand" "")
+ (match_operand 2 "const0_operand" "")])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
+ ""
+{
+ ix86_compare_op0 = operands[1];
+ ix86_compare_op1 = operands[2];
+ ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
+ DONE;
+})
+
+(define_expand "cstorecc4"
+ [(set (match_operand:QI 0 "register_operand" "")
+ (match_operator 1 "comparison_operator"
+ [(match_operand 2 "flags_reg_operand" "")
+ (match_operand 3 "const0_operand" "")]))]
""
{
- ix86_compare_op0 = operands[0];
- ix86_compare_op1 = operands[1];
+ ix86_compare_op0 = operands[2];
+ ix86_compare_op1 = operands[3];
+ ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
DONE;
})
+
;; FP compares, step 1:
;; Set the FP condition codes.
;;
@@ -1336,7 +1539,7 @@
(unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
"TARGET_80387"
"fnstsw\t%0"
- [(set_attr "length" "2")
+ [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
(set_attr "mode" "SI")
(set_attr "unit" "i387")])
@@ -1376,6 +1579,17 @@
(if_then_else (match_operand:SF 1 "" "")
(const_string "SF")
(const_string "DF")))
+ (set (attr "prefix_rep")
+ (if_then_else (eq_attr "type" "ssecomi")
+ (const_string "0")
+ (const_string "*")))
+ (set (attr "prefix_data16")
+ (cond [(eq_attr "type" "fcmp")
+ (const_string "*")
+ (eq_attr "mode" "DF")
+ (const_string "1")
+ ]
+ (const_string "0")))
(set_attr "athlon_decode" "vector")
(set_attr "amdfam10_decode" "direct")])
@@ -1393,6 +1607,11 @@
(if_then_else (match_operand:SF 1 "" "")
(const_string "SF")
(const_string "DF")))
+ (set_attr "prefix_rep" "0")
+ (set (attr "prefix_data16")
+ (if_then_else (eq_attr "mode" "DF")
+ (const_string "1")
+ (const_string "0")))
(set_attr "athlon_decode" "vector")
(set_attr "amdfam10_decode" "direct")])
@@ -1430,6 +1649,17 @@
(if_then_else (match_operand:SF 1 "" "")
(const_string "SF")
(const_string "DF")))
+ (set (attr "prefix_rep")
+ (if_then_else (eq_attr "type" "ssecomi")
+ (const_string "0")
+ (const_string "*")))
+ (set (attr "prefix_data16")
+ (cond [(eq_attr "type" "fcmp")
+ (const_string "*")
+ (eq_attr "mode" "DF")
+ (const_string "1")
+ ]
+ (const_string "0")))
(set_attr "athlon_decode" "vector")
(set_attr "amdfam10_decode" "direct")])
@@ -1447,6 +1677,11 @@
(if_then_else (match_operand:SF 1 "" "")
(const_string "SF")
(const_string "DF")))
+ (set_attr "prefix_rep" "0")
+ (set (attr "prefix_data16")
+ (if_then_else (eq_attr "mode" "DF")
+ (const_string "1")
+ (const_string "0")))
(set_attr "athlon_decode" "vector")
(set_attr "amdfam10_decode" "direct")])
@@ -1622,6 +1857,10 @@
(if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
(const_string "orig")
(const_string "maybe_vex")))
+ (set (attr "prefix_data16")
+ (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
+ (const_string "1")
+ (const_string "*")))
(set (attr "mode")
(cond [(eq_attr "alternative" "2,3")
(const_string "DI")
@@ -2113,7 +2352,7 @@
"TARGET_64BIT"
"movz{bl|x}\t{%h1, %k0|%k0, %h1}"
[(set_attr "type" "imovx")
- (set_attr "mode" "DI")])
+ (set_attr "mode" "SI")])
(define_insn "*movsi_extzv_1"
[(set (match_operand:SI 0 "register_operand" "=R")
@@ -2461,8 +2700,18 @@
(const_string "lea")
]
(const_string "imov")))
- (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
- (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
+ (set (attr "modrm")
+ (if_then_else
+ (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
+ (const_string "0")
+ (const_string "*")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
+ (const_string "8")
+ (const_string "*")))
+ (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
+ (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
(set (attr "prefix")
(if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
(const_string "maybe_vex")
@@ -3047,6 +3296,10 @@
(if_then_else (eq_attr "alternative" "0,1,2,3,4")
(const_string "orig")
(const_string "maybe_vex")))
+ (set (attr "prefix_data16")
+ (if_then_else (eq_attr "mode" "V1DF")
+ (const_string "1")
+ (const_string "*")))
(set (attr "mode")
(cond [(eq_attr "alternative" "0,1,2")
(const_string "DF")
@@ -3181,6 +3434,10 @@
(if_then_else (eq_attr "alternative" "0,1,2,3,4")
(const_string "orig")
(const_string "maybe_vex")))
+ (set (attr "prefix_data16")
+ (if_then_else (eq_attr "mode" "V1DF")
+ (const_string "1")
+ (const_string "*")))
(set (attr "mode")
(cond [(eq_attr "alternative" "0,1,2")
(const_string "DF")
@@ -3301,6 +3558,10 @@
}
}
[(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
+ (set (attr "prefix_data16")
+ (if_then_else (eq_attr "mode" "V1DF")
+ (const_string "1")
+ (const_string "*")))
(set (attr "mode")
(cond [(eq_attr "alternative" "0,1,2")
(const_string "DF")
@@ -3931,6 +4192,7 @@
%vmovd\t{%1, %0|%0, %1}"
[(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
(set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
+ (set_attr "prefix_0f" "0,*,*,*,*,*")
(set_attr "mode" "SI,DI,DI,DI,TI,TI")])
(define_split
@@ -3965,7 +4227,7 @@
"TARGET_64BIT"
"movz{wl|x}\t{%1, %k0|%k0, %1}"
[(set_attr "type" "imovx")
- (set_attr "mode" "DI")])
+ (set_attr "mode" "SI")])
(define_insn "zero_extendqidi2"
[(set (match_operand:DI 0 "register_operand" "=r")
@@ -3973,7 +4235,7 @@
"TARGET_64BIT"
"movz{bl|x}\t{%1, %k0|%k0, %1}"
[(set_attr "type" "imovx")
- (set_attr "mode" "DI")])
+ (set_attr "mode" "SI")])
;; Sign extension instructions
@@ -4005,7 +4267,7 @@
"TARGET_64BIT"
"@
{cltq|cdqe}
- movs{lq|x}\t{%1,%0|%0, %1}"
+ movs{lq|x}\t{%1, %0|%0, %1}"
[(set_attr "type" "imovx")
(set_attr "mode" "DI")
(set_attr "prefix_0f" "0")
@@ -4015,7 +4277,7 @@
[(set (match_operand:DI 0 "register_operand" "=r")
(sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
"TARGET_64BIT"
- "movs{wq|x}\t{%1,%0|%0, %1}"
+ "movs{wq|x}\t{%1, %0|%0, %1}"
[(set_attr "type" "imovx")
(set_attr "mode" "DI")])
@@ -4023,7 +4285,7 @@
[(set (match_operand:DI 0 "register_operand" "=r")
(sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
"TARGET_64BIT"
- "movs{bq|x}\t{%1,%0|%0, %1}"
+ "movs{bq|x}\t{%1, %0|%0, %1}"
[(set_attr "type" "imovx")
(set_attr "mode" "DI")])
@@ -4111,7 +4373,7 @@
case 0:
return "{cwtl|cwde}";
default:
- return "movs{wl|x}\t{%1,%0|%0, %1}";
+ return "movs{wl|x}\t{%1, %0|%0, %1}";
}
}
[(set_attr "type" "imovx")
@@ -4138,7 +4400,7 @@
case 0:
return "{cwtl|cwde}";
default:
- return "movs{wl|x}\t{%1,%k0|%k0, %1}";
+ return "movs{wl|x}\t{%1, %k0|%k0, %1}";
}
}
[(set_attr "type" "imovx")
@@ -4164,7 +4426,7 @@
case 0:
return "{cbtw|cbw}";
default:
- return "movs{bw|x}\t{%1,%0|%0, %1}";
+ return "movs{bw|x}\t{%1, %0|%0, %1}";
}
}
[(set_attr "type" "imovx")
@@ -4184,7 +4446,7 @@
[(set (match_operand:SI 0 "register_operand" "=r")
(sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
""
- "movs{bl|x}\t{%1,%0|%0, %1}"
+ "movs{bl|x}\t{%1, %0|%0, %1}"
[(set_attr "type" "imovx")
(set_attr "mode" "SI")])
@@ -4193,7 +4455,7 @@
(zero_extend:DI
(sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
"TARGET_64BIT"
- "movs{bl|x}\t{%1,%k0|%k0, %1}"
+ "movs{bl|x}\t{%1, %k0|%k0, %1}"
[(set_attr "type" "imovx")
(set_attr "mode" "SI")])
@@ -4805,6 +5067,7 @@
"%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
[(set_attr "type" "sseicvt")
(set_attr "prefix" "maybe_vex")
+ (set_attr "prefix_rex" "1")
(set_attr "mode" "<MODE>")
(set_attr "athlon_decode" "double,vector")
(set_attr "amdfam10_decode" "double,double")])
@@ -5079,7 +5342,7 @@
(unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
"TARGET_80387"
"fnstcw\t%0"
- [(set_attr "length" "2")
+ [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
(set_attr "mode" "HI")
(set_attr "unit" "i387")])
@@ -5088,7 +5351,7 @@
(unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
"TARGET_80387"
"fldcw\t%0"
- [(set_attr "length" "2")
+ [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
(set_attr "mode" "HI")
(set_attr "unit" "i387")
(set_attr "athlon_decode" "vector")
@@ -5318,6 +5581,12 @@
[(set_attr "type" "fmov,sseicvt,sseicvt")
(set_attr "prefix" "orig,maybe_vex,maybe_vex")
(set_attr "mode" "<MODEF:MODE>")
+ (set (attr "prefix_rex")
+ (if_then_else
+ (and (eq_attr "prefix" "maybe_vex")
+ (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
+ (const_string "1")
+ (const_string "*")))
(set_attr "unit" "i387,*,*")
(set_attr "athlon_decode" "*,double,direct")
(set_attr "amdfam10_decode" "*,vector,double")
@@ -5336,6 +5605,12 @@
[(set_attr "type" "fmov,sseicvt")
(set_attr "prefix" "orig,maybe_vex")
(set_attr "mode" "<MODEF:MODE>")
+ (set (attr "prefix_rex")
+ (if_then_else
+ (and (eq_attr "prefix" "maybe_vex")
+ (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
+ (const_string "1")
+ (const_string "*")))
(set_attr "athlon_decode" "*,direct")
(set_attr "amdfam10_decode" "*,double")
(set_attr "fp_int_src" "true")])
@@ -5512,6 +5787,12 @@
[(set_attr "type" "sseicvt")
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "<MODEF:MODE>")
+ (set (attr "prefix_rex")
+ (if_then_else
+ (and (eq_attr "prefix" "maybe_vex")
+ (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
+ (const_string "1")
+ (const_string "*")))
(set_attr "athlon_decode" "double,direct")
(set_attr "amdfam10_decode" "vector,double")
(set_attr "fp_int_src" "true")])
@@ -5541,6 +5822,12 @@
[(set_attr "type" "sseicvt")
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "<MODEF:MODE>")
+ (set (attr "prefix_rex")
+ (if_then_else
+ (and (eq_attr "prefix" "maybe_vex")
+ (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
+ (const_string "1")
+ (const_string "*")))
(set_attr "athlon_decode" "direct")
(set_attr "amdfam10_decode" "double")
(set_attr "fp_int_src" "true")])
@@ -6260,6 +6547,11 @@
(const_string "incdec")
]
(const_string "alu")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+ (const_string "1")
+ (const_string "*")))
(set_attr "mode" "DI")])
;; Convert lea to the lea pattern to avoid flags dependency.
@@ -6324,6 +6616,11 @@
(if_then_else (match_operand:DI 2 "incdec_operand" "")
(const_string "incdec")
(const_string "alu")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+ (const_string "1")
+ (const_string "*")))
(set_attr "mode" "DI")])
(define_insn "*adddi_3_rex64"
@@ -6373,6 +6670,11 @@
(if_then_else (match_operand:DI 2 "incdec_operand" "")
(const_string "incdec")
(const_string "alu")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+ (const_string "1")
+ (const_string "*")))
(set_attr "mode" "DI")])
; For comparisons against 1, -1 and 128, we may generate better code
@@ -6420,6 +6722,11 @@
(if_then_else (match_operand:DI 2 "incdec_operand" "")
(const_string "incdec")
(const_string "alu")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+ (const_string "1")
+ (const_string "*")))
(set_attr "mode" "DI")])
(define_insn "*adddi_5_rex64"
@@ -6469,6 +6776,11 @@
(if_then_else (match_operand:DI 2 "incdec_operand" "")
(const_string "incdec")
(const_string "alu")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+ (const_string "1")
+ (const_string "*")))
(set_attr "mode" "DI")])
@@ -6529,6 +6841,11 @@
(const_string "incdec")
]
(const_string "alu")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+ (const_string "1")
+ (const_string "*")))
(set_attr "mode" "SI")])
;; Convert lea to the lea pattern to avoid flags dependency.
@@ -6609,6 +6926,11 @@
(const_string "incdec")
]
(const_string "alu")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+ (const_string "1")
+ (const_string "*")))
(set_attr "mode" "SI")])
;; Convert lea to the lea pattern to avoid flags dependency.
@@ -6672,6 +6994,11 @@
(if_then_else (match_operand:SI 2 "incdec_operand" "")
(const_string "incdec")
(const_string "alu")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+ (const_string "1")
+ (const_string "*")))
(set_attr "mode" "SI")])
;; See comment for addsi_1_zext why we do use nonimmediate_operand
@@ -6718,6 +7045,11 @@
(if_then_else (match_operand:SI 2 "incdec_operand" "")
(const_string "incdec")
(const_string "alu")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+ (const_string "1")
+ (const_string "*")))
(set_attr "mode" "SI")])
(define_insn "*addsi_3"
@@ -6762,6 +7094,11 @@
(if_then_else (match_operand:SI 2 "incdec_operand" "")
(const_string "incdec")
(const_string "alu")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+ (const_string "1")
+ (const_string "*")))
(set_attr "mode" "SI")])
;; See comment for addsi_1_zext why we do use nonimmediate_operand
@@ -6806,6 +7143,11 @@
(if_then_else (match_operand:SI 2 "incdec_operand" "")
(const_string "incdec")
(const_string "alu")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+ (const_string "1")
+ (const_string "*")))
(set_attr "mode" "SI")])
; For comparisons against 1, -1 and 128, we may generate better code
@@ -6851,6 +7193,11 @@
(if_then_else (match_operand:SI 2 "incdec_operand" "")
(const_string "incdec")
(const_string "alu")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+ (const_string "1")
+ (const_string "*")))
(set_attr "mode" "SI")])
(define_insn "*addsi_5"
@@ -6897,6 +7244,11 @@
(if_then_else (match_operand:SI 2 "incdec_operand" "")
(const_string "incdec")
(const_string "alu")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+ (const_string "1")
+ (const_string "*")))
(set_attr "mode" "SI")])
(define_expand "addhi3"
@@ -6951,6 +7303,11 @@
(if_then_else (match_operand:HI 2 "incdec_operand" "")
(const_string "incdec")
(const_string "alu"))))
+ (set (attr "length_immediate")
+ (if_then_else
+ (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+ (const_string "1")
+ (const_string "*")))
(set_attr "mode" "HI,HI,SI")])
(define_insn "*addhi_1"
@@ -6990,6 +7347,11 @@
(if_then_else (match_operand:HI 2 "incdec_operand" "")
(const_string "incdec")
(const_string "alu")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+ (const_string "1")
+ (const_string "*")))
(set_attr "mode" "HI")])
(define_insn "*addhi_2"
@@ -7032,6 +7394,11 @@
(if_then_else (match_operand:HI 2 "incdec_operand" "")
(const_string "incdec")
(const_string "alu")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+ (const_string "1")
+ (const_string "*")))
(set_attr "mode" "HI")])
(define_insn "*addhi_3"
@@ -7071,6 +7438,11 @@
(if_then_else (match_operand:HI 2 "incdec_operand" "")
(const_string "incdec")
(const_string "alu")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+ (const_string "1")
+ (const_string "*")))
(set_attr "mode" "HI")])
; See comments above addsi_4 for details.
@@ -7109,7 +7481,12 @@
(if_then_else (match_operand:HI 2 "incdec_operand" "")
(const_string "incdec")
(const_string "alu")))
- (set_attr "mode" "SI")])
+ (set (attr "length_immediate")
+ (if_then_else
+ (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+ (const_string "1")
+ (const_string "*")))
+ (set_attr "mode" "HI")])
(define_insn "*addhi_5"
@@ -7151,6 +7528,11 @@
(if_then_else (match_operand:HI 2 "incdec_operand" "")
(const_string "incdec")
(const_string "alu")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+ (const_string "1")
+ (const_string "*")))
(set_attr "mode" "HI")])
(define_expand "addqi3"
@@ -7209,6 +7591,11 @@
(if_then_else (match_operand:QI 2 "incdec_operand" "")
(const_string "incdec")
(const_string "alu"))))
+ (set (attr "length_immediate")
+ (if_then_else
+ (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+ (const_string "1")
+ (const_string "*")))
(set_attr "mode" "QI,QI,SI,SI")])
(define_insn "*addqi_1"
@@ -7255,6 +7642,11 @@
(if_then_else (match_operand:QI 2 "incdec_operand" "")
(const_string "incdec")
(const_string "alu")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
+ (const_string "1")
+ (const_string "*")))
(set_attr "mode" "QI,QI,SI")])
(define_insn "*addqi_1_slp"
@@ -7490,6 +7882,7 @@
(if_then_else (match_operand:QI 2 "incdec_operand" "")
(const_string "incdec")
(const_string "alu")))
+ (set_attr "modrm" "1")
(set_attr "mode" "QI")])
(define_insn "*addqi_ext_1_rex64"
@@ -7526,6 +7919,7 @@
(if_then_else (match_operand:QI 2 "incdec_operand" "")
(const_string "incdec")
(const_string "alu")))
+ (set_attr "modrm" "1")
(set_attr "mode" "QI")])
(define_insn "*addqi_ext_2"
@@ -8990,6 +9384,7 @@
[(set_attr "type" "test")
(set_attr "mode" "QI")
(set_attr "length_immediate" "1")
+ (set_attr "modrm" "1")
(set_attr "pent_pair" "np")])
(define_insn "*testqi_ext_1"
@@ -9216,9 +9611,9 @@
operands[1] = gen_lowpart (mode, operands[1]);
if (mode == QImode)
- return "movz{bq|x}\t{%1,%0|%0, %1}";
+ return "movz{bl|x}\t{%1, %k0|%k0, %1}";
else
- return "movz{wq|x}\t{%1,%0|%0, %1}";
+ return "movz{wl|x}\t{%1, %k0|%k0, %1}";
}
default:
@@ -9231,7 +9626,14 @@
}
[(set_attr "type" "alu,alu,alu,imovx")
(set_attr "length_immediate" "*,*,*,0")
- (set_attr "mode" "SI,DI,DI,DI")])
+ (set (attr "prefix_rex")
+ (if_then_else
+ (and (eq_attr "type" "imovx")
+ (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
+ (match_operand 1 "ext_QIreg_nomode_operand" "")))
+ (const_string "1")
+ (const_string "*")))
+ (set_attr "mode" "SI,DI,DI,SI")])
(define_insn "*anddi_2"
[(set (reg FLAGS_REG)
@@ -9280,9 +9682,9 @@
operands[1] = gen_lowpart (mode, operands[1]);
if (mode == QImode)
- return "movz{bl|x}\t{%1,%0|%0, %1}";
+ return "movz{bl|x}\t{%1, %0|%0, %1}";
else
- return "movz{wl|x}\t{%1,%0|%0, %1}";
+ return "movz{wl|x}\t{%1, %0|%0, %1}";
}
default:
@@ -9291,6 +9693,13 @@
}
}
[(set_attr "type" "alu,alu,imovx")
+ (set (attr "prefix_rex")
+ (if_then_else
+ (and (eq_attr "type" "imovx")
+ (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
+ (match_operand 1 "ext_QIreg_nomode_operand" "")))
+ (const_string "1")
+ (const_string "*")))
(set_attr "length_immediate" "*,*,0")
(set_attr "mode" "SI")])
@@ -9399,6 +9808,12 @@
}
[(set_attr "type" "alu,alu,imovx")
(set_attr "length_immediate" "*,*,0")
+ (set (attr "prefix_rex")
+ (if_then_else
+ (and (eq_attr "type" "imovx")
+ (match_operand 1 "ext_QIreg_nomode_operand" ""))
+ (const_string "1")
+ (const_string "*")))
(set_attr "mode" "HI,HI,SI")])
(define_insn "*andhi_2"
@@ -9518,6 +9933,7 @@
"and{b}\t{%2, %h0|%h0, %2}"
[(set_attr "type" "alu")
(set_attr "length_immediate" "1")
+ (set_attr "modrm" "1")
(set_attr "mode" "QI")])
;; Generated by peephole translating test to and. This shows up
@@ -9546,6 +9962,7 @@
"and{b}\t{%2, %h0|%h0, %2}"
[(set_attr "type" "alu")
(set_attr "length_immediate" "1")
+ (set_attr "modrm" "1")
(set_attr "mode" "QI")])
(define_insn "*andqi_ext_1"
@@ -9920,6 +10337,7 @@
"or{b}\t{%2, %h0|%h0, %2}"
[(set_attr "type" "alu")
(set_attr "length_immediate" "1")
+ (set_attr "modrm" "1")
(set_attr "mode" "QI")])
(define_insn "*iorqi_ext_1"
@@ -10250,6 +10668,7 @@
"xor{b}\t{%2, %h0|%h0, %2}"
[(set_attr "type" "alu")
(set_attr "length_immediate" "1")
+ (set_attr "modrm" "1")
(set_attr "mode" "QI")])
(define_insn "*xorqi_ext_1"
@@ -10368,6 +10787,7 @@
"!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
"xor{b}\t{%2, %h0|%h0, %2}"
[(set_attr "type" "alu")
+ (set_attr "modrm" "1")
(set_attr "mode" "QI")])
(define_insn "*xorqi_cc_ext_1_rex64"
@@ -10389,6 +10809,7 @@
"TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
"xor{b}\t{%2, %h0|%h0, %2}"
[(set_attr "type" "alu")
+ (set_attr "modrm" "1")
(set_attr "mode" "QI")])
(define_expand "xorqi_cc_ext_1"
@@ -11191,6 +11612,7 @@
}
[(set_attr "type" "sseishft")
(set_attr "prefix" "vex")
+ (set_attr "length_immediate" "1")
(set_attr "mode" "TI")])
(define_insn "sse2_ashlti3"
@@ -11204,6 +11626,7 @@
}
[(set_attr "type" "sseishft")
(set_attr "prefix_data16" "1")
+ (set_attr "length_immediate" "1")
(set_attr "mode" "TI")])
(define_insn "*ashlti3_1"
@@ -11343,6 +11766,15 @@
(const_string "alu")
]
(const_string "ishift")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (ior (eq_attr "type" "alu")
+ (and (eq_attr "type" "ishift")
+ (and (match_operand 2 "const1_operand" "")
+ (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
+ (const_int 0)))))
+ (const_string "0")
+ (const_string "*")))
(set_attr "mode" "DI")])
;; Convert lea to the lea pattern to avoid flags dependency.
@@ -11402,6 +11834,15 @@
(const_string "alu")
]
(const_string "ishift")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (ior (eq_attr "type" "alu")
+ (and (eq_attr "type" "ishift")
+ (and (match_operand 2 "const1_operand" "")
+ (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
+ (const_int 0)))))
+ (const_string "0")
+ (const_string "*")))
(set_attr "mode" "DI")])
(define_insn "*ashldi3_cconly_rex64"
@@ -11444,6 +11885,15 @@
(const_string "alu")
]
(const_string "ishift")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (ior (eq_attr "type" "alu")
+ (and (eq_attr "type" "ishift")
+ (and (match_operand 2 "const1_operand" "")
+ (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
+ (const_int 0)))))
+ (const_string "0")
+ (const_string "*")))
(set_attr "mode" "DI")])
(define_insn "*ashldi3_1"
@@ -11583,6 +12033,15 @@
(const_string "alu")
]
(const_string "ishift")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (ior (eq_attr "type" "alu")
+ (and (eq_attr "type" "ishift")
+ (and (match_operand 2 "const1_operand" "")
+ (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
+ (const_int 0)))))
+ (const_string "0")
+ (const_string "*")))
(set_attr "mode" "SI")])
;; Convert lea to the lea pattern to avoid flags dependency.
@@ -11667,6 +12126,15 @@
(const_string "alu")
]
(const_string "ishift")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (ior (eq_attr "type" "alu")
+ (and (eq_attr "type" "ishift")
+ (and (match_operand 2 "const1_operand" "")
+ (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
+ (const_int 0)))))
+ (const_string "0")
+ (const_string "*")))
(set_attr "mode" "SI")])
;; Convert lea to the lea pattern to avoid flags dependency.
@@ -11728,6 +12196,15 @@
(const_string "alu")
]
(const_string "ishift")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (ior (eq_attr "type" "alu")
+ (and (eq_attr "type" "ishift")
+ (and (match_operand 2 "const1_operand" "")
+ (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
+ (const_int 0)))))
+ (const_string "0")
+ (const_string "*")))
(set_attr "mode" "SI")])
(define_insn "*ashlsi3_cconly"
@@ -11769,6 +12246,15 @@
(const_string "alu")
]
(const_string "ishift")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (ior (eq_attr "type" "alu")
+ (and (eq_attr "type" "ishift")
+ (and (match_operand 2 "const1_operand" "")
+ (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
+ (const_int 0)))))
+ (const_string "0")
+ (const_string "*")))
(set_attr "mode" "SI")])
(define_insn "*ashlsi3_cmp_zext"
@@ -11811,6 +12297,15 @@
(const_string "alu")
]
(const_string "ishift")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (ior (eq_attr "type" "alu")
+ (and (eq_attr "type" "ishift")
+ (and (match_operand 2 "const1_operand" "")
+ (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
+ (const_int 0)))))
+ (const_string "0")
+ (const_string "*")))
(set_attr "mode" "SI")])
(define_expand "ashlhi3"
@@ -11856,6 +12351,15 @@
(const_string "alu")
]
(const_string "ishift")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (ior (eq_attr "type" "alu")
+ (and (eq_attr "type" "ishift")
+ (and (match_operand 2 "const1_operand" "")
+ (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
+ (const_int 0)))))
+ (const_string "0")
+ (const_string "*")))
(set_attr "mode" "HI,SI")])
(define_insn "*ashlhi3_1"
@@ -11890,6 +12394,15 @@
(const_string "alu")
]
(const_string "ishift")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (ior (eq_attr "type" "alu")
+ (and (eq_attr "type" "ishift")
+ (and (match_operand 2 "const1_operand" "")
+ (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
+ (const_int 0)))))
+ (const_string "0")
+ (const_string "*")))
(set_attr "mode" "HI")])
;; This pattern can't accept a variable shift count, since shifts by
@@ -11935,6 +12448,15 @@
(const_string "alu")
]
(const_string "ishift")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (ior (eq_attr "type" "alu")
+ (and (eq_attr "type" "ishift")
+ (and (match_operand 2 "const1_operand" "")
+ (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
+ (const_int 0)))))
+ (const_string "0")
+ (const_string "*")))
(set_attr "mode" "HI")])
(define_insn "*ashlhi3_cconly"
@@ -11976,6 +12498,15 @@
(const_string "alu")
]
(const_string "ishift")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (ior (eq_attr "type" "alu")
+ (and (eq_attr "type" "ishift")
+ (and (match_operand 2 "const1_operand" "")
+ (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
+ (const_int 0)))))
+ (const_string "0")
+ (const_string "*")))
(set_attr "mode" "HI")])
(define_expand "ashlqi3"
@@ -12041,6 +12572,15 @@
(const_string "alu")
]
(const_string "ishift")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (ior (eq_attr "type" "alu")
+ (and (eq_attr "type" "ishift")
+ (and (match_operand 2 "const1_operand" "")
+ (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
+ (const_int 0)))))
+ (const_string "0")
+ (const_string "*")))
(set_attr "mode" "QI,SI,SI")])
(define_insn "*ashlqi3_1"
@@ -12093,6 +12633,15 @@
(const_string "alu")
]
(const_string "ishift")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (ior (eq_attr "type" "alu")
+ (and (eq_attr "type" "ishift")
+ (and (match_operand 2 "const1_operand" "")
+ (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
+ (const_int 0)))))
+ (const_string "0")
+ (const_string "*")))
(set_attr "mode" "QI,SI")])
;; This pattern can't accept a variable shift count, since shifts by
@@ -12138,6 +12687,15 @@
(const_string "alu")
]
(const_string "ishift")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (ior (eq_attr "type" "alu")
+ (and (eq_attr "type" "ishift")
+ (and (match_operand 2 "const1_operand" "")
+ (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
+ (const_int 0)))))
+ (const_string "0")
+ (const_string "*")))
(set_attr "mode" "QI")])
(define_insn "*ashlqi3_cconly"
@@ -12179,6 +12737,15 @@
(const_string "alu")
]
(const_string "ishift")))
+ (set (attr "length_immediate")
+ (if_then_else
+ (ior (eq_attr "type" "alu")
+ (and (eq_attr "type" "ishift")
+ (and (match_operand 2 "const1_operand" "")
+ (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
+ (const_int 0)))))
+ (const_string "0")
+ (const_string "*")))
(set_attr "mode" "QI")])
;; See comment above `ashldi3' about how this works.
@@ -12297,10 +12864,8 @@
&& ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
"sar{q}\t%0"
[(set_attr "type" "ishift")
- (set (attr "length")
- (if_then_else (match_operand:DI 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "DI")])
(define_insn "*ashrdi3_1_rex64"
[(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
@@ -12331,10 +12896,8 @@
&& ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
"sar{q}\t%0"
[(set_attr "type" "ishift")
- (set (attr "length")
- (if_then_else (match_operand:DI 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "DI")])
(define_insn "*ashrdi3_one_bit_cconly_rex64"
[(set (reg FLAGS_REG)
@@ -12349,7 +12912,8 @@
&& ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
"sar{q}\t%0"
[(set_attr "type" "ishift")
- (set_attr "length" "2")])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "DI")])
;; This pattern can't accept a variable shift count, since shifts by
;; zero don't affect the flags. We assume that shifts by constant
@@ -12517,10 +13081,8 @@
&& ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
"sar{l}\t%0"
[(set_attr "type" "ishift")
- (set (attr "length")
- (if_then_else (match_operand:SI 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "SI")])
(define_insn "*ashrsi3_1_one_bit_zext"
[(set (match_operand:DI 0 "register_operand" "=r")
@@ -12532,7 +13094,8 @@
&& ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
"sar{l}\t%k0"
[(set_attr "type" "ishift")
- (set_attr "length" "2")])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "SI")])
(define_insn "*ashrsi3_1"
[(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
@@ -12574,10 +13137,8 @@
&& ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
"sar{l}\t%0"
[(set_attr "type" "ishift")
- (set (attr "length")
- (if_then_else (match_operand:SI 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "SI")])
(define_insn "*ashrsi3_one_bit_cconly"
[(set (reg FLAGS_REG)
@@ -12591,7 +13152,8 @@
&& ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
"sar{l}\t%0"
[(set_attr "type" "ishift")
- (set_attr "length" "2")])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "SI")])
(define_insn "*ashrsi3_one_bit_cmp_zext"
[(set (reg FLAGS_REG)
@@ -12607,7 +13169,8 @@
&& ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
"sar{l}\t%k0"
[(set_attr "type" "ishift")
- (set_attr "length" "2")])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "SI")])
;; This pattern can't accept a variable shift count, since shifts by
;; zero don't affect the flags. We assume that shifts by constant
@@ -12673,10 +13236,8 @@
&& ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
"sar{w}\t%0"
[(set_attr "type" "ishift")
- (set (attr "length")
- (if_then_else (match_operand 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "HI")])
(define_insn "*ashrhi3_1"
[(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
@@ -12706,10 +13267,8 @@
&& ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
"sar{w}\t%0"
[(set_attr "type" "ishift")
- (set (attr "length")
- (if_then_else (match_operand 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "HI")])
(define_insn "*ashrhi3_one_bit_cconly"
[(set (reg FLAGS_REG)
@@ -12723,7 +13282,8 @@
&& ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
"sar{w}\t%0"
[(set_attr "type" "ishift")
- (set_attr "length" "2")])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "HI")])
;; This pattern can't accept a variable shift count, since shifts by
;; zero don't affect the flags. We assume that shifts by constant
@@ -12773,10 +13333,8 @@
&& ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
"sar{b}\t%0"
[(set_attr "type" "ishift")
- (set (attr "length")
- (if_then_else (match_operand 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "QI")])
(define_insn "*ashrqi3_1_one_bit_slp"
[(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
@@ -12788,10 +13346,8 @@
&& ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
"sar{b}\t%0"
[(set_attr "type" "ishift1")
- (set (attr "length")
- (if_then_else (match_operand 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "QI")])
(define_insn "*ashrqi3_1"
[(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
@@ -12834,10 +13390,8 @@
&& ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
"sar{b}\t%0"
[(set_attr "type" "ishift")
- (set (attr "length")
- (if_then_else (match_operand 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "QI")])
(define_insn "*ashrqi3_one_bit_cconly"
[(set (reg FLAGS_REG)
@@ -12851,7 +13405,8 @@
&& ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
"sar{b}\t%0"
[(set_attr "type" "ishift")
- (set_attr "length" "2")])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "QI")])
;; This pattern can't accept a variable shift count, since shifts by
;; zero don't affect the flags. We assume that shifts by constant
@@ -12911,6 +13466,7 @@
}
[(set_attr "type" "sseishft")
(set_attr "prefix" "vex")
+ (set_attr "length_immediate" "1")
(set_attr "mode" "TI")])
(define_insn "sse2_lshrti3"
@@ -12924,6 +13480,7 @@
}
[(set_attr "type" "sseishft")
(set_attr "prefix_data16" "1")
+ (set_attr "length_immediate" "1")
(set_attr "mode" "TI")])
(define_insn "*lshrti3_1"
@@ -12973,10 +13530,8 @@
&& ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
"shr{q}\t%0"
[(set_attr "type" "ishift")
- (set (attr "length")
- (if_then_else (match_operand:DI 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "DI")])
(define_insn "*lshrdi3_1_rex64"
[(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
@@ -13007,10 +13562,8 @@
&& ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
"shr{q}\t%0"
[(set_attr "type" "ishift")
- (set (attr "length")
- (if_then_else (match_operand:DI 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "DI")])
(define_insn "*lshrdi3_cconly_one_bit_rex64"
[(set (reg FLAGS_REG)
@@ -13025,7 +13578,8 @@
&& ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
"shr{q}\t%0"
[(set_attr "type" "ishift")
- (set_attr "length" "2")])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "DI")])
;; This pattern can't accept a variable shift count, since shifts by
;; zero don't affect the flags. We assume that shifts by constant
@@ -13110,10 +13664,8 @@
&& ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
"shr{l}\t%0"
[(set_attr "type" "ishift")
- (set (attr "length")
- (if_then_else (match_operand:SI 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "SI")])
(define_insn "*lshrsi3_1_one_bit_zext"
[(set (match_operand:DI 0 "register_operand" "=r")
@@ -13125,7 +13677,8 @@
&& ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
"shr{l}\t%k0"
[(set_attr "type" "ishift")
- (set_attr "length" "2")])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "SI")])
(define_insn "*lshrsi3_1"
[(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
@@ -13168,10 +13721,8 @@
&& ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
"shr{l}\t%0"
[(set_attr "type" "ishift")
- (set (attr "length")
- (if_then_else (match_operand:SI 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "SI")])
(define_insn "*lshrsi3_one_bit_cconly"
[(set (reg FLAGS_REG)
@@ -13185,7 +13736,8 @@
&& ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
"shr{l}\t%0"
[(set_attr "type" "ishift")
- (set_attr "length" "2")])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "SI")])
(define_insn "*lshrsi3_cmp_one_bit_zext"
[(set (reg FLAGS_REG)
@@ -13201,7 +13753,8 @@
&& ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
"shr{l}\t%k0"
[(set_attr "type" "ishift")
- (set_attr "length" "2")])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "SI")])
;; This pattern can't accept a variable shift count, since shifts by
;; zero don't affect the flags. We assume that shifts by constant
@@ -13267,10 +13820,8 @@
&& ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
"shr{w}\t%0"
[(set_attr "type" "ishift")
- (set (attr "length")
- (if_then_else (match_operand 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "HI")])
(define_insn "*lshrhi3_1"
[(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
@@ -13300,10 +13851,8 @@
&& ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
"shr{w}\t%0"
[(set_attr "type" "ishift")
- (set (attr "length")
- (if_then_else (match_operand:SI 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "HI")])
(define_insn "*lshrhi3_one_bit_cconly"
[(set (reg FLAGS_REG)
@@ -13317,7 +13866,8 @@
&& ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
"shr{w}\t%0"
[(set_attr "type" "ishift")
- (set_attr "length" "2")])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "HI")])
;; This pattern can't accept a variable shift count, since shifts by
;; zero don't affect the flags. We assume that shifts by constant
@@ -13367,10 +13917,8 @@
&& ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
"shr{b}\t%0"
[(set_attr "type" "ishift")
- (set (attr "length")
- (if_then_else (match_operand 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "QI")])
(define_insn "*lshrqi3_1_one_bit_slp"
[(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
@@ -13381,10 +13929,8 @@
&& (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
"shr{b}\t%0"
[(set_attr "type" "ishift1")
- (set (attr "length")
- (if_then_else (match_operand 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "QI")])
(define_insn "*lshrqi3_1"
[(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
@@ -13427,10 +13973,8 @@
&& ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
"shr{b}\t%0"
[(set_attr "type" "ishift")
- (set (attr "length")
- (if_then_else (match_operand:SI 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "QI")])
(define_insn "*lshrqi2_one_bit_cconly"
[(set (reg FLAGS_REG)
@@ -13444,7 +13988,8 @@
&& ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
"shr{b}\t%0"
[(set_attr "type" "ishift")
- (set_attr "length" "2")])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "QI")])
;; This pattern can't accept a variable shift count, since shifts by
;; zero don't affect the flags. We assume that shifts by constant
@@ -13533,10 +14078,8 @@
&& ix86_binary_operator_ok (ROTATE, DImode, operands)"
"rol{q}\t%0"
[(set_attr "type" "rotate")
- (set (attr "length")
- (if_then_else (match_operand:DI 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "DI")])
(define_insn "*rotldi3_1_rex64"
[(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
@@ -13566,10 +14109,8 @@
&& ix86_binary_operator_ok (ROTATE, SImode, operands)"
"rol{l}\t%0"
[(set_attr "type" "rotate")
- (set (attr "length")
- (if_then_else (match_operand:SI 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "SI")])
(define_insn "*rotlsi3_1_one_bit_zext"
[(set (match_operand:DI 0 "register_operand" "=r")
@@ -13582,7 +14123,8 @@
&& ix86_binary_operator_ok (ROTATE, SImode, operands)"
"rol{l}\t%k0"
[(set_attr "type" "rotate")
- (set_attr "length" "2")])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "SI")])
(define_insn "*rotlsi3_1"
[(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
@@ -13625,10 +14167,8 @@
&& ix86_binary_operator_ok (ROTATE, HImode, operands)"
"rol{w}\t%0"
[(set_attr "type" "rotate")
- (set (attr "length")
- (if_then_else (match_operand 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "HI")])
(define_insn "*rotlhi3_1"
[(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
@@ -13668,10 +14208,8 @@
&& (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
"rol{b}\t%0"
[(set_attr "type" "rotate1")
- (set (attr "length")
- (if_then_else (match_operand 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "QI")])
(define_insn "*rotlqi3_1_one_bit"
[(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
@@ -13682,10 +14220,8 @@
&& ix86_binary_operator_ok (ROTATE, QImode, operands)"
"rol{b}\t%0"
[(set_attr "type" "rotate")
- (set (attr "length")
- (if_then_else (match_operand 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "QI")])
(define_insn "*rotlqi3_1_slp"
[(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
@@ -13765,10 +14301,8 @@
&& ix86_binary_operator_ok (ROTATERT, DImode, operands)"
"ror{q}\t%0"
[(set_attr "type" "rotate")
- (set (attr "length")
- (if_then_else (match_operand:DI 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "DI")])
(define_insn "*rotrdi3_1_rex64"
[(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
@@ -13798,10 +14332,8 @@
&& ix86_binary_operator_ok (ROTATERT, SImode, operands)"
"ror{l}\t%0"
[(set_attr "type" "rotate")
- (set (attr "length")
- (if_then_else (match_operand:SI 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "SI")])
(define_insn "*rotrsi3_1_one_bit_zext"
[(set (match_operand:DI 0 "register_operand" "=r")
@@ -13814,10 +14346,8 @@
&& ix86_binary_operator_ok (ROTATERT, SImode, operands)"
"ror{l}\t%k0"
[(set_attr "type" "rotate")
- (set (attr "length")
- (if_then_else (match_operand:SI 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "SI")])
(define_insn "*rotrsi3_1"
[(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
@@ -13860,10 +14390,8 @@
&& ix86_binary_operator_ok (ROTATERT, HImode, operands)"
"ror{w}\t%0"
[(set_attr "type" "rotate")
- (set (attr "length")
- (if_then_else (match_operand 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "HI")])
(define_insn "*rotrhi3_1"
[(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
@@ -13903,10 +14431,8 @@
&& ix86_binary_operator_ok (ROTATERT, QImode, operands)"
"ror{b}\t%0"
[(set_attr "type" "rotate")
- (set (attr "length")
- (if_then_else (match_operand 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "QI")])
(define_insn "*rotrqi3_1_one_bit_slp"
[(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
@@ -13917,10 +14443,8 @@
&& (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
"ror{b}\t%0"
[(set_attr "type" "rotate1")
- (set (attr "length")
- (if_then_else (match_operand 0 "register_operand" "")
- (const_string "2")
- (const_string "*")))])
+ (set_attr "length_immediate" "0")
+ (set_attr "mode" "QI")])
(define_insn "*rotrqi3_1"
[(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
@@ -14028,7 +14552,9 @@
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
"bts{q}\t{%1, %0|%0, %1}"
- [(set_attr "type" "alu1")])
+ [(set_attr "type" "alu1")
+ (set_attr "prefix_0f" "1")
+ (set_attr "mode" "DI")])
(define_insn "*btrq"
[(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
@@ -14038,7 +14564,9 @@
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
"btr{q}\t{%1, %0|%0, %1}"
- [(set_attr "type" "alu1")])
+ [(set_attr "type" "alu1")
+ (set_attr "prefix_0f" "1")
+ (set_attr "mode" "DI")])
(define_insn "*btcq"
[(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
@@ -14048,7 +14576,9 @@
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
"btc{q}\t{%1, %0|%0, %1}"
- [(set_attr "type" "alu1")])
+ [(set_attr "type" "alu1")
+ (set_attr "prefix_0f" "1")
+ (set_attr "mode" "DI")])
;; Allow Nocona to avoid these instructions if a register is available.
@@ -14159,7 +14689,9 @@
(const_int 0)))]
"TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
"bt{q}\t{%1, %0|%0, %1}"
- [(set_attr "type" "alu1")])
+ [(set_attr "type" "alu1")
+ (set_attr "prefix_0f" "1")
+ (set_attr "mode" "DI")])
(define_insn "*btsi"
[(set (reg:CCC FLAGS_REG)
@@ -14171,7 +14703,9 @@
(const_int 0)))]
"TARGET_USE_BT || optimize_function_for_size_p (cfun)"
"bt{l}\t{%1, %0|%0, %1}"
- [(set_attr "type" "alu1")])
+ [(set_attr "type" "alu1")
+ (set_attr "prefix_0f" "1")
+ (set_attr "mode" "SI")])
;; Store-flag instructions.
@@ -14182,18 +14716,6 @@
;; to avoid partial register stalls. Otherwise do things the setcc+movzx
;; way, which can later delete the movzx if only QImode is needed.
-(define_expand "s<code>"
- [(set (match_operand:QI 0 "register_operand" "")
- (int_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
- ""
- "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
-
-(define_expand "s<code>"
- [(set (match_operand:QI 0 "register_operand" "")
- (fp_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
- "TARGET_80387 || TARGET_SSE"
- "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
-
(define_insn "*setcc_1"
[(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
(match_operator:QI 1 "ix86_comparison_operator"
@@ -14296,6 +14818,7 @@
"vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
[(set_attr "type" "ssecmp")
(set_attr "prefix" "vex")
+ (set_attr "length_immediate" "1")
(set_attr "mode" "<MODE>")])
(define_insn "*sse_setcc<mode>"
@@ -14306,6 +14829,7 @@
"SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
"cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
[(set_attr "type" "ssecmp")
+ (set_attr "length_immediate" "1")
(set_attr "mode" "<MODE>")])
(define_insn "*sse5_setcc<mode>"
@@ -14316,33 +14840,13 @@
"TARGET_SSE5"
"com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
[(set_attr "type" "sse4arg")
+ (set_attr "length_immediate" "1")
(set_attr "mode" "<MODE>")])
;; Basic conditional jump instructions.
;; We ignore the overflow flag for signed branch instructions.
-;; For all bCOND expanders, also expand the compare or test insn that
-;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
-
-(define_expand "b<code>"
- [(set (pc)
- (if_then_else (int_cond:CC (reg:CC FLAGS_REG)
- (const_int 0))
- (label_ref (match_operand 0 ""))
- (pc)))]
- ""
- "ix86_expand_branch (<CODE>, operands[0]); DONE;")
-
-(define_expand "b<code>"
- [(set (pc)
- (if_then_else (fp_cond:CC (reg:CC FLAGS_REG)
- (const_int 0))
- (label_ref (match_operand 0 ""))
- (pc)))]
- "TARGET_80387 || TARGET_SSE_MATH"
- "ix86_expand_branch (<CODE>, operands[0]); DONE;")
-
(define_insn "*jcc_1"
[(set (pc)
(if_then_else (match_operator 1 "ix86_comparison_operator"
@@ -15260,7 +15764,7 @@
GEN_INT ((TARGET_64BIT
? (ix86_abi == SYSV_ABI
? X86_64_SSE_REGPARM_MAX
- : X64_SSE_REGPARM_MAX)
+ : X86_64_MS_SSE_REGPARM_MAX)
: X86_32_SSE_REGPARM_MAX)
- 1),
NULL, 0);
@@ -15350,7 +15854,7 @@
(unspec [(const_int 0)] UNSPEC_REP)]
"reload_completed"
"rep\;ret"
- [(set_attr "length" "1")
+ [(set_attr "length" "2")
(set_attr "atom_unit" "jeu")
(set_attr "length_immediate" "0")
(set_attr "prefix_rep" "1")
@@ -15382,16 +15886,16 @@
(set_attr "length_immediate" "0")
(set_attr "modrm" "0")])
-;; Align to 16-byte boundary, max skip in op0. Used to avoid
+;; Pad to 16-byte boundary, max skip in op0. Used to avoid
;; branch prediction penalty for the third jump in a 16-byte
;; block on K8.
-(define_insn "align"
+(define_insn "pad"
[(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
""
{
-#ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
- ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
+#ifdef ASM_OUTPUT_MAX_SKIP_PAD
+ ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
#else
/* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
The align insn is used to avoid 3 jump instructions in the row to improve
@@ -15432,7 +15936,8 @@
"TARGET_64BIT"
"lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
[(set_attr "type" "lea")
- (set_attr "length" "6")])
+ (set_attr "length_address" "4")
+ (set_attr "mode" "DI")])
(define_insn "set_rip_rex64"
[(set (match_operand:DI 0 "register_operand" "=r")
@@ -15440,7 +15945,8 @@
"TARGET_64BIT"
"lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
[(set_attr "type" "lea")
- (set_attr "length" "6")])
+ (set_attr "length_address" "4")
+ (set_attr "mode" "DI")])
(define_insn "set_got_offset_rex64"
[(set (match_operand:DI 0 "register_operand" "=r")
@@ -15450,7 +15956,9 @@
"TARGET_64BIT"
"movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
[(set_attr "type" "imov")
- (set_attr "length" "11")])
+ (set_attr "length_immediate" "0")
+ (set_attr "length_address" "8")
+ (set_attr "mode" "DI")])
(define_expand "epilogue"
[(const_int 0)]
@@ -15476,21 +15984,16 @@
tmp = gen_rtx_MEM (Pmode, tmp);
emit_move_insn (tmp, ra);
- if (Pmode == SImode)
- emit_jump_insn (gen_eh_return_si (sa));
- else
- emit_jump_insn (gen_eh_return_di (sa));
+ emit_jump_insn (gen_eh_return_internal ());
emit_barrier ();
DONE;
})
-(define_insn_and_split "eh_return_<mode>"
- [(set (pc)
- (unspec [(match_operand:P 0 "register_operand" "c")]
- UNSPEC_EH_RETURN))]
+(define_insn_and_split "eh_return_internal"
+ [(eh_return)]
""
"#"
- "reload_completed"
+ "epilogue_completed"
[(const_int 0)]
"ix86_expand_epilogue (2); DONE;")
@@ -15573,7 +16076,9 @@
(ctz:SI (match_dup 1)))]
""
"bsf{l}\t{%1, %0|%0, %1}"
- [(set_attr "prefix_0f" "1")])
+ [(set_attr "type" "alu1")
+ (set_attr "prefix_0f" "1")
+ (set_attr "mode" "SI")])
(define_expand "ffsdi2"
[(set (match_dup 2) (const_int -1))
@@ -15599,7 +16104,9 @@
(ctz:DI (match_dup 1)))]
"TARGET_64BIT"
"bsf{q}\t{%1, %0|%0, %1}"
- [(set_attr "prefix_0f" "1")])
+ [(set_attr "type" "alu1")
+ (set_attr "prefix_0f" "1")
+ (set_attr "mode" "DI")])
(define_insn "ctzsi2"
[(set (match_operand:SI 0 "register_operand" "=r")
@@ -15607,7 +16114,9 @@
(clobber (reg:CC FLAGS_REG))]
""
"bsf{l}\t{%1, %0|%0, %1}"
- [(set_attr "prefix_0f" "1")])
+ [(set_attr "type" "alu1")
+ (set_attr "prefix_0f" "1")
+ (set_attr "mode" "SI")])
(define_insn "ctzdi2"
[(set (match_operand:DI 0 "register_operand" "=r")
@@ -15615,7 +16124,9 @@
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT"
"bsf{q}\t{%1, %0|%0, %1}"
- [(set_attr "prefix_0f" "1")])
+ [(set_attr "type" "alu1")
+ (set_attr "prefix_0f" "1")
+ (set_attr "mode" "DI")])
(define_expand "clzsi2"
[(parallel
@@ -15645,14 +16156,15 @@
(set_attr "type" "bitmanip")
(set_attr "mode" "SI")])
-(define_insn "*bsr"
+(define_insn "bsr"
[(set (match_operand:SI 0 "register_operand" "=r")
(minus:SI (const_int 31)
(clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
(clobber (reg:CC FLAGS_REG))]
""
"bsr{l}\t{%1, %0|%0, %1}"
- [(set_attr "prefix_0f" "1")
+ [(set_attr "type" "alu1")
+ (set_attr "prefix_0f" "1")
(set_attr "mode" "SI")])
(define_insn "popcount<mode>2"
@@ -15716,7 +16228,7 @@
(bswap:SI (match_operand:SI 1 "register_operand" "")))]
""
{
- if (!TARGET_BSWAP)
+ if (!(TARGET_BSWAP || TARGET_MOVBE))
{
rtx x = operands[0];
@@ -15728,6 +16240,21 @@
}
})
+(define_insn "*bswapsi_movbe"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m")
+ (bswap:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,r")))]
+ "TARGET_MOVBE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
+ "@
+ bswap\t%0
+ movbe\t{%1, %0|%0, %1}
+ movbe\t{%1, %0|%0, %1}"
+ [(set_attr "type" "*,imov,imov")
+ (set_attr "modrm" "*,1,1")
+ (set_attr "prefix_0f" "1")
+ (set_attr "prefix_extra" "*,1,1")
+ (set_attr "length" "2,*,*")
+ (set_attr "mode" "SI")])
+
(define_insn "*bswapsi_1"
[(set (match_operand:SI 0 "register_operand" "=r")
(bswap:SI (match_operand:SI 1 "register_operand" "0")))]
@@ -15756,7 +16283,29 @@
[(set_attr "length" "4")
(set_attr "mode" "HI")])
-(define_insn "bswapdi2"
+(define_expand "bswapdi2"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (bswap:DI (match_operand:DI 1 "register_operand" "")))]
+ "TARGET_64BIT"
+ "")
+
+(define_insn "*bswapdi_movbe"
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
+ (bswap:DI (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
+ "TARGET_64BIT && TARGET_MOVBE
+ && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
+ "@
+ bswap\t%0
+ movbe\t{%1, %0|%0, %1}
+ movbe\t{%1, %0|%0, %1}"
+ [(set_attr "type" "*,imov,imov")
+ (set_attr "modrm" "*,1,1")
+ (set_attr "prefix_0f" "1")
+ (set_attr "prefix_extra" "*,1,1")
+ (set_attr "length" "3,*,*")
+ (set_attr "mode" "DI")])
+
+(define_insn "*bswapdi_1"
[(set (match_operand:DI 0 "register_operand" "=r")
(bswap:DI (match_operand:DI 1 "register_operand" "0")))]
"TARGET_64BIT"
@@ -15792,14 +16341,15 @@
(set_attr "type" "bitmanip")
(set_attr "mode" "DI")])
-(define_insn "*bsr_rex64"
+(define_insn "bsr_rex64"
[(set (match_operand:DI 0 "register_operand" "=r")
(minus:DI (const_int 63)
(clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT"
"bsr{q}\t{%1, %0|%0, %1}"
- [(set_attr "prefix_0f" "1")
+ [(set_attr "type" "alu1")
+ (set_attr "prefix_0f" "1")
(set_attr "mode" "DI")])
(define_expand "clzhi2"
@@ -15837,7 +16387,8 @@
(clobber (reg:CC FLAGS_REG))]
""
"bsr{w}\t{%1, %0|%0, %1}"
- [(set_attr "prefix_0f" "1")
+ [(set_attr "type" "alu1")
+ (set_attr "prefix_0f" "1")
(set_attr "mode" "HI")])
(define_expand "paritydi2"
@@ -18937,6 +19488,7 @@
"TARGET_USE_FANCY_MATH_387"
"fxam\n\tfnstsw\t%0"
[(set_attr "type" "multi")
+ (set_attr "length" "4")
(set_attr "unit" "i387")
(set_attr "mode" "<MODE>")])
@@ -19228,6 +19780,7 @@
"movsb"
[(set_attr "type" "str")
(set_attr "memory" "both")
+ (set_attr "prefix_rex" "0")
(set_attr "mode" "QI")])
(define_expand "rep_mov"
@@ -19484,6 +20037,7 @@
"stosb"
[(set_attr "type" "str")
(set_attr "memory" "store")
+ (set_attr "prefix_rex" "0")
(set_attr "mode" "QI")])
(define_expand "rep_stos"
@@ -19577,6 +20131,7 @@
[(set_attr "type" "str")
(set_attr "prefix_rep" "1")
(set_attr "memory" "store")
+ (set_attr "prefix_rex" "0")
(set_attr "mode" "QI")])
(define_expand "cmpstrnsi"
@@ -19703,6 +20258,7 @@
"repz cmpsb"
[(set_attr "type" "str")
(set_attr "mode" "QI")
+ (set_attr "prefix_rex" "0")
(set_attr "prefix_rep" "1")])
;; The same, but the count is not known to not be zero.
@@ -19756,6 +20312,7 @@
"repz cmpsb"
[(set_attr "type" "str")
(set_attr "mode" "QI")
+ (set_attr "prefix_rex" "0")
(set_attr "prefix_rep" "1")])
(define_expand "strlensi"
@@ -19817,6 +20374,7 @@
"repnz scasb"
[(set_attr "type" "str")
(set_attr "mode" "QI")
+ (set_attr "prefix_rex" "0")
(set_attr "prefix_rep" "1")])
;; Peephole optimizations to clean up after cmpstrn*. This should be
@@ -20337,6 +20895,14 @@
(const_string "imov")
]
(const_string "lea")))
+ (set (attr "length_immediate")
+ (cond [(eq_attr "type" "imov")
+ (const_string "0")
+ (and (eq_attr "type" "alu")
+ (match_operand 2 "const128_operand" ""))
+ (const_string "1")
+ ]
+ (const_string "*")))
(set_attr "mode" "SI")])
(define_insn "pro_epilogue_adjust_stack_rex64"
@@ -20381,6 +20947,14 @@
(const_string "imov")
]
(const_string "lea")))
+ (set (attr "length_immediate")
+ (cond [(eq_attr "type" "imov")
+ (const_string "0")
+ (and (eq_attr "type" "alu")
+ (match_operand 2 "const128_operand" ""))
+ (const_string "1")
+ ]
+ (const_string "*")))
(set_attr "mode" "DI")])
(define_insn "pro_epilogue_adjust_stack_rex64_2"
@@ -21868,6 +22442,7 @@
}
[(set_attr "type" "sse")
(set_attr "atom_sse_attr" "prefetch")
+ (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
(set_attr "memory" "none")])
(define_insn "*prefetch_sse_rex"
@@ -21887,6 +22462,7 @@
}
[(set_attr "type" "sse")
(set_attr "atom_sse_attr" "prefetch")
+ (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
(set_attr "memory" "none")])
(define_insn "*prefetch_3dnow"
@@ -21901,6 +22477,7 @@
return "prefetchw\t%a0";
}
[(set_attr "type" "mmx")
+ (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
(set_attr "memory" "none")])
(define_insn "*prefetch_3dnow_rex"
@@ -21915,6 +22492,7 @@
return "prefetchw\t%a0";
}
[(set_attr "type" "mmx")
+ (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
(set_attr "memory" "none")])
(define_expand "stack_protect_set"
@@ -22004,9 +22582,8 @@
emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
#endif
- ix86_compare_op0 = flags;
- ix86_compare_op1 = const0_rtx;
- emit_jump_insn (gen_beq (operands[2]));
+ emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
+ flags, const0_rtx, operands[2]));
DONE;
})
@@ -22068,11 +22645,19 @@
[(match_operand:SI 1 "register_operand" "0")
(match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
UNSPEC_CRC32))]
- "TARGET_SSE4_2"
+ "TARGET_SSE4_2 || TARGET_CRC32"
"crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
[(set_attr "type" "sselog1")
(set_attr "prefix_rep" "1")
(set_attr "prefix_extra" "1")
+ (set (attr "prefix_data16")
+ (if_then_else (match_operand:HI 2 "" "")
+ (const_string "1")
+ (const_string "*")))
+ (set (attr "prefix_rex")
+ (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
+ (const_string "1")
+ (const_string "*")))
(set_attr "mode" "SI")])
(define_insn "sse4_2_crc32di"
@@ -22081,13 +22666,176 @@
[(match_operand:DI 1 "register_operand" "0")
(match_operand:DI 2 "nonimmediate_operand" "rm")]
UNSPEC_CRC32))]
- "TARGET_SSE4_2 && TARGET_64BIT"
+ "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
"crc32q\t{%2, %0|%0, %2}"
[(set_attr "type" "sselog1")
(set_attr "prefix_rep" "1")
(set_attr "prefix_extra" "1")
(set_attr "mode" "DI")])
+(define_expand "rdpmc"
+ [(match_operand:DI 0 "register_operand" "")
+ (match_operand:SI 1 "register_operand" "")]
+ ""
+{
+ rtx reg = gen_reg_rtx (DImode);
+ rtx si;
+
+ /* Force operand 1 into ECX. */
+ rtx ecx = gen_rtx_REG (SImode, CX_REG);
+ emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
+ si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
+ UNSPECV_RDPMC);
+
+ if (TARGET_64BIT)
+ {
+ rtvec vec = rtvec_alloc (2);
+ rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
+ rtx upper = gen_reg_rtx (DImode);
+ rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
+ gen_rtvec (1, const0_rtx),
+ UNSPECV_RDPMC);
+ RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
+ RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
+ emit_insn (load);
+ upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
+ NULL, 1, OPTAB_DIRECT);
+ reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
+ OPTAB_DIRECT);
+ }
+ else
+ emit_insn (gen_rtx_SET (VOIDmode, reg, si));
+ emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
+ DONE;
+})
+
+(define_insn "*rdpmc"
+ [(set (match_operand:DI 0 "register_operand" "=A")
+ (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
+ UNSPECV_RDPMC))]
+ "!TARGET_64BIT"
+ "rdpmc"
+ [(set_attr "type" "other")
+ (set_attr "length" "2")])
+
+(define_insn "*rdpmc_rex64"
+ [(set (match_operand:DI 0 "register_operand" "=a")
+ (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
+ UNSPECV_RDPMC))
+ (set (match_operand:DI 1 "register_operand" "=d")
+ (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
+ "TARGET_64BIT"
+ "rdpmc"
+ [(set_attr "type" "other")
+ (set_attr "length" "2")])
+
+(define_expand "rdtsc"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
+ ""
+{
+ if (TARGET_64BIT)
+ {
+ rtvec vec = rtvec_alloc (2);
+ rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
+ rtx upper = gen_reg_rtx (DImode);
+ rtx lower = gen_reg_rtx (DImode);
+ rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
+ gen_rtvec (1, const0_rtx),
+ UNSPECV_RDTSC);
+ RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
+ RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
+ emit_insn (load);
+ upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
+ NULL, 1, OPTAB_DIRECT);
+ lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
+ OPTAB_DIRECT);
+ emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
+ DONE;
+ }
+})
+
+(define_insn "*rdtsc"
+ [(set (match_operand:DI 0 "register_operand" "=A")
+ (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
+ "!TARGET_64BIT"
+ "rdtsc"
+ [(set_attr "type" "other")
+ (set_attr "length" "2")])
+
+(define_insn "*rdtsc_rex64"
+ [(set (match_operand:DI 0 "register_operand" "=a")
+ (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
+ (set (match_operand:DI 1 "register_operand" "=d")
+ (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
+ "TARGET_64BIT"
+ "rdtsc"
+ [(set_attr "type" "other")
+ (set_attr "length" "2")])
+
+(define_expand "rdtscp"
+ [(match_operand:DI 0 "register_operand" "")
+ (match_operand:SI 1 "memory_operand" "")]
+ ""
+{
+ rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
+ gen_rtvec (1, const0_rtx),
+ UNSPECV_RDTSCP);
+ rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
+ gen_rtvec (1, const0_rtx),
+ UNSPECV_RDTSCP);
+ rtx reg = gen_reg_rtx (DImode);
+ rtx tmp = gen_reg_rtx (SImode);
+
+ if (TARGET_64BIT)
+ {
+ rtvec vec = rtvec_alloc (3);
+ rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
+ rtx upper = gen_reg_rtx (DImode);
+ RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
+ RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
+ RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
+ emit_insn (load);
+ upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
+ NULL, 1, OPTAB_DIRECT);
+ reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
+ OPTAB_DIRECT);
+ }
+ else
+ {
+ rtvec vec = rtvec_alloc (2);
+ rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
+ RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
+ RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
+ emit_insn (load);
+ }
+ emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
+ emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
+ DONE;
+})
+
+(define_insn "*rdtscp"
+ [(set (match_operand:DI 0 "register_operand" "=A")
+ (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
+ (set (match_operand:SI 1 "register_operand" "=c")
+ (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
+ "!TARGET_64BIT"
+ "rdtscp"
+ [(set_attr "type" "other")
+ (set_attr "length" "3")])
+
+(define_insn "*rdtscp_rex64"
+ [(set (match_operand:DI 0 "register_operand" "=a")
+ (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
+ (set (match_operand:DI 1 "register_operand" "=d")
+ (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
+ (set (match_operand:SI 2 "register_operand" "=c")
+ (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
+ "TARGET_64BIT"
+ "rdtscp"
+ [(set_attr "type" "other")
+ (set_attr "length" "3")])
+
(include "mmx.md")
(include "sse.md")
(include "sync.md")
diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt
index 6fd218f8ede..9ec93d8c2a8 100644
--- a/gcc/config/i386/i386.opt
+++ b/gcc/config/i386/i386.opt
@@ -339,6 +339,14 @@ msahf
Target Report Mask(ISA_SAHF) Var(ix86_isa_flags) VarExists Save
Support code generation of sahf instruction in 64bit x86-64 code.
+mmovbe
+Target Report Mask(ISA_MOVBE) Var(ix86_isa_flags) VarExists Save
+Support code generation of movbe instruction.
+
+mcrc32
+Target Report Mask(ISA_CRC32) Var(ix86_isa_flags) VarExists Save
+Support code generation of crc32 instruction.
+
maes
Target Report Mask(ISA_AES) Var(ix86_isa_flags) VarExists Save
Support AES built-in functions and code generation
diff --git a/gcc/config/i386/ia32intrin.h b/gcc/config/i386/ia32intrin.h
new file mode 100644
index 00000000000..e701b19e2a8
--- /dev/null
+++ b/gcc/config/i386/ia32intrin.h
@@ -0,0 +1,230 @@
+/* Copyright (C) 2009 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/>. */
+
+#ifndef _X86INTRIN_H_INCLUDED
+# error "Never use <ia32intrin.h> directly; include <x86intrin.h> instead."
+#endif
+
+/* 32bit bsf */
+extern __inline int
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__bsfd (int __X)
+{
+ return __builtin_ctz (__X);
+}
+
+/* 32bit bsr */
+extern __inline int
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__bsrd (int __X)
+{
+ return __builtin_ia32_bsrsi (__X);
+}
+
+/* 32bit bswap */
+extern __inline int
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__bswapd (int __X)
+{
+ return __builtin_bswap32 (__X);
+}
+
+/* 32bit accumulate CRC32 (polynomial 0x11EDC6F41) value. */
+extern __inline unsigned int
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__crc32b (unsigned int __C, unsigned char __V)
+{
+ return __builtin_ia32_crc32qi (__C, __V);
+}
+
+extern __inline unsigned int
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__crc32w (unsigned int __C, unsigned short __V)
+{
+ return __builtin_ia32_crc32hi (__C, __V);
+}
+
+extern __inline unsigned int
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__crc32d (unsigned int __C, unsigned int __V)
+{
+ return __builtin_ia32_crc32si (__C, __V);
+}
+
+/* 32bit popcnt */
+extern __inline int
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__popcntd (unsigned int __X)
+{
+ return __builtin_popcount (__X);
+}
+
+/* rdpmc */
+extern __inline unsigned long long
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__rdpmc (int __S)
+{
+ return __builtin_ia32_rdpmc (__S);
+}
+
+/* rdtsc */
+extern __inline unsigned long long
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__rdtsc (void)
+{
+ return __builtin_ia32_rdtsc ();
+}
+
+/* rdtscp */
+extern __inline unsigned long long
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__rdtscp (unsigned int *__A)
+{
+ return __builtin_ia32_rdtscp (__A);
+}
+
+/* 8bit rol */
+extern __inline unsigned char
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__rolb (unsigned char __X, int __C)
+{
+ return __builtin_ia32_rolqi (__X, __C);
+}
+
+/* 16bit rol */
+extern __inline unsigned short
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__rolw (unsigned short __X, int __C)
+{
+ return __builtin_ia32_rolhi (__X, __C);
+}
+
+/* 32bit rol */
+extern __inline unsigned int
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__rold (unsigned int __X, int __C)
+{
+ return (__X << __C) | (__X >> (32 - __C));
+}
+
+/* 8bit ror */
+extern __inline unsigned char
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__rorb (unsigned char __X, int __C)
+{
+ return __builtin_ia32_rorqi (__X, __C);
+}
+
+/* 16bit ror */
+extern __inline unsigned short
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__rorw (unsigned short __X, int __C)
+{
+ return __builtin_ia32_rorhi (__X, __C);
+}
+
+/* 32bit ror */
+extern __inline unsigned int
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__rord (unsigned int __X, int __C)
+{
+ return (__X >> __C) | (__X << (32 - __C));
+}
+
+#ifdef __x86_64__
+/* 64bit bsf */
+extern __inline int
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__bsfq (long long __X)
+{
+ return __builtin_ctzll (__X);
+}
+
+/* 64bit bsr */
+extern __inline int
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__bsrq (long long __X)
+{
+ return __builtin_ia32_bsrdi (__X);
+}
+
+/* 64bit bswap */
+extern __inline long long
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__bswapq (long long __X)
+{
+ return __builtin_bswap64 (__X);
+}
+
+/* 64bit accumulate CRC32 (polynomial 0x11EDC6F41) value. */
+extern __inline unsigned long long
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__crc32q (unsigned long long __C, unsigned long long __V)
+{
+ return __builtin_ia32_crc32di (__C, __V);
+}
+
+/* 64bit popcnt */
+extern __inline long long
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__popcntq (unsigned long long __X)
+{
+ return __builtin_popcountll (__X);
+}
+
+/* 64bit rol */
+extern __inline unsigned long long
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__rolq (unsigned long long __X, int __C)
+{
+ return (__X << __C) | (__X >> (64 - __C));
+}
+
+/* 64bit ror */
+extern __inline unsigned long long
+__attribute__((__gnu_inline__, __always_inline__, __artificial__))
+__rorq (unsigned long long __X, int __C)
+{
+ return (__X >> __C) | (__X << (64 - __C));
+}
+
+#define _bswap64(a) __bswapq(a)
+#define _popcnt64(a) __popcntq(a)
+#define _lrotl(a,b) __rolq((a), (b))
+#define _lrotr(a,b) __rorq((a), (b))
+#else
+#define _lrotl(a,b) __rold((a), (b))
+#define _lrotr(a,b) __rord((a), (b))
+#endif
+
+#define _bit_scan_forward(a) __bsfd(a)
+#define _bit_scan_reverse(a) __bsrd(a)
+#define _bswap(a) __bswapd(a)
+#define _popcnt32(a) __popcntd(a)
+#define _rdpmc(a) __rdpmc(a)
+#define _rdtsc() __rdtsc()
+#define _rdtscp(a) __rdtscp(a)
+#define _rotwl(a,b) __rolw((a), (b))
+#define _rotwr(a,b) __rorw((a), (b))
+#define _rotl(a,b) __rold((a), (b))
+#define _rotr(a,b) __rord((a), (b))
diff --git a/gcc/config/i386/linux.h b/gcc/config/i386/linux.h
index 229316867fd..9742b9b5ccf 100644
--- a/gcc/config/i386/linux.h
+++ b/gcc/config/i386/linux.h
@@ -1,6 +1,6 @@
/* Definitions for Intel 386 running Linux-based GNU systems with ELF format.
Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2001, 2002, 2004, 2005,
- 2006, 2007, 2008 Free Software Foundation, Inc.
+ 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
Contributed by Eric Youngdale.
Modified for stabs-in-ELF by H.J. Lu.
@@ -153,7 +153,9 @@ along with GCC; see the file COPYING3. If not see
fprintf ((FILE), "\t.p2align %d,,%d\n", (LOG), (MAX_SKIP)); \
/* Make sure that we have at least 8 byte alignment if > 8 byte \
alignment is preferred. */ \
- if ((LOG) > 3 && (1 << (LOG)) > ((MAX_SKIP) + 1)) \
+ if ((LOG) > 3 \
+ && (1 << (LOG)) > ((MAX_SKIP) + 1) \
+ && (MAX_SKIP) >= 7) \
fprintf ((FILE), "\t.p2align 3\n"); \
} \
} \
diff --git a/gcc/config/i386/mingw-tls.c b/gcc/config/i386/mingw-tls.c
new file mode 100644
index 00000000000..7a5c7758b2e
--- /dev/null
+++ b/gcc/config/i386/mingw-tls.c
@@ -0,0 +1,233 @@
+/* Catch and clean up data allocated in TLS.
+ Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+ 2009 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/>. */
+
+/* This part is based on the implementation of Mumit Khan <khan@nanotech.wisc.edu>
+ * provided to mingw under public domain and ported for libgcc by Kai Tietz.
+ */
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef WIN32_LEAN_AND_MEAN
+#include <stdlib.h>
+
+/* The list of threads active with key/dtor pairs. */
+typedef struct __mingwthr_key {
+ DWORD key;
+ void (*dtor) (void *);
+ struct __mingwthr_key *next;
+} __mingwthr_key_t;
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+
+/* Possibly we could define this here for none MT too and avoid use of
+ mingwthrd.a at all, but well ... */
+#ifdef SHARED
+__declspec(dllexport)
+int _CRT_MT = 1;
+#else
+#if 0
+int _CRT_MT = 0;
+#endif
+#endif
+
+/* Static functions for libgcc. */
+#ifndef SHARED
+
+int __mingwthr_key_dtor (DWORD,void (*dtor)(void *));
+int __mingwthr_remove_key_dtor (DWORD);
+
+
+int
+__mingwthr_key_dtor (DWORD key __attribute__ ((__unused__)),
+ void (*dtor) (void *) __attribute__ ((__unused__)))
+{
+ return 0;
+}
+
+int
+__mingwthr_remove_key_dtor (DWORD key __attribute__ ((__unused__)))
+{
+ return 0;
+}
+
+#else
+/* Shared functions for libgcc. */
+
+/* Prototypes. */
+__declspec(dllexport) int __mingwthr_key_dtor (DWORD key, void (*) (void *));
+__declspec(dllexport) int __mingwthr_remove_key_dtor (DWORD);
+BOOL APIENTRY DllMain (HANDLE, DWORD, LPVOID);
+
+
+/* To protect the thread/key association data structure modifications. */
+static CRITICAL_SECTION __mingwthr_cs;
+static __mingwthr_key_t *key_dtor_list;
+
+/*
+ * __mingwthr_key_add:
+ *
+ * Add key/dtor association for this thread. If the thread entry does not
+ * exist, create a new one and add to the head of the threads list; add
+ * the new assoc at the head of the keys list.
+ *
+ */
+
+static int
+___mingwthr_add_key_dtor (DWORD key, void (*dtor) (void *))
+{
+ __mingwthr_key_t *new_key;
+
+ new_key = (__mingwthr_key_t *) calloc (1, sizeof (__mingwthr_key_t));
+ if (new_key == NULL)
+ return -1;
+
+ new_key->key = key;
+ new_key->dtor = dtor;
+
+ EnterCriticalSection (&__mingwthr_cs);
+
+ new_key->next = key_dtor_list;
+ key_dtor_list = new_key;
+
+ LeaveCriticalSection (&__mingwthr_cs);
+
+ return 0;
+}
+
+static int
+___mingwthr_remove_key_dtor (DWORD key)
+{
+ __mingwthr_key_t *prev_key;
+ __mingwthr_key_t *cur_key;
+
+ EnterCriticalSection (&__mingwthr_cs);
+
+ prev_key = NULL;
+ cur_key = key_dtor_list;
+
+ while (cur_key != NULL)
+ {
+ if( cur_key->key == key )
+ {
+ /* take key/dtor out of list */
+ if (prev_key == NULL)
+ key_dtor_list = cur_key->next;
+ else
+ prev_key->next = cur_key->next;
+
+ free (cur_key);
+ break;
+ }
+
+ prev_key = cur_key;
+ cur_key = cur_key->next;
+ }
+
+ LeaveCriticalSection (&__mingwthr_cs);
+
+ return 0;
+}
+
+/*
+ * __mingwthr_run_key_dtors (void):
+ *
+ * Callback from DllMain when thread detaches to clean up the key
+ * storage.
+ *
+ * Note that this does not delete the key itself, but just runs
+ * the dtor if the current value are both non-NULL. Note that the
+ * keys with NULL dtors are not added by __mingwthr_key_dtor, the
+ * only public interface, so we don't need to check.
+ *
+ */
+
+static void
+__mingwthr_run_key_dtors (void)
+{
+ __mingwthr_key_t *keyp;
+
+ EnterCriticalSection (&__mingwthr_cs);
+
+ for (keyp = key_dtor_list; keyp; )
+ {
+ LPVOID value = TlsGetValue (keyp->key);
+ if (GetLastError () == ERROR_SUCCESS)
+ {
+ if (value)
+ (*keyp->dtor) (value);
+ }
+ keyp = keyp->next;
+ }
+
+ LeaveCriticalSection (&__mingwthr_cs);
+}
+
+/*
+ * __mingwthr_register_key_dtor (DWORD key, void (*dtor) (void *))
+ *
+ * Public interface called by C++ exception handling mechanism in
+ * libgcc (cf: __gthread_key_create).
+ *
+ */
+
+__declspec(dllexport)
+int
+__mingwthr_key_dtor (DWORD key, void (*dtor) (void *))
+{
+ if (dtor)
+ return ___mingwthr_add_key_dtor (key, dtor);
+
+ return 0;
+}
+
+__declspec(dllexport)
+int
+__mingwthr_remove_key_dtor (DWORD key)
+{
+ return ___mingwthr_remove_key_dtor (key);
+}
+
+BOOL APIENTRY
+DllMain (HANDLE hDllHandle __attribute__ ((__unused__)),
+ DWORD reason /* Reason this function is being called. */,
+ LPVOID reserved __attribute__ ((__unused__)))
+{
+ switch (reason)
+ {
+ case DLL_PROCESS_ATTACH:
+ InitializeCriticalSection (&__mingwthr_cs);
+ break;
+
+ case DLL_PROCESS_DETACH:
+ __mingwthr_run_key_dtors ();
+ DeleteCriticalSection (&__mingwthr_cs);
+ break;
+
+ case DLL_THREAD_ATTACH:
+ break;
+
+ case DLL_THREAD_DETACH:
+ __mingwthr_run_key_dtors ();
+ break;
+ }
+ return TRUE;
+}
+#endif
+#endif
diff --git a/gcc/config/i386/mmx.md b/gcc/config/i386/mmx.md
index 5184b1d7f5c..dea9322f9a8 100644
--- a/gcc/config/i386/mmx.md
+++ b/gcc/config/i386/mmx.md
@@ -1,5 +1,5 @@
;; GCC machine description for MMX and 3dNOW! instructions
-;; Copyright (C) 2005, 2007, 2008
+;; Copyright (C) 2005, 2007, 2008, 2009
;; Free Software Foundation, Inc.
;;
;; This file is part of GCC.
@@ -85,6 +85,12 @@
%vmovq\t{%1, %0|%0, %1}"
[(set_attr "type" "imov,imov,mmx,mmxmov,mmxmov,ssecvt,ssecvt,sselog1,ssemov,ssemov,ssemov,ssemov")
(set_attr "unit" "*,*,*,*,*,mmx,mmx,*,*,*,*,*")
+ (set_attr "prefix_rep" "*,*,*,*,*,1,1,*,1,*,*,*")
+ (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,1,1,1")
+ (set (attr "prefix_rex")
+ (if_then_else (eq_attr "alternative" "8,9")
+ (symbol_ref "x86_extended_reg_mentioned_p (insn)")
+ (const_string "*")))
(set (attr "prefix")
(if_then_else (eq_attr "alternative" "7,8,9,10,11")
(const_string "maybe_vex")
@@ -111,6 +117,7 @@
#"
[(set_attr "type" "mmx,mmxmov,mmxmov,ssecvt,ssecvt,sselog1,ssemov,ssemov,*,*")
(set_attr "unit" "*,*,*,mmx,mmx,*,*,*,*,*")
+ (set_attr "prefix_rep" "*,*,*,1,1,*,*,*,*,*")
(set (attr "prefix")
(if_then_else (eq_attr "alternative" "5,6,7")
(const_string "vex")
@@ -141,6 +148,8 @@
#"
[(set_attr "type" "mmx,mmxmov,mmxmov,ssecvt,ssecvt,sselog1,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov,*,*")
(set_attr "unit" "*,*,*,mmx,mmx,*,*,*,*,*,*,*,*,*")
+ (set_attr "prefix_rep" "*,*,*,1,1,*,1,*,*,*,*,*,*,*")
+ (set_attr "prefix_data16" "*,*,*,*,*,*,*,1,*,*,*,*,*,*")
(set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,DI,V4SF,V4SF,V2SF,V2SF,DI,DI")])
(define_expand "movv2sf"
@@ -175,6 +184,8 @@
vmovq\t{%1, %0|%0, %1}"
[(set_attr "type" "imov,imov,mmx,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,sselog1,ssemov,ssemov,ssemov,ssemov")
(set_attr "unit" "*,*,*,*,*,mmx,mmx,*,*,*,*,*,*")
+ (set_attr "prefix_rep" "*,*,*,*,*,1,1,*,*,*,*,*,*")
+ (set_attr "length_vex" "*,*,*,*,*,*,*,*,*,*,*,4,4")
(set (attr "prefix")
(if_then_else (eq_attr "alternative" "7,8,9,10,11,12")
(const_string "vex")
@@ -204,6 +215,7 @@
movd\t{%1, %0|%0, %1}"
[(set_attr "type" "imov,imov,mmx,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,sselog1,ssemov,ssemov,ssemov,ssemov")
(set_attr "unit" "*,*,*,*,*,mmx,mmx,*,*,*,*,*,*")
+ (set_attr "prefix_rep" "*,*,*,*,*,1,1,*,*,*,*,*,*")
(set_attr "mode" "DI,DI,DI,DI,DI,DI,DI,V4SF,V4SF,V2SF,V2SF,DI,DI")])
(define_insn "*movv2sf_internal_avx"
@@ -227,6 +239,7 @@
#"
[(set_attr "type" "mmx,mmxmov,mmxmov,ssecvt,ssecvt,sselog1,ssemov,ssemov,ssemov,*,*")
(set_attr "unit" "*,*,*,mmx,mmx,*,*,*,*,*,*")
+ (set_attr "prefix_rep" "*,*,*,1,1,*,*,*,*,*,*")
(set (attr "prefix")
(if_then_else (eq_attr "alternative" "5,6,7,8")
(const_string "vex")
@@ -254,6 +267,7 @@
#"
[(set_attr "type" "mmx,mmxmov,mmxmov,ssecvt,ssecvt,sselog1,ssemov,ssemov,ssemov,*,*")
(set_attr "unit" "*,*,*,mmx,mmx,*,*,*,*,*,*")
+ (set_attr "prefix_rep" "*,*,*,1,1,*,*,*,*,*,*")
(set_attr "mode" "DI,DI,DI,DI,DI,V4SF,V4SF,V2SF,V2SF,DI,DI")])
;; %%% This multiword shite has got to go.
@@ -313,6 +327,7 @@
"TARGET_3DNOW && ix86_binary_operator_ok (PLUS, V2SFmode, operands)"
"pfadd\t{%2, %0|%0, %2}"
[(set_attr "type" "mmxadd")
+ (set_attr "prefix_extra" "1")
(set_attr "mode" "V2SF")])
(define_expand "mmx_subv2sf3"
@@ -338,6 +353,7 @@
pfsub\t{%2, %0|%0, %2}
pfsubr\t{%2, %0|%0, %2}"
[(set_attr "type" "mmxadd")
+ (set_attr "prefix_extra" "1")
(set_attr "mode" "V2SF")])
(define_expand "mmx_mulv2sf3"
@@ -354,6 +370,7 @@
"TARGET_3DNOW && ix86_binary_operator_ok (MULT, V2SFmode, operands)"
"pfmul\t{%2, %0|%0, %2}"
[(set_attr "type" "mmxmul")
+ (set_attr "prefix_extra" "1")
(set_attr "mode" "V2SF")])
;; ??? For !flag_finite_math_only, the representation with SMIN/SMAX
@@ -381,6 +398,7 @@
&& ix86_binary_operator_ok (<CODE>, V2SFmode, operands)"
"pf<maxminfprefix>\t{%2, %0|%0, %2}"
[(set_attr "type" "mmxadd")
+ (set_attr "prefix_extra" "1")
(set_attr "mode" "V2SF")])
(define_insn "*mmx_<code>v2sf3"
@@ -391,6 +409,7 @@
"TARGET_3DNOW"
"pf<maxminfprefix>\t{%2, %0|%0, %2}"
[(set_attr "type" "mmxadd")
+ (set_attr "prefix_extra" "1")
(set_attr "mode" "V2SF")])
(define_insn "mmx_rcpv2sf2"
@@ -400,6 +419,7 @@
"TARGET_3DNOW"
"pfrcp\t{%1, %0|%0, %1}"
[(set_attr "type" "mmx")
+ (set_attr "prefix_extra" "1")
(set_attr "mode" "V2SF")])
(define_insn "mmx_rcpit1v2sf3"
@@ -410,6 +430,7 @@
"TARGET_3DNOW"
"pfrcpit1\t{%2, %0|%0, %2}"
[(set_attr "type" "mmx")
+ (set_attr "prefix_extra" "1")
(set_attr "mode" "V2SF")])
(define_insn "mmx_rcpit2v2sf3"
@@ -420,6 +441,7 @@
"TARGET_3DNOW"
"pfrcpit2\t{%2, %0|%0, %2}"
[(set_attr "type" "mmx")
+ (set_attr "prefix_extra" "1")
(set_attr "mode" "V2SF")])
(define_insn "mmx_rsqrtv2sf2"
@@ -429,6 +451,7 @@
"TARGET_3DNOW"
"pfrsqrt\t{%1, %0|%0, %1}"
[(set_attr "type" "mmx")
+ (set_attr "prefix_extra" "1")
(set_attr "mode" "V2SF")])
(define_insn "mmx_rsqit1v2sf3"
@@ -439,6 +462,7 @@
"TARGET_3DNOW"
"pfrsqit1\t{%2, %0|%0, %2}"
[(set_attr "type" "mmx")
+ (set_attr "prefix_extra" "1")
(set_attr "mode" "V2SF")])
(define_insn "mmx_haddv2sf3"
@@ -457,6 +481,7 @@
"TARGET_3DNOW"
"pfacc\t{%2, %0|%0, %2}"
[(set_attr "type" "mmxadd")
+ (set_attr "prefix_extra" "1")
(set_attr "mode" "V2SF")])
(define_insn "mmx_hsubv2sf3"
@@ -475,6 +500,7 @@
"TARGET_3DNOW_A"
"pfnacc\t{%2, %0|%0, %2}"
[(set_attr "type" "mmxadd")
+ (set_attr "prefix_extra" "1")
(set_attr "mode" "V2SF")])
(define_insn "mmx_addsubv2sf3"
@@ -488,6 +514,7 @@
"TARGET_3DNOW_A"
"pfpnacc\t{%2, %0|%0, %2}"
[(set_attr "type" "mmxadd")
+ (set_attr "prefix_extra" "1")
(set_attr "mode" "V2SF")])
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -510,6 +537,7 @@
"TARGET_3DNOW && ix86_binary_operator_ok (EQ, V2SFmode, operands)"
"pfcmpeq\t{%2, %0|%0, %2}"
[(set_attr "type" "mmxcmp")
+ (set_attr "prefix_extra" "1")
(set_attr "mode" "V2SF")])
(define_insn "mmx_gtv2sf3"
@@ -519,6 +547,7 @@
"TARGET_3DNOW"
"pfcmpgt\t{%2, %0|%0, %2}"
[(set_attr "type" "mmxcmp")
+ (set_attr "prefix_extra" "1")
(set_attr "mode" "V2SF")])
(define_insn "mmx_gev2sf3"
@@ -528,6 +557,7 @@
"TARGET_3DNOW"
"pfcmpge\t{%2, %0|%0, %2}"
[(set_attr "type" "mmxcmp")
+ (set_attr "prefix_extra" "1")
(set_attr "mode" "V2SF")])
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -542,6 +572,7 @@
"TARGET_3DNOW"
"pf2id\t{%1, %0|%0, %1}"
[(set_attr "type" "mmxcvt")
+ (set_attr "prefix_extra" "1")
(set_attr "mode" "V2SF")])
(define_insn "mmx_pf2iw"
@@ -553,6 +584,7 @@
"TARGET_3DNOW_A"
"pf2iw\t{%1, %0|%0, %1}"
[(set_attr "type" "mmxcvt")
+ (set_attr "prefix_extra" "1")
(set_attr "mode" "V2SF")])
(define_insn "mmx_pi2fw"
@@ -564,6 +596,7 @@
"TARGET_3DNOW_A"
"pi2fw\t{%1, %0|%0, %1}"
[(set_attr "type" "mmxcvt")
+ (set_attr "prefix_extra" "1")
(set_attr "mode" "V2SF")])
(define_insn "mmx_floatv2si2"
@@ -572,6 +605,7 @@
"TARGET_3DNOW"
"pi2fd\t{%1, %0|%0, %1}"
[(set_attr "type" "mmxcvt")
+ (set_attr "prefix_extra" "1")
(set_attr "mode" "V2SF")])
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -587,6 +621,7 @@
"TARGET_3DNOW_A"
"pswapd\t{%1, %0|%0, %1}"
[(set_attr "type" "mmxcvt")
+ (set_attr "prefix_extra" "1")
(set_attr "mode" "V2SF")])
(define_insn "*vec_dupv2sf"
@@ -887,6 +922,7 @@
"TARGET_3DNOW && ix86_binary_operator_ok (MULT, V4HImode, operands)"
"pmulhrw\t{%2, %0|%0, %2}"
[(set_attr "type" "mmxmul")
+ (set_attr "prefix_extra" "1")
(set_attr "mode" "DI")])
(define_expand "sse2_umulv1siv1di3"
@@ -965,6 +1001,10 @@
"TARGET_MMX"
"psra<mmxvecsize>\t{%2, %0|%0, %2}"
[(set_attr "type" "mmxshft")
+ (set (attr "length_immediate")
+ (if_then_else (match_operand 2 "const_int_operand" "")
+ (const_string "1")
+ (const_string "0")))
(set_attr "mode" "DI")])
(define_insn "mmx_lshr<mode>3"
@@ -975,6 +1015,10 @@
"TARGET_MMX"
"psrl<mmxvecsize>\t{%2, %0|%0, %2}"
[(set_attr "type" "mmxshft")
+ (set (attr "length_immediate")
+ (if_then_else (match_operand 2 "const_int_operand" "")
+ (const_string "1")
+ (const_string "0")))
(set_attr "mode" "DI")])
(define_insn "mmx_ashl<mode>3"
@@ -985,6 +1029,10 @@
"TARGET_MMX"
"psll<mmxvecsize>\t{%2, %0|%0, %2}"
[(set_attr "type" "mmxshft")
+ (set (attr "length_immediate")
+ (if_then_else (match_operand 2 "const_int_operand" "")
+ (const_string "1")
+ (const_string "0")))
(set_attr "mode" "DI")])
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -1205,6 +1253,7 @@
return "pinsrw\t{%3, %k2, %0|%0, %k2, %3}";
}
[(set_attr "type" "mmxcvt")
+ (set_attr "length_immediate" "1")
(set_attr "mode" "DI")])
(define_insn "mmx_pextrw"
@@ -1216,6 +1265,7 @@
"TARGET_SSE || TARGET_3DNOW_A"
"pextrw\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "type" "mmxcvt")
+ (set_attr "length_immediate" "1")
(set_attr "mode" "DI")])
(define_expand "mmx_pshufw"
@@ -1253,6 +1303,7 @@
return "pshufw\t{%2, %1, %0|%0, %1, %2}";
}
[(set_attr "type" "mmxcvt")
+ (set_attr "length_immediate" "1")
(set_attr "mode" "DI")])
(define_insn "mmx_pswapdv2si2"
@@ -1263,6 +1314,7 @@
"TARGET_3DNOW_A"
"pswapd\t{%1, %0|%0, %1}"
[(set_attr "type" "mmxcvt")
+ (set_attr "prefix_extra" "1")
(set_attr "mode" "DI")])
(define_insn "*vec_dupv4hi"
@@ -1273,6 +1325,7 @@
"TARGET_SSE || TARGET_3DNOW_A"
"pshufw\t{$0, %0, %0|%0, %0, 0}"
[(set_attr "type" "mmxcvt")
+ (set_attr "length_immediate" "1")
(set_attr "mode" "DI")])
(define_insn "*vec_dupv2si"
@@ -1345,6 +1398,7 @@
#
#"
[(set_attr "type" "mmxcvt,sselog1,sselog1,sselog1,mmxmov,ssemov,imov")
+ (set_attr "length_immediate" "*,*,1,*,*,*,*")
(set_attr "mode" "DI,TI,TI,V4SF,SI,SI,SI")])
(define_split
@@ -1492,6 +1546,11 @@
return "pavgusb\t{%2, %0|%0, %2}";
}
[(set_attr "type" "mmxshft")
+ (set (attr "prefix_extra")
+ (if_then_else
+ (eq (symbol_ref "(TARGET_SSE || TARGET_3DNOW_A)") (const_int 0))
+ (const_string "1")
+ (const_string "*")))
(set_attr "mode" "DI")])
(define_expand "mmx_uavgv4hi3"
@@ -1602,6 +1661,7 @@
"TARGET_MMX"
"emms"
[(set_attr "type" "mmx")
+ (set_attr "modrm" "0")
(set_attr "memory" "unknown")])
(define_insn "mmx_femms"
@@ -1625,4 +1685,5 @@
"TARGET_3DNOW"
"femms"
[(set_attr "type" "mmx")
+ (set_attr "modrm" "0")
(set_attr "memory" "none")])
diff --git a/gcc/config/i386/msformat-c.c b/gcc/config/i386/msformat-c.c
index 4648c8d582b..dec8f40d478 100644
--- a/gcc/config/i386/msformat-c.c
+++ b/gcc/config/i386/msformat-c.c
@@ -36,12 +36,12 @@ along with GCC; see the file COPYING3. If not see
static format_length_info ms_printf_length_specs[] =
{
- { "h", FMT_LEN_h, STD_C89, NULL, 0, 0 },
- { "l", FMT_LEN_l, STD_C89, NULL, 0, 0 },
- { "I32", FMT_LEN_l, STD_EXT, NULL, 0, 0 },
- { "I64", FMT_LEN_ll, STD_EXT, NULL, 0, 0 },
- { "I", FMT_LEN_L, STD_EXT, NULL, 0, 0 },
- { NULL, 0, 0, NULL, 0, 0 }
+ { "h", FMT_LEN_h, STD_C89, NULL, FMT_LEN_none, STD_C89 },
+ { "l", FMT_LEN_l, STD_C89, NULL, FMT_LEN_none, STD_C89 },
+ { "I32", FMT_LEN_l, STD_EXT, NULL, FMT_LEN_none, STD_C89 },
+ { "I64", FMT_LEN_ll, STD_EXT, NULL, FMT_LEN_none, STD_C89 },
+ { "I", FMT_LEN_L, STD_EXT, NULL, FMT_LEN_none, STD_C89 },
+ { NULL, FMT_LEN_none, STD_C89, NULL, FMT_LEN_none, STD_C89 }
};
static const format_flag_spec ms_printf_flag_specs[] =
@@ -55,7 +55,7 @@ static const format_flag_spec ms_printf_flag_specs[] =
{ 'w', 0, 0, N_("field width"), N_("field width in printf format"), STD_C89 },
{ 'p', 0, 0, N_("precision"), N_("precision in printf format"), STD_C89 },
{ 'L', 0, 0, N_("length modifier"), N_("length modifier in printf format"), STD_C89 },
- { 0, 0, 0, NULL, NULL, 0 }
+ { 0, 0, 0, NULL, NULL, STD_C89 }
};
static const format_flag_pair ms_printf_flag_pairs[] =
@@ -72,7 +72,7 @@ static const format_flag_spec ms_scanf_flag_specs[] =
{ 'w', 0, 0, N_("field width"), N_("field width in scanf format"), STD_C89 },
{ 'L', 0, 0, N_("length modifier"), N_("length modifier in scanf format"), STD_C89 },
{ '\'', 0, 0, N_("''' flag"), N_("the ''' scanf flag"), STD_EXT },
- { 0, 0, 0, NULL, NULL, 0 }
+ { 0, 0, 0, NULL, NULL, STD_C89 }
};
static const format_flag_pair ms_scanf_flag_pairs[] =
@@ -84,7 +84,7 @@ static const format_flag_pair ms_scanf_flag_pairs[] =
static const format_flag_spec ms_strftime_flag_specs[] =
{
{ '#', 0, 0, N_("'#' flag"), N_("the '#' strftime flag"), STD_EXT },
- { 0, 0, 0, NULL, NULL, 0 }
+ { 0, 0, 0, NULL, NULL, STD_C89 }
};
static const format_flag_pair ms_strftime_flag_pairs[] =
@@ -107,7 +107,7 @@ static const format_char_info ms_print_char_table[] =
/* X/Open conversion specifiers. */
{ "C", 0, STD_EXT, { TEX_WI, BADLEN, T89_S, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL },
{ "S", 1, STD_EXT, { TEX_W, BADLEN, T89_S, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "R", NULL },
- { NULL, 0, 0, NOLENGTHS, NULL, NULL, NULL }
+ { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
};
static const format_char_info ms_scan_char_table[] =
@@ -125,7 +125,7 @@ static const format_char_info ms_scan_char_table[] =
/* X/Open conversion specifiers. */
{ "C", 1, STD_EXT, { TEX_W, BADLEN, T89_S, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL },
{ "S", 1, STD_EXT, { TEX_W, BADLEN, T89_S, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "W", NULL },
- { NULL, 0, 0, NOLENGTHS, NULL, NULL, NULL }
+ { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
};
static const format_char_info ms_time_char_table[] =
@@ -142,7 +142,7 @@ static const format_char_info ms_time_char_table[] =
{ "%", 0, STD_C89, NOLENGTHS, "", "", NULL },
/* C99 conversion specifiers. */
{ "z", 0, STD_C99, NOLENGTHS, "#", "", NULL },
- { NULL, 0, 0, NOLENGTHS, NULL, NULL, NULL }
+ { NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
};
const format_kind_info mingw_format_attributes[3] =
diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md
index 785ff5d6033..2089de768ce 100644
--- a/gcc/config/i386/predicates.md
+++ b/gcc/config/i386/predicates.md
@@ -76,16 +76,30 @@
(and (match_code "reg")
(match_test "REGNO (op) == FLAGS_REG")))
+;; Return true if op is a QImode register operand other than
+;; %[abcd][hl].
+(define_predicate "ext_QIreg_operand"
+ (and (match_code "reg")
+ (match_test "TARGET_64BIT
+ && GET_MODE (op) == QImode
+ && REGNO (op) > BX_REG")))
+
+;; Similarly, but don't check mode of the operand.
+(define_predicate "ext_QIreg_nomode_operand"
+ (and (match_code "reg")
+ (match_test "TARGET_64BIT
+ && REGNO (op) > BX_REG")))
+
;; Return true if op is not xmm0 register.
(define_predicate "reg_not_xmm0_operand"
(and (match_operand 0 "register_operand")
- (match_test "GET_CODE (op) != REG
+ (match_test "!REG_P (op)
|| REGNO (op) != FIRST_SSE_REG")))
;; As above, but allow nonimmediate operands.
(define_predicate "nonimm_not_xmm0_operand"
(and (match_operand 0 "nonimmediate_operand")
- (match_test "GET_CODE (op) != REG
+ (match_test "!REG_P (op)
|| REGNO (op) != FIRST_SSE_REG")))
;; Return 1 if VALUE can be stored in a sign extended immediate field.
@@ -574,6 +588,11 @@
(and (match_code "const_int")
(match_test "INTVAL (op) == 8")))
+;; Match exactly 128.
+(define_predicate "const128_operand"
+ (and (match_code "const_int")
+ (match_test "INTVAL (op) == 128")))
+
;; Match 2, 4, or 8. Used for leal multiplicands.
(define_predicate "const248_operand"
(match_code "const_int")
@@ -811,7 +830,7 @@
int ok;
/* Registers and immediate operands are always "aligned". */
- if (GET_CODE (op) != MEM)
+ if (!MEM_P (op))
return 1;
/* All patterns using aligned_operand on memory operands ends up
@@ -878,6 +897,9 @@
struct ix86_address parts;
int ok;
+ if (TARGET_64BIT)
+ return 0;
+
ok = ix86_decompose_address (XEXP (op, 0), &parts);
gcc_assert (ok);
diff --git a/gcc/config/i386/sol2.h b/gcc/config/i386/sol2.h
index 1d21cd9c043..4c2dfe975cf 100644
--- a/gcc/config/i386/sol2.h
+++ b/gcc/config/i386/sol2.h
@@ -1,6 +1,6 @@
/* Target definitions for GCC for Intel 80386 running Solaris 2
Copyright (C) 1993, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
- 2004, 2007, 2008 Free Software Foundation, Inc.
+ 2004, 2007, 2008, 2009 Free Software Foundation, Inc.
Contributed by Fred Fish (fnf@cygnus.com).
This file is part of GCC.
@@ -112,3 +112,9 @@ along with GCC; see the file COPYING3. If not see
/* We do not need NT_VERSION notes. */
#undef X86_FILE_START_VERSION_DIRECTIVE
#define X86_FILE_START_VERSION_DIRECTIVE false
+
+/* Only recent versions of Solaris 11 ld properly support hidden .gnu.linkonce
+ sections, so don't use them. */
+#ifndef TARGET_GNU_LD
+#define USE_HIDDEN_LINKONCE 0
+#endif
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index ae23746e2a0..da06d44c41a 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -437,6 +437,7 @@
"TARGET_SSE2"
"movnti\t{%1, %0|%0, %1}"
[(set_attr "type" "ssemov")
+ (set_attr "prefix_data16" "0")
(set_attr "mode" "V2DF")])
(define_insn "avx_lddqu<avxmodesuffix>"
@@ -459,6 +460,7 @@
"lddqu\t{%1, %0|%0, %1}"
[(set_attr "type" "ssemov")
(set_attr "movu" "1")
+ (set_attr "prefix_data16" "0")
(set_attr "prefix_rep" "1")
(set_attr "mode" "TI")])
@@ -1407,6 +1409,7 @@
"TARGET_AVX"
"vcmpp<avxmodesuffixf2c>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
[(set_attr "type" "ssecmp")
+ (set_attr "length_immediate" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "<MODE>")])
@@ -1423,6 +1426,7 @@
"TARGET_AVX"
"vcmps<ssemodesuffixf2c>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
[(set_attr "type" "ssecmp")
+ (set_attr "length_immediate" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "<ssescalarmode>")])
@@ -1437,6 +1441,7 @@
"vcmp%D3p<avxmodesuffixf2c>\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "type" "ssecmp")
(set_attr "prefix" "vex")
+ (set_attr "length_immediate" "1")
(set_attr "mode" "<avxvecmode>")])
(define_insn "<sse>_maskcmp<mode>3"
@@ -1448,6 +1453,7 @@
&& !TARGET_SSE5"
"cmp%D3<ssemodesuffixf4>\t{%2, %0|%0, %2}"
[(set_attr "type" "ssecmp")
+ (set_attr "length_immediate" "1")
(set_attr "mode" "<MODE>")])
(define_insn "<sse>_vmmaskcmp<mode>3"
@@ -1461,6 +1467,7 @@
"SSE_VEC_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
"cmp%D3s<ssemodesuffixf2c>\t{%2, %0|%0, %2}"
[(set_attr "type" "ssecmp")
+ (set_attr "length_immediate" "1")
(set_attr "mode" "<ssescalarmode>")])
(define_insn "<sse>_comi"
@@ -1476,6 +1483,11 @@
"%vcomis<ssemodefsuffix>\t{%1, %0|%0, %1}"
[(set_attr "type" "ssecomi")
(set_attr "prefix" "maybe_vex")
+ (set_attr "prefix_rep" "0")
+ (set (attr "prefix_data16")
+ (if_then_else (eq_attr "mode" "DF")
+ (const_string "1")
+ (const_string "0")))
(set_attr "mode" "<MODE>")])
(define_insn "<sse>_ucomi"
@@ -1491,6 +1503,11 @@
"%vucomis<ssemodefsuffix>\t{%1, %0|%0, %1}"
[(set_attr "type" "ssecomi")
(set_attr "prefix" "maybe_vex")
+ (set_attr "prefix_rep" "0")
+ (set (attr "prefix_data16")
+ (if_then_else (eq_attr "mode" "DF")
+ (const_string "1")
+ (const_string "0")))
(set_attr "mode" "<MODE>")])
(define_expand "vcond<mode>"
@@ -2222,6 +2239,7 @@
"cvttps2pi\t{%1, %0|%0, %1}"
[(set_attr "type" "ssecvt")
(set_attr "unit" "mmx")
+ (set_attr "prefix_rep" "0")
(set_attr "mode" "SF")])
(define_insn "*avx_cvtsi2ss"
@@ -2261,6 +2279,7 @@
"TARGET_AVX && TARGET_64BIT"
"vcvtsi2ssq\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "type" "sseicvt")
+ (set_attr "length_vex" "4")
(set_attr "prefix" "vex")
(set_attr "mode" "SF")])
@@ -2274,6 +2293,7 @@
"TARGET_SSE && TARGET_64BIT"
"cvtsi2ssq\t{%2, %0|%0, %2}"
[(set_attr "type" "sseicvt")
+ (set_attr "prefix_rex" "1")
(set_attr "athlon_decode" "vector,double")
(set_attr "amdfam10_decode" "vector,double")
(set_attr "mode" "SF")])
@@ -2420,6 +2440,7 @@
"cvttps2dq\t{%1, %0|%0, %1}"
[(set_attr "type" "ssecvt")
(set_attr "prefix_rep" "1")
+ (set_attr "prefix_data16" "0")
(set_attr "mode" "TI")])
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -2435,6 +2456,7 @@
"cvtpi2pd\t{%1, %0|%0, %1}"
[(set_attr "type" "ssecvt")
(set_attr "unit" "mmx,*")
+ (set_attr "prefix_data16" "1,*")
(set_attr "mode" "V2DF")])
(define_insn "sse2_cvtpd2pi"
@@ -2495,6 +2517,7 @@
"TARGET_AVX && TARGET_64BIT"
"vcvtsi2sdq\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "type" "sseicvt")
+ (set_attr "length_vex" "4")
(set_attr "prefix" "vex")
(set_attr "mode" "DF")])
@@ -2508,6 +2531,7 @@
"TARGET_SSE2 && TARGET_64BIT"
"cvtsi2sdq\t{%2, %0|%0, %2}"
[(set_attr "type" "sseicvt")
+ (set_attr "prefix_rex" "1")
(set_attr "mode" "DF")
(set_attr "athlon_decode" "double,direct")
(set_attr "amdfam10_decode" "vector,double")])
@@ -2649,6 +2673,7 @@
: \"cvtpd2dq\t{%1, %0|%0, %1}\";"
[(set_attr "type" "ssecvt")
(set_attr "prefix_rep" "1")
+ (set_attr "prefix_data16" "0")
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "TI")
(set_attr "amdfam10_decode" "double")])
@@ -2679,7 +2704,6 @@
"* return TARGET_AVX ? \"vcvttpd2dq{x}\t{%1, %0|%0, %1}\"
: \"cvttpd2dq\t{%1, %0|%0, %1}\";"
[(set_attr "type" "ssecvt")
- (set_attr "prefix_rep" "1")
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "TI")
(set_attr "amdfam10_decode" "double")])
@@ -2798,6 +2822,7 @@
[(set_attr "type" "ssecvt")
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "V2DF")
+ (set_attr "prefix_data16" "0")
(set_attr "amdfam10_decode" "direct")])
(define_expand "vec_unpacks_hi_v4sf"
@@ -3268,6 +3293,7 @@
return "vshufps\t{%3, %2, %1, %0|%0, %1, %2, %3}";
}
[(set_attr "type" "sselog")
+ (set_attr "length_immediate" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "V8SF")])
@@ -3309,6 +3335,7 @@
return "vshufps\t{%3, %2, %1, %0|%0, %1, %2, %3}";
}
[(set_attr "type" "sselog")
+ (set_attr "length_immediate" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "V4SF")])
@@ -3334,6 +3361,7 @@
return "shufps\t{%3, %2, %0|%0, %2, %3}";
}
[(set_attr "type" "sselog")
+ (set_attr "length_immediate" "1")
(set_attr "mode" "V4SF")])
(define_insn "sse_storehps"
@@ -3441,6 +3469,7 @@
vmovlps\t{%2, %1, %0|%0, %1, %2}
vmovlps\t{%2, %0|%0, %2}"
[(set_attr "type" "sselog,ssemov,ssemov")
+ (set_attr "length_immediate" "1,*,*")
(set_attr "prefix" "vex")
(set_attr "mode" "V4SF,V2SF,V2SF")])
@@ -3457,6 +3486,7 @@
movlps\t{%2, %0|%0, %2}
movlps\t{%2, %0|%0, %2}"
[(set_attr "type" "sselog,ssemov,ssemov")
+ (set_attr "length_immediate" "1,*,*")
(set_attr "mode" "V4SF,V2SF,V2SF")])
(define_insn "*avx_movss"
@@ -3489,6 +3519,7 @@
"TARGET_AVX"
"vshufps\t{$0, %1, %1, %0|%0, %1, %1, 0}"
[(set_attr "type" "sselog1")
+ (set_attr "length_immediate" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "V4SF")])
@@ -3499,6 +3530,7 @@
"TARGET_SSE"
"shufps\t{$0, %0, %0|%0, %0, 0}"
[(set_attr "type" "sselog1")
+ (set_attr "length_immediate" "1")
(set_attr "mode" "V4SF")])
(define_insn "*vec_concatv2sf_avx"
@@ -3514,6 +3546,8 @@
punpckldq\t{%2, %0|%0, %2}
movd\t{%1, %0|%0, %1}"
[(set_attr "type" "sselog,sselog,ssemov,mmxcvt,mmxmov")
+ (set_attr "length_immediate" "*,1,*,*,*")
+ (set_attr "prefix_extra" "*,1,*,*,*")
(set (attr "prefix")
(if_then_else (eq_attr "alternative" "3,4")
(const_string "orig")
@@ -3535,7 +3569,9 @@
punpckldq\t{%2, %0|%0, %2}
movd\t{%1, %0|%0, %1}"
[(set_attr "type" "sselog,sselog,ssemov,mmxcvt,mmxmov")
+ (set_attr "prefix_data16" "*,1,*,*,*")
(set_attr "prefix_extra" "*,1,*,*,*")
+ (set_attr "length_immediate" "*,1,*,*,*")
(set_attr "mode" "V4SF,V4SF,SF,DI,DI")])
;; ??? In theory we can match memory for the MMX alternative, but allowing
@@ -3636,6 +3672,8 @@
return "vinsertps\t{%3, %2, %1, %0|%0, %1, %2, %3}";
}
[(set_attr "type" "sselog")
+ (set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "V4SF")])
@@ -3652,7 +3690,9 @@
return "insertps\t{%3, %2, %0|%0, %2, %3}";
}
[(set_attr "type" "sselog")
+ (set_attr "prefix_data16" "1")
(set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "mode" "V4SF")])
(define_insn "*avx_insertps"
@@ -3665,6 +3705,8 @@
"vinsertps\t{%3, %2, %1, %0|%0, %1, %2, %3}";
[(set_attr "type" "sselog")
(set_attr "prefix" "vex")
+ (set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "mode" "V4SF")])
(define_insn "sse4_1_insertps"
@@ -3676,7 +3718,9 @@
"TARGET_SSE4_1"
"insertps\t{%3, %2, %0|%0, %2, %3}";
[(set_attr "type" "sselog")
+ (set_attr "prefix_data16" "1")
(set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "mode" "V4SF")])
(define_split
@@ -3751,6 +3795,8 @@
"TARGET_AVX"
"vextractf128\t{$0x0, %1, %0|%0, %1, 0x0}"
[(set_attr "type" "sselog")
+ (set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "memory" "none,store")
(set_attr "prefix" "vex")
(set_attr "mode" "V8SF")])
@@ -3763,6 +3809,8 @@
"TARGET_AVX"
"vextractf128\t{$0x1, %1, %0|%0, %1, 0x1}"
[(set_attr "type" "sselog")
+ (set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "memory" "none,store")
(set_attr "prefix" "vex")
(set_attr "mode" "V8SF")])
@@ -3776,6 +3824,8 @@
"TARGET_AVX"
"vextractf128\t{$0x1, %1, %0|%0, %1, 0x1}"
[(set_attr "type" "sselog")
+ (set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "memory" "none,store")
(set_attr "prefix" "vex")
(set_attr "mode" "V8SF")])
@@ -3789,6 +3839,8 @@
"TARGET_AVX"
"vextractf128\t{$0x1, %1, %0|%0, %1, 0x1}"
[(set_attr "type" "sselog")
+ (set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "memory" "none,store")
(set_attr "prefix" "vex")
(set_attr "mode" "V8SF")])
@@ -3804,6 +3856,8 @@
"TARGET_AVX"
"vextractf128\t{$0x1, %1, %0|%0, %1, 0x1}"
[(set_attr "type" "sselog")
+ (set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "memory" "none,store")
(set_attr "prefix" "vex")
(set_attr "mode" "V8SF")])
@@ -3819,6 +3873,8 @@
"TARGET_AVX"
"vextractf128\t{$0x1, %1, %0|%0, %1, 0x1}"
[(set_attr "type" "sselog")
+ (set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "memory" "none,store")
(set_attr "prefix" "vex")
(set_attr "mode" "V8SF")])
@@ -3838,6 +3894,8 @@
"TARGET_AVX"
"vextractf128\t{$0x1, %1, %0|%0, %1, 0x1}"
[(set_attr "type" "sselog")
+ (set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "memory" "none,store")
(set_attr "prefix" "vex")
(set_attr "mode" "V8SF")])
@@ -3857,6 +3915,8 @@
"TARGET_AVX"
"vextractf128\t{$0x1, %1, %0|%0, %1, 0x1}"
[(set_attr "type" "sselog")
+ (set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "memory" "none,store")
(set_attr "prefix" "vex")
(set_attr "mode" "V8SF")])
@@ -3869,7 +3929,9 @@
"TARGET_SSE4_1"
"%vextractps\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "type" "sselog")
+ (set_attr "prefix_data16" "1")
(set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "V4SF")])
@@ -3962,6 +4024,7 @@
movlpd\t{%H1, %0|%0, %H1}
movhpd\t{%1, %0|%0, %1}"
[(set_attr "type" "sselog,ssemov,ssemov")
+ (set_attr "prefix_data16" "*,1,1")
(set_attr "mode" "V2DF,V1DF,V1DF")])
(define_insn "avx_movddup256"
@@ -4082,6 +4145,7 @@
movhpd\t{%2, %0|%0, %2}
movlpd\t{%2, %H0|%H0, %2}"
[(set_attr "type" "sselog,ssemov,ssemov")
+ (set_attr "prefix_data16" "*,1,1")
(set_attr "mode" "V2DF,V1DF,V1DF")])
(define_expand "avx_shufpd256"
@@ -4122,6 +4186,7 @@
return "vshufpd\t{%3, %2, %1, %0|%0, %1, %2, %3}";
}
[(set_attr "type" "sselog")
+ (set_attr "length_immediate" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "V4DF")])
@@ -4258,6 +4323,7 @@
return "vshufpd\t{%3, %2, %1, %0|%0, %1, %2, %3}";
}
[(set_attr "type" "sselog")
+ (set_attr "length_immediate" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "V2DF")])
@@ -4279,6 +4345,7 @@
return "shufpd\t{%3, %2, %0|%0, %2, %3}";
}
[(set_attr "type" "sselog")
+ (set_attr "length_immediate" "1")
(set_attr "mode" "V2DF")])
;; Avoid combining registers from different units in a single alternative,
@@ -4312,6 +4379,7 @@
#
#"
[(set_attr "type" "ssemov,sselog1,ssemov,fmov,imov")
+ (set_attr "prefix_data16" "1,*,*,*,*")
(set_attr "mode" "V1DF,V2DF,DF,DF,DF")])
(define_split
@@ -4340,6 +4408,7 @@
#
#"
[(set_attr "type" "ssemov,ssemov,ssemov,fmov,imov")
+ (set_attr "prefix_data16" "1,*,*,*,*")
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "V1DF,DF,DF,DF,DF")])
@@ -4406,6 +4475,8 @@
#
#"
[(set_attr "type" "ssemov,sselog,sselog,ssemov,fmov,imov")
+ (set_attr "prefix_data16" "1,*,*,*,*,*")
+ (set_attr "length_immediate" "*,*,1,*,*,*")
(set_attr "mode" "V1DF,V2DF,V2DF,DF,DF,DF")])
(define_split
@@ -4469,6 +4540,8 @@
#
#"
[(set_attr "type" "ssemov,ssemov,ssemov,sselog,ssemov,ssemov,fmov,imov")
+ (set_attr "prefix_data16" "*,1,*,*,1,*,*,*")
+ (set_attr "length_immediate" "*,*,*,1,*,*,*,*")
(set_attr "mode" "DF,V1DF,V1DF,V2DF,V1DF,DF,DF,DF")])
(define_split
@@ -4544,6 +4617,8 @@
movhps\t{%H1, %0|%0, %H1}
movhps\t{%1, %H0|%H0, %1}"
[(set_attr "type" "ssemov,ssemov,ssemov,sselog,ssemov,ssemov")
+ (set_attr "prefix_data16" "*,1,1,*,*,*")
+ (set_attr "length_immediate" "*,*,*,1,*,*")
(set_attr "mode" "DF,V1DF,V1DF,V2DF,V1DF,V1DF")])
(define_insn "*vec_dupv2df_sse3"
@@ -4603,6 +4678,7 @@
movlhps\t{%2, %0|%0, %2}
movhps\t{%2, %0|%0, %2}"
[(set_attr "type" "sselog,ssemov,ssemov,ssemov,ssemov")
+ (set_attr "prefix_data16" "*,1,*,*,*")
(set_attr "mode" "V2DF,V1DF,DF,V4SF,V2SF")])
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -4951,6 +5027,7 @@
"TARGET_AVX && ix86_binary_operator_ok (MULT, V4SImode, operands)"
"vpmuldq\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "type" "sseimul")
+ (set_attr "prefix_extra" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "TI")])
@@ -5097,6 +5174,7 @@
"TARGET_AVX && ix86_binary_operator_ok (MULT, V4SImode, operands)"
"vpmulld\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "type" "sseimul")
+ (set_attr "prefix_extra" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "TI")])
@@ -5492,6 +5570,10 @@
"vpsra<ssevecsize>\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "type" "sseishft")
(set_attr "prefix" "vex")
+ (set (attr "length_immediate")
+ (if_then_else (match_operand 2 "const_int_operand" "")
+ (const_string "1")
+ (const_string "0")))
(set_attr "mode" "TI")])
(define_insn "ashr<mode>3"
@@ -5503,6 +5585,10 @@
"psra<ssevecsize>\t{%2, %0|%0, %2}"
[(set_attr "type" "sseishft")
(set_attr "prefix_data16" "1")
+ (set (attr "length_immediate")
+ (if_then_else (match_operand 2 "const_int_operand" "")
+ (const_string "1")
+ (const_string "0")))
(set_attr "mode" "TI")])
(define_insn "*avx_lshr<mode>3"
@@ -5514,6 +5600,10 @@
"vpsrl<ssevecsize>\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "type" "sseishft")
(set_attr "prefix" "vex")
+ (set (attr "length_immediate")
+ (if_then_else (match_operand 2 "const_int_operand" "")
+ (const_string "1")
+ (const_string "0")))
(set_attr "mode" "TI")])
(define_insn "lshr<mode>3"
@@ -5525,6 +5615,10 @@
"psrl<ssevecsize>\t{%2, %0|%0, %2}"
[(set_attr "type" "sseishft")
(set_attr "prefix_data16" "1")
+ (set (attr "length_immediate")
+ (if_then_else (match_operand 2 "const_int_operand" "")
+ (const_string "1")
+ (const_string "0")))
(set_attr "mode" "TI")])
(define_insn "*avx_ashl<mode>3"
@@ -5536,6 +5630,10 @@
"vpsll<ssevecsize>\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "type" "sseishft")
(set_attr "prefix" "vex")
+ (set (attr "length_immediate")
+ (if_then_else (match_operand 2 "const_int_operand" "")
+ (const_string "1")
+ (const_string "0")))
(set_attr "mode" "TI")])
(define_insn "ashl<mode>3"
@@ -5547,6 +5645,10 @@
"psll<ssevecsize>\t{%2, %0|%0, %2}"
[(set_attr "type" "sseishft")
(set_attr "prefix_data16" "1")
+ (set (attr "length_immediate")
+ (if_then_else (match_operand 2 "const_int_operand" "")
+ (const_string "1")
+ (const_string "0")))
(set_attr "mode" "TI")])
(define_expand "vec_shl_<mode>"
@@ -5577,6 +5679,12 @@
"TARGET_AVX && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
"vp<maxminiprefix><ssevecsize>\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "type" "sseiadd")
+ (set (attr "prefix_extra")
+ (if_then_else
+ (ne (symbol_ref "<MODE>mode != ((<CODE> == SMAX || <CODE> == SMIN) ? V8HImode : V16QImode)")
+ (const_int 0))
+ (const_string "1")
+ (const_string "0")))
(set_attr "prefix" "vex")
(set_attr "mode" "TI")])
@@ -5781,6 +5889,10 @@
"TARGET_AVX && ix86_binary_operator_ok (EQ, <MODE>mode, operands)"
"vpcmpeq<ssevecsize>\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "type" "ssecmp")
+ (set (attr "prefix_extra")
+ (if_then_else (match_operand:V2DI 0 "" "")
+ (const_string "1")
+ (const_string "*")))
(set_attr "prefix" "vex")
(set_attr "mode" "TI")])
@@ -5823,6 +5935,10 @@
"TARGET_AVX"
"vpcmpgt<ssevecsize>\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "type" "ssecmp")
+ (set (attr "prefix_extra")
+ (if_then_else (match_operand:V2DI 0 "" "")
+ (const_string "1")
+ (const_string "*")))
(set_attr "prefix" "vex")
(set_attr "mode" "TI")])
@@ -5845,6 +5961,7 @@
"TARGET_SSE4_2"
"pcmpgtq\t{%2, %0|%0, %2}"
[(set_attr "type" "ssecmp")
+ (set_attr "prefix_extra" "1")
(set_attr "mode" "TI")])
(define_expand "vcond<mode>"
@@ -6603,6 +6720,11 @@
return "vpinsr<ssevecsize>\t{%3, %k2, %1, %0|%0, %1, %k2, %3}";
}
[(set_attr "type" "sselog")
+ (set (attr "prefix_extra")
+ (if_then_else (match_operand:V8HI 0 "register_operand" "")
+ (const_string "0")
+ (const_string "1")))
+ (set_attr "length_immediate" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "TI")])
@@ -6620,6 +6742,7 @@
}
[(set_attr "type" "sselog")
(set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "mode" "TI")])
(define_insn "*sse2_pinsrw"
@@ -6636,6 +6759,7 @@
}
[(set_attr "type" "sselog")
(set_attr "prefix_data16" "1")
+ (set_attr "length_immediate" "1")
(set_attr "mode" "TI")])
;; It must come before sse2_loadld since it is preferred.
@@ -6653,6 +6777,7 @@
}
[(set_attr "type" "sselog")
(set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "mode" "TI")])
(define_insn "*avx_pinsrq"
@@ -6668,6 +6793,8 @@
return "vpinsrq\t{%3, %2, %1, %0|%0, %1, %2, %3}";
}
[(set_attr "type" "sselog")
+ (set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "TI")])
@@ -6684,7 +6811,9 @@
return "pinsrq\t{%3, %2, %0|%0, %2, %3}";
}
[(set_attr "type" "sselog")
+ (set_attr "prefix_rex" "1")
(set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "mode" "TI")])
(define_insn "*sse4_1_pextrb"
@@ -6697,6 +6826,7 @@
"%vpextrb\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "type" "sselog")
(set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "TI")])
@@ -6709,6 +6839,7 @@
"%vpextrb\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "type" "sselog")
(set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "TI")])
@@ -6722,6 +6853,7 @@
"%vpextrw\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "type" "sselog")
(set_attr "prefix_data16" "1")
+ (set_attr "length_immediate" "1")
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "TI")])
@@ -6734,6 +6866,7 @@
"%vpextrw\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "type" "sselog")
(set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "TI")])
@@ -6746,6 +6879,7 @@
"%vpextrd\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "type" "sselog")
(set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "TI")])
@@ -6758,7 +6892,9 @@
"TARGET_SSE4_1 && TARGET_64BIT"
"%vpextrq\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "type" "sselog")
+ (set_attr "prefix_rex" "1")
(set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "TI")])
@@ -6798,7 +6934,8 @@
}
[(set_attr "type" "sselog1")
(set_attr "prefix_data16" "1")
- (set_attr "prefix" "vex")
+ (set_attr "prefix" "maybe_vex")
+ (set_attr "length_immediate" "1")
(set_attr "mode" "TI")])
(define_expand "sse2_pshuflw"
@@ -6840,8 +6977,10 @@
return "%vpshuflw\t{%2, %1, %0|%0, %1, %2}";
}
[(set_attr "type" "sselog")
+ (set_attr "prefix_data16" "0")
(set_attr "prefix_rep" "1")
(set_attr "prefix" "maybe_vex")
+ (set_attr "length_immediate" "1")
(set_attr "mode" "TI")])
(define_expand "sse2_pshufhw"
@@ -6884,7 +7023,9 @@
}
[(set_attr "type" "sselog")
(set_attr "prefix_rep" "1")
+ (set_attr "prefix_data16" "0")
(set_attr "prefix" "maybe_vex")
+ (set_attr "length_immediate" "1")
(set_attr "mode" "TI")])
(define_expand "sse2_loadd"
@@ -7020,6 +7161,7 @@
vmovq\t{%H1, %0|%0, %H1}
vmov{q}\t{%H1, %0|%0, %H1}"
[(set_attr "type" "ssemov,sseishft,ssemov,imov")
+ (set_attr "length_immediate" "*,1,*,*")
(set_attr "memory" "*,none,*,*")
(set_attr "prefix" "vex")
(set_attr "mode" "V2SF,TI,TI,DI")])
@@ -7036,6 +7178,7 @@
movq\t{%H1, %0|%0, %H1}
mov{q}\t{%H1, %0|%0, %H1}"
[(set_attr "type" "ssemov,sseishft,ssemov,imov")
+ (set_attr "length_immediate" "*,1,*,*")
(set_attr "atom_unit" "*,sishuf,*,*")
(set_attr "memory" "*,none,*,*")
(set_attr "mode" "V2SF,TI,TI,DI")])
@@ -7053,6 +7196,7 @@
vpsrldq\t{$8, %1, %0|%0, %1, 8}
vmovq\t{%H1, %0|%0, %H1}"
[(set_attr "type" "ssemov,sseishft,ssemov")
+ (set_attr "length_immediate" "*,1,*")
(set_attr "memory" "*,none,*")
(set_attr "prefix" "vex")
(set_attr "mode" "V2SF,TI,TI")])
@@ -7069,6 +7213,7 @@
psrldq\t{$8, %0|%0, 8}
movq\t{%H1, %0|%0, %H1}"
[(set_attr "type" "ssemov,sseishft,ssemov")
+ (set_attr "length_immediate" "*,1,*")
(set_attr "atom_unit" "*,sishuf,*")
(set_attr "memory" "*,none,*")
(set_attr "mode" "V2SF,TI,TI")])
@@ -7098,6 +7243,7 @@
shufps\t{$0, %0, %0|%0, %0, 0}"
[(set_attr "type" "sselog1")
(set_attr "prefix" "maybe_vex,orig")
+ (set_attr "length_immediate" "1")
(set_attr "mode" "TI,V4SF")])
(define_insn "*vec_dupv2di_avx"
@@ -7134,6 +7280,8 @@
punpckldq\t{%2, %0|%0, %2}
movd\t{%1, %0|%0, %1}"
[(set_attr "type" "sselog,sselog,ssemov,mmxcvt,mmxmov")
+ (set_attr "prefix_extra" "1,*,*,*,*")
+ (set_attr "length_immediate" "1,*,*,*,*")
(set (attr "prefix")
(if_then_else (eq_attr "alternative" "3,4")
(const_string "orig")
@@ -7154,6 +7302,7 @@
movd\t{%1, %0|%0, %1}"
[(set_attr "type" "sselog,sselog,ssemov,mmxcvt,mmxmov")
(set_attr "prefix_extra" "1,*,*,*,*")
+ (set_attr "length_immediate" "1,*,*,*,*")
(set_attr "mode" "TI,TI,TI,DI,DI")])
;; ??? In theory we can match memory for the MMX alternative, but allowing
@@ -7260,6 +7409,8 @@
vpunpcklqdq\t{%2, %1, %0|%0, %1, %2}
vmovhps\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "type" "sselog,ssemov,ssemov,ssemov,sselog,ssemov")
+ (set_attr "prefix_extra" "1,*,*,*,*,*")
+ (set_attr "length_immediate" "1,*,*,*,*,*")
(set (attr "prefix")
(if_then_else (eq_attr "alternative" "3")
(const_string "orig")
@@ -7281,7 +7432,9 @@
movlhps\t{%2, %0|%0, %2}
movhps\t{%2, %0|%0, %2}"
[(set_attr "type" "sselog,ssemov,ssemov,ssemov,sselog,ssemov,ssemov")
+ (set_attr "prefix_rex" "1,*,1,*,*,*,*")
(set_attr "prefix_extra" "1,*,*,*,*,*,*")
+ (set_attr "length_immediate" "1,*,*,*,*,*,*")
(set_attr "mode" "TI,TI,TI,TI,TI,V4SF,V2SF")])
(define_insn "*vec_concatv2di_rex64_sse"
@@ -7298,6 +7451,7 @@
movlhps\t{%2, %0|%0, %2}
movhps\t{%2, %0|%0, %2}"
[(set_attr "type" "ssemov,ssemov,ssemov,sselog,ssemov,ssemov")
+ (set_attr "prefix_rex" "*,1,*,*,*,*")
(set_attr "mode" "TI,TI,TI,TI,V4SF,V2SF")])
(define_expand "vec_unpacku_hi_v16qi"
@@ -7684,6 +7838,8 @@
"%vmaskmovdqu\t{%2, %1|%1, %2}"
[(set_attr "type" "ssemov")
(set_attr "prefix_data16" "1")
+ ;; The implicit %rdi operand confuses default length_vex computation.
+ (set_attr "length_vex" "3")
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "TI")])
@@ -7698,6 +7854,9 @@
"%vmaskmovdqu\t{%2, %1|%1, %2}"
[(set_attr "type" "ssemov")
(set_attr "prefix_data16" "1")
+ ;; The implicit %rdi operand confuses default length_vex computation.
+ (set (attr "length_vex")
+ (symbol_ref ("REGNO (operands[2]) >= FIRST_REX_SSE_REG ? 3 + 1 : 2 + 1")))
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "TI")])
@@ -7736,6 +7895,7 @@
"TARGET_SSE || TARGET_3DNOW_A"
"sfence"
[(set_attr "type" "sse")
+ (set_attr "length_address" "0")
(set_attr "atom_sse_attr" "fence")
(set_attr "memory" "unknown")])
@@ -7763,6 +7923,7 @@
"TARGET_64BIT || TARGET_SSE2"
"mfence"
[(set_attr "type" "sse")
+ (set_attr "length_address" "0")
(set_attr "atom_sse_attr" "fence")
(set_attr "memory" "unknown")])
@@ -7781,6 +7942,7 @@
"TARGET_SSE2"
"lfence"
[(set_attr "type" "sse")
+ (set_attr "length_address" "0")
(set_attr "atom_sse_attr" "lfence")
(set_attr "memory" "unknown")])
@@ -7862,6 +8024,7 @@
"TARGET_AVX"
"vphaddw\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "type" "sseiadd")
+ (set_attr "prefix_extra" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "TI")])
@@ -7936,6 +8099,7 @@
[(set_attr "type" "sseiadd")
(set_attr "atom_unit" "complex")
(set_attr "prefix_extra" "1")
+ (set (attr "prefix_rex") (symbol_ref "x86_extended_reg_mentioned_p (insn)"))
(set_attr "mode" "DI")])
(define_insn "*avx_phadddv4si3"
@@ -7962,6 +8126,7 @@
"TARGET_AVX"
"vphaddd\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "type" "sseiadd")
+ (set_attr "prefix_extra" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "TI")])
@@ -8012,6 +8177,7 @@
[(set_attr "type" "sseiadd")
(set_attr "atom_unit" "complex")
(set_attr "prefix_extra" "1")
+ (set (attr "prefix_rex") (symbol_ref "x86_extended_reg_mentioned_p (insn)"))
(set_attr "mode" "DI")])
(define_insn "*avx_phaddswv8hi3"
@@ -8054,6 +8220,7 @@
"TARGET_AVX"
"vphaddsw\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "type" "sseiadd")
+ (set_attr "prefix_extra" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "TI")])
@@ -8128,6 +8295,7 @@
[(set_attr "type" "sseiadd")
(set_attr "atom_unit" "complex")
(set_attr "prefix_extra" "1")
+ (set (attr "prefix_rex") (symbol_ref "x86_extended_reg_mentioned_p (insn)"))
(set_attr "mode" "DI")])
(define_insn "*avx_phsubwv8hi3"
@@ -8170,6 +8338,7 @@
"TARGET_AVX"
"vphsubw\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "type" "sseiadd")
+ (set_attr "prefix_extra" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "TI")])
@@ -8244,6 +8413,7 @@
[(set_attr "type" "sseiadd")
(set_attr "atom_unit" "complex")
(set_attr "prefix_extra" "1")
+ (set (attr "prefix_rex") (symbol_ref "x86_extended_reg_mentioned_p (insn)"))
(set_attr "mode" "DI")])
(define_insn "*avx_phsubdv4si3"
@@ -8270,6 +8440,7 @@
"TARGET_AVX"
"vphsubd\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "type" "sseiadd")
+ (set_attr "prefix_extra" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "TI")])
@@ -8320,6 +8491,7 @@
[(set_attr "type" "sseiadd")
(set_attr "atom_unit" "complex")
(set_attr "prefix_extra" "1")
+ (set (attr "prefix_rex") (symbol_ref "x86_extended_reg_mentioned_p (insn)"))
(set_attr "mode" "DI")])
(define_insn "*avx_phsubswv8hi3"
@@ -8362,6 +8534,7 @@
"TARGET_AVX"
"vphsubsw\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "type" "sseiadd")
+ (set_attr "prefix_extra" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "TI")])
@@ -8436,6 +8609,7 @@
[(set_attr "type" "sseiadd")
(set_attr "atom_unit" "complex")
(set_attr "prefix_extra" "1")
+ (set (attr "prefix_rex") (symbol_ref "x86_extended_reg_mentioned_p (insn)"))
(set_attr "mode" "DI")])
(define_insn "*avx_pmaddubsw128"
@@ -8488,6 +8662,7 @@
"TARGET_AVX"
"vpmaddubsw\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "type" "sseiadd")
+ (set_attr "prefix_extra" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "TI")])
@@ -8582,6 +8757,7 @@
[(set_attr "type" "sseiadd")
(set_attr "atom_unit" "simul")
(set_attr "prefix_extra" "1")
+ (set (attr "prefix_rex") (symbol_ref "x86_extended_reg_mentioned_p (insn)"))
(set_attr "mode" "DI")])
(define_expand "ssse3_pmulhrswv8hi3"
@@ -8624,6 +8800,7 @@
"TARGET_AVX && ix86_binary_operator_ok (MULT, V8HImode, operands)"
"vpmulhrsw\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "type" "sseimul")
+ (set_attr "prefix_extra" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "TI")])
@@ -8688,6 +8865,7 @@
"pmulhrsw\t{%2, %0|%0, %2}"
[(set_attr "type" "sseimul")
(set_attr "prefix_extra" "1")
+ (set (attr "prefix_rex") (symbol_ref "x86_extended_reg_mentioned_p (insn)"))
(set_attr "mode" "DI")])
(define_insn "*avx_pshufbv16qi3"
@@ -8698,6 +8876,7 @@
"TARGET_AVX"
"vpshufb\t{%2, %1, %0|%0, %1, %2}";
[(set_attr "type" "sselog1")
+ (set_attr "prefix_extra" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "TI")])
@@ -8722,6 +8901,7 @@
"pshufb\t{%2, %0|%0, %2}";
[(set_attr "type" "sselog1")
(set_attr "prefix_extra" "1")
+ (set (attr "prefix_rex") (symbol_ref "x86_extended_reg_mentioned_p (insn)"))
(set_attr "mode" "DI")])
(define_insn "*avx_psign<mode>3"
@@ -8733,6 +8913,7 @@
"TARGET_AVX"
"vpsign<ssevecsize>\t{%2, %1, %0|%0, %1, %2}";
[(set_attr "type" "sselog1")
+ (set_attr "prefix_extra" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "TI")])
@@ -8759,6 +8940,7 @@
"psign<mmxvecsize>\t{%2, %0|%0, %2}";
[(set_attr "type" "sselog1")
(set_attr "prefix_extra" "1")
+ (set (attr "prefix_rex") (symbol_ref "x86_extended_reg_mentioned_p (insn)"))
(set_attr "mode" "DI")])
(define_insn "*avx_palignrti"
@@ -8773,6 +8955,8 @@
return "vpalignr\t{%3, %2, %1, %0|%0, %1, %2, %3}";
}
[(set_attr "type" "sseishft")
+ (set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "TI")])
@@ -8791,6 +8975,7 @@
(set_attr "atom_unit" "sishuf")
(set_attr "prefix_data16" "1")
(set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "mode" "TI")])
(define_insn "ssse3_palignrdi"
@@ -8807,6 +8992,8 @@
[(set_attr "type" "sseishft")
(set_attr "atom_unit" "sishuf")
(set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
+ (set (attr "prefix_rex") (symbol_ref "x86_extended_reg_mentioned_p (insn)"))
(set_attr "mode" "DI")])
(define_insn "abs<mode>2"
@@ -8826,7 +9013,9 @@
"TARGET_SSSE3"
"pabs<mmxvecsize>\t{%1, %0|%0, %1}";
[(set_attr "type" "sselog1")
+ (set_attr "prefix_rep" "0")
(set_attr "prefix_extra" "1")
+ (set (attr "prefix_rex") (symbol_ref "x86_extended_reg_mentioned_p (insn)"))
(set_attr "mode" "DI")])
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -8867,6 +9056,7 @@
"extrq\t{%3, %2, %0|%0, %2, %3}"
[(set_attr "type" "sse")
(set_attr "prefix_data16" "1")
+ (set_attr "length_immediate" "2")
(set_attr "mode" "TI")])
(define_insn "sse4a_extrq"
@@ -8890,7 +9080,9 @@
"TARGET_SSE4A"
"insertq\t{%4, %3, %2, %0|%0, %2, %3, %4}"
[(set_attr "type" "sseins")
+ (set_attr "prefix_data16" "0")
(set_attr "prefix_rep" "1")
+ (set_attr "length_immediate" "2")
(set_attr "mode" "TI")])
(define_insn "sse4a_insertq"
@@ -8901,6 +9093,7 @@
"TARGET_SSE4A"
"insertq\t{%2, %0|%0, %2}"
[(set_attr "type" "sseins")
+ (set_attr "prefix_data16" "0")
(set_attr "prefix_rep" "1")
(set_attr "mode" "TI")])
@@ -8919,6 +9112,8 @@
"TARGET_AVX"
"vblendp<avxmodesuffixf2c>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
[(set_attr "type" "ssemov")
+ (set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "<avxvecmode>")])
@@ -8932,6 +9127,8 @@
"TARGET_AVX"
"vblendvp<avxmodesuffixf2c>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
[(set_attr "type" "ssemov")
+ (set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "<avxvecmode>")])
@@ -8944,7 +9141,9 @@
"TARGET_SSE4_1"
"blendp<ssemodesuffixf2c>\t{%3, %2, %0|%0, %2, %3}"
[(set_attr "type" "ssemov")
+ (set_attr "prefix_data16" "1")
(set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "mode" "<MODE>")])
(define_insn "sse4_1_blendvp<ssemodesuffixf2c>"
@@ -8957,6 +9156,7 @@
"TARGET_SSE4_1"
"blendvp<ssemodesuffixf2c>\t{%3, %2, %0|%0, %2, %3}"
[(set_attr "type" "ssemov")
+ (set_attr "prefix_data16" "1")
(set_attr "prefix_extra" "1")
(set_attr "mode" "<MODE>")])
@@ -8971,6 +9171,8 @@
"vdpp<avxmodesuffixf2c>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
[(set_attr "type" "ssemul")
(set_attr "prefix" "vex")
+ (set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "mode" "<avxvecmode>")])
(define_insn "sse4_1_dpp<ssemodesuffixf2c>"
@@ -8983,7 +9185,9 @@
"TARGET_SSE4_1"
"dpp<ssemodesuffixf2c>\t{%3, %2, %0|%0, %2, %3}"
[(set_attr "type" "ssemul")
+ (set_attr "prefix_data16" "1")
(set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "mode" "<MODE>")])
(define_insn "sse4_1_movntdqa"
@@ -9007,6 +9211,8 @@
"vmpsadbw\t{%3, %2, %1, %0|%0, %1, %2, %3}"
[(set_attr "type" "sselog1")
(set_attr "prefix" "vex")
+ (set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "mode" "TI")])
(define_insn "sse4_1_mpsadbw"
@@ -9019,6 +9225,7 @@
"mpsadbw\t{%3, %2, %0|%0, %2, %3}"
[(set_attr "type" "sselog1")
(set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "mode" "TI")])
(define_insn "*avx_packusdw"
@@ -9031,6 +9238,7 @@
"TARGET_AVX"
"vpackusdw\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "type" "sselog")
+ (set_attr "prefix_extra" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "TI")])
@@ -9056,6 +9264,8 @@
"TARGET_AVX"
"vpblendvb\t{%3, %2, %1, %0|%0, %1, %2, %3}"
[(set_attr "type" "ssemov")
+ (set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "TI")])
@@ -9081,6 +9291,8 @@
"vpblendw\t{%3, %2, %1, %0|%0, %1, %2, %3}"
[(set_attr "type" "ssemov")
(set_attr "prefix" "vex")
+ (set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "mode" "TI")])
(define_insn "sse4_1_pblendw"
@@ -9093,6 +9305,7 @@
"pblendw\t{%3, %2, %0|%0, %2, %3}"
[(set_attr "type" "ssemov")
(set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "mode" "TI")])
(define_insn "sse4_1_phminposuw"
@@ -9504,6 +9717,7 @@
"TARGET_AVX"
"vtestp<avxmodesuffixf2c>\t{%1, %0|%0, %1}"
[(set_attr "type" "ssecomi")
+ (set_attr "prefix_extra" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "<MODE>")])
@@ -9517,6 +9731,7 @@
"TARGET_AVX"
"vptest\t{%1, %0|%0, %1}"
[(set_attr "type" "ssecomi")
+ (set_attr "prefix_extra" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "OI")])
@@ -9541,6 +9756,8 @@
"TARGET_AVX"
"vroundp<avxmodesuffixf2c>\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "type" "ssecvt")
+ (set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "<MODE>")])
@@ -9553,7 +9770,9 @@
"TARGET_ROUND"
"%vroundp<ssemodesuffixf2c>\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "type" "ssecvt")
+ (set_attr "prefix_data16" "1")
(set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "<MODE>")])
@@ -9569,6 +9788,8 @@
"TARGET_AVX"
"vrounds<ssemodesuffixf2c>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
[(set_attr "type" "ssecvt")
+ (set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "<MODE>")])
@@ -9584,7 +9805,9 @@
"TARGET_ROUND"
"rounds<ssemodesuffixf2c>\t{%3, %2, %0|%0, %2, %3}"
[(set_attr "type" "ssecvt")
+ (set_attr "prefix_data16" "1")
(set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "mode" "<MODE>")])
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -9646,6 +9869,7 @@
[(set_attr "type" "sselog")
(set_attr "prefix_data16" "1")
(set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "memory" "none,load")
(set_attr "mode" "TI")])
@@ -9672,6 +9896,7 @@
(set_attr "prefix_data16" "1")
(set_attr "prefix_extra" "1")
(set_attr "prefix" "maybe_vex")
+ (set_attr "length_immediate" "1")
(set_attr "memory" "none,load")
(set_attr "mode" "TI")])
@@ -9697,6 +9922,7 @@
[(set_attr "type" "sselog")
(set_attr "prefix_data16" "1")
(set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "prefix" "maybe_vex")
(set_attr "memory" "none,load")
(set_attr "mode" "TI")])
@@ -9721,6 +9947,7 @@
[(set_attr "type" "sselog")
(set_attr "prefix_data16" "1")
(set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "memory" "none,load,none,load")
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "TI")])
@@ -9769,6 +9996,7 @@
[(set_attr "type" "sselog")
(set_attr "prefix_data16" "1")
(set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "memory" "none,load")
(set_attr "mode" "TI")])
@@ -9790,6 +10018,7 @@
[(set_attr "type" "sselog")
(set_attr "prefix_data16" "1")
(set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "prefix" "maybe_vex")
(set_attr "memory" "none,load")
(set_attr "mode" "TI")])
@@ -9812,6 +10041,7 @@
[(set_attr "type" "sselog")
(set_attr "prefix_data16" "1")
(set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "prefix" "maybe_vex")
(set_attr "memory" "none,load")
(set_attr "mode" "TI")])
@@ -9834,6 +10064,7 @@
[(set_attr "type" "sselog")
(set_attr "prefix_data16" "1")
(set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "memory" "none,load,none,load")
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "TI")])
@@ -10832,6 +11063,8 @@
|| register_operand (operands[2], V16QImode))"
"pperm\t{%3, %1, %0, %0|%0, %0, %1, %3}"
[(set_attr "type" "sseadd")
+ (set_attr "prefix_data16" "0")
+ (set_attr "prefix_extra" "2")
(set_attr "mode" "TI")])
(define_insn "sse5_pperm_sign_v16qi_v8hi"
@@ -10846,6 +11079,8 @@
|| register_operand (operands[2], V16QImode))"
"pperm\t{%3, %1, %0, %0|%0, %0, %1, %3}"
[(set_attr "type" "sseadd")
+ (set_attr "prefix_data16" "0")
+ (set_attr "prefix_extra" "2")
(set_attr "mode" "TI")])
(define_insn "sse5_pperm_zero_v8hi_v4si"
@@ -10860,6 +11095,8 @@
|| register_operand (operands[2], V16QImode))"
"pperm\t{%3, %1, %0, %0|%0, %0, %1, %3}"
[(set_attr "type" "sseadd")
+ (set_attr "prefix_data16" "0")
+ (set_attr "prefix_extra" "2")
(set_attr "mode" "TI")])
(define_insn "sse5_pperm_sign_v8hi_v4si"
@@ -10874,6 +11111,8 @@
|| register_operand (operands[2], V16QImode))"
"pperm\t{%3, %1, %0, %0|%0, %0, %1, %3}"
[(set_attr "type" "sseadd")
+ (set_attr "prefix_data16" "0")
+ (set_attr "prefix_extra" "2")
(set_attr "mode" "TI")])
(define_insn "sse5_pperm_zero_v4si_v2di"
@@ -10888,6 +11127,8 @@
|| register_operand (operands[2], V16QImode))"
"pperm\t{%3, %1, %0, %0|%0, %0, %1, %3}"
[(set_attr "type" "sseadd")
+ (set_attr "prefix_data16" "0")
+ (set_attr "prefix_extra" "2")
(set_attr "mode" "TI")])
(define_insn "sse5_pperm_sign_v4si_v2di"
@@ -10902,6 +11143,8 @@
|| register_operand (operands[2], V16QImode))"
"pperm\t{%3, %1, %0, %0|%0, %0, %1, %3}"
[(set_attr "type" "sseadd")
+ (set_attr "prefix_data16" "0")
+ (set_attr "prefix_extra" "2")
(set_attr "mode" "TI")])
;; SSE5 pack instructions that combine two vectors into a smaller vector
@@ -11030,6 +11273,7 @@
"TARGET_SSE5"
"prot<ssevecsize>\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "type" "sseishft")
+ (set_attr "length_immediate" "1")
(set_attr "mode" "TI")])
(define_insn "sse5_rotr<mode>3"
@@ -11043,6 +11287,7 @@
return \"prot<ssevecsize>\t{%3, %1, %0|%0, %1, %3}\";
}
[(set_attr "type" "sseishft")
+ (set_attr "length_immediate" "1")
(set_attr "mode" "TI")])
(define_expand "vrotr<mode>3"
@@ -11082,6 +11327,8 @@
"TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 3, true, 1, false)"
"prot<ssevecsize>\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "type" "sseishft")
+ (set_attr "prefix_data16" "0")
+ (set_attr "prefix_extra" "2")
(set_attr "mode" "TI")])
;; SSE5 packed shift instructions.
@@ -11135,6 +11382,8 @@
"TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 3, true, 1, false)"
"psha<ssevecsize>\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "type" "sseishft")
+ (set_attr "prefix_data16" "0")
+ (set_attr "prefix_extra" "2")
(set_attr "mode" "TI")])
(define_insn "sse5_lshl<mode>3"
@@ -11152,6 +11401,8 @@
"TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 3, true, 1, false)"
"pshl<ssevecsize>\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "type" "sseishft")
+ (set_attr "prefix_data16" "0")
+ (set_attr "prefix_extra" "2")
(set_attr "mode" "TI")])
;; SSE2 doesn't have some shift varients, so define versions for SSE5
@@ -11201,7 +11452,7 @@
rtx par = gen_rtx_PARALLEL (V16QImode, vs);
rtx reg = gen_reg_rtx (V16QImode);
int i;
- rtx ele = ((GET_CODE (operands[2]) == CONST_INT)
+ rtx ele = ((CONST_INT_P (operands[2]))
? GEN_INT (- INTVAL (operands[2]))
: operands[2]);
@@ -11210,7 +11461,7 @@
emit_insn (gen_vec_initv16qi (reg, par));
- if (GET_CODE (operands[2]) != CONST_INT)
+ if (!CONST_INT_P (operands[2]))
{
rtx neg = gen_reg_rtx (V16QImode);
emit_insn (gen_negv16qi2 (neg, reg));
@@ -11233,7 +11484,7 @@
rtx reg = gen_reg_rtx (V2DImode);
rtx ele;
- if (GET_CODE (operands[2]) == CONST_INT)
+ if (CONST_INT_P (operands[2]))
ele = GEN_INT (- INTVAL (operands[2]));
else if (GET_MODE (operands[2]) != DImode)
{
@@ -11265,7 +11516,6 @@
"TARGET_SSE5"
"frcz<ssemodesuffixf4>\t{%1, %0|%0, %1}"
[(set_attr "type" "ssecvt1")
- (set_attr "prefix_extra" "1")
(set_attr "mode" "<MODE>")])
;; scalar insns
@@ -11280,7 +11530,6 @@
"TARGET_SSE5"
"frcz<ssemodesuffixf2s>\t{%2, %0|%0, %2}"
[(set_attr "type" "ssecvt1")
- (set_attr "prefix_extra" "1")
(set_attr "mode" "<MODE>")])
(define_insn "sse5_cvtph2ps"
@@ -11329,6 +11578,10 @@
"TARGET_SSE5"
"com%Y1<ssemodesuffixf2s>\t{%3, %2, %0|%0, %2, %3}"
[(set_attr "type" "sse4arg")
+ (set_attr "prefix_data16" "0")
+ (set_attr "prefix_rep" "0")
+ (set_attr "prefix_extra" "2")
+ (set_attr "length_immediate" "1")
(set_attr "mode" "<ssescalarmode>")])
;; We don't have a comparison operator that always returns true/false, so
@@ -11369,6 +11622,10 @@
return ret;
}
[(set_attr "type" "ssecmp")
+ (set_attr "prefix_data16" "0")
+ (set_attr "prefix_rep" "0")
+ (set_attr "prefix_extra" "2")
+ (set_attr "length_immediate" "1")
(set_attr "mode" "<MODE>")])
(define_insn "sse5_maskcmp<mode>3"
@@ -11379,6 +11636,10 @@
"TARGET_SSE5"
"com%Y1<ssemodesuffixf4>\t{%3, %2, %0|%0, %2, %3}"
[(set_attr "type" "ssecmp")
+ (set_attr "prefix_data16" "0")
+ (set_attr "prefix_rep" "0")
+ (set_attr "prefix_extra" "2")
+ (set_attr "length_immediate" "1")
(set_attr "mode" "<MODE>")])
(define_insn "sse5_maskcmp<mode>3"
@@ -11389,6 +11650,10 @@
"TARGET_SSE5"
"pcom%Y1<ssevecsize>\t{%3, %2, %0|%0, %2, %3}"
[(set_attr "type" "sse4arg")
+ (set_attr "prefix_data16" "0")
+ (set_attr "prefix_rep" "0")
+ (set_attr "prefix_extra" "2")
+ (set_attr "length_immediate" "1")
(set_attr "mode" "TI")])
(define_insn "sse5_maskcmp_uns<mode>3"
@@ -11399,6 +11664,10 @@
"TARGET_SSE5"
"pcom%Y1u<ssevecsize>\t{%3, %2, %0|%0, %2, %3}"
[(set_attr "type" "ssecmp")
+ (set_attr "prefix_data16" "0")
+ (set_attr "prefix_rep" "0")
+ (set_attr "prefix_extra" "2")
+ (set_attr "length_immediate" "1")
(set_attr "mode" "TI")])
;; Version of pcom*u* that is called from the intrinsics that allows pcomequ*
@@ -11414,6 +11683,9 @@
"TARGET_SSE5"
"pcom%Y1u<ssevecsize>\t{%3, %2, %0|%0, %2, %3}"
[(set_attr "type" "ssecmp")
+ (set_attr "prefix_data16" "0")
+ (set_attr "prefix_extra" "2")
+ (set_attr "length_immediate" "1")
(set_attr "mode" "TI")])
;; Pcomtrue and pcomfalse support. These are useless instructions, but are
@@ -11432,6 +11704,9 @@
: "pcomfalse<ssevecsize>\t{%2, %1, %0|%0, %1, %2}");
}
[(set_attr "type" "ssecmp")
+ (set_attr "prefix_data16" "0")
+ (set_attr "prefix_extra" "2")
+ (set_attr "length_immediate" "1")
(set_attr "mode" "TI")])
(define_insn "*avx_aesenc"
@@ -11442,6 +11717,7 @@
"TARGET_AES && TARGET_AVX"
"vaesenc\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "type" "sselog1")
+ (set_attr "prefix_extra" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "TI")])
@@ -11464,6 +11740,7 @@
"TARGET_AES && TARGET_AVX"
"vaesenclast\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "type" "sselog1")
+ (set_attr "prefix_extra" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "TI")])
@@ -11486,6 +11763,7 @@
"TARGET_AES && TARGET_AVX"
"vaesdec\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "type" "sselog1")
+ (set_attr "prefix_extra" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "TI")])
@@ -11508,6 +11786,7 @@
"TARGET_AES && TARGET_AVX"
"vaesdeclast\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "type" "sselog1")
+ (set_attr "prefix_extra" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "TI")])
@@ -11542,6 +11821,7 @@
"%vaeskeygenassist\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "type" "sselog1")
(set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "TI")])
@@ -11554,6 +11834,8 @@
"TARGET_PCLMUL && TARGET_AVX"
"vpclmulqdq\t{%3, %2, %1, %0|%0, %1, %2, %3}"
[(set_attr "type" "sselog1")
+ (set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "TI")])
@@ -11567,6 +11849,7 @@
"pclmulqdq\t{%3, %2, %0|%0, %2, %3}"
[(set_attr "type" "sselog1")
(set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "mode" "TI")])
(define_expand "avx_vzeroall"
@@ -11597,6 +11880,7 @@
"TARGET_AVX"
"vzeroall"
[(set_attr "type" "sse")
+ (set_attr "modrm" "0")
(set_attr "memory" "none")
(set_attr "prefix" "vex")
(set_attr "mode" "OI")])
@@ -11615,6 +11899,7 @@
"TARGET_AVX && !TARGET_64BIT"
"vzeroupper"
[(set_attr "type" "sse")
+ (set_attr "modrm" "0")
(set_attr "memory" "none")
(set_attr "prefix" "vex")
(set_attr "mode" "OI")])
@@ -11640,6 +11925,7 @@
"TARGET_AVX && TARGET_64BIT"
"vzeroupper"
[(set_attr "type" "sse")
+ (set_attr "modrm" "0")
(set_attr "memory" "none")
(set_attr "prefix" "vex")
(set_attr "mode" "OI")])
@@ -11653,6 +11939,8 @@
"TARGET_AVX"
"vpermilp<avxmodesuffixf2c>\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "type" "sselog")
+ (set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "<MODE>")])
@@ -11665,6 +11953,7 @@
"TARGET_AVX"
"vpermilp<avxmodesuffixf2c>\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "type" "sselog")
+ (set_attr "prefix_extra" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "<MODE>")])
@@ -11678,6 +11967,8 @@
"TARGET_AVX"
"vperm2f128\t{%3, %2, %1, %0|%0, %1, %2, %3}"
[(set_attr "type" "sselog")
+ (set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "V8SF")])
@@ -11693,6 +11984,7 @@
"TARGET_AVX"
"vbroadcasts<avxmodesuffixf2c>\t{%1, %0|%0, %1}"
[(set_attr "type" "ssemov")
+ (set_attr "prefix_extra" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "<avxscalarmode>")])
@@ -11716,6 +12008,7 @@
"TARGET_AVX"
"vbroadcastss\t{%1, %0|%0, %1}"
[(set_attr "type" "ssemov")
+ (set_attr "prefix_extra" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "SF")])
@@ -11727,6 +12020,7 @@
"TARGET_AVX"
"vbroadcastf128\t{%1, %0|%0, %1}"
[(set_attr "type" "ssemov")
+ (set_attr "prefix_extra" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "V4SF")])
@@ -11763,6 +12057,8 @@
"TARGET_AVX"
"vinsertf128\t{$0x0, %2, %1, %0|%0, %1, %2, 0x0}"
[(set_attr "type" "sselog")
+ (set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "V8SF")])
@@ -11776,6 +12072,8 @@
"TARGET_AVX"
"vinsertf128\t{$0x1, %2, %1, %0|%0, %1, %2, 0x1}"
[(set_attr "type" "sselog")
+ (set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "V8SF")])
@@ -11790,6 +12088,8 @@
"TARGET_AVX"
"vinsertf128\t{$0x0, %2, %1, %0|%0, %1, %2, 0x0}"
[(set_attr "type" "sselog")
+ (set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "V8SF")])
@@ -11804,6 +12104,8 @@
"TARGET_AVX"
"vinsertf128\t{$0x1, %2, %1, %0|%0, %1, %2, 0x1}"
[(set_attr "type" "sselog")
+ (set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "V8SF")])
@@ -11820,6 +12122,8 @@
"TARGET_AVX"
"vinsertf128\t{$0x0, %2, %1, %0|%0, %1, %2, 0x0}"
[(set_attr "type" "sselog")
+ (set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "V8SF")])
@@ -11836,6 +12140,8 @@
"TARGET_AVX"
"vinsertf128\t{$0x1, %2, %1, %0|%0, %1, %2, 0x1}"
[(set_attr "type" "sselog")
+ (set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "V8SF")])
@@ -11856,6 +12162,8 @@
"TARGET_AVX"
"vinsertf128\t{$0x0, %2, %1, %0|%0, %1, %2, 0x0}"
[(set_attr "type" "sselog")
+ (set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "V8SF")])
@@ -11876,6 +12184,8 @@
"TARGET_AVX"
"vinsertf128\t{$0x1, %2, %1, %0|%0, %1, %2, 0x1}"
[(set_attr "type" "sselog")
+ (set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "V8SF")])
@@ -11889,6 +12199,7 @@
"TARGET_AVX"
"vmaskmovp<avxmodesuffixf2c>\t{%1, %2, %0|%0, %2, %1}"
[(set_attr "type" "sselog1")
+ (set_attr "prefix_extra" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "<MODE>")])
@@ -11902,6 +12213,7 @@
"TARGET_AVX"
"vmaskmovp<avxmodesuffixf2c>\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "type" "sselog1")
+ (set_attr "prefix_extra" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "<MODE>")])
@@ -12012,5 +12324,7 @@
}
}
[(set_attr "type" "sselog,ssemov")
+ (set_attr "prefix_extra" "1,*")
+ (set_attr "length_immediate" "1,*")
(set_attr "prefix" "vex")
(set_attr "mode" "<avxvecmode>")])
diff --git a/gcc/config/i386/t-cygming b/gcc/config/i386/t-cygming
index 2cc3a308d8d..4268633b7c8 100644
--- a/gcc/config/i386/t-cygming
+++ b/gcc/config/i386/t-cygming
@@ -31,26 +31,26 @@ LIBGCC2_INCLUDES = -I$(srcdir)/../winsup/w32api/include
winnt.o: $(srcdir)/config/i386/winnt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(RTL_H) $(REGS_H) hard-reg-set.h output.h $(TREE_H) flags.h \
$(TM_P_H) toplev.h $(HASHTAB_H) $(GGC_H)
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
$(srcdir)/config/i386/winnt.c
winnt-cxx.o: $(srcdir)/config/i386/winnt-cxx.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(RTL_H) $(REGS_H) hard-reg-set.h output.h $(TREE_H) flags.h \
$(TM_P_H) toplev.h $(HASHTAB_H) $(GGC_H)
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
$(srcdir)/config/i386/winnt-cxx.c
winnt-stubs.o: $(srcdir)/config/i386/winnt-stubs.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(RTL_H) $(REGS_H) hard-reg-set.h output.h $(TREE_H) flags.h \
$(TM_P_H) toplev.h $(HASHTAB_H) $(GGC_H)
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
$(srcdir)/config/i386/winnt-stubs.c
msformat-c.o: $(srcdir)/config/i386/msformat-c.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(RTL_H) $(REGS_H) hard-reg-set.h output.h $(TREE_H) flags.h \
$(TM_P_H) toplev.h $(HASHTAB_H) $(GGC_H)
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
$(srcdir)/config/i386/msformat-c.c
STMP_FIXINC=stmp-fixinc
diff --git a/gcc/config/i386/t-cygwin b/gcc/config/i386/t-cygwin
index 69d61035211..8fec6f761d7 100644
--- a/gcc/config/i386/t-cygwin
+++ b/gcc/config/i386/t-cygwin
@@ -1,5 +1,5 @@
-# Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2008,
-# 2009 Free Software Foundation, Inc.
+# Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2008, 2009
+# Free Software Foundation, Inc.
#
# This file is part of GCC.
#
@@ -25,12 +25,12 @@ LIBGCC2_INCLUDES += -I$(srcdir)/../winsup/include \
cygwin1.o: $(srcdir)/config/i386/cygwin1.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(TM_P_H)
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
$(srcdir)/config/i386/cygwin1.c
cygwin2.o: $(srcdir)/config/i386/cygwin2.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(TM_P_H)
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
$(srcdir)/config/i386/cygwin2.c
# Cygwin-specific parts of LIB_SPEC
diff --git a/gcc/config/i386/t-gthr-win32 b/gcc/config/i386/t-gthr-win32
index 204a485bcd1..e3977ce6336 100644
--- a/gcc/config/i386/t-gthr-win32
+++ b/gcc/config/i386/t-gthr-win32
@@ -1,3 +1,3 @@
# We hide calls to w32api needed for w32 thread support here:
-LIB2FUNCS_EXTRA = $(srcdir)/config/i386/gthr-win32.c
-
+LIB2FUNCS_EXTRA = $(srcdir)/config/i386/gthr-win32.c \
+ $(srcdir)/config/i386/mingw-tls.c
diff --git a/gcc/config/i386/t-i386 b/gcc/config/i386/t-i386
index f79c38b8ec7..01e5ce413e4 100644
--- a/gcc/config/i386/t-i386
+++ b/gcc/config/i386/t-i386
@@ -1,4 +1,4 @@
-# Copyright (C) 2008 Free Software Foundation, Inc.
+# Copyright (C) 2008, 2009 Free Software Foundation, Inc.
#
# This file is part of GCC.
#
@@ -28,4 +28,5 @@ i386-c.o: $(srcdir)/config/i386/i386-c.c \
$(srcdir)/config/i386/i386-protos.h $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(FLAGS_H) $(C_COMMON_H) $(GGC_H) \
$(TARGET_H) $(TARGET_DEF_H) $(CPPLIB_H) $(C_PRAGMA_H)
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/config/i386/i386-c.c
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $(srcdir)/config/i386/i386-c.c
diff --git a/gcc/config/i386/t-interix b/gcc/config/i386/t-interix
index d5fff6167b7..9a25831f135 100644
--- a/gcc/config/i386/t-interix
+++ b/gcc/config/i386/t-interix
@@ -4,4 +4,5 @@ LIB1ASMFUNCS = _chkstk
winnt.o: $(srcdir)/config/i386/winnt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(RTL_H) $(REGS_H) hard-reg-set.h output.h $(TREE_H) flags.h \
$(TM_P_H) toplev.h $(HASHTAB_H) $(GGC_H)
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/config/i386/winnt.c
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $(srcdir)/config/i386/winnt.c
diff --git a/gcc/config/i386/t-netware b/gcc/config/i386/t-netware
index 2d3a828a5e5..405c98f6a8d 100644
--- a/gcc/config/i386/t-netware
+++ b/gcc/config/i386/t-netware
@@ -1,7 +1,8 @@
TARGET_LIBGCC2_CFLAGS = -mpreferred-stack-boundary=2 -fomit-frame-pointer
netware.o: $(srcdir)/config/i386/netware.c $(RTL_H) $(TREE_H) $(CONFIG_H) $(TM_P_H)
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/config/i386/netware.c
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $(srcdir)/config/i386/netware.c
# We don't need some of GCC's own include files.
USER_H = $(srcdir)/ginclude/stdarg.h \
diff --git a/gcc/config/i386/t-nwld b/gcc/config/i386/t-nwld
index 2c372f12ad7..e7727911636 100644
--- a/gcc/config/i386/t-nwld
+++ b/gcc/config/i386/t-nwld
@@ -1,4 +1,5 @@
-# Copyright (C) 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009
+# Free Software Foundation, Inc.
#
# This file is part of GCC.
#
@@ -39,7 +40,8 @@ $(T)posixpre.def: $(srcdir)/config/i386/t-nwld
echo "check POSIX_CheckUnload" >>$@
nwld.o: $(srcdir)/config/i386/nwld.c $(RTL_H) $(TREE_H) $(CONFIG_H) $(TM_P_H)
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/config/i386/nwld.c
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $(srcdir)/config/i386/nwld.c
s-crt0: $(srcdir)/unwind-dw2-fde.h
diff --git a/gcc/config/i386/winnt.c b/gcc/config/i386/winnt.c
index 3d88517c234..fe5081d37a5 100644
--- a/gcc/config/i386/winnt.c
+++ b/gcc/config/i386/winnt.c
@@ -285,7 +285,7 @@ i386_pe_encode_section_info (tree decl, rtx rtl, int first)
ctor is protected by a link-once guard variable, so that
the object still has link-once semantics, */
|| TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
- make_decl_one_only (decl);
+ make_decl_one_only (decl, DECL_ASSEMBLER_NAME (decl));
else
error ("%q+D:'selectany' attribute applies only to "
"initialized objects", decl);
@@ -499,8 +499,11 @@ i386_pe_asm_output_aligned_decl_common (FILE *stream, tree decl,
{
HOST_WIDE_INT rounded;
- /* Compute as in assemble_noswitch_variable, since we don't actually
- support aligned common. */
+ /* Compute as in assemble_noswitch_variable, since we don't have
+ support for aligned common on older binutils. We must also
+ avoid emitting a common symbol of size zero, as this is the
+ overloaded representation that indicates an undefined external
+ symbol in the PE object file format. */
rounded = size ? size : 1;
rounded += (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1;
rounded = (rounded / (BIGGEST_ALIGNMENT / BITS_PER_UNIT)
@@ -510,9 +513,13 @@ i386_pe_asm_output_aligned_decl_common (FILE *stream, tree decl,
fprintf (stream, "\t.comm\t");
assemble_name (stream, name);
- fprintf (stream, ", " HOST_WIDE_INT_PRINT_DEC "\t" ASM_COMMENT_START
- " " HOST_WIDE_INT_PRINT_DEC "\n",
- rounded, size);
+ if (use_pe_aligned_common)
+ fprintf (stream, ", " HOST_WIDE_INT_PRINT_DEC ", %d\n",
+ size ? size : (HOST_WIDE_INT) 1,
+ exact_log2 (align) - exact_log2 (CHAR_BIT));
+ else
+ fprintf (stream, ", " HOST_WIDE_INT_PRINT_DEC "\t" ASM_COMMENT_START
+ " " HOST_WIDE_INT_PRINT_DEC "\n", rounded, size);
}
/* The Microsoft linker requires that every function be marked as
diff --git a/gcc/config/i386/x-cygwin b/gcc/config/i386/x-cygwin
index cfd7758cfb3..752af76ef6a 100644
--- a/gcc/config/i386/x-cygwin
+++ b/gcc/config/i386/x-cygwin
@@ -1,4 +1,4 @@
host-cygwin.o : $(srcdir)/config/i386/host-cygwin.c $(CONFIG_H) $(SYSTEM_H) \
coretypes.h hosthooks.h $(HOSTHOOKS_DEF_H) toplev.h diagnostic.h
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
$(srcdir)/config/i386/host-cygwin.c
diff --git a/gcc/config/i386/x-darwin b/gcc/config/i386/x-darwin
index 9a3b0f262ce..f0196bac41d 100644
--- a/gcc/config/i386/x-darwin
+++ b/gcc/config/i386/x-darwin
@@ -1,4 +1,4 @@
host-i386-darwin.o : $(srcdir)/config/i386/host-i386-darwin.c \
$(CONFIG_H) $(SYSTEM_H) coretypes.h hosthooks.h $(HOSTHOOKS_DEF_H) \
config/host-darwin.h
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
diff --git a/gcc/config/i386/x-i386 b/gcc/config/i386/x-i386
index 9f03de4535e..2bf8fed5db5 100644
--- a/gcc/config/i386/x-i386
+++ b/gcc/config/i386/x-i386
@@ -1,4 +1,4 @@
driver-i386.o : $(srcdir)/config/i386/driver-i386.c \
$(srcdir)/config/i386/cpuid.h \
$(CONFIG_H) $(SYSTEM_H) $(TM_H) coretypes.h
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
diff --git a/gcc/config/i386/x-mingw32 b/gcc/config/i386/x-mingw32
index 5023e06cdcd..2a1ca47c7c4 100644
--- a/gcc/config/i386/x-mingw32
+++ b/gcc/config/i386/x-mingw32
@@ -27,5 +27,5 @@ WERROR_FLAGS += -Wno-format
host-mingw32.o : $(srcdir)/config/i386/host-mingw32.c $(CONFIG_H) $(SYSTEM_H) \
coretypes.h hosthooks.h hosthooks-def.h toplev.h $(DIAGNOSTIC_H) $(HOOKS_H)
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
$(srcdir)/config/i386/host-mingw32.c
diff --git a/gcc/config/i386/x86-64.h b/gcc/config/i386/x86-64.h
index 46dcad156f8..5d6958cc4ad 100644
--- a/gcc/config/i386/x86-64.h
+++ b/gcc/config/i386/x86-64.h
@@ -74,11 +74,22 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
fprintf ((FILE), "\t.p2align %d,,%d\n", (LOG), (MAX_SKIP)); \
/* Make sure that we have at least 8 byte alignment if > 8 byte \
alignment is preferred. */ \
- if ((LOG) > 3 && (1 << (LOG)) > ((MAX_SKIP) + 1)) \
+ if ((LOG) > 3 \
+ && (1 << (LOG)) > ((MAX_SKIP) + 1) \
+ && (MAX_SKIP) >= 7) \
fprintf ((FILE), "\t.p2align 3\n"); \
} \
} \
} while (0)
+#undef ASM_OUTPUT_MAX_SKIP_PAD
+#define ASM_OUTPUT_MAX_SKIP_PAD(FILE, LOG, MAX_SKIP) \
+ if ((LOG) != 0) \
+ { \
+ if ((MAX_SKIP) == 0) \
+ fprintf ((FILE), "\t.p2align %d\n", (LOG)); \
+ else \
+ fprintf ((FILE), "\t.p2align %d,,%d\n", (LOG), (MAX_SKIP)); \
+ }
#endif
diff --git a/gcc/config/i386/x86intrin.h b/gcc/config/i386/x86intrin.h
index d848811d34c..705300c23eb 100644
--- a/gcc/config/i386/x86intrin.h
+++ b/gcc/config/i386/x86intrin.h
@@ -24,6 +24,8 @@
#ifndef _X86INTRIN_H_INCLUDED
#define _X86INTRIN_H_INCLUDED
+#include <ia32intrin.h>
+
#ifdef __MMX__
#include <mmintrin.h>
#endif
diff --git a/gcc/config/ia64/div.md b/gcc/config/ia64/div.md
index 5f9d005b3f6..f443a28e7ec 100644
--- a/gcc/config/ia64/div.md
+++ b/gcc/config/ia64/div.md
@@ -222,6 +222,32 @@
operands[2] = gen_rtx_REG (<MODE>mode, REGNO (operands[1]));
})
+;; Float to integer truncations using an alternative status register.
+
+(define_insn "fix_truncrfdi2_alts"
+ [(set (match_operand:DI 0 "fr_register_operand" "=f")
+ (fix:DI (match_operand:RF 1 "fr_register_operand" "f")))
+ (use (match_operand:SI 2 "const_int_operand" ""))]
+ ""
+ "fcvt.fx.trunc.s%2 %0 = %1"
+ [(set_attr "itanium_class" "fcvtfx")])
+
+(define_insn "fixuns_truncrfdi2_alts"
+ [(set (match_operand:DI 0 "fr_register_operand" "=f")
+ (unsigned_fix:DI (match_operand:RF 1 "fr_register_operand" "f")))
+ (use (match_operand:SI 2 "const_int_operand" ""))]
+ ""
+ "fcvt.fxu.trunc.s%2 %0 = %1"
+ [(set_attr "itanium_class" "fcvtfx")])
+
+(define_insn "setf_exp_rf"
+ [(set (match_operand:RF 0 "fr_register_operand" "=f")
+ (unspec:RF [(match_operand:DI 1 "register_operand" "r")]
+ UNSPEC_SETF_EXP))]
+ ""
+ "setf.exp %0 = %1"
+ [(set_attr "itanium_class" "frfr")])
+
;; Reciprocal approximation
(define_insn "recip_approx_rf"
@@ -237,6 +263,23 @@
[(set_attr "itanium_class" "fmisc")
(set_attr "predicable" "no")])
+;; Single precision floating point division
+
+(define_expand "divsf3"
+ [(set (match_operand:SF 0 "fr_register_operand" "")
+ (div:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "")
+ (match_operand:SF 2 "fr_reg_or_fp01_operand" "")))]
+ "TARGET_INLINE_FLOAT_DIV"
+{
+ rtx insn;
+ if (TARGET_INLINE_FLOAT_DIV == INL_MIN_LAT)
+ insn = gen_divsf3_internal_lat (operands[0], operands[1], operands[2]);
+ else
+ insn = gen_divsf3_internal_thr (operands[0], operands[1], operands[2]);
+ emit_insn (insn);
+ DONE;
+})
+
;; Single precision floating point division (maximum throughput algorithm).
(define_expand "divsf3_internal_thr"
@@ -334,6 +377,22 @@
DONE;
})
+;; Double precision floating point division
+
+(define_expand "divdf3"
+ [(set (match_operand:DF 0 "fr_register_operand" "")
+ (div:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "")
+ (match_operand:DF 2 "fr_reg_or_fp01_operand" "")))]
+ "TARGET_INLINE_FLOAT_DIV"
+{
+ rtx insn;
+ if (TARGET_INLINE_FLOAT_DIV == INL_MIN_LAT)
+ insn = gen_divdf3_internal_lat (operands[0], operands[1], operands[2]);
+ else
+ insn = gen_divdf3_internal_thr (operands[0], operands[1], operands[2]);
+ emit_insn (insn);
+ DONE;
+})
;; Double precision floating point division (maximum throughput algorithm).
@@ -454,7 +513,7 @@
;; Extended precision floating point division.
-(define_expand "divxf3_internal"
+(define_expand "divxf3"
[(set (match_operand:XF 0 "fr_register_operand" "")
(div:XF (match_operand:XF 1 "fr_reg_or_fp01_operand" "")
(match_operand:XF 2 "fr_reg_or_fp01_operand" "")))]
@@ -518,3 +577,645 @@
emit_insn (gen_truncrfxf2 (operands[0], q_res));
DONE;
})
+
+
+;; Integer division operations
+
+(define_expand "divsi3"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (div:SI (match_operand:SI 1 "general_operand" "")
+ (match_operand:SI 2 "general_operand" "")))]
+ "TARGET_INLINE_INT_DIV"
+{
+ rtx op1_rf, op2_rf, op0_rf, op0_di;
+
+ op0_rf = gen_reg_rtx (RFmode);
+ op0_di = gen_reg_rtx (DImode);
+
+ if (! register_operand (operands[1], SImode))
+ operands[1] = force_reg (SImode, operands[1]);
+ op1_rf = gen_reg_rtx (RFmode);
+ expand_float (op1_rf, operands[1], 0);
+
+ if (! register_operand (operands[2], SImode))
+ operands[2] = force_reg (SImode, operands[2]);
+ op2_rf = gen_reg_rtx (RFmode);
+ expand_float (op2_rf, operands[2], 0);
+
+ emit_insn (gen_cond_trap (EQ, operands[2], CONST0_RTX (SImode),
+ CONST1_RTX (SImode)));
+
+ emit_insn (gen_divsi3_internal (op0_rf, op1_rf, op2_rf));
+
+ emit_insn (gen_fix_truncrfdi2_alts (op0_di, op0_rf, const1_rtx));
+ emit_move_insn (operands[0], gen_lowpart (SImode, op0_di));
+ DONE;
+})
+
+(define_expand "modsi3"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (mod:SI (match_operand:SI 1 "general_operand" "")
+ (match_operand:SI 2 "general_operand" "")))]
+ "TARGET_INLINE_INT_DIV"
+{
+ rtx op2_neg, op1_di, div;
+
+ div = gen_reg_rtx (SImode);
+ emit_insn (gen_divsi3 (div, operands[1], operands[2]));
+
+ op2_neg = expand_unop (SImode, neg_optab, operands[2], NULL_RTX, 0);
+
+ /* This is a trick to get us to reuse the value that we're sure to
+ have already copied to the FP regs. */
+ op1_di = gen_reg_rtx (DImode);
+ convert_move (op1_di, operands[1], 0);
+
+ emit_insn (gen_maddsi4 (operands[0], div, op2_neg,
+ gen_lowpart (SImode, op1_di)));
+ DONE;
+})
+
+(define_expand "udivsi3"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (udiv:SI (match_operand:SI 1 "general_operand" "")
+ (match_operand:SI 2 "general_operand" "")))]
+ "TARGET_INLINE_INT_DIV"
+{
+ rtx op1_rf, op2_rf, op0_rf, op0_di;
+
+ op0_rf = gen_reg_rtx (RFmode);
+ op0_di = gen_reg_rtx (DImode);
+
+ if (! register_operand (operands[1], SImode))
+ operands[1] = force_reg (SImode, operands[1]);
+ op1_rf = gen_reg_rtx (RFmode);
+ expand_float (op1_rf, operands[1], 1);
+
+ if (! register_operand (operands[2], SImode))
+ operands[2] = force_reg (SImode, operands[2]);
+ op2_rf = gen_reg_rtx (RFmode);
+ expand_float (op2_rf, operands[2], 1);
+
+ emit_insn (gen_cond_trap (EQ, operands[2], CONST0_RTX (SImode),
+ CONST1_RTX (SImode)));
+
+ emit_insn (gen_divsi3_internal (op0_rf, op1_rf, op2_rf));
+
+ emit_insn (gen_fixuns_truncrfdi2_alts (op0_di, op0_rf, const1_rtx));
+ emit_move_insn (operands[0], gen_lowpart (SImode, op0_di));
+ DONE;
+})
+
+(define_expand "umodsi3"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (umod:SI (match_operand:SI 1 "general_operand" "")
+ (match_operand:SI 2 "general_operand" "")))]
+ "TARGET_INLINE_INT_DIV"
+{
+ rtx op2_neg, op1_di, div;
+
+ div = gen_reg_rtx (SImode);
+ emit_insn (gen_udivsi3 (div, operands[1], operands[2]));
+
+ op2_neg = expand_unop (SImode, neg_optab, operands[2], NULL_RTX, 0);
+
+ /* This is a trick to get us to reuse the value that we're sure to
+ have already copied to the FP regs. */
+ op1_di = gen_reg_rtx (DImode);
+ convert_move (op1_di, operands[1], 1);
+
+ emit_insn (gen_maddsi4 (operands[0], div, op2_neg,
+ gen_lowpart (SImode, op1_di)));
+ DONE;
+})
+
+(define_expand "divsi3_internal"
+ [(set (match_operand:RF 0 "fr_register_operand" "")
+ (float:RF (div:SI (match_operand:RF 1 "fr_register_operand" "")
+ (match_operand:RF 2 "fr_register_operand" ""))))]
+ "TARGET_INLINE_INT_DIV"
+{
+ rtx a = operands[1];
+ rtx b = operands[2];
+ rtx y = gen_reg_rtx (RFmode);
+ rtx e = gen_reg_rtx (RFmode);
+ rtx e1 = gen_reg_rtx (RFmode);
+ rtx q = gen_reg_rtx (RFmode);
+ rtx q1 = gen_reg_rtx (RFmode);
+ rtx cond = gen_reg_rtx (BImode);
+ rtx zero = CONST0_RTX (RFmode);
+ rtx one = CONST1_RTX (RFmode);
+ rtx status1 = CONST1_RTX (SImode);
+ rtx trunc_off = CONST2_RTX (SImode);
+ rtx twon34_exp = gen_reg_rtx (DImode);
+ rtx twon34 = gen_reg_rtx (RFmode);
+
+ /* Load cosntant 2**(-34) */
+ emit_move_insn (twon34_exp, GEN_INT (65501));
+ emit_insn (gen_setf_exp_rf (twon34, twon34_exp));
+
+ /* y = 1 / b */
+ emit_insn (gen_recip_approx_rf (y, a, b, cond, status1));
+ /* e = 1 - (b * y) */
+ emit_insn (gen_m2subrf4_cond (e, cond, one, b, y, zero, status1, trunc_off));
+ /* q = a * y */
+ emit_insn (gen_mulrf3_cond (q, cond, a, y, zero, status1, trunc_off));
+ /* q1 = q + (q * e) */
+ emit_insn (gen_m2addrf4_cond (q1, cond, q, q, e, zero, status1, trunc_off));
+ /* e1 = (2**-34) + (e * e) */
+ emit_insn (gen_m2addrf4_cond (e1, cond, twon34, e, e, zero, status1, trunc_off));
+ /* q2 = q1 + (e1 * q1) */
+ emit_insn (gen_m2addrf4_cond (operands[0], cond, q1, e1, q1, y, status1, trunc_off));
+ DONE;
+})
+
+(define_expand "divdi3"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (div:DI (match_operand:DI 1 "general_operand" "")
+ (match_operand:DI 2 "general_operand" "")))]
+ "TARGET_INLINE_INT_DIV"
+{
+ rtx op1_rf, op2_rf, op0_rf;
+
+ op0_rf = gen_reg_rtx (RFmode);
+
+ if (! register_operand (operands[1], DImode))
+ operands[1] = force_reg (DImode, operands[1]);
+ op1_rf = gen_reg_rtx (RFmode);
+ expand_float (op1_rf, operands[1], 0);
+
+ if (! register_operand (operands[2], DImode))
+ operands[2] = force_reg (DImode, operands[2]);
+ op2_rf = gen_reg_rtx (RFmode);
+ expand_float (op2_rf, operands[2], 0);
+
+ emit_insn (gen_cond_trap (EQ, operands[2], CONST0_RTX (DImode),
+ CONST1_RTX (DImode)));
+
+ if (TARGET_INLINE_INT_DIV == INL_MIN_LAT)
+ emit_insn (gen_divdi3_internal_lat (op0_rf, op1_rf, op2_rf));
+ else
+ emit_insn (gen_divdi3_internal_thr (op0_rf, op1_rf, op2_rf));
+
+ emit_insn (gen_fix_truncrfdi2_alts (operands[0], op0_rf, const1_rtx));
+ DONE;
+})
+
+(define_expand "moddi3"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (mod:SI (match_operand:DI 1 "general_operand" "")
+ (match_operand:DI 2 "general_operand" "")))]
+ "TARGET_INLINE_INT_DIV"
+{
+ rtx op2_neg, div;
+
+ div = gen_reg_rtx (DImode);
+ emit_insn (gen_divdi3 (div, operands[1], operands[2]));
+
+ op2_neg = expand_unop (DImode, neg_optab, operands[2], NULL_RTX, 0);
+
+ emit_insn (gen_madddi4 (operands[0], div, op2_neg, operands[1]));
+ DONE;
+})
+
+(define_expand "udivdi3"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (udiv:DI (match_operand:DI 1 "general_operand" "")
+ (match_operand:DI 2 "general_operand" "")))]
+ "TARGET_INLINE_INT_DIV"
+{
+ rtx op1_rf, op2_rf, op0_rf;
+
+ op0_rf = gen_reg_rtx (RFmode);
+
+ if (! register_operand (operands[1], DImode))
+ operands[1] = force_reg (DImode, operands[1]);
+ op1_rf = gen_reg_rtx (RFmode);
+ expand_float (op1_rf, operands[1], 1);
+
+ if (! register_operand (operands[2], DImode))
+ operands[2] = force_reg (DImode, operands[2]);
+ op2_rf = gen_reg_rtx (RFmode);
+ expand_float (op2_rf, operands[2], 1);
+
+ emit_insn (gen_cond_trap (EQ, operands[2], CONST0_RTX (DImode),
+ CONST1_RTX (DImode)));
+
+ if (TARGET_INLINE_INT_DIV == INL_MIN_LAT)
+ emit_insn (gen_divdi3_internal_lat (op0_rf, op1_rf, op2_rf));
+ else
+ emit_insn (gen_divdi3_internal_thr (op0_rf, op1_rf, op2_rf));
+
+ emit_insn (gen_fixuns_truncrfdi2_alts (operands[0], op0_rf, const1_rtx));
+ DONE;
+})
+
+(define_expand "umoddi3"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (umod:DI (match_operand:DI 1 "general_operand" "")
+ (match_operand:DI 2 "general_operand" "")))]
+ "TARGET_INLINE_INT_DIV"
+{
+ rtx op2_neg, div;
+
+ div = gen_reg_rtx (DImode);
+ emit_insn (gen_udivdi3 (div, operands[1], operands[2]));
+
+ op2_neg = expand_unop (DImode, neg_optab, operands[2], NULL_RTX, 0);
+
+ emit_insn (gen_madddi4 (operands[0], div, op2_neg, operands[1]));
+ DONE;
+})
+
+(define_expand "divdi3_internal_lat"
+ [(set (match_operand:RF 0 "fr_register_operand" "")
+ (float:RF (div:DI (match_operand:RF 1 "fr_register_operand" "")
+ (match_operand:RF 2 "fr_register_operand" ""))))]
+ "TARGET_INLINE_INT_DIV"
+{
+ rtx a = operands[1];
+ rtx b = operands[2];
+ rtx y = gen_reg_rtx (RFmode);
+ rtx y1 = gen_reg_rtx (RFmode);
+ rtx y2 = gen_reg_rtx (RFmode);
+ rtx e = gen_reg_rtx (RFmode);
+ rtx e1 = gen_reg_rtx (RFmode);
+ rtx q = gen_reg_rtx (RFmode);
+ rtx q1 = gen_reg_rtx (RFmode);
+ rtx q2 = gen_reg_rtx (RFmode);
+ rtx r = gen_reg_rtx (RFmode);
+ rtx cond = gen_reg_rtx (BImode);
+ rtx zero = CONST0_RTX (RFmode);
+ rtx one = CONST1_RTX (RFmode);
+ rtx status1 = CONST1_RTX (SImode);
+ rtx trunc_off = CONST2_RTX (SImode);
+
+ /* y = 1 / b */
+ emit_insn (gen_recip_approx_rf (y, a, b, cond, status1));
+ /* e = 1 - (b * y) */
+ emit_insn (gen_m2subrf4_cond (e, cond, one, b, y, zero, status1, trunc_off));
+ /* q = a * y */
+ emit_insn (gen_mulrf3_cond (q, cond, a, y, zero, status1, trunc_off));
+ /* q1 = q + (q * e) */
+ emit_insn (gen_m2addrf4_cond (q1, cond, q, q, e, zero, status1, trunc_off));
+ /* e1 = e * e */
+ emit_insn (gen_mulrf3_cond (e1, cond, e, e, zero, status1, trunc_off));
+ /* q2 = q1 + (e1 * q1) */
+ emit_insn (gen_m2addrf4_cond (q2, cond, q1, e1, q1, zero, status1, trunc_off));
+ /* y1 = y + (y * e) */
+ emit_insn (gen_m2addrf4_cond (y1, cond, y, y, e, zero, status1, trunc_off));
+ /* r = a - (b * q2) */
+ emit_insn (gen_m2subrf4_cond (r, cond, a, b, q2, zero, status1, trunc_off));
+ /* y2 = y1 + (y1 * e1) */
+ emit_insn (gen_m2addrf4_cond (y2, cond, y1, y1, e1, zero, status1, trunc_off));
+ /* q3 = q2 + (r * y2) */
+ emit_insn (gen_m2addrf4_cond (operands[0], cond, q2, r, y2, y, status1, trunc_off));
+ DONE;
+})
+
+(define_expand "divdi3_internal_thr"
+ [(set (match_operand:RF 0 "fr_register_operand" "")
+ (float:RF (div:DI (match_operand:RF 1 "fr_register_operand" "")
+ (match_operand:RF 2 "fr_register_operand" ""))))]
+ "TARGET_INLINE_INT_DIV"
+{
+ rtx a = operands[1];
+ rtx b = operands[2];
+ rtx y = gen_reg_rtx (RFmode);
+ rtx y1 = gen_reg_rtx (RFmode);
+ rtx y2 = gen_reg_rtx (RFmode);
+ rtx e = gen_reg_rtx (RFmode);
+ rtx e1 = gen_reg_rtx (RFmode);
+ rtx q2 = gen_reg_rtx (RFmode);
+ rtx r = gen_reg_rtx (RFmode);
+ rtx cond = gen_reg_rtx (BImode);
+ rtx zero = CONST0_RTX (RFmode);
+ rtx one = CONST1_RTX (RFmode);
+ rtx status1 = CONST1_RTX (SImode);
+ rtx trunc_off = CONST2_RTX (SImode);
+
+ /* y = 1 / b */
+ emit_insn (gen_recip_approx_rf (y, a, b, cond, status1));
+ /* e = 1 - (b * y) */
+ emit_insn (gen_m2subrf4_cond (e, cond, one, b, y, zero, status1, trunc_off));
+ /* y1 = y + (y * e) */
+ emit_insn (gen_m2addrf4_cond (y1, cond, y, y, e, zero, status1, trunc_off));
+ /* e1 = e * e */
+ emit_insn (gen_mulrf3_cond (e1, cond, e, e, zero, status1, trunc_off));
+ /* y2 = y1 + (y1 * e1) */
+ emit_insn (gen_m2addrf4_cond (y2, cond, y1, y1, e1, zero, status1, trunc_off));
+ /* q2 = y2 * a */
+ emit_insn (gen_mulrf3_cond (q2, cond, y2, a, zero, status1, trunc_off));
+ /* r = a - (b * q2) */
+ emit_insn (gen_m2subrf4_cond (r, cond, a, b, q2, zero, status1, trunc_off));
+ /* q3 = q2 + (r * y2) */
+ emit_insn (gen_m2addrf4_cond (operands[0], cond, q2, r, y2, y, status1, trunc_off));
+ DONE;
+})
+
+;; SQRT operations
+
+
+(define_insn "sqrt_approx_rf"
+ [(set (match_operand:RF 0 "fr_register_operand" "=f")
+ (unspec:RF [(match_operand:RF 1 "fr_reg_or_fp01_operand" "fG")]
+ UNSPEC_FR_SQRT_RECIP_APPROX_RES))
+ (set (match_operand:BI 2 "register_operand" "=c")
+ (unspec:BI [(match_dup 1)] UNSPEC_FR_SQRT_RECIP_APPROX))
+ (use (match_operand:SI 3 "const_int_operand" ""))]
+ ""
+ "frsqrta.s%3 %0, %2 = %F1"
+ [(set_attr "itanium_class" "fmisc")
+ (set_attr "predicable" "no")])
+
+(define_expand "sqrtsf2"
+ [(set (match_operand:SF 0 "fr_register_operand" "=&f")
+ (sqrt:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")))]
+ "TARGET_INLINE_SQRT"
+{
+ rtx insn;
+ if (TARGET_INLINE_SQRT == INL_MIN_LAT)
+ insn = gen_sqrtsf2_internal_lat (operands[0], operands[1]);
+ else
+ insn = gen_sqrtsf2_internal_thr (operands[0], operands[1]);
+ emit_insn (insn);
+ DONE;
+})
+
+(define_expand "sqrtsf2_internal_thr"
+ [(set (match_operand:SF 0 "fr_register_operand" "")
+ (sqrt:SF (match_operand:SF 1 "fr_register_operand" "")))]
+ "TARGET_INLINE_SQRT"
+{
+ rtx y = gen_reg_rtx (RFmode);
+ rtx b = gen_reg_rtx (RFmode);
+ rtx g = gen_reg_rtx (RFmode);
+ rtx e = gen_reg_rtx (RFmode);
+ rtx s = gen_reg_rtx (RFmode);
+ rtx f = gen_reg_rtx (RFmode);
+ rtx y1 = gen_reg_rtx (RFmode);
+ rtx g1 = gen_reg_rtx (RFmode);
+ rtx h = gen_reg_rtx (RFmode);
+ rtx d = gen_reg_rtx (RFmode);
+ rtx g2 = gen_reg_rtx (RFmode);
+ rtx cond = gen_reg_rtx (BImode);
+ rtx zero = CONST0_RTX (RFmode);
+ rtx one = CONST1_RTX (RFmode);
+ rtx c1 = ia64_dconst_0_5();
+ rtx c2 = ia64_dconst_0_375();
+ rtx reg_df_c1 = gen_reg_rtx (DFmode);
+ rtx reg_df_c2 = gen_reg_rtx (DFmode);
+ rtx reg_rf_c1 = gen_reg_rtx (RFmode);
+ rtx reg_rf_c2 = gen_reg_rtx (RFmode);
+ rtx status0 = CONST0_RTX (SImode);
+ rtx status1 = CONST1_RTX (SImode);
+ rtx trunc_sgl = CONST0_RTX (SImode);
+ rtx trunc_off = CONST2_RTX (SImode);
+
+ /* Put needed constants into registers. */
+ emit_insn (gen_movdf (reg_df_c1, c1));
+ emit_insn (gen_movdf (reg_df_c2, c2));
+ emit_insn (gen_extenddfrf2 (reg_rf_c1, reg_df_c1));
+ emit_insn (gen_extenddfrf2 (reg_rf_c2, reg_df_c2));
+ /* Empty conversion to put input into RFmode. */
+ emit_insn (gen_extendsfrf2 (b, operands[1]));
+ /* y = sqrt (1 / b) */
+ emit_insn (gen_sqrt_approx_rf (y, b, cond, status0));
+ /* g = b * y */
+ emit_insn (gen_mulrf3_cond (g, cond, b, y, zero, status1, trunc_off));
+ /* e = 1 - (g * y) */
+ emit_insn (gen_m2subrf4_cond (e, cond, one, g, y, zero, status1, trunc_off));
+ /* s = 0.5 + (0.375 * e) */
+ emit_insn (gen_m2addrf4_cond (s, cond, reg_rf_c1, reg_rf_c2, e, zero, status1, trunc_off));
+ /* f = y * e */
+ emit_insn (gen_mulrf3_cond (f, cond, y, e, zero, status1, trunc_off));
+ /* y1 = y + (f * s) */
+ emit_insn (gen_m2addrf4_cond (y1, cond, y, f, s, zero, status1, trunc_off));
+ /* g1 = single (b * y1) */
+ emit_insn (gen_mulrf3_cond (g1, cond, b, y1, zero, status1, trunc_sgl));
+ /* h = 0.5 * y1 */
+ emit_insn (gen_mulrf3_cond (h, cond, reg_rf_c1, y1, zero, status1, trunc_off));
+ /* d = b - g1 * g1 */
+ emit_insn (gen_m2subrf4_cond (d, cond, b, g1, g1, zero, status1, trunc_off));
+ /* g2 = single(g1 + (d * h)) */
+ emit_insn (gen_m2addrf4_cond (g2, cond, g1, d, h, y, status0, trunc_sgl));
+ /* Conversion back into SFmode. */
+ emit_insn (gen_truncrfsf2 (operands[0], g2));
+ DONE;
+})
+
+(define_expand "sqrtsf2_internal_lat"
+ [(set (match_operand:SF 0 "fr_register_operand" "")
+ (sqrt:SF (match_operand:SF 1 "fr_register_operand" "")))]
+ "TARGET_INLINE_SQRT"
+{
+ rtx y = gen_reg_rtx (RFmode);
+ rtx b = gen_reg_rtx (RFmode);
+ rtx g = gen_reg_rtx (RFmode);
+ rtx g1 = gen_reg_rtx (RFmode);
+ rtx g2 = gen_reg_rtx (RFmode);
+ rtx e = gen_reg_rtx (RFmode);
+ rtx s = gen_reg_rtx (RFmode);
+ rtx f = gen_reg_rtx (RFmode);
+ rtx f1 = gen_reg_rtx (RFmode);
+ rtx h = gen_reg_rtx (RFmode);
+ rtx h1 = gen_reg_rtx (RFmode);
+ rtx d = gen_reg_rtx (RFmode);
+ rtx cond = gen_reg_rtx (BImode);
+ rtx zero = CONST0_RTX (RFmode);
+ rtx one = CONST1_RTX (RFmode);
+ rtx c1 = ia64_dconst_0_5();
+ rtx c2 = ia64_dconst_0_375();
+ rtx reg_df_c1 = gen_reg_rtx (DFmode);
+ rtx reg_df_c2 = gen_reg_rtx (DFmode);
+ rtx reg_rf_c1 = gen_reg_rtx (RFmode);
+ rtx reg_rf_c2 = gen_reg_rtx (RFmode);
+ rtx status0 = CONST0_RTX (SImode);
+ rtx status1 = CONST1_RTX (SImode);
+ rtx trunc_sgl = CONST0_RTX (SImode);
+ rtx trunc_off = CONST2_RTX (SImode);
+
+ /* Put needed constants into registers. */
+ emit_insn (gen_movdf (reg_df_c1, c1));
+ emit_insn (gen_movdf (reg_df_c2, c2));
+ emit_insn (gen_extenddfrf2 (reg_rf_c1, reg_df_c1));
+ emit_insn (gen_extenddfrf2 (reg_rf_c2, reg_df_c2));
+ /* Empty conversion to put input into RFmode. */
+ emit_insn (gen_extendsfrf2 (b, operands[1]));
+ /* y = sqrt (1 / b) */
+ emit_insn (gen_sqrt_approx_rf (y, b, cond, status0));
+ /* g = b * y */
+ emit_insn (gen_mulrf3_cond (g, cond, b, y, zero, status1, trunc_off));
+ /* e = 1 - (g * y) */
+ emit_insn (gen_m2subrf4_cond (e, cond, one, g, y, zero, status1, trunc_off));
+ /* h = 0.5 * y */
+ emit_insn (gen_mulrf3_cond (h, cond, reg_rf_c1, y, zero, status1, trunc_off));
+ /* s = 0.5 + (0.375 * e) */
+ emit_insn (gen_m2addrf4_cond (s, cond, reg_rf_c1, reg_rf_c2, e, zero, status1, trunc_off));
+ /* f = e * g */
+ emit_insn (gen_mulrf3_cond (f, cond, e, g, zero, status1, trunc_off));
+ /* g1 = single (g + (f * s)) */
+ emit_insn (gen_m2addrf4_cond (g1, cond, g, f, s, zero, status1, trunc_sgl));
+ /* f1 = e * h */
+ emit_insn (gen_mulrf3_cond (f1, cond, e, h, zero, status1, trunc_off));
+ /* d = b - g1 * g1 */
+ emit_insn (gen_m2subrf4_cond (d, cond, b, g1, g1, zero, status1, trunc_off));
+ /* h1 = h + (f1 * s) */
+ emit_insn (gen_m2addrf4_cond (h1, cond, h, f1, s, zero, status1, trunc_off));
+ /* g2 = single(g1 + (d * h1)) */
+ emit_insn (gen_m2addrf4_cond (g2, cond, g1, d, h1, y, status0, trunc_sgl));
+ /* Conversion back into SFmode. */
+ emit_insn (gen_truncrfsf2 (operands[0], g2));
+ DONE;
+})
+
+(define_expand "sqrtdf2"
+ [(set (match_operand:DF 0 "fr_register_operand" "=&f")
+ (sqrt:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")))]
+ "TARGET_INLINE_SQRT"
+{
+ rtx insn;
+#if 0
+ if (TARGET_INLINE_SQRT == INL_MIN_LAT)
+ insn = gen_sqrtdf2_internal_lat (operands[0], operands[1]);
+ else
+#endif
+ insn = gen_sqrtdf2_internal_thr (operands[0], operands[1]);
+ emit_insn (insn);
+ DONE;
+})
+
+(define_expand "sqrtdf2_internal_thr"
+ [(set (match_operand:DF 0 "fr_register_operand" "")
+ (sqrt:DF (match_operand:DF 1 "fr_register_operand" "")))]
+ "TARGET_INLINE_SQRT"
+{
+ rtx y = gen_reg_rtx (RFmode);
+ rtx b = gen_reg_rtx (RFmode);
+ rtx g = gen_reg_rtx (RFmode);
+ rtx g1 = gen_reg_rtx (RFmode);
+ rtx g2 = gen_reg_rtx (RFmode);
+ rtx g3 = gen_reg_rtx (RFmode);
+ rtx g4 = gen_reg_rtx (RFmode);
+ rtx r = gen_reg_rtx (RFmode);
+ rtx r1 = gen_reg_rtx (RFmode);
+ rtx h = gen_reg_rtx (RFmode);
+ rtx h1 = gen_reg_rtx (RFmode);
+ rtx h2 = gen_reg_rtx (RFmode);
+ rtx d = gen_reg_rtx (RFmode);
+ rtx d1 = gen_reg_rtx (RFmode);
+ rtx cond = gen_reg_rtx (BImode);
+ rtx zero = CONST0_RTX (RFmode);
+ rtx c1 = ia64_dconst_0_5();
+ rtx reg_df_c1 = gen_reg_rtx (DFmode);
+ rtx reg_rf_c1 = gen_reg_rtx (RFmode);
+ rtx status0 = CONST0_RTX (SImode);
+ rtx status1 = CONST1_RTX (SImode);
+ rtx trunc_dbl = CONST1_RTX (SImode);
+ rtx trunc_off = CONST2_RTX (SImode);
+
+ /* Put needed constants into registers. */
+ emit_insn (gen_movdf (reg_df_c1, c1));
+ emit_insn (gen_extenddfrf2 (reg_rf_c1, reg_df_c1));
+ /* Empty conversion to put input into RFmode. */
+ emit_insn (gen_extenddfrf2 (b, operands[1]));
+ /* y = sqrt (1 / b) */
+ emit_insn (gen_sqrt_approx_rf (y, b, cond, status0));
+ /* g = b * y */
+ emit_insn (gen_mulrf3_cond (g, cond, b, y, zero, status1, trunc_off));
+ /* h = 0.5 * y */
+ emit_insn (gen_mulrf3_cond (h, cond, reg_rf_c1, y, zero, status1, trunc_off));
+ /* r = 0.5 - (g * h) */
+ emit_insn (gen_m2subrf4_cond (r, cond, reg_rf_c1, g, h, zero, status1, trunc_off));
+ /* g1 = g + (g * r) */
+ emit_insn (gen_m2addrf4_cond (g1, cond, g, g, r, zero, status1, trunc_off));
+ /* h1 = h + (h * r) */
+ emit_insn (gen_m2addrf4_cond (h1, cond, h, h, r, zero, status1, trunc_off));
+ /* r1 = 0.5 - (g1 * h1) */
+ emit_insn (gen_m2subrf4_cond (r1, cond, reg_rf_c1, g1, h1, zero, status1, trunc_off));
+ /* g2 = g1 + (g1 * r1) */
+ emit_insn (gen_m2addrf4_cond (g2, cond, g1, g1, r1, zero, status1, trunc_off));
+ /* h2 = h1 + (h1 * r1) */
+ emit_insn (gen_m2addrf4_cond (h2, cond, h1, h1, r1, zero, status1, trunc_off));
+ /* d = b - (g2 * g2) */
+ emit_insn (gen_m2subrf4_cond (d, cond, b, g2, g2, zero, status1, trunc_off));
+ /* g3 = g2 + (d * h2) */
+ emit_insn (gen_m2addrf4_cond (g3, cond, g2, d, h2, zero, status1, trunc_off));
+ /* d1 = b - (g3 * g3) */
+ emit_insn (gen_m2subrf4_cond (d1, cond, b, g3, g3, zero, status1, trunc_off));
+ /* g4 = g3 + (d1 * h2) */
+ emit_insn (gen_m2addrf4_cond (g4, cond, g3, d1, h2, y, status1, trunc_dbl));
+ /* Conversion back into SFmode. */
+ emit_insn (gen_truncrfdf2 (operands[0], g4));
+ DONE;
+})
+
+(define_expand "sqrtxf2"
+ [(set (match_operand:XF 0 "fr_register_operand" "")
+ (sqrt:XF (match_operand:XF 1 "fr_register_operand" "")))]
+ "TARGET_INLINE_SQRT"
+{
+ rtx y = gen_reg_rtx (RFmode);
+ rtx b = gen_reg_rtx (RFmode);
+ rtx g = gen_reg_rtx (RFmode);
+ rtx g1 = gen_reg_rtx (RFmode);
+ rtx g2 = gen_reg_rtx (RFmode);
+ rtx g3 = gen_reg_rtx (RFmode);
+ rtx g4 = gen_reg_rtx (RFmode);
+ rtx e = gen_reg_rtx (RFmode);
+ rtx e1 = gen_reg_rtx (RFmode);
+ rtx e2 = gen_reg_rtx (RFmode);
+ rtx h = gen_reg_rtx (RFmode);
+ rtx h1 = gen_reg_rtx (RFmode);
+ rtx h2 = gen_reg_rtx (RFmode);
+ rtx h3 = gen_reg_rtx (RFmode);
+ rtx d = gen_reg_rtx (RFmode);
+ rtx d1 = gen_reg_rtx (RFmode);
+ rtx cond = gen_reg_rtx (BImode);
+ rtx zero = CONST0_RTX (RFmode);
+ rtx c1 = ia64_dconst_0_5();
+ rtx reg_df_c1 = gen_reg_rtx (DFmode);
+ rtx reg_rf_c1 = gen_reg_rtx (RFmode);
+ rtx status0 = CONST0_RTX (SImode);
+ rtx status1 = CONST1_RTX (SImode);
+ rtx trunc_off = CONST2_RTX (SImode);
+
+ /* Put needed constants into registers. */
+ emit_insn (gen_movdf (reg_df_c1, c1));
+ emit_insn (gen_extenddfrf2 (reg_rf_c1, reg_df_c1));
+ /* Empty conversion to put input into RFmode. */
+ emit_insn (gen_extendxfrf2 (b, operands[1]));
+ /* y = sqrt (1 / b) */
+ emit_insn (gen_sqrt_approx_rf (y, b, cond, status0));
+ /* g = b * y */
+ emit_insn (gen_mulrf3_cond (g, cond, b, y, zero, status1, trunc_off));
+ /* h = 0.5 * y */
+ emit_insn (gen_mulrf3_cond (h, cond, reg_rf_c1, y, zero, status1, trunc_off));
+ /* e = 0.5 - (g * h) */
+ emit_insn (gen_m2subrf4_cond (e, cond, reg_rf_c1, g, h, zero, status1, trunc_off));
+ /* g1 = g + (g * e) */
+ emit_insn (gen_m2addrf4_cond (g1, cond, g, g, e, zero, status1, trunc_off));
+ /* h1 = h + (h * e) */
+ emit_insn (gen_m2addrf4_cond (h1, cond, h, h, e, zero, status1, trunc_off));
+ /* e1 = 0.5 - (g1 * h1) */
+ emit_insn (gen_m2subrf4_cond (e1, cond, reg_rf_c1, g1, h1, zero, status1, trunc_off));
+ /* g2 = g1 + (g1 * e1) */
+ emit_insn (gen_m2addrf4_cond (g2, cond, g1, g1, e1, zero, status1, trunc_off));
+ /* h2 = h1 + (h1 * e1) */
+ emit_insn (gen_m2addrf4_cond (h2, cond, h1, h1, e1, zero, status1, trunc_off));
+ /* d = b - (g2 * g2) */
+ emit_insn (gen_m2subrf4_cond (d, cond, b, g2, g2, zero, status1, trunc_off));
+ /* e2 = 0.5 - (g2 * h2) */
+ emit_insn (gen_m2subrf4_cond (e2, cond, reg_rf_c1, g2, h2, zero, status1, trunc_off));
+ /* g3 = g2 + (d * h2) */
+ emit_insn (gen_m2addrf4_cond (g3, cond, g2, d, h2, zero, status1, trunc_off));
+ /* h3 = h2 + (e2 * h2) */
+ emit_insn (gen_m2addrf4_cond (h3, cond, h2, e2, h2, zero, status1, trunc_off));
+ /* d1 = b - (g3 * g3) */
+ emit_insn (gen_m2subrf4_cond (d1, cond, b, g3, g3, zero, status1, trunc_off));
+ /* g4 = g3 + (d1 * h3) */
+ emit_insn (gen_m2addrf4_cond (g4, cond, g3, d1, h3, y, status1, trunc_off));
+ /* Conversion back into SFmode. */
+ emit_insn (gen_truncrfxf2 (operands[0], g4));
+ DONE;
+})
diff --git a/gcc/config/ia64/hpux.h b/gcc/config/ia64/hpux.h
index f7918d21aa4..e91d1340e8a 100644
--- a/gcc/config/ia64/hpux.h
+++ b/gcc/config/ia64/hpux.h
@@ -106,7 +106,7 @@ do { \
#undef TARGET_DEFAULT
#define TARGET_DEFAULT \
- (MASK_DWARF2_ASM | MASK_BIG_ENDIAN | MASK_ILP32)
+ (MASK_DWARF2_ASM | MASK_BIG_ENDIAN | MASK_ILP32 | MASK_FUSED_MADD)
/* ??? Might not be needed anymore. */
#define MEMBER_TYPE_FORCES_BLK(FIELD, MODE) ((MODE) == TFmode)
diff --git a/gcc/config/ia64/ia64-protos.h b/gcc/config/ia64/ia64-protos.h
index e3b78641eb8..5a68854296f 100644
--- a/gcc/config/ia64/ia64-protos.h
+++ b/gcc/config/ia64/ia64-protos.h
@@ -18,13 +18,6 @@ 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/>. */
-/* Variables defined in ia64.c. */
-
-#ifdef RTX_CODE
-extern GTY(()) rtx ia64_compare_op0;
-extern GTY(()) rtx ia64_compare_op1;
-#endif
-
/* Functions defined in ia64.c */
extern int bundling_p;
@@ -43,7 +36,7 @@ extern void ia64_emit_cond_move (rtx, rtx, rtx);
extern int ia64_depz_field_mask (rtx, rtx);
extern void ia64_split_tmode_move (rtx[]);
extern bool ia64_expand_movxf_movrf (enum machine_mode, rtx[]);
-extern rtx ia64_expand_compare (enum rtx_code, enum machine_mode);
+extern void ia64_expand_compare (rtx *, rtx *, rtx *);
extern void ia64_expand_vecint_cmov (rtx[]);
extern bool ia64_expand_vecint_minmax (enum rtx_code, enum machine_mode, rtx[]);
extern void ia64_expand_widen_sum (rtx[], bool);
@@ -109,3 +102,6 @@ extern void ia64_profile_hook (int);
extern void ia64_optimization_options (int, int);
extern void ia64_init_expanders (void);
+
+extern rtx ia64_dconst_0_5 (void);
+extern rtx ia64_dconst_0_375 (void);
diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c
index b3fca988f34..c4b92abc47d 100644
--- a/gcc/config/ia64/ia64.c
+++ b/gcc/config/ia64/ia64.c
@@ -63,11 +63,6 @@ along with GCC; see the file COPYING3. If not see
ASM_OUTPUT_LABELREF. */
int ia64_asm_output_label = 0;
-/* Define the information needed to generate branch and scc insns. This is
- stored from the compare operation. */
-struct rtx_def * ia64_compare_op0;
-struct rtx_def * ia64_compare_op1;
-
/* Register names for ia64_expand_prologue. */
static const char * const ia64_reg_numbers[96] =
{ "r32", "r33", "r34", "r35", "r36", "r37", "r38", "r39",
@@ -1493,28 +1488,28 @@ ia64_expand_movxf_movrf (enum machine_mode mode, rtx operands[])
return false;
}
-/* Emit comparison instruction if necessary, returning the expression
- that holds the compare result in the proper mode. */
+/* Emit comparison instruction if necessary, replacing *EXPR, *OP0, *OP1
+ with the expression that holds the compare result (in VOIDmode). */
static GTY(()) rtx cmptf_libfunc;
-rtx
-ia64_expand_compare (enum rtx_code code, enum machine_mode mode)
+void
+ia64_expand_compare (rtx *expr, rtx *op0, rtx *op1)
{
- rtx op0 = ia64_compare_op0, op1 = ia64_compare_op1;
+ enum rtx_code code = GET_CODE (*expr);
rtx cmp;
/* If we have a BImode input, then we already have a compare result, and
do not need to emit another comparison. */
- if (GET_MODE (op0) == BImode)
+ if (GET_MODE (*op0) == BImode)
{
- gcc_assert ((code == NE || code == EQ) && op1 == const0_rtx);
- cmp = op0;
+ gcc_assert ((code == NE || code == EQ) && *op1 == const0_rtx);
+ cmp = *op0;
}
/* HPUX TFmode compare requires a library call to _U_Qfcmp, which takes a
magic number as its third argument, that indicates what to do.
The return value is an integer to be compared against zero. */
- else if (TARGET_HPUX && GET_MODE (op0) == TFmode)
+ else if (TARGET_HPUX && GET_MODE (*op0) == TFmode)
{
enum qfcmp_magic {
QCMP_INV = 1, /* Raise FP_INVALID on SNaN as a side effect. */
@@ -1527,7 +1522,7 @@ ia64_expand_compare (enum rtx_code code, enum machine_mode mode)
enum rtx_code ncode;
rtx ret, insns;
- gcc_assert (cmptf_libfunc && GET_MODE (op1) == TFmode);
+ gcc_assert (cmptf_libfunc && GET_MODE (*op1) == TFmode);
switch (code)
{
/* 1 = equal, 0 = not equal. Equality operators do
@@ -1552,7 +1547,7 @@ ia64_expand_compare (enum rtx_code code, enum machine_mode mode)
start_sequence ();
ret = emit_library_call_value (cmptf_libfunc, 0, LCT_CONST, DImode, 3,
- op0, TFmode, op1, TFmode,
+ *op0, TFmode, *op1, TFmode,
GEN_INT (magic), DImode);
cmp = gen_reg_rtx (BImode);
emit_insn (gen_rtx_SET (VOIDmode, cmp,
@@ -1563,18 +1558,20 @@ ia64_expand_compare (enum rtx_code code, enum machine_mode mode)
end_sequence ();
emit_libcall_block (insns, cmp, cmp,
- gen_rtx_fmt_ee (code, BImode, op0, op1));
+ gen_rtx_fmt_ee (code, BImode, *op0, *op1));
code = NE;
}
else
{
cmp = gen_reg_rtx (BImode);
emit_insn (gen_rtx_SET (VOIDmode, cmp,
- gen_rtx_fmt_ee (code, BImode, op0, op1)));
+ gen_rtx_fmt_ee (code, BImode, *op0, *op1)));
code = NE;
}
- return gen_rtx_fmt_ee (code, mode, cmp, const0_rtx);
+ *expr = gen_rtx_fmt_ee (code, VOIDmode, cmp, const0_rtx);
+ *op0 = cmp;
+ *op1 = const0_rtx;
}
/* Generate an integral vector comparison. Return true if the condition has
@@ -1946,7 +1943,7 @@ get_reg (enum ia64_frame_regs r)
static bool
is_emitted (int regno)
{
- enum ia64_frame_regs r;
+ unsigned int r;
for (r = reg_fp; r < number_of_ia64_frame_regs; r++)
if (emitted_frame_related_regs[r] == regno)
@@ -3660,7 +3657,7 @@ int
ia64_hard_regno_rename_ok (int from, int to)
{
/* Don't clobber any of the registers we reserved for the prologue. */
- enum ia64_frame_regs r;
+ unsigned int r;
for (r = reg_fp; r <= reg_save_ar_lc; r++)
if (to == current_frame_info.r[r]
@@ -5283,12 +5280,6 @@ ia64_override_options (void)
if (TARGET_AUTO_PIC)
target_flags |= MASK_CONST_GP;
- if (TARGET_INLINE_SQRT == INL_MIN_LAT)
- {
- warning (0, "not yet implemented: latency-optimized inline square root");
- TARGET_INLINE_SQRT = INL_MAX_THR;
- }
-
ia64_flag_schedule_insns2 = flag_schedule_insns_after_reload;
flag_schedule_insns_after_reload = 0;
@@ -9330,7 +9321,7 @@ ia64_epilogue_uses (int regno)
int
ia64_eh_uses (int regno)
{
- enum ia64_frame_regs r;
+ unsigned int r;
if (! reload_completed)
return 0;
@@ -10585,4 +10576,33 @@ ia64_c_mode_for_suffix (char suffix)
return VOIDmode;
}
+static GTY(()) rtx ia64_dconst_0_5_rtx;
+
+rtx
+ia64_dconst_0_5 (void)
+{
+ if (! ia64_dconst_0_5_rtx)
+ {
+ REAL_VALUE_TYPE rv;
+ real_from_string (&rv, "0.5");
+ ia64_dconst_0_5_rtx = const_double_from_real_value (rv, DFmode);
+ }
+ return ia64_dconst_0_5_rtx;
+}
+
+static GTY(()) rtx ia64_dconst_0_375_rtx;
+
+rtx
+ia64_dconst_0_375 (void)
+{
+ if (! ia64_dconst_0_375_rtx)
+ {
+ REAL_VALUE_TYPE rv;
+ real_from_string (&rv, "0.375");
+ ia64_dconst_0_375_rtx = const_double_from_real_value (rv, DFmode);
+ }
+ return ia64_dconst_0_375_rtx;
+}
+
+
#include "gt-ia64.h"
diff --git a/gcc/config/ia64/ia64.h b/gcc/config/ia64/ia64.h
index 05957ea12db..ff02f754caa 100644
--- a/gcc/config/ia64/ia64.h
+++ b/gcc/config/ia64/ia64.h
@@ -94,7 +94,7 @@ enum ia64_inline_type
/* Default target_flags if no switches are specified */
#ifndef TARGET_DEFAULT
-#define TARGET_DEFAULT (MASK_DWARF2_ASM)
+#define TARGET_DEFAULT (MASK_DWARF2_ASM | MASK_FUSED_MADD)
#endif
#ifndef TARGET_CPU_DEFAULT
diff --git a/gcc/config/ia64/ia64.md b/gcc/config/ia64/ia64.md
index 26e71f841b5..f9c6de2dbe4 100644
--- a/gcc/config/ia64/ia64.md
+++ b/gcc/config/ia64/ia64.md
@@ -409,6 +409,7 @@
(set_attr "speculable2" "no, no, no, no, yes,no,no, no, no, yes,no, no, no, no, no, no, no, no, no")])
(define_mode_iterator MODE [BI QI HI SI DI SF DF XF TI])
+(define_mode_iterator MODE_FOR_CMP [BI SI DI SF DF XF (TF "TARGET_HPUX")])
(define_mode_iterator MODE_FOR_EXTEND [QI HI SI])
(define_mode_attr output_a [
@@ -1233,6 +1234,13 @@
;; Convert between signed integer types and floating point.
+(define_insn "floatdirf2"
+ [(set (match_operand:RF 0 "fr_register_operand" "=f")
+ (float:RF (match_operand:DI 1 "fr_reg_or_fp01_operand" "fG")))]
+ ""
+ "fcvt.xf %0 = %F1"
+ [(set_attr "itanium_class" "fcvtfx")])
+
(define_insn "floatdixf2"
[(set (match_operand:XF 0 "fr_register_operand" "=f")
(float:XF (match_operand:DI 1 "fr_reg_or_fp01_operand" "fG")))]
@@ -1261,12 +1269,11 @@
"fcvt.fx.trunc %0 = %F1"
[(set_attr "itanium_class" "fcvtfx")])
-(define_insn "fix_truncxfdi2_alts"
+(define_insn "fix_truncrfdi2"
[(set (match_operand:DI 0 "fr_register_operand" "=f")
- (fix:DI (match_operand:XF 1 "fr_reg_or_fp01_operand" "fG")))
- (use (match_operand:SI 2 "const_int_operand" ""))]
+ (fix:DI (match_operand:RF 1 "fr_reg_or_fp01_operand" "fG")))]
""
- "fcvt.fx.trunc.s%2 %0 = %F1"
+ "fcvt.fx.trunc %0 = %F1"
[(set_attr "itanium_class" "fcvtfx")])
;; Convert between unsigned integer types and floating point.
@@ -1292,6 +1299,13 @@
"fcvt.xuf %0 = %F1"
[(set_attr "itanium_class" "fcvtfx")])
+(define_insn "floatunsdirf2"
+ [(set (match_operand:RF 0 "fr_register_operand" "=f")
+ (unsigned_float:RF (match_operand:DI 1 "fr_reg_or_fp01_operand" "fG")))]
+ ""
+ "fcvt.xuf %0 = %F1"
+ [(set_attr "itanium_class" "fcvtfx")])
+
(define_insn "fixuns_truncsfdi2"
[(set (match_operand:DI 0 "fr_register_operand" "=f")
(unsigned_fix:DI (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")))]
@@ -1313,12 +1327,11 @@
"fcvt.fxu.trunc %0 = %F1"
[(set_attr "itanium_class" "fcvtfx")])
-(define_insn "fixuns_truncxfdi2_alts"
+(define_insn "fixuns_truncrfdi2"
[(set (match_operand:DI 0 "fr_register_operand" "=f")
- (unsigned_fix:DI (match_operand:XF 1 "fr_reg_or_fp01_operand" "fG")))
- (use (match_operand:SI 2 "const_int_operand" ""))]
+ (unsigned_fix:DI (match_operand:RF 1 "fr_reg_or_fp01_operand" "fG")))]
""
- "fcvt.fxu.trunc.s%2 %0 = %F1"
+ "fcvt.fxu.trunc %0 = %F1"
[(set_attr "itanium_class" "fcvtfx")])
;; ::::::::::::::::::::
@@ -2175,169 +2188,6 @@
(match_dup 1) (match_dup 2)))]
""
{ operands[3] = gen_reg_rtx (BImode); })
-
-(define_expand "divsi3"
- [(set (match_operand:SI 0 "register_operand" "")
- (div:SI (match_operand:SI 1 "general_operand" "")
- (match_operand:SI 2 "general_operand" "")))]
- "TARGET_INLINE_INT_DIV"
-{
- rtx op1_xf, op2_xf, op0_xf, op0_di, twon34, twon34_exp;
-
- op0_xf = gen_reg_rtx (XFmode);
- op0_di = gen_reg_rtx (DImode);
-
- if (CONSTANT_P (operands[1]))
- operands[1] = force_reg (SImode, operands[1]);
- op1_xf = gen_reg_rtx (XFmode);
- expand_float (op1_xf, operands[1], 0);
-
- if (CONSTANT_P (operands[2]))
- operands[2] = force_reg (SImode, operands[2]);
- op2_xf = gen_reg_rtx (XFmode);
- expand_float (op2_xf, operands[2], 0);
-
- /* 2^-34 */
- twon34_exp = gen_reg_rtx (DImode);
- emit_move_insn (twon34_exp, GEN_INT (65501));
- twon34 = gen_reg_rtx (XFmode);
- emit_insn (gen_setf_exp_xf (twon34, twon34_exp));
-
- emit_insn (gen_cond_trap (EQ, operands[2], CONST0_RTX (SImode),
- CONST1_RTX (SImode)));
-
- emit_insn (gen_divsi3_internal (op0_xf, op1_xf, op2_xf, twon34));
-
- emit_insn (gen_fix_truncxfdi2_alts (op0_di, op0_xf, const1_rtx));
- emit_move_insn (operands[0], gen_lowpart (SImode, op0_di));
- DONE;
-})
-
-(define_expand "modsi3"
- [(set (match_operand:SI 0 "register_operand" "")
- (mod:SI (match_operand:SI 1 "general_operand" "")
- (match_operand:SI 2 "general_operand" "")))]
- "TARGET_INLINE_INT_DIV"
-{
- rtx op2_neg, op1_di, div;
-
- div = gen_reg_rtx (SImode);
- emit_insn (gen_divsi3 (div, operands[1], operands[2]));
-
- op2_neg = expand_unop (SImode, neg_optab, operands[2], NULL_RTX, 0);
-
- /* This is a trick to get us to reuse the value that we're sure to
- have already copied to the FP regs. */
- op1_di = gen_reg_rtx (DImode);
- convert_move (op1_di, operands[1], 0);
-
- emit_insn (gen_maddsi4 (operands[0], div, op2_neg,
- gen_lowpart (SImode, op1_di)));
- DONE;
-})
-
-(define_expand "udivsi3"
- [(set (match_operand:SI 0 "register_operand" "")
- (udiv:SI (match_operand:SI 1 "general_operand" "")
- (match_operand:SI 2 "general_operand" "")))]
- "TARGET_INLINE_INT_DIV"
-{
- rtx op1_xf, op2_xf, op0_xf, op0_di, twon34, twon34_exp;
-
- op0_xf = gen_reg_rtx (XFmode);
- op0_di = gen_reg_rtx (DImode);
-
- if (CONSTANT_P (operands[1]))
- operands[1] = force_reg (SImode, operands[1]);
- op1_xf = gen_reg_rtx (XFmode);
- expand_float (op1_xf, operands[1], 1);
-
- if (CONSTANT_P (operands[2]))
- operands[2] = force_reg (SImode, operands[2]);
- op2_xf = gen_reg_rtx (XFmode);
- expand_float (op2_xf, operands[2], 1);
-
- /* 2^-34 */
- twon34_exp = gen_reg_rtx (DImode);
- emit_move_insn (twon34_exp, GEN_INT (65501));
- twon34 = gen_reg_rtx (XFmode);
- emit_insn (gen_setf_exp_xf (twon34, twon34_exp));
-
- emit_insn (gen_cond_trap (EQ, operands[2], CONST0_RTX (SImode),
- CONST1_RTX (SImode)));
-
- emit_insn (gen_divsi3_internal (op0_xf, op1_xf, op2_xf, twon34));
-
- emit_insn (gen_fixuns_truncxfdi2_alts (op0_di, op0_xf, const1_rtx));
- emit_move_insn (operands[0], gen_lowpart (SImode, op0_di));
- DONE;
-})
-
-(define_expand "umodsi3"
- [(set (match_operand:SI 0 "register_operand" "")
- (umod:SI (match_operand:SI 1 "general_operand" "")
- (match_operand:SI 2 "general_operand" "")))]
- "TARGET_INLINE_INT_DIV"
-{
- rtx op2_neg, op1_di, div;
-
- div = gen_reg_rtx (SImode);
- emit_insn (gen_udivsi3 (div, operands[1], operands[2]));
-
- op2_neg = expand_unop (SImode, neg_optab, operands[2], NULL_RTX, 0);
-
- /* This is a trick to get us to reuse the value that we're sure to
- have already copied to the FP regs. */
- op1_di = gen_reg_rtx (DImode);
- convert_move (op1_di, operands[1], 1);
-
- emit_insn (gen_maddsi4 (operands[0], div, op2_neg,
- gen_lowpart (SImode, op1_di)));
- DONE;
-})
-
-(define_insn_and_split "divsi3_internal"
- [(set (match_operand:XF 0 "fr_register_operand" "=&f")
- (float:XF (div:SI (match_operand:XF 1 "fr_reg_or_fp01_operand" "fG")
- (match_operand:XF 2 "fr_reg_or_fp01_operand" "fG"))))
- (clobber (match_scratch:XF 4 "=&f"))
- (clobber (match_scratch:XF 5 "=&f"))
- (clobber (match_scratch:BI 6 "=c"))
- (use (match_operand:XF 3 "fr_register_operand" "f"))]
- "TARGET_INLINE_INT_DIV"
- "#"
- "&& reload_completed"
- [(parallel [(set (match_dup 0) (unspec:XF [(const_int 1) (match_dup 2)]
- UNSPEC_FR_RECIP_APPROX_RES))
- (set (match_dup 6) (unspec:BI [(match_dup 1) (match_dup 2)]
- UNSPEC_FR_RECIP_APPROX))
- (use (const_int 1))])
- (cond_exec (ne (match_dup 6) (const_int 0))
- (parallel [(set (match_dup 4) (mult:XF (match_dup 1) (match_dup 0)))
- (use (const_int 1))]))
- (cond_exec (ne (match_dup 6) (const_int 0))
- (parallel [(set (match_dup 5)
- (minus:XF (match_dup 7)
- (mult:XF (match_dup 2) (match_dup 0))))
- (use (const_int 1))]))
- (cond_exec (ne (match_dup 6) (const_int 0))
- (parallel [(set (match_dup 4)
- (plus:XF (mult:XF (match_dup 5) (match_dup 4))
- (match_dup 4)))
- (use (const_int 1))]))
- (cond_exec (ne (match_dup 6) (const_int 0))
- (parallel [(set (match_dup 5)
- (plus:XF (mult:XF (match_dup 5) (match_dup 5))
- (match_dup 3)))
- (use (const_int 1))]))
- (cond_exec (ne (match_dup 6) (const_int 0))
- (parallel [(set (match_dup 0)
- (plus:XF (mult:XF (match_dup 5) (match_dup 4))
- (match_dup 4)))
- (use (const_int 1))]))
- ]
- "operands[7] = CONST1_RTX (XFmode);"
- [(set_attr "predicable" "no")])
;; ::::::::::::::::::::
;; ::
@@ -2611,215 +2461,6 @@
""
"getf.exp %0 = %F1"
[(set_attr "itanium_class" "frfr")])
-
-(define_expand "divdi3"
- [(set (match_operand:DI 0 "register_operand" "")
- (div:DI (match_operand:DI 1 "general_operand" "")
- (match_operand:DI 2 "general_operand" "")))]
- "TARGET_INLINE_INT_DIV"
-{
- rtx op1_xf, op2_xf, op0_xf;
-
- op0_xf = gen_reg_rtx (XFmode);
-
- if (CONSTANT_P (operands[1]))
- operands[1] = force_reg (DImode, operands[1]);
- op1_xf = gen_reg_rtx (XFmode);
- expand_float (op1_xf, operands[1], 0);
-
- if (CONSTANT_P (operands[2]))
- operands[2] = force_reg (DImode, operands[2]);
- op2_xf = gen_reg_rtx (XFmode);
- expand_float (op2_xf, operands[2], 0);
-
- emit_insn (gen_cond_trap (EQ, operands[2], CONST0_RTX (DImode),
- CONST1_RTX (DImode)));
-
- if (TARGET_INLINE_INT_DIV == INL_MIN_LAT)
- emit_insn (gen_divdi3_internal_lat (op0_xf, op1_xf, op2_xf));
- else
- emit_insn (gen_divdi3_internal_thr (op0_xf, op1_xf, op2_xf));
-
- emit_insn (gen_fix_truncxfdi2_alts (operands[0], op0_xf, const1_rtx));
- DONE;
-})
-
-(define_expand "moddi3"
- [(set (match_operand:DI 0 "register_operand" "")
- (mod:SI (match_operand:DI 1 "general_operand" "")
- (match_operand:DI 2 "general_operand" "")))]
- "TARGET_INLINE_INT_DIV"
-{
- rtx op2_neg, div;
-
- div = gen_reg_rtx (DImode);
- emit_insn (gen_divdi3 (div, operands[1], operands[2]));
-
- op2_neg = expand_unop (DImode, neg_optab, operands[2], NULL_RTX, 0);
-
- emit_insn (gen_madddi4 (operands[0], div, op2_neg, operands[1]));
- DONE;
-})
-
-(define_expand "udivdi3"
- [(set (match_operand:DI 0 "register_operand" "")
- (udiv:DI (match_operand:DI 1 "general_operand" "")
- (match_operand:DI 2 "general_operand" "")))]
- "TARGET_INLINE_INT_DIV"
-{
- rtx op1_xf, op2_xf, op0_xf;
-
- op0_xf = gen_reg_rtx (XFmode);
-
- if (CONSTANT_P (operands[1]))
- operands[1] = force_reg (DImode, operands[1]);
- op1_xf = gen_reg_rtx (XFmode);
- expand_float (op1_xf, operands[1], 1);
-
- if (CONSTANT_P (operands[2]))
- operands[2] = force_reg (DImode, operands[2]);
- op2_xf = gen_reg_rtx (XFmode);
- expand_float (op2_xf, operands[2], 1);
-
- emit_insn (gen_cond_trap (EQ, operands[2], CONST0_RTX (DImode),
- CONST1_RTX (DImode)));
-
- if (TARGET_INLINE_INT_DIV == INL_MIN_LAT)
- emit_insn (gen_divdi3_internal_lat (op0_xf, op1_xf, op2_xf));
- else
- emit_insn (gen_divdi3_internal_thr (op0_xf, op1_xf, op2_xf));
-
- emit_insn (gen_fixuns_truncxfdi2_alts (operands[0], op0_xf, const1_rtx));
- DONE;
-})
-
-(define_expand "umoddi3"
- [(set (match_operand:DI 0 "register_operand" "")
- (umod:DI (match_operand:DI 1 "general_operand" "")
- (match_operand:DI 2 "general_operand" "")))]
- "TARGET_INLINE_INT_DIV"
-{
- rtx op2_neg, div;
-
- div = gen_reg_rtx (DImode);
- emit_insn (gen_udivdi3 (div, operands[1], operands[2]));
-
- op2_neg = expand_unop (DImode, neg_optab, operands[2], NULL_RTX, 0);
-
- emit_insn (gen_madddi4 (operands[0], div, op2_neg, operands[1]));
- DONE;
-})
-
-(define_insn_and_split "divdi3_internal_lat"
- [(set (match_operand:XF 0 "fr_register_operand" "=&f")
- (float:XF (div:SI (match_operand:XF 1 "fr_reg_or_fp01_operand" "fG")
- (match_operand:XF 2 "fr_reg_or_fp01_operand" "fG"))))
- (clobber (match_scratch:XF 3 "=&f"))
- (clobber (match_scratch:XF 4 "=&f"))
- (clobber (match_scratch:XF 5 "=&f"))
- (clobber (match_scratch:BI 6 "=c"))]
- "TARGET_INLINE_INT_DIV == INL_MIN_LAT"
- "#"
- "&& reload_completed"
- [(parallel [(set (match_dup 0) (unspec:XF [(const_int 1) (match_dup 2)]
- UNSPEC_FR_RECIP_APPROX_RES))
- (set (match_dup 6) (unspec:BI [(match_dup 1) (match_dup 2)]
- UNSPEC_FR_RECIP_APPROX))
- (use (const_int 1))])
- (cond_exec (ne (match_dup 6) (const_int 0))
- (parallel [(set (match_dup 3)
- (minus:XF (match_dup 7)
- (mult:XF (match_dup 2) (match_dup 0))))
- (use (const_int 1))]))
- (cond_exec (ne (match_dup 6) (const_int 0))
- (parallel [(set (match_dup 4) (mult:XF (match_dup 1) (match_dup 0)))
- (use (const_int 1))]))
- (cond_exec (ne (match_dup 6) (const_int 0))
- (parallel [(set (match_dup 5) (mult:XF (match_dup 3) (match_dup 3)))
- (use (const_int 1))]))
- (cond_exec (ne (match_dup 6) (const_int 0))
- (parallel [(set (match_dup 4)
- (plus:XF (mult:XF (match_dup 3) (match_dup 4))
- (match_dup 4)))
- (use (const_int 1))]))
- (cond_exec (ne (match_dup 6) (const_int 0))
- (parallel [(set (match_dup 0)
- (plus:XF (mult:XF (match_dup 3) (match_dup 0))
- (match_dup 0)))
- (use (const_int 1))]))
- (cond_exec (ne (match_dup 6) (const_int 0))
- (parallel [(set (match_dup 3)
- (plus:XF (mult:XF (match_dup 5) (match_dup 4))
- (match_dup 4)))
- (use (const_int 1))]))
- (cond_exec (ne (match_dup 6) (const_int 0))
- (parallel [(set (match_dup 0)
- (plus:XF (mult:XF (match_dup 5) (match_dup 0))
- (match_dup 0)))
- (use (const_int 1))]))
- (cond_exec (ne (match_dup 6) (const_int 0))
- (parallel [(set (match_dup 4)
- (minus:XF (match_dup 1)
- (mult:XF (match_dup 2) (match_dup 3))))
- (use (const_int 1))]))
- (cond_exec (ne (match_dup 6) (const_int 0))
- (parallel [(set (match_dup 0)
- (plus:XF (mult:XF (match_dup 4) (match_dup 0))
- (match_dup 3)))
- (use (const_int 1))]))
- ]
- "operands[7] = CONST1_RTX (XFmode);"
- [(set_attr "predicable" "no")])
-
-(define_insn_and_split "divdi3_internal_thr"
- [(set (match_operand:XF 0 "fr_register_operand" "=&f")
- (float:XF (div:SI (match_operand:XF 1 "fr_reg_or_fp01_operand" "fG")
- (match_operand:XF 2 "fr_reg_or_fp01_operand" "fG"))))
- (clobber (match_scratch:XF 3 "=&f"))
- (clobber (match_scratch:XF 4 "=f"))
- (clobber (match_scratch:BI 5 "=c"))]
- "TARGET_INLINE_INT_DIV == INL_MAX_THR"
- "#"
- "&& reload_completed"
- [(parallel [(set (match_dup 0) (unspec:XF [(const_int 1) (match_dup 2)]
- UNSPEC_FR_RECIP_APPROX_RES))
- (set (match_dup 5) (unspec:BI [(match_dup 1) (match_dup 2)]
- UNSPEC_FR_RECIP_APPROX))
- (use (const_int 1))])
- (cond_exec (ne (match_dup 5) (const_int 0))
- (parallel [(set (match_dup 3)
- (minus:XF (match_dup 6)
- (mult:XF (match_dup 2) (match_dup 0))))
- (use (const_int 1))]))
- (cond_exec (ne (match_dup 5) (const_int 0))
- (parallel [(set (match_dup 0)
- (plus:XF (mult:XF (match_dup 3) (match_dup 0))
- (match_dup 0)))
- (use (const_int 1))]))
- (cond_exec (ne (match_dup 5) (const_int 0))
- (parallel [(set (match_dup 3) (mult:XF (match_dup 3) (match_dup 3)))
- (use (const_int 1))]))
- (cond_exec (ne (match_dup 5) (const_int 0))
- (parallel [(set (match_dup 0)
- (plus:XF (mult:XF (match_dup 3) (match_dup 0))
- (match_dup 0)))
- (use (const_int 1))]))
- (cond_exec (ne (match_dup 5) (const_int 0))
- (parallel [(set (match_dup 3) (mult:XF (match_dup 0) (match_dup 1)))
- (use (const_int 1))]))
- (cond_exec (ne (match_dup 5) (const_int 0))
- (parallel [(set (match_dup 4)
- (minus:XF (match_dup 1)
- (mult:XF (match_dup 2) (match_dup 3))))
- (use (const_int 1))]))
- (cond_exec (ne (match_dup 5) (const_int 0))
- (parallel [(set (match_dup 0)
- (plus:XF (mult:XF (match_dup 4) (match_dup 0))
- (match_dup 3)))
- (use (const_int 1))]))
- ]
- "operands[6] = CONST1_RTX (XFmode);"
- [(set_attr "predicable" "no")])
;; ::::::::::::::::::::
;; ::
@@ -3105,7 +2746,7 @@
(plus:SF (mult:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")
(match_operand:SF 2 "fr_reg_or_fp01_operand" "fG"))
(match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")))]
- ""
+ "TARGET_FUSED_MADD"
"fma.s %0 = %F1, %F2, %F3"
[(set_attr "itanium_class" "fmac")])
@@ -3114,7 +2755,7 @@
(minus:SF (mult:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")
(match_operand:SF 2 "fr_reg_or_fp01_operand" "fG"))
(match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")))]
- ""
+ "TARGET_FUSED_MADD"
"fms.s %0 = %F1, %F2, %F3"
[(set_attr "itanium_class" "fmac")])
@@ -3131,185 +2772,9 @@
(minus:SF (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")
(mult:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")
(match_operand:SF 2 "fr_reg_or_fp01_operand" "fG"))))]
- ""
+ "TARGET_FUSED_MADD"
"fnma.s %0 = %F1, %F2, %F3"
[(set_attr "itanium_class" "fmac")])
-
-(define_insn "*nmaddsf4_alts"
- [(set (match_operand:SF 0 "fr_register_operand" "=f")
- (minus:SF (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")
- (mult:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")
- (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG"))))
- (use (match_operand:SI 4 "const_int_operand" ""))]
- ""
- "fnma.s.s%4 %0 = %F1, %F2, %F3"
- [(set_attr "itanium_class" "fmac")])
-
-(define_expand "divsf3"
- [(set (match_operand:SF 0 "fr_register_operand" "")
- (div:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "")
- (match_operand:SF 2 "fr_reg_or_fp01_operand" "")))]
- "TARGET_INLINE_FLOAT_DIV"
-{
- rtx insn;
- if (TARGET_INLINE_FLOAT_DIV == INL_MIN_LAT)
- insn = gen_divsf3_internal_lat (operands[0], operands[1], operands[2]);
- else
- insn = gen_divsf3_internal_thr (operands[0], operands[1], operands[2]);
- emit_insn (insn);
- DONE;
-})
-
-;; Inline square root.
-
-(define_insn "*sqrt_approx"
- [(set (match_operand:XF 0 "fr_register_operand" "=f")
- (div:XF (const_int 1)
- (unspec:XF [(match_operand:XF 2 "fr_reg_or_fp01_operand" "fG")]
- UNSPEC_FR_SQRT_RECIP_APPROX_RES)))
- (set (match_operand:BI 1 "register_operand" "=c")
- (unspec:BI [(match_dup 2)] UNSPEC_FR_SQRT_RECIP_APPROX))
- (use (match_operand:SI 3 "const_int_operand" "")) ]
- ""
- "frsqrta.s%3 %0, %1 = %2"
- [(set_attr "itanium_class" "fmisc")
- (set_attr "predicable" "no")])
-
-(define_insn "setf_exp_xf"
- [(set (match_operand:XF 0 "fr_register_operand" "=f")
- (unspec:XF [(match_operand:DI 1 "register_operand" "r")]
- UNSPEC_SETF_EXP))]
- ""
- "setf.exp %0 = %1"
- [(set_attr "itanium_class" "frfr")])
-
-(define_expand "sqrtsf2"
- [(set (match_operand:SF 0 "fr_register_operand" "=&f")
- (sqrt:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")))]
- "TARGET_INLINE_SQRT"
-{
- rtx insn;
-#if 0
- if (TARGET_INLINE_SQRT == INL_MIN_LAT)
- insn = gen_sqrtsf2_internal_lat (operands[0], operands[1]);
- else
-#else
- gcc_assert (TARGET_INLINE_SQRT != INL_MIN_LAT);
-#endif
- insn = gen_sqrtsf2_internal_thr (operands[0], operands[1]);
- emit_insn (insn);
- DONE;
-})
-
-;; Latency-optimized square root.
-;; FIXME: Implement.
-
-;; Throughput-optimized square root.
-
-(define_insn_and_split "sqrtsf2_internal_thr"
- [(set (match_operand:SF 0 "fr_register_operand" "=&f")
- (sqrt:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")))
- ;; Register r2 in optimization guide.
- (clobber (match_scratch:DI 2 "=r"))
- ;; Register f8 in optimization guide
- (clobber (match_scratch:XF 3 "=&f"))
- ;; Register f9 in optimization guide
- (clobber (match_scratch:XF 4 "=&f"))
- ;; Register f10 in optimization guide
- (clobber (match_scratch:XF 5 "=&f"))
- ;; Register p6 in optimization guide.
- (clobber (match_scratch:BI 6 "=c"))]
- "TARGET_INLINE_SQRT == INL_MAX_THR"
- "#"
- "&& reload_completed"
- [ ;; exponent of +1/2 in r2
- (set (match_dup 2) (const_int 65534))
- ;; +1/2 in f8
- (set (match_dup 3)
- (unspec:XF [(match_dup 2)] UNSPEC_SETF_EXP))
- ;; Step 1
- ;; y0 = 1/sqrt(a) in f7
- (parallel [(set (match_dup 7)
- (div:XF (const_int 1)
- (unspec:XF [(match_dup 8)]
- UNSPEC_FR_SQRT_RECIP_APPROX_RES)))
- (set (match_dup 6)
- (unspec:BI [(match_dup 8)]
- UNSPEC_FR_SQRT_RECIP_APPROX))
- (use (const_int 0))])
- ;; Step 2
- ;; H0 = 1/2 * y0 in f9
- (cond_exec (ne (match_dup 6) (const_int 0))
- (parallel [(set (match_dup 4)
- (plus:XF (mult:XF (match_dup 3) (match_dup 7))
- (match_dup 9)))
- (use (const_int 1))]))
- ;; Step 3
- ;; S0 = a * y0 in f7
- (cond_exec (ne (match_dup 6) (const_int 0))
- (parallel [(set (match_dup 7)
- (plus:XF (mult:XF (match_dup 8) (match_dup 7))
- (match_dup 9)))
- (use (const_int 1))]))
- ;; Step 4
- ;; d = 1/2 - S0 * H0 in f10
- (cond_exec (ne (match_dup 6) (const_int 0))
- (parallel [(set (match_dup 5)
- (minus:XF (match_dup 3)
- (mult:XF (match_dup 7) (match_dup 4))))
- (use (const_int 1))]))
- ;; Step 5
- ;; d' = d + 1/2 * d in f8
- (cond_exec (ne (match_dup 6) (const_int 0))
- (parallel [(set (match_dup 3)
- (plus:XF (mult:XF (match_dup 3) (match_dup 5))
- (match_dup 5)))
- (use (const_int 1))]))
- ;; Step 6
- ;; e = d + d * d' in f8
- (cond_exec (ne (match_dup 6) (const_int 0))
- (parallel [(set (match_dup 3)
- (plus:XF (mult:XF (match_dup 5) (match_dup 3))
- (match_dup 5)))
- (use (const_int 1))]))
- ;; Step 7
- ;; S1 = S0 + e * S0 in f7
- (cond_exec (ne (match_dup 6) (const_int 0))
- (parallel [(set (match_dup 0)
- (float_truncate:SF
- (plus:XF (mult:XF (match_dup 3) (match_dup 7))
- (match_dup 7))))
- (use (const_int 1))]))
- ;; Step 8
- ;; H1 = H0 + e * H0 in f8
- (cond_exec (ne (match_dup 6) (const_int 0))
- (parallel [(set (match_dup 3)
- (plus:XF (mult:XF (match_dup 3) (match_dup 4))
- (match_dup 4)))
- (use (const_int 1))]))
- ;; Step 9
- ;; d1 = a - S1 * S1 in f9
- (cond_exec (ne (match_dup 6) (const_int 0))
- (parallel [(set (match_dup 4)
- (minus:XF (match_dup 8)
- (mult:XF (match_dup 7) (match_dup 7))))
- (use (const_int 1))]))
- ;; Step 10
- ;; S = S1 + d1 * H1 in f7
- (cond_exec (ne (match_dup 6) (const_int 0))
- (parallel [(set (match_dup 0)
- (float_truncate:SF
- (plus:XF (mult:XF (match_dup 4) (match_dup 3))
- (match_dup 7))))
- (use (const_int 0))]))]
-{
- /* Generate 82-bit versions of the input and output operands. */
- operands[7] = gen_rtx_REG (XFmode, REGNO (operands[0]));
- operands[8] = gen_rtx_REG (XFmode, REGNO (operands[1]));
- /* Generate required floating-point constants. */
- operands[9] = CONST0_RTX (XFmode);
-}
- [(set_attr "predicable" "no")])
;; ::::::::::::::::::::
;; ::
@@ -3428,7 +2893,7 @@
(plus:DF (mult:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
(match_operand:DF 2 "fr_reg_or_fp01_operand" "fG"))
(match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))]
- ""
+ "TARGET_FUSED_MADD"
"fma.d %0 = %F1, %F2, %F3"
[(set_attr "itanium_class" "fmac")])
@@ -3438,7 +2903,7 @@
(plus:DF (mult:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
(match_operand:DF 2 "fr_reg_or_fp01_operand" "fG"))
(match_operand:DF 3 "fr_reg_or_fp01_operand" "fG"))))]
- ""
+ "TARGET_FUSED_MADD"
"fma.s %0 = %F1, %F2, %F3"
[(set_attr "itanium_class" "fmac")])
@@ -3447,7 +2912,7 @@
(minus:DF (mult:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
(match_operand:DF 2 "fr_reg_or_fp01_operand" "fG"))
(match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))]
- ""
+ "TARGET_FUSED_MADD"
"fms.d %0 = %F1, %F2, %F3"
[(set_attr "itanium_class" "fmac")])
@@ -3457,7 +2922,7 @@
(minus:DF (mult:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
(match_operand:DF 2 "fr_reg_or_fp01_operand" "fG"))
(match_operand:DF 3 "fr_reg_or_fp01_operand" "fG"))))]
- ""
+ "TARGET_FUSED_MADD"
"fms.s %0 = %F1, %F2, %F3"
[(set_attr "itanium_class" "fmac")])
@@ -3483,205 +2948,19 @@
(minus:DF (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")
(mult:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
(match_operand:DF 2 "fr_reg_or_fp01_operand" "fG"))))]
- ""
+ "TARGET_FUSED_MADD"
"fnma.d %0 = %F1, %F2, %F3"
[(set_attr "itanium_class" "fmac")])
-(define_insn "*nmadddf4_alts"
- [(set (match_operand:DF 0 "fr_register_operand" "=f")
- (minus:DF (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")
- (mult:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
- (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG"))))
- (use (match_operand:SI 4 "const_int_operand" ""))]
- ""
- "fnma.d.s%4 %0 = %F1, %F2, %F3"
- [(set_attr "itanium_class" "fmac")])
-
(define_insn "*nmadddf4_truncsf"
[(set (match_operand:SF 0 "fr_register_operand" "=f")
(float_truncate:SF
(minus:DF (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")
(mult:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
(match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))))]
- ""
+ "TARGET_FUSED_MADD"
"fnma.s %0 = %F1, %F2, %F3"
[(set_attr "itanium_class" "fmac")])
-
-(define_insn "*nmadddf4_truncsf_alts"
- [(set (match_operand:SF 0 "fr_register_operand" "=f")
- (float_truncate:SF
- (minus:DF (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")
- (mult:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
- (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))))
- (use (match_operand:SI 4 "const_int_operand" ""))]
- ""
- "fnma.s.s%4 %0 = %F1, %F2, %F3"
- [(set_attr "itanium_class" "fmac")])
-
-(define_expand "divdf3"
- [(set (match_operand:DF 0 "fr_register_operand" "")
- (div:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "")
- (match_operand:DF 2 "fr_reg_or_fp01_operand" "")))]
- "TARGET_INLINE_FLOAT_DIV"
-{
- rtx insn;
- if (TARGET_INLINE_FLOAT_DIV == INL_MIN_LAT)
- insn = gen_divdf3_internal_lat (operands[0], operands[1], operands[2]);
- else
- insn = gen_divdf3_internal_thr (operands[0], operands[1], operands[2]);
- emit_insn (insn);
- DONE;
-})
-
-;; Inline square root.
-
-(define_expand "sqrtdf2"
- [(set (match_operand:DF 0 "fr_register_operand" "=&f")
- (sqrt:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")))]
- "TARGET_INLINE_SQRT"
-{
- rtx insn;
-#if 0
- if (TARGET_INLINE_SQRT == INL_MIN_LAT)
- insn = gen_sqrtdf2_internal_lat (operands[0], operands[1]);
- else
-#else
- gcc_assert (TARGET_INLINE_SQRT != INL_MIN_LAT);
-#endif
- insn = gen_sqrtdf2_internal_thr (operands[0], operands[1]);
- emit_insn (insn);
- DONE;
-})
-
-;; Latency-optimized square root.
-;; FIXME: Implement.
-
-;; Throughput-optimized square root.
-
-(define_insn_and_split "sqrtdf2_internal_thr"
- [(set (match_operand:DF 0 "fr_register_operand" "=&f")
- (sqrt:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")))
- ;; Register r2 in optimization guide.
- (clobber (match_scratch:DI 2 "=r"))
- ;; Register f8 in optimization guide
- (clobber (match_scratch:XF 3 "=&f"))
- ;; Register f9 in optimization guide
- (clobber (match_scratch:XF 4 "=&f"))
- ;; Register f10 in optimization guide
- (clobber (match_scratch:XF 5 "=&f"))
- ;; Register p6 in optimization guide.
- (clobber (match_scratch:BI 6 "=c"))]
- "TARGET_INLINE_SQRT == INL_MAX_THR"
- "#"
- "&& reload_completed"
- [ ;; exponent of +1/2 in r2
- (set (match_dup 2) (const_int 65534))
- ;; +1/2 in f10
- (set (match_dup 5)
- (unspec:XF [(match_dup 2)] UNSPEC_SETF_EXP))
- ;; Step 1
- ;; y0 = 1/sqrt(a) in f7
- (parallel [(set (match_dup 7)
- (div:XF (const_int 1)
- (unspec:XF [(match_dup 8)]
- UNSPEC_FR_SQRT_RECIP_APPROX_RES)))
- (set (match_dup 6)
- (unspec:BI [(match_dup 8)]
- UNSPEC_FR_SQRT_RECIP_APPROX))
- (use (const_int 0))])
- ;; Step 2
- ;; H0 = 1/2 * y0 in f8
- (cond_exec (ne (match_dup 6) (const_int 0))
- (parallel [(set (match_dup 3)
- (plus:XF (mult:XF (match_dup 5) (match_dup 7))
- (match_dup 9)))
- (use (const_int 1))]))
- ;; Step 3
- ;; G0 = a * y0 in f7
- (cond_exec (ne (match_dup 6) (const_int 0))
- (parallel [(set (match_dup 7)
- (plus:XF (mult:XF (match_dup 8) (match_dup 7))
- (match_dup 9)))
- (use (const_int 1))]))
- ;; Step 4
- ;; r0 = 1/2 - G0 * H0 in f9
- (cond_exec (ne (match_dup 6) (const_int 0))
- (parallel [(set (match_dup 4)
- (minus:XF (match_dup 5)
- (mult:XF (match_dup 7) (match_dup 3))))
- (use (const_int 1))]))
- ;; Step 5
- ;; H1 = H0 + r0 * H0 in f8
- (cond_exec (ne (match_dup 6) (const_int 0))
- (parallel [(set (match_dup 3)
- (plus:XF (mult:XF (match_dup 4) (match_dup 3))
- (match_dup 3)))
- (use (const_int 1))]))
- ;; Step 6
- ;; G1 = G0 + r0 * G0 in f7
- (cond_exec (ne (match_dup 6) (const_int 0))
- (parallel [(set (match_dup 7)
- (plus:XF (mult:XF (match_dup 4) (match_dup 7))
- (match_dup 7)))
- (use (const_int 1))]))
- ;; Step 7
- ;; r1 = 1/2 - G1 * H1 in f9
- (cond_exec (ne (match_dup 6) (const_int 0))
- (parallel [(set (match_dup 4)
- (minus:XF (match_dup 5)
- (mult:XF (match_dup 7) (match_dup 3))))
- (use (const_int 1))]))
- ;; Step 8
- ;; H2 = H1 + r1 * H1 in f8
- (cond_exec (ne (match_dup 6) (const_int 0))
- (parallel [(set (match_dup 3)
- (plus:XF (mult:XF (match_dup 4) (match_dup 3))
- (match_dup 3)))
- (use (const_int 1))]))
- ;; Step 9
- ;; G2 = G1 + r1 * G1 in f7
- (cond_exec (ne (match_dup 6) (const_int 0))
- (parallel [(set (match_dup 7)
- (plus:XF (mult:XF (match_dup 4) (match_dup 7))
- (match_dup 7)))
- (use (const_int 1))]))
- ;; Step 10
- ;; d2 = a - G2 * G2 in f9
- (cond_exec (ne (match_dup 6) (const_int 0))
- (parallel [(set (match_dup 4)
- (minus:XF (match_dup 8)
- (mult:XF (match_dup 7) (match_dup 7))))
- (use (const_int 1))]))
- ;; Step 11
- ;; G3 = G2 + d2 * H2 in f7
- (cond_exec (ne (match_dup 6) (const_int 0))
- (parallel [(set (match_dup 7)
- (plus:XF (mult:XF (match_dup 4) (match_dup 3))
- (match_dup 7)))
- (use (const_int 1))]))
- ;; Step 12
- ;; d3 = a - G3 * G3 in f9
- (cond_exec (ne (match_dup 6) (const_int 0))
- (parallel [(set (match_dup 4)
- (minus:XF (match_dup 8)
- (mult:XF (match_dup 7) (match_dup 7))))
- (use (const_int 1))]))
- ;; Step 13
- ;; S = G3 + d3 * H2 in f7
- (cond_exec (ne (match_dup 6) (const_int 0))
- (parallel [(set (match_dup 0)
- (float_truncate:DF
- (plus:XF (mult:XF (match_dup 4) (match_dup 3))
- (match_dup 7))))
- (use (const_int 0))]))]
-{
- /* Generate 82-bit versions of the input and output operands. */
- operands[7] = gen_rtx_REG (XFmode, REGNO (operands[0]));
- operands[8] = gen_rtx_REG (XFmode, REGNO (operands[1]));
- /* Generate required floating-point constants. */
- operands[9] = CONST0_RTX (XFmode);
-}
- [(set_attr "predicable" "no")])
;; ::::::::::::::::::::
;; ::
@@ -3767,35 +3046,6 @@
"fmpy.d %0 = %F1, %F2"
[(set_attr "itanium_class" "fmac")])
-(define_insn "*mulxf3_alts"
- [(set (match_operand:XF 0 "fr_register_operand" "=f")
- (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
- (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))
- (use (match_operand:SI 3 "const_int_operand" ""))]
- ""
- "fmpy.s%3 %0 = %F1, %F2"
- [(set_attr "itanium_class" "fmac")])
-
-(define_insn "*mulxf3_truncsf_alts"
- [(set (match_operand:SF 0 "fr_register_operand" "=f")
- (float_truncate:SF
- (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
- (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))
- (use (match_operand:SI 3 "const_int_operand" ""))]
- ""
- "fmpy.s.s%3 %0 = %F1, %F2"
- [(set_attr "itanium_class" "fmac")])
-
-(define_insn "*mulxf3_truncdf_alts"
- [(set (match_operand:DF 0 "fr_register_operand" "=f")
- (float_truncate:DF
- (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
- (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))
- (use (match_operand:SI 3 "const_int_operand" ""))]
- ""
- "fmpy.d.s%3 %0 = %F1, %F2"
- [(set_attr "itanium_class" "fmac")])
-
(define_insn "absxf2"
[(set (match_operand:XF 0 "fr_register_operand" "=f")
(abs:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")))]
@@ -3856,7 +3106,7 @@
(plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
(match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
(match_operand:XF 3 "xfreg_or_fp01_operand" "fG")))]
- ""
+ "TARGET_FUSED_MADD"
"fma %0 = %F1, %F2, %F3"
[(set_attr "itanium_class" "fmac")])
@@ -3866,7 +3116,7 @@
(plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
(match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
(match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))]
- ""
+ "TARGET_FUSED_MADD"
"fma.s %0 = %F1, %F2, %F3"
[(set_attr "itanium_class" "fmac")])
@@ -3876,48 +3126,16 @@
(plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
(match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
(match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))]
- ""
+ "TARGET_FUSED_MADD"
"fma.d %0 = %F1, %F2, %F3"
[(set_attr "itanium_class" "fmac")])
-(define_insn "*maddxf4_alts"
- [(set (match_operand:XF 0 "fr_register_operand" "=f")
- (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
- (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
- (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")))
- (use (match_operand:SI 4 "const_int_operand" ""))]
- ""
- "fma.s%4 %0 = %F1, %F2, %F3"
- [(set_attr "itanium_class" "fmac")])
-
-(define_insn "*maddxf4_alts_truncsf"
- [(set (match_operand:SF 0 "fr_register_operand" "=f")
- (float_truncate:SF
- (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
- (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
- (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))
- (use (match_operand:SI 4 "const_int_operand" ""))]
- ""
- "fma.s.s%4 %0 = %F1, %F2, %F3"
- [(set_attr "itanium_class" "fmac")])
-
-(define_insn "*maddxf4_alts_truncdf"
- [(set (match_operand:DF 0 "fr_register_operand" "=f")
- (float_truncate:DF
- (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
- (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
- (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))
- (use (match_operand:SI 4 "const_int_operand" ""))]
- ""
- "fma.d.s%4 %0 = %F1, %F2, %F3"
- [(set_attr "itanium_class" "fmac")])
-
(define_insn "*msubxf4"
[(set (match_operand:XF 0 "fr_register_operand" "=f")
(minus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
(match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
(match_operand:XF 3 "xfreg_or_fp01_operand" "fG")))]
- ""
+ "TARGET_FUSED_MADD"
"fms %0 = %F1, %F2, %F3"
[(set_attr "itanium_class" "fmac")])
@@ -3927,7 +3145,7 @@
(minus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
(match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
(match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))]
- ""
+ "TARGET_FUSED_MADD"
"fms.s %0 = %F1, %F2, %F3"
[(set_attr "itanium_class" "fmac")])
@@ -3937,7 +3155,7 @@
(minus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
(match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
(match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))]
- ""
+ "TARGET_FUSED_MADD"
"fms.d %0 = %F1, %F2, %F3"
[(set_attr "itanium_class" "fmac")])
@@ -3975,7 +3193,7 @@
(mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
(match_operand:XF 2 "xfreg_or_fp01_operand" "fG")
)))]
- ""
+ "TARGET_FUSED_MADD"
"fnma %0 = %F1, %F2, %F3"
[(set_attr "itanium_class" "fmac")])
@@ -3986,7 +3204,7 @@
(mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
(match_operand:XF 2 "xfreg_or_fp01_operand" "fG")
))))]
- ""
+ "TARGET_FUSED_MADD"
"fnma.s %0 = %F1, %F2, %F3"
[(set_attr "itanium_class" "fmac")])
@@ -3997,236 +3215,9 @@
(mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
(match_operand:XF 2 "xfreg_or_fp01_operand" "fG")
))))]
- ""
+ "TARGET_FUSED_MADD"
"fnma.d %0 = %F1, %F2, %F3"
[(set_attr "itanium_class" "fmac")])
-
-(define_insn "*nmaddxf4_alts"
- [(set (match_operand:XF 0 "fr_register_operand" "=f")
- (minus:XF (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")
- (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
- (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")
- )))
- (use (match_operand:SI 4 "const_int_operand" ""))]
- ""
- "fnma.s%4 %0 = %F1, %F2, %F3"
- [(set_attr "itanium_class" "fmac")])
-
-(define_insn "*nmaddxf4_truncsf_alts"
- [(set (match_operand:SF 0 "fr_register_operand" "=f")
- (float_truncate:SF
- (minus:XF (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")
- (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
- (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")
- ))))
- (use (match_operand:SI 4 "const_int_operand" ""))]
- ""
- "fnma.s.s%4 %0 = %F1, %F2, %F3"
- [(set_attr "itanium_class" "fmac")])
-
-(define_insn "*nmaddxf4_truncdf_alts"
- [(set (match_operand:DF 0 "fr_register_operand" "=f")
- (float_truncate:DF
- (minus:XF (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")
- (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
- (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")
- ))))
- (use (match_operand:SI 4 "const_int_operand" ""))]
- ""
- "fnma.d.s%4 %0 = %F1, %F2, %F3"
- [(set_attr "itanium_class" "fmac")])
-
-(define_expand "divxf3"
- [(set (match_operand:XF 0 "fr_register_operand" "")
- (div:XF (match_operand:XF 1 "fr_reg_or_fp01_operand" "")
- (match_operand:XF 2 "fr_reg_or_fp01_operand" "")))]
- "TARGET_INLINE_FLOAT_DIV"
-{
- /* There is only one divxf3 sequence, not two like for divsf and divdf. */
- emit_insn (gen_divxf3_internal (operands[0], operands[1], operands[2]));
- DONE;
-})
-
-;; Inline square root.
-
-(define_expand "sqrtxf2"
- [(set (match_operand:XF 0 "fr_register_operand" "=&f")
- (sqrt:XF (match_operand:XF 1 "fr_reg_or_fp01_operand" "fG")))]
- "TARGET_INLINE_SQRT"
-{
- rtx insn;
-#if 0
- if (TARGET_INLINE_SQRT == INL_MIN_LAT)
- insn = gen_sqrtxf2_internal_lat (operands[0], operands[1]);
- else
-#else
- gcc_assert (TARGET_INLINE_SQRT != INL_MIN_LAT);
-#endif
- insn = gen_sqrtxf2_internal_thr (operands[0], operands[1]);
- emit_insn (insn);
- DONE;
-})
-
-;; Latency-optimized square root.
-;; FIXME: Implement.
-
-;; Throughput-optimized square root.
-
-(define_insn_and_split "sqrtxf2_internal_thr"
- [(set (match_operand:XF 0 "fr_register_operand" "=&f")
- (sqrt:XF (match_operand:XF 1 "fr_reg_or_fp01_operand" "fG")))
- ;; Register r2 in optimization guide.
- (clobber (match_scratch:DI 2 "=r"))
- ;; Register f8 in optimization guide
- (clobber (match_scratch:XF 3 "=&f"))
- ;; Register f9 in optimization guide
- (clobber (match_scratch:XF 4 "=&f"))
- ;; Register f10 in optimization guide
- (clobber (match_scratch:XF 5 "=&f"))
- ;; Register f11 in optimization guide
- (clobber (match_scratch:XF 6 "=&f"))
- ;; Register p6 in optimization guide.
- (clobber (match_scratch:BI 7 "=c"))]
- "TARGET_INLINE_SQRT == INL_MAX_THR"
- "#"
- "&& reload_completed"
- [ ;; exponent of +1/2 in r2
- (set (match_dup 2) (const_int 65534))
- ;; +1/2 in f8. The Intel manual mistakenly specifies f10.
- (set (match_dup 3)
- (unspec:XF [(match_dup 2)] UNSPEC_SETF_EXP))
- ;; Step 1
- ;; y0 = 1/sqrt(a) in f7
- (parallel [(set (match_dup 8)
- (div:XF (const_int 1)
- (unspec:XF [(match_dup 9)]
- UNSPEC_FR_SQRT_RECIP_APPROX_RES)))
- (set (match_dup 7)
- (unspec:BI [(match_dup 9)]
- UNSPEC_FR_SQRT_RECIP_APPROX))
- (use (const_int 0))])
- ;; Step 2
- ;; H0 = 1/2 * y0 in f9
- (cond_exec (ne (match_dup 7) (const_int 0))
- (parallel [(set (match_dup 4)
- (plus:XF (mult:XF (match_dup 3) (match_dup 8))
- (match_dup 10)))
- (use (const_int 1))]))
- ;; Step 3
- ;; S0 = a * y0 in f7
- (cond_exec (ne (match_dup 7) (const_int 0))
- (parallel [(set (match_dup 8)
- (plus:XF (mult:XF (match_dup 9) (match_dup 8))
- (match_dup 10)))
- (use (const_int 1))]))
- ;; Step 4
- ;; d0 = 1/2 - S0 * H0 in f10
- (cond_exec (ne (match_dup 7) (const_int 0))
- (parallel [(set (match_dup 5)
- (minus:XF (match_dup 3)
- (mult:XF (match_dup 8) (match_dup 4))))
- (use (const_int 1))]))
- ;; Step 5
- ;; H1 = H0 + d0 * H0 in f9
- (cond_exec (ne (match_dup 7) (const_int 0))
- (parallel [(set (match_dup 4)
- (plus:XF (mult:XF (match_dup 5) (match_dup 4))
- (match_dup 4)))
- (use (const_int 1))]))
- ;; Step 6
- ;; S1 = S0 + d0 * S0 in f7
- (cond_exec (ne (match_dup 7) (const_int 0))
- (parallel [(set (match_dup 8)
- (plus:XF (mult:XF (match_dup 5) (match_dup 8))
- (match_dup 8)))
- (use (const_int 1))]))
- ;; Step 7
- ;; d1 = 1/2 - S1 * H1 in f10
- (cond_exec (ne (match_dup 7) (const_int 0))
- (parallel [(set (match_dup 5)
- (minus:XF (match_dup 3)
- (mult:XF (match_dup 8) (match_dup 4))))
- (use (const_int 1))]))
- ;; Step 8
- ;; H2 = H1 + d1 * H1 in f9
- (cond_exec (ne (match_dup 7) (const_int 0))
- (parallel [(set (match_dup 4)
- (plus:XF (mult:XF (match_dup 5) (match_dup 4))
- (match_dup 4)))
- (use (const_int 1))]))
- ;; Step 9
- ;; S2 = S1 + d1 * S1 in f7
- (cond_exec (ne (match_dup 7) (const_int 0))
- (parallel [(set (match_dup 8)
- (plus:XF (mult:XF (match_dup 5) (match_dup 8))
- (match_dup 8)))
- (use (const_int 1))]))
- ;; Step 10
- ;; d2 = 1/2 - S2 * H2 in f10
- (cond_exec (ne (match_dup 7) (const_int 0))
- (parallel [(set (match_dup 5)
- (minus:XF (match_dup 3)
- (mult:XF (match_dup 8) (match_dup 4))))
- (use (const_int 1))]))
- ;; Step 11
- ;; e2 = a - S2 * S2 in f8
- (cond_exec (ne (match_dup 7) (const_int 0))
- (parallel [(set (match_dup 3)
- (minus:XF (match_dup 9)
- (mult:XF (match_dup 8) (match_dup 8))))
- (use (const_int 1))]))
- ;; Step 12
- ;; S3 = S2 + e2 * H2 in f7
- (cond_exec (ne (match_dup 7) (const_int 0))
- (parallel [(set (match_dup 8)
- (plus:XF (mult:XF (match_dup 3) (match_dup 4))
- (match_dup 8)))
- (use (const_int 1))]))
- ;; Step 13
- ;; H3 = H2 + d2 * H2 in f9
- (cond_exec (ne (match_dup 7) (const_int 0))
- (parallel [(set (match_dup 4)
- (plus:XF (mult:XF (match_dup 5) (match_dup 4))
- (match_dup 4)))
- (use (const_int 1))]))
- ;; Step 14
- ;; e3 = a - S3 * S3 in f8
- (cond_exec (ne (match_dup 7) (const_int 0))
- (parallel [(set (match_dup 3)
- (minus:XF (match_dup 9)
- (mult:XF (match_dup 8) (match_dup 8))))
- (use (const_int 1))]))
- ;; Step 15
- ;; S = S3 + e3 * H3 in f7
- (cond_exec (ne (match_dup 7) (const_int 0))
- (parallel [(set (match_dup 0)
- (plus:XF (mult:XF (match_dup 3) (match_dup 4))
- (match_dup 8)))
- (use (const_int 0))]))]
-{
- /* Generate 82-bit versions of the input and output operands. */
- operands[8] = gen_rtx_REG (XFmode, REGNO (operands[0]));
- operands[9] = gen_rtx_REG (XFmode, REGNO (operands[1]));
- /* Generate required floating-point constants. */
- operands[10] = CONST0_RTX (XFmode);
-}
- [(set_attr "predicable" "no")])
-
-;; ??? frcpa works like cmp.foo.unc.
-
-(define_insn "*recip_approx"
- [(set (match_operand:XF 0 "fr_register_operand" "=f")
- (unspec:XF [(const_int 1)
- (match_operand:XF 3 "fr_reg_or_fp01_operand" "fG")]
- UNSPEC_FR_RECIP_APPROX_RES))
- (set (match_operand:BI 1 "register_operand" "=c")
- (unspec:BI [(match_operand:XF 2 "fr_reg_or_fp01_operand" "fG")
- (match_dup 3)] UNSPEC_FR_RECIP_APPROX))
- (use (match_operand:SI 4 "const_int_operand" ""))]
- ""
- "frcpa.s%4 %0, %1 = %F2, %F3"
- [(set_attr "itanium_class" "fmisc")
- (set_attr "predicable" "no")])
;; ::::::::::::::::::::
;; ::
@@ -4759,82 +3750,76 @@
;; ::
;; ::::::::::::::::::::
-(define_expand "cmpbi"
- [(set (cc0)
- (compare (match_operand:BI 0 "register_operand" "")
- (match_operand:BI 1 "const_int_operand" "")))]
+(define_expand "cbranchbi4"
+ [(set (pc)
+ (if_then_else (match_operator 0 "ia64_cbranch_operator"
+ [(match_operand:BI 1 "register_operand" "")
+ (match_operand:BI 2 "const_int_operand" "")])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
""
-{
- ia64_compare_op0 = operands[0];
- ia64_compare_op1 = operands[1];
- DONE;
-})
+ "ia64_expand_compare (&operands[0], &operands[1], &operands[2]);")
-(define_expand "cmpsi"
- [(set (cc0)
- (compare (match_operand:SI 0 "gr_register_operand" "")
- (match_operand:SI 1 "gr_reg_or_8bit_and_adjusted_operand" "")))]
+(define_expand "cbranchsi4"
+ [(set (pc)
+ (if_then_else (match_operator 0 "ia64_cbranch_operator"
+ [(match_operand:SI 1 "gr_register_operand" "")
+ (match_operand:SI 2 "gr_reg_or_8bit_and_adjusted_operand" "")])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
""
-{
- ia64_compare_op0 = operands[0];
- ia64_compare_op1 = operands[1];
- DONE;
-})
+ "ia64_expand_compare (&operands[0], &operands[1], &operands[2]);")
-(define_expand "cmpdi"
- [(set (cc0)
- (compare (match_operand:DI 0 "gr_register_operand" "")
- (match_operand:DI 1 "gr_reg_or_8bit_and_adjusted_operand" "")))]
+(define_expand "cbranchdi4"
+ [(set (pc)
+ (if_then_else (match_operator 0 "ia64_cbranch_operator"
+ [(match_operand:DI 1 "gr_register_operand" "")
+ (match_operand:DI 2 "gr_reg_or_8bit_and_adjusted_operand" "")])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
""
-{
- ia64_compare_op0 = operands[0];
- ia64_compare_op1 = operands[1];
- DONE;
-})
+ "ia64_expand_compare (&operands[0], &operands[1], &operands[2]);")
-(define_expand "cmpsf"
- [(set (cc0)
- (compare (match_operand:SF 0 "fr_reg_or_fp01_operand" "")
- (match_operand:SF 1 "fr_reg_or_fp01_operand" "")))]
+(define_expand "cbranchsf4"
+ [(set (pc)
+ (if_then_else (match_operator 0 "ia64_cbranch_operator"
+ [(match_operand:SF 1 "fr_reg_or_fp01_operand" "")
+ (match_operand:SF 2 "fr_reg_or_fp01_operand" "")])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
""
-{
- ia64_compare_op0 = operands[0];
- ia64_compare_op1 = operands[1];
- DONE;
-})
+ "ia64_expand_compare (&operands[0], &operands[1], &operands[2]);")
-(define_expand "cmpdf"
- [(set (cc0)
- (compare (match_operand:DF 0 "fr_reg_or_fp01_operand" "")
- (match_operand:DF 1 "fr_reg_or_fp01_operand" "")))]
+(define_expand "cbranchdf4"
+ [(set (pc)
+ (if_then_else (match_operator 0 "ia64_cbranch_operator"
+ [(match_operand:DF 1 "fr_reg_or_fp01_operand" "")
+ (match_operand:DF 2 "fr_reg_or_fp01_operand" "")])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
""
-{
- ia64_compare_op0 = operands[0];
- ia64_compare_op1 = operands[1];
- DONE;
-})
+ "ia64_expand_compare (&operands[0], &operands[1], &operands[2]);")
-(define_expand "cmpxf"
- [(set (cc0)
- (compare (match_operand:XF 0 "xfreg_or_fp01_operand" "")
- (match_operand:XF 1 "xfreg_or_fp01_operand" "")))]
+(define_expand "cbranchxf4"
+ [(set (pc)
+ (if_then_else (match_operator 0 "ia64_cbranch_operator"
+ [(match_operand:XF 1 "xfreg_or_fp01_operand" "")
+ (match_operand:XF 2 "xfreg_or_fp01_operand" "")])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
""
-{
- ia64_compare_op0 = operands[0];
- ia64_compare_op1 = operands[1];
- DONE;
-})
+ "ia64_expand_compare (&operands[0], &operands[1], &operands[2]);")
-(define_expand "cmptf"
- [(set (cc0)
- (compare (match_operand:TF 0 "gr_register_operand" "")
- (match_operand:TF 1 "gr_register_operand" "")))]
+(define_expand "cbranchtf4"
+ [(set (pc)
+ (if_then_else (match_operator 0 "ia64_cbranch_operator"
+ [(match_operand:TF 1 "gr_register_operand" "")
+ (match_operand:TF 2 "gr_register_operand" "")])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
"TARGET_HPUX"
-{
- ia64_compare_op0 = operands[0];
- ia64_compare_op1 = operands[1];
- DONE;
-})
+ "ia64_expand_compare (&operands[0], &operands[1], &operands[2]);")
+
(define_insn "*cmpsi_normal"
[(set (match_operand:BI 0 "register_operand" "=c")
@@ -4933,102 +3918,6 @@
;; ::
;; ::::::::::::::::::::
-(define_expand "beq"
- [(set (pc)
- (if_then_else (match_dup 1)
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "operands[1] = ia64_expand_compare (EQ, VOIDmode);")
-
-(define_expand "bne"
- [(set (pc)
- (if_then_else (match_dup 1)
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "operands[1] = ia64_expand_compare (NE, VOIDmode);")
-
-(define_expand "blt"
- [(set (pc)
- (if_then_else (match_dup 1)
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "operands[1] = ia64_expand_compare (LT, VOIDmode);")
-
-(define_expand "ble"
- [(set (pc)
- (if_then_else (match_dup 1)
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "operands[1] = ia64_expand_compare (LE, VOIDmode);")
-
-(define_expand "bgt"
- [(set (pc)
- (if_then_else (match_dup 1)
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "operands[1] = ia64_expand_compare (GT, VOIDmode);")
-
-(define_expand "bge"
- [(set (pc)
- (if_then_else (match_dup 1)
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "operands[1] = ia64_expand_compare (GE, VOIDmode);")
-
-(define_expand "bltu"
- [(set (pc)
- (if_then_else (match_dup 1)
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "operands[1] = ia64_expand_compare (LTU, VOIDmode);")
-
-(define_expand "bleu"
- [(set (pc)
- (if_then_else (match_dup 1)
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "operands[1] = ia64_expand_compare (LEU, VOIDmode);")
-
-(define_expand "bgtu"
- [(set (pc)
- (if_then_else (match_dup 1)
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "operands[1] = ia64_expand_compare (GTU, VOIDmode);")
-
-(define_expand "bgeu"
- [(set (pc)
- (if_then_else (match_dup 1)
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "operands[1] = ia64_expand_compare (GEU, VOIDmode);")
-
-(define_expand "bunordered"
- [(set (pc)
- (if_then_else (match_dup 1)
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "operands[1] = ia64_expand_compare (UNORDERED, VOIDmode);")
-
-(define_expand "bordered"
- [(set (pc)
- (if_then_else (match_dup 1)
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "operands[1] = ia64_expand_compare (ORDERED, VOIDmode);")
-
(define_insn "*br_true"
[(set (pc)
(if_then_else (match_operator 0 "predicate_operator"
@@ -5094,65 +3983,61 @@
;; ::
;; ::::::::::::::::::::
-(define_expand "seq"
- [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
- ""
- "operands[1] = ia64_expand_compare (EQ, DImode);")
-
-(define_expand "sne"
- [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
- ""
- "operands[1] = ia64_expand_compare (NE, DImode);")
-
-(define_expand "slt"
- [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
- ""
- "operands[1] = ia64_expand_compare (LT, DImode);")
-
-(define_expand "sle"
- [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
- ""
- "operands[1] = ia64_expand_compare (LE, DImode);")
-
-(define_expand "sgt"
- [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
+(define_expand "cstorebi4"
+ [(set (match_operand:DI 0 "gr_register_operand" "")
+ (match_operator:DI 1 "ia64_cbranch_operator"
+ [(match_operand:BI 2 "register_operand" "")
+ (match_operand:BI 3 "const_int_operand" "")]))]
""
- "operands[1] = ia64_expand_compare (GT, DImode);")
+ "ia64_expand_compare (&operands[0], &operands[1], &operands[2]);")
-(define_expand "sge"
- [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
+(define_expand "cstoresi4"
+ [(set (match_operand:DI 0 "gr_register_operand" "")
+ (match_operator:DI 1 "ia64_cbranch_operator"
+ [(match_operand:SI 2 "gr_register_operand" "")
+ (match_operand:SI 3 "gr_reg_or_8bit_and_adjusted_operand" "")]))]
""
- "operands[1] = ia64_expand_compare (GE, DImode);")
+ "ia64_expand_compare (&operands[1], &operands[2], &operands[3]);")
-(define_expand "sltu"
- [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
+(define_expand "cstoredi4"
+ [(set (match_operand:DI 0 "gr_register_operand" "")
+ (match_operator:DI 1 "ia64_cbranch_operator"
+ [(match_operand:DI 2 "gr_register_operand" "")
+ (match_operand:DI 3 "gr_reg_or_8bit_and_adjusted_operand" "")]))]
""
- "operands[1] = ia64_expand_compare (LTU, DImode);")
+ "ia64_expand_compare (&operands[1], &operands[2], &operands[3]);")
-(define_expand "sleu"
- [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
+(define_expand "cstoresf4"
+ [(set (match_operand:DI 0 "gr_register_operand" "")
+ (match_operator:DI 1 "ia64_cbranch_operator"
+ [(match_operand:SF 2 "fr_reg_or_fp01_operand" "")
+ (match_operand:SF 3 "fr_reg_or_fp01_operand" "")]))]
""
- "operands[1] = ia64_expand_compare (LEU, DImode);")
+ "ia64_expand_compare (&operands[1], &operands[2], &operands[3]);")
-(define_expand "sgtu"
- [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
+(define_expand "cstoredf4"
+ [(set (match_operand:DI 0 "gr_register_operand" "")
+ (match_operator:DI 1 "ia64_cbranch_operator"
+ [(match_operand:DF 2 "fr_reg_or_fp01_operand" "")
+ (match_operand:DF 3 "fr_reg_or_fp01_operand" "")]))]
""
- "operands[1] = ia64_expand_compare (GTU, DImode);")
+ "ia64_expand_compare (&operands[1], &operands[2], &operands[3]);")
-(define_expand "sgeu"
- [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
+(define_expand "cstorexf4"
+ [(set (match_operand:DI 0 "gr_register_operand" "")
+ (match_operator:DI 1 "ia64_cbranch_operator"
+ [(match_operand:XF 2 "xfreg_or_fp01_operand" "")
+ (match_operand:XF 3 "xfreg_or_fp01_operand" "")]))]
""
- "operands[1] = ia64_expand_compare (GEU, DImode);")
+ "ia64_expand_compare (&operands[1], &operands[2], &operands[3]);")
-(define_expand "sunordered"
- [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
- ""
- "operands[1] = ia64_expand_compare (UNORDERED, DImode);")
-
-(define_expand "sordered"
- [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))]
- ""
- "operands[1] = ia64_expand_compare (ORDERED, DImode);")
+(define_expand "cstoretf4"
+ [(set (match_operand:DI 0 "gr_register_operand" "")
+ (match_operator:DI 1 "ia64_cbranch_operator"
+ [(match_operand:TF 2 "gr_register_operand" "")
+ (match_operand:TF 3 "gr_register_operand" "")]))]
+ "TARGET_HPUX"
+ "ia64_expand_compare (&operands[1], &operands[2], &operands[3]);")
;; Don't allow memory as destination here, because cmov/cmov/st is more
;; efficient than mov/mov/cst/cst.
@@ -6018,12 +4903,62 @@
"break %0"
[(set_attr "itanium_class" "chk_s_i")])
-(define_expand "conditional_trap"
- [(trap_if (match_operand 0 "" "") (match_operand 1 "" ""))]
+(define_expand "ctrapbi4"
+ [(trap_if (match_operator 0 "ia64_cbranch_operator"
+ [(match_operand:BI 1 "register_operand" "")
+ (match_operand:BI 2 "const_int_operand" "")])
+ (match_operand 3 "" ""))]
""
-{
- operands[0] = ia64_expand_compare (GET_CODE (operands[0]), VOIDmode);
-})
+ "ia64_expand_compare (&operands[0], &operands[1], &operands[2]);")
+
+(define_expand "ctrapsi4"
+ [(trap_if (match_operator 0 "ia64_cbranch_operator"
+ [(match_operand:SI 1 "gr_register_operand" "")
+ (match_operand:SI 2 "gr_reg_or_8bit_and_adjusted_operand" "")])
+ (match_operand 3 "" ""))]
+ ""
+ "ia64_expand_compare (&operands[0], &operands[1], &operands[2]);")
+
+(define_expand "ctrapdi4"
+ [(trap_if (match_operator 0 "ia64_cbranch_operator"
+ [(match_operand:DI 1 "gr_register_operand" "")
+ (match_operand:DI 2 "gr_reg_or_8bit_and_adjusted_operand" "")])
+ (match_operand 3 "" ""))]
+ ""
+ "ia64_expand_compare (&operands[0], &operands[1], &operands[2]);")
+
+(define_expand "ctrapsf4"
+ [(trap_if (match_operator 0 "ia64_cbranch_operator"
+ [(match_operand:SF 1 "fr_reg_or_fp01_operand" "")
+ (match_operand:SF 2 "fr_reg_or_fp01_operand" "")])
+ (match_operand 3 "" ""))]
+ ""
+ "ia64_expand_compare (&operands[0], &operands[1], &operands[2]);")
+
+(define_expand "ctrapdf4"
+ [(trap_if (match_operator 0 "ia64_cbranch_operator"
+ [(match_operand:DF 1 "fr_reg_or_fp01_operand" "")
+ (match_operand:DF 2 "fr_reg_or_fp01_operand" "")])
+ (match_operand 3 "" ""))]
+ ""
+ "ia64_expand_compare (&operands[0], &operands[1], &operands[2]);")
+
+(define_expand "ctrapxf4"
+ [(trap_if (match_operator 0 "ia64_cbranch_operator"
+ [(match_operand:XF 1 "xfreg_or_fp01_operand" "")
+ (match_operand:XF 2 "xfreg_or_fp01_operand" "")])
+ (match_operand 3 "" ""))]
+ ""
+ "ia64_expand_compare (&operands[0], &operands[1], &operands[2]);")
+
+(define_expand "ctraptf4"
+ [(trap_if (match_operator 0 "ia64_cbranch_operator"
+ [(match_operand:TF 1 "gr_register_operand" "")
+ (match_operand:TF 2 "gr_register_operand" "")])
+ (match_operand 3 "" ""))]
+ "TARGET_HPUX"
+ "ia64_expand_compare (&operands[0], &operands[1], &operands[2]);")
+
(define_insn "*conditional_trap"
[(trap_if (match_operator 0 "predicate_operator"
diff --git a/gcc/config/ia64/ia64.opt b/gcc/config/ia64/ia64.opt
index 79198585719..27cd5b1eaeb 100644
--- a/gcc/config/ia64/ia64.opt
+++ b/gcc/config/ia64/ia64.opt
@@ -178,4 +178,8 @@ msel-sched-dont-check-control-spec
Target Report Var(mflag_sel_sched_dont_check_control_spec) Init(0)
Don't generate checks for control speculation in selective scheduling
+mfused-madd
+Target Report Mask(FUSED_MADD)
+Enable fused multiply/add and multiply/subtract instructions
+
; This comment is to ensure we retain the blank line above.
diff --git a/gcc/config/ia64/predicates.md b/gcc/config/ia64/predicates.md
index 5a957490390..1503a0520cb 100644
--- a/gcc/config/ia64/predicates.md
+++ b/gcc/config/ia64/predicates.md
@@ -536,6 +536,11 @@
(and (match_code "const_double,const_vector")
(match_test "op == CONST0_RTX (GET_MODE (op))"))))
+;; Return 1 if OP is a valid comparison operator for "cbranch" instructions.
+(define_predicate "ia64_cbranch_operator"
+ (ior (match_operand 0 "ordered_comparison_operator")
+ (match_code "ordered,unordered")))
+
;; True if this is a comparison operator, which accepts a normal 8-bit
;; signed immediate operand.
(define_predicate "normal_comparison_operator"
diff --git a/gcc/config/ia64/t-ia64 b/gcc/config/ia64/t-ia64
index 4f78c64df70..db7a8298d17 100644
--- a/gcc/config/ia64/t-ia64
+++ b/gcc/config/ia64/t-ia64
@@ -1,5 +1,5 @@
-# Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
-# 2008 Free Software Foundation, Inc.
+# Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+# Free Software Foundation, Inc.
#
# This file is part of GCC.
#
@@ -47,7 +47,8 @@ LIB2ADDEH = $(srcdir)/config/ia64/unwind-ia64.c $(srcdir)/unwind-sjlj.c \
ia64-c.o: $(srcdir)/config/ia64/ia64-c.c $(CONFIG_H) $(SYSTEM_H) \
coretypes.h $(TM_H) $(TREE_H) $(CPPLIB_H) $(C_COMMON_H) c-pragma.h toplev.h
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/config/ia64/ia64-c.c
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $(srcdir)/config/ia64/ia64-c.c
# genattrtab generates very long string literals.
insn-attrtab.o-warn = -Wno-error
diff --git a/gcc/config/ia64/vect.md b/gcc/config/ia64/vect.md
index 994ec90b2eb..ae23c755e18 100644
--- a/gcc/config/ia64/vect.md
+++ b/gcc/config/ia64/vect.md
@@ -873,8 +873,8 @@
if (which_alternative == 1)
{
- operands[2] = XVECEXP (operands[1], 0, 1);
- operands[1] = XVECEXP (operands[1], 0, 0);
+ operands[2] = XVECEXP (operands[1], 0, TARGET_BIG_ENDIAN ? 0 : 1);
+ operands[1] = XVECEXP (operands[1], 0, TARGET_BIG_ENDIAN ? 1 : 0);
}
return alt[which_alternative];
@@ -915,6 +915,11 @@
{
rtvec v = gen_rtvec (2, CONST1_RTX (SFmode), CONST1_RTX (SFmode));
operands[3] = force_reg (V2SFmode, gen_rtx_CONST_VECTOR (V2SFmode, v));
+ if (!TARGET_FUSED_MADD)
+ {
+ emit_insn (gen_fpma (operands[0], operands[1], operands[3], operands[2]));
+ DONE;
+ }
})
;; The split condition here could be combine_completed, if we had such.
@@ -960,6 +965,11 @@
{
rtvec v = gen_rtvec (2, CONST1_RTX (SFmode), CONST1_RTX (SFmode));
operands[3] = force_reg (V2SFmode, gen_rtx_CONST_VECTOR (V2SFmode, v));
+ if (!TARGET_FUSED_MADD)
+ {
+ emit_insn (gen_fpms (operands[0], operands[1], operands[3], operands[2]));
+ DONE;
+ }
})
;; The split condition here could be combine_completed, if we had such.
@@ -1001,7 +1011,7 @@
"fpmpy %0 = %1, %2"
[(set_attr "itanium_class" "fmac")])
-(define_insn "*fpma"
+(define_insn "fpma"
[(set (match_operand:V2SF 0 "fr_register_operand" "=f")
(plus:V2SF
(mult:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
@@ -1011,7 +1021,7 @@
"fpma %0 = %1, %2, %3"
[(set_attr "itanium_class" "fmac")])
-(define_insn "*fpms"
+(define_insn "fpms"
[(set (match_operand:V2SF 0 "fr_register_operand" "=f")
(minus:V2SF
(mult:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
diff --git a/gcc/config/iq2000/iq2000-protos.h b/gcc/config/iq2000/iq2000-protos.h
index 094bcbf2f12..0e4dba77eb4 100644
--- a/gcc/config/iq2000/iq2000-protos.h
+++ b/gcc/config/iq2000/iq2000-protos.h
@@ -22,7 +22,6 @@
extern int iq2000_check_split (rtx, enum machine_mode);
extern int iq2000_reg_mode_ok_for_base_p (rtx, enum machine_mode, int);
-extern int iq2000_legitimate_address_p (enum machine_mode, rtx, int);
extern const char * iq2000_fill_delay_slot (const char *, enum delay_type, rtx *, rtx);
extern const char * iq2000_move_1word (rtx *, rtx, int);
extern void override_options (void);
@@ -41,7 +40,7 @@ extern void print_operand (FILE *, rtx, int);
#ifdef RTX_CODE
extern rtx gen_int_relational (enum rtx_code, rtx, rtx, rtx, int *);
-extern void gen_conditional_branch (rtx *, enum rtx_code);
+extern void gen_conditional_branch (rtx *, enum machine_mode);
#endif
#ifdef TREE_CODE
diff --git a/gcc/config/iq2000/iq2000.c b/gcc/config/iq2000/iq2000.c
index 3b9e1166b27..b99043efa99 100644
--- a/gcc/config/iq2000/iq2000.c
+++ b/gcc/config/iq2000/iq2000.c
@@ -118,13 +118,6 @@ enum processor_type iq2000_tune;
/* Which instruction set architecture to use. */
int iq2000_isa;
-/* Cached operands, and operator to compare for use in set/branch/trap
- on condition codes. */
-rtx branch_cmp[2];
-
-/* What type of branch to use. */
-enum cmp_type branch_type;
-
/* Local variables. */
/* The next branch instruction is a branch likely, not branch normal. */
@@ -171,6 +164,7 @@ static bool iq2000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
static int iq2000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
tree, bool);
static void iq2000_va_start (tree, rtx);
+static bool iq2000_legitimate_address_p (enum machine_mode, rtx, bool);
#undef TARGET_INIT_BUILTINS
#define TARGET_INIT_BUILTINS iq2000_init_builtins
@@ -219,6 +213,9 @@ static void iq2000_va_start (tree, rtx);
#undef TARGET_EXPAND_BUILTIN_VA_START
#define TARGET_EXPAND_BUILTIN_VA_START iq2000_va_start
+#undef TARGET_LEGITIMATE_ADDRESS_P
+#define TARGET_LEGITIMATE_ADDRESS_P iq2000_legitimate_address_p
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* Return nonzero if we split the address into high and low parts. */
@@ -256,12 +253,12 @@ iq2000_reg_mode_ok_for_base_p (rtx reg,
memory operand of the indicated MODE. STRICT is nonzero if this
function is called during reload. */
-int
-iq2000_legitimate_address_p (enum machine_mode mode, rtx xinsn, int strict)
+bool
+iq2000_legitimate_address_p (enum machine_mode mode, rtx xinsn, bool strict)
{
if (TARGET_DEBUG_A_MODE)
{
- GO_PRINTF2 ("\n========== GO_IF_LEGITIMATE_ADDRESS, %sstrict\n",
+ GO_PRINTF2 ("\n========== legitimate_address_p, %sstrict\n",
strict ? "" : "not ");
GO_DEBUG_RTX (xinsn);
}
@@ -318,7 +315,7 @@ iq2000_legitimate_address_p (enum machine_mode mode, rtx xinsn, int strict)
}
if (TARGET_DEBUG_A_MODE)
- GO_PRINTF ("Not a legitimate address\n");
+ GO_PRINTF ("Not a enum machine_mode mode, legitimate address\n");
/* The address was not legitimate. */
return 0;
@@ -1010,60 +1007,31 @@ gen_int_relational (enum rtx_code test_code, rtx result, rtx cmp0, rtx cmp1,
The comparison operands are saved away by cmp{si,di,sf,df}. */
void
-gen_conditional_branch (rtx operands[], enum rtx_code test_code)
+gen_conditional_branch (rtx operands[], enum machine_mode mode)
{
- enum cmp_type type = branch_type;
- rtx cmp0 = branch_cmp[0];
- rtx cmp1 = branch_cmp[1];
- enum machine_mode mode;
+ enum rtx_code test_code = GET_CODE (operands[0]);
+ rtx cmp0 = operands[1];
+ rtx cmp1 = operands[2];
rtx reg;
int invert;
rtx label1, label2;
- switch (type)
- {
- case CMP_SI:
- case CMP_DI:
- mode = type == CMP_SI ? SImode : DImode;
- invert = 0;
- reg = gen_int_relational (test_code, NULL_RTX, cmp0, cmp1, &invert);
-
- if (reg)
- {
- cmp0 = reg;
- cmp1 = const0_rtx;
- test_code = NE;
- }
- else if (GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) != 0)
- /* We don't want to build a comparison against a nonzero
- constant. */
- cmp1 = force_reg (mode, cmp1);
-
- break;
-
- case CMP_SF:
- case CMP_DF:
- reg = gen_reg_rtx (CCmode);
-
- /* For cmp0 != cmp1, build cmp0 == cmp1, and test for result == 0. */
- emit_insn (gen_rtx_SET (VOIDmode, reg,
- gen_rtx_fmt_ee (test_code == NE ? EQ : test_code,
- CCmode, cmp0, cmp1)));
+ invert = 0;
+ reg = gen_int_relational (test_code, NULL_RTX, cmp0, cmp1, &invert);
- test_code = test_code == NE ? EQ : NE;
- mode = CCmode;
+ if (reg)
+ {
cmp0 = reg;
cmp1 = const0_rtx;
- invert = 0;
- break;
-
- default:
- abort_with_insn (gen_rtx_fmt_ee (test_code, VOIDmode, cmp0, cmp1),
- "bad test");
+ test_code = NE;
}
+ else if (GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) != 0)
+ /* We don't want to build a comparison against a nonzero
+ constant. */
+ cmp1 = force_reg (mode, cmp1);
/* Generate the branch. */
- label1 = gen_rtx_LABEL_REF (VOIDmode, operands[0]);
+ label1 = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
label2 = pc_rtx;
if (invert)
@@ -1892,7 +1860,8 @@ iq2000_expand_prologue (void)
&& targetm.calls.struct_value_rtx (TREE_TYPE (fndecl), 1) == 0)
{
tree type = build_pointer_type (fntype);
- tree function_result_decl = build_decl (PARM_DECL, NULL_TREE, type);
+ tree function_result_decl = build_decl (BUILTINS_LOCATION,
+ PARM_DECL, NULL_TREE, type);
DECL_ARG_TYPE (function_result_decl) = type;
TREE_CHAIN (function_result_decl) = fnargs;
diff --git a/gcc/config/iq2000/iq2000.h b/gcc/config/iq2000/iq2000.h
index 30642b2a13f..c1506a4a1f1 100644
--- a/gcc/config/iq2000/iq2000.h
+++ b/gcc/config/iq2000/iq2000.h
@@ -528,20 +528,6 @@ typedef struct iq2000_args
#define MAX_REGS_PER_ADDRESS 1
-#ifdef REG_OK_STRICT
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
- { \
- if (iq2000_legitimate_address_p (MODE, X, 1)) \
- goto ADDR; \
- }
-#else
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
- { \
- if (iq2000_legitimate_address_p (MODE, X, 0)) \
- goto ADDR; \
- }
-#endif
-
#define REG_OK_FOR_INDEX_P(X) 0
#define LEGITIMATE_CONSTANT_P(X) (1)
@@ -1001,13 +987,6 @@ extern enum processor_type iq2000_tune;
/* Which instruction set architecture to use. */
extern int iq2000_isa;
-/* Cached operands, and operator to compare for use in set/branch/trap
- on condition codes. */
-extern rtx branch_cmp[2];
-
-/* What type of branch to use. */
-extern enum cmp_type branch_type;
-
enum iq2000_builtins
{
IQ2000_BUILTIN_ADO16,
diff --git a/gcc/config/iq2000/iq2000.md b/gcc/config/iq2000/iq2000.md
index 919f6a20231..61275f2c671 100644
--- a/gcc/config/iq2000/iq2000.md
+++ b/gcc/config/iq2000/iq2000.md
@@ -989,63 +989,25 @@
;;
;; ....................
;;
-;; COMPARISONS
+;; CONDITIONAL BRANCHES
;;
;; ....................
-;; Flow here is rather complex:
-;;
-;; 1) The cmp{si,di,sf,df} routine is called. It deposits the
-;; arguments into the branch_cmp array, and the type into
-;; branch_type. No RTL is generated.
-;;
-;; 2) The appropriate branch define_expand is called, which then
-;; creates the appropriate RTL for the comparison and branch.
-;; Different CC modes are used, based on what type of branch is
-;; done, so that we can constrain things appropriately. There
-;; are assumptions in the rest of GCC that break if we fold the
-;; operands into the branches for integer operations, and use cc0
-;; for floating point, so we use the fp status register instead.
-;; If needed, an appropriate temporary is created to hold the
-;; of the integer compare.
-
-(define_expand "cmpsi"
- [(set (cc0)
- (compare:CC (match_operand:SI 0 "register_operand" "")
- (match_operand:SI 1 "arith_operand" "")))]
+(define_expand "cbranchsi4"
+ [(set (pc)
+ (if_then_else
+ (match_operator:SI 0 "ordered_comparison_operator"
+ [(match_operand:SI 1 "register_operand")
+ (match_operand:SI 2 "reg_or_const_operand")])
+ (label_ref (match_operand:SI 3 ""))
+ (pc)))]
""
"
{
- if (operands[0]) /* avoid unused code message */
- {
- branch_cmp[0] = operands[0];
- branch_cmp[1] = operands[1];
- branch_type = CMP_SI;
- DONE;
- }
+ gen_conditional_branch (operands, SImode);
+ DONE;
}")
-(define_expand "tstsi"
- [(set (cc0)
- (match_operand:SI 0 "register_operand" ""))]
- ""
- "
-{
- if (operands[0]) /* avoid unused code message */
- {
- branch_cmp[0] = operands[0];
- branch_cmp[1] = const0_rtx;
- branch_type = CMP_SI;
- DONE;
- }
-}")
-
-;;
-;; ....................
-;;
-;; CONDITIONAL BRANCHES
-;;
-;; ....................
;; Conditional branches on comparisons with zero.
@@ -1135,166 +1097,6 @@
[(set_attr "type" "branch")
(set_attr "mode" "none")])
-(define_expand "beq"
- [(set (pc)
- (if_then_else (eq:CC (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (operands[0]) /* avoid unused code warning */
- {
- gen_conditional_branch (operands, EQ);
- DONE;
- }
-}")
-
-(define_expand "bne"
- [(set (pc)
- (if_then_else (ne:CC (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (operands[0]) /* avoid unused code warning */
- {
- gen_conditional_branch (operands, NE);
- DONE;
- }
-}")
-
-(define_expand "bgt"
- [(set (pc)
- (if_then_else (gt:CC (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (operands[0]) /* avoid unused code warning */
- {
- gen_conditional_branch (operands, GT);
- DONE;
- }
-}")
-
-(define_expand "bge"
- [(set (pc)
- (if_then_else (ge:CC (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (operands[0]) /* avoid unused code warning */
- {
- gen_conditional_branch (operands, GE);
- DONE;
- }
-}")
-
-(define_expand "blt"
- [(set (pc)
- (if_then_else (lt:CC (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (operands[0]) /* avoid unused code warning */
- {
- gen_conditional_branch (operands, LT);
- DONE;
- }
-}")
-
-(define_expand "ble"
- [(set (pc)
- (if_then_else (le:CC (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (operands[0]) /* avoid unused code warning */
- {
- gen_conditional_branch (operands, LE);
- DONE;
- }
-}")
-
-(define_expand "bgtu"
- [(set (pc)
- (if_then_else (gtu:CC (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (operands[0]) /* avoid unused code warning */
- {
- gen_conditional_branch (operands, GTU);
- DONE;
- }
-}")
-
-(define_expand "bgeu"
- [(set (pc)
- (if_then_else (geu:CC (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (operands[0]) /* avoid unused code warning */
- {
- gen_conditional_branch (operands, GEU);
- DONE;
- }
-}")
-
-
-(define_expand "bltu"
- [(set (pc)
- (if_then_else (ltu:CC (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (operands[0]) /* avoid unused code warning */
- {
- gen_conditional_branch (operands, LTU);
- DONE;
- }
-}")
-
-(define_expand "bleu"
- [(set (pc)
- (if_then_else (leu:CC (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (operands[0]) /* avoid unused code warning */
- {
- gen_conditional_branch (operands, LEU);
- DONE;
- }
-}")
;; Recognize bbi and bbin instructions. These use two unusual template
;; patterns, %Ax and %Px. %Ax outputs an 'i' if operand `x' is a LABEL_REF
@@ -1390,25 +1192,19 @@
;;
;; ....................
-(define_expand "seq"
+(define_expand "cstoresi4"
[(set (match_operand:SI 0 "register_operand" "=d")
- (eq:SI (match_dup 1)
- (match_dup 2)))]
+ (match_operator:SI 1 "ordered_comparison_operator"
+ [(match_operand:SI 2 "register_operand")
+ (match_operand:SI 3 "reg_or_const_operand")]))]
""
"
{
- if (branch_type != CMP_SI && (branch_type != CMP_DI))
- FAIL;
-
- /* Set up operands from compare. */
- operands[1] = branch_cmp[0];
- operands[2] = branch_cmp[1];
-
- gen_int_relational (EQ, operands[0], operands[1], operands[2], (int *)0);
+ gen_int_relational (GET_CODE (operands[1]), operands[0],
+ operands[2], operands[3], (int *)0);
DONE;
}")
-
(define_insn "seq_si_zero"
[(set (match_operand:SI 0 "register_operand" "=d")
(eq:SI (match_operand:SI 1 "register_operand" "d")
@@ -1418,24 +1214,6 @@
[(set_attr "type" "arith")
(set_attr "mode" "SI")])
-(define_expand "sne"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (ne:SI (match_dup 1)
- (match_dup 2)))]
- ""
- "
-{
- if (branch_type != CMP_SI && (branch_type != CMP_DI))
- FAIL;
-
- /* Set up operands from compare. */
- operands[1] = branch_cmp[0];
- operands[2] = branch_cmp[1];
-
- gen_int_relational (NE, operands[0], operands[1], operands[2], (int *)0);
- DONE;
-}")
-
(define_insn "sne_si_zero"
[(set (match_operand:SI 0 "register_operand" "=d")
(ne:SI (match_operand:SI 1 "register_operand" "d")
@@ -1445,24 +1223,6 @@
[(set_attr "type" "arith")
(set_attr "mode" "SI")])
-(define_expand "sgt"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (gt:SI (match_dup 1)
- (match_dup 2)))]
- ""
- "
-{
- if (branch_type != CMP_SI && (branch_type != CMP_DI))
- FAIL;
-
- /* Set up operands from compare. */
- operands[1] = branch_cmp[0];
- operands[2] = branch_cmp[1];
-
- gen_int_relational (GT, operands[0], operands[1], operands[2], (int *)0);
- DONE;
-}")
-
(define_insn "sgt_si"
[(set (match_operand:SI 0 "register_operand" "=d,=d")
(gt:SI (match_operand:SI 1 "register_operand" "d,d")
@@ -1474,42 +1234,6 @@
[(set_attr "type" "arith,arith")
(set_attr "mode" "SI,SI")])
-(define_expand "sge"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (ge:SI (match_dup 1)
- (match_dup 2)))]
- ""
- "
-{
- if (branch_type != CMP_SI && (branch_type != CMP_DI))
- FAIL;
-
- /* Set up operands from compare. */
- operands[1] = branch_cmp[0];
- operands[2] = branch_cmp[1];
-
- gen_int_relational (GE, operands[0], operands[1], operands[2], (int *)0);
- DONE;
-}")
-
-(define_expand "slt"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (lt:SI (match_dup 1)
- (match_dup 2)))]
- ""
- "
-{
- if (branch_type != CMP_SI && (branch_type != CMP_DI))
- FAIL;
-
- /* Set up operands from compare. */
- operands[1] = branch_cmp[0];
- operands[2] = branch_cmp[1];
-
- gen_int_relational (LT, operands[0], operands[1], operands[2], (int *)0);
- DONE;
-}")
-
(define_insn "slt_si"
[(set (match_operand:SI 0 "register_operand" "=d,=d")
(lt:SI (match_operand:SI 1 "register_operand" "d,d")
@@ -1521,24 +1245,6 @@
[(set_attr "type" "arith,arith")
(set_attr "mode" "SI,SI")])
-(define_expand "sle"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (le:SI (match_dup 1)
- (match_dup 2)))]
- ""
- "
-{
- if (branch_type != CMP_SI && (branch_type != CMP_DI))
- FAIL;
-
- /* Set up operands from compare. */
- operands[1] = branch_cmp[0];
- operands[2] = branch_cmp[1];
-
- gen_int_relational (LE, operands[0], operands[1], operands[2], (int *)0);
- DONE;
-}")
-
(define_insn "sle_si_const"
[(set (match_operand:SI 0 "register_operand" "=d")
(le:SI (match_operand:SI 1 "register_operand" "d")
@@ -1552,24 +1258,6 @@
[(set_attr "type" "arith")
(set_attr "mode" "SI")])
-(define_expand "sgtu"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (gtu:SI (match_dup 1)
- (match_dup 2)))]
- ""
- "
-{
- if (branch_type != CMP_SI && (branch_type != CMP_DI))
- FAIL;
-
- /* Set up operands from compare. */
- operands[1] = branch_cmp[0];
- operands[2] = branch_cmp[1];
-
- gen_int_relational (GTU, operands[0], operands[1], operands[2], (int *)0);
- DONE;
-}")
-
(define_insn "sgtu_si"
[(set (match_operand:SI 0 "register_operand" "=d")
(gtu:SI (match_operand:SI 1 "register_operand" "d")
@@ -1588,42 +1276,6 @@
[(set_attr "type" "arith")
(set_attr "mode" "SI")])
-(define_expand "sgeu"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (geu:SI (match_dup 1)
- (match_dup 2)))]
- ""
- "
-{
- if (branch_type != CMP_SI && (branch_type != CMP_DI))
- FAIL;
-
- /* Set up operands from compare. */
- operands[1] = branch_cmp[0];
- operands[2] = branch_cmp[1];
-
- gen_int_relational (GEU, operands[0], operands[1], operands[2], (int *)0);
- DONE;
-}")
-
-(define_expand "sltu"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (ltu:SI (match_dup 1)
- (match_dup 2)))]
- ""
- "
-{
- if (branch_type != CMP_SI && (branch_type != CMP_DI))
- FAIL;
-
- /* Set up operands from compare. */
- operands[1] = branch_cmp[0];
- operands[2] = branch_cmp[1];
-
- gen_int_relational (LTU, operands[0], operands[1], operands[2], (int *)0);
- DONE;
-}")
-
(define_insn "sltu_si"
[(set (match_operand:SI 0 "register_operand" "=d,=d")
(ltu:SI (match_operand:SI 1 "register_operand" "d,d")
@@ -1635,24 +1287,6 @@
[(set_attr "type" "arith,arith")
(set_attr "mode" "SI,SI")])
-(define_expand "sleu"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (leu:SI (match_dup 1)
- (match_dup 2)))]
- ""
- "
-{
- if (branch_type != CMP_SI && (branch_type != CMP_DI))
- FAIL;
-
- /* Set up operands from compare. */
- operands[1] = branch_cmp[0];
- operands[2] = branch_cmp[1];
-
- gen_int_relational (LEU, operands[0], operands[1], operands[2], (int *)0);
- DONE;
-}")
-
(define_insn "sleu_si_const"
[(set (match_operand:SI 0 "register_operand" "=d")
(leu:SI (match_operand:SI 1 "register_operand" "d")
diff --git a/gcc/config/iq2000/predicates.md b/gcc/config/iq2000/predicates.md
index 53471e455ad..f275090309b 100644
--- a/gcc/config/iq2000/predicates.md
+++ b/gcc/config/iq2000/predicates.md
@@ -41,6 +41,14 @@
return register_operand (op, mode);
})
+;; Return 1 if OP is a register or a constant. gen_int_relational
+;; takes care of forcing out-of-range constants into a register.
+
+(define_predicate "reg_or_const_operand"
+ (ior (match_code "const_int")
+ (and (match_code "reg,subreg")
+ (match_operand 0 "register_operand"))))
+
;; Return 1 if OP is a integer which fits in 16 bits.
(define_predicate "small_int"
diff --git a/gcc/config/m32c/cond.md b/gcc/config/m32c/cond.md
index 60d83eea6ca..c751070e716 100644
--- a/gcc/config/m32c/cond.md
+++ b/gcc/config/m32c/cond.md
@@ -58,12 +58,23 @@
[(set (reg:CC FLG_REGNO)
(compare (match_dup 1)
(match_dup 2)))
- (set (pc) (if_then_else (match_dup 4)
+ (set (pc) (if_then_else (match_op_dup 0 [(reg:CC FLG_REGNO) (const_int 0)])
(label_ref (match_dup 3))
(pc)))]
- "operands[4] = m32c_cmp_flg_0 (operands[0]);"
+ ""
)
+(define_insn "bcc_op"
+ [(set (pc)
+ (if_then_else (match_operator 0 "ordered_comparison_operator"
+ [(reg:CC FLG_REGNO) (const_int 0)])
+ (label_ref (match_operand 1 ""))
+ (pc)))]
+ ""
+ "j%c0\t%l1"
+ [(set_attr "flags" "n")]
+)
+
(define_insn "stzx_16"
[(set (match_operand:QI 0 "mrai_operand" "=R0w,R0w,R0w")
(if_then_else:QI (eq (reg:CC FLG_REGNO) (const_int 0))
@@ -113,34 +124,6 @@
"* return m32c_output_compare(insn, operands); "
[(set_attr "flags" "oszc")])
-(define_expand "cmp<mode>"
- [(set (reg:CC FLG_REGNO)
- (compare (match_operand:QHPSI 0 "mra_operand" "RraSd")
- (match_operand:QHPSI 1 "mrai_operand" "RraSdi")))]
- ""
- "m32c_pend_compare (operands); DONE;")
-
-(define_insn "b<code>_op"
- [(set (pc)
- (if_then_else (any_cond (reg:CC FLG_REGNO)
- (const_int 0))
- (label_ref (match_operand 0 ""))
- (pc)))]
- ""
- "j<code>\t%l0"
- [(set_attr "flags" "n")]
-)
-
-(define_expand "b<code>"
- [(set (pc)
- (if_then_else (any_cond (reg:CC FLG_REGNO)
- (const_int 0))
- (label_ref (match_operand 0 ""))
- (pc)))]
- ""
- "m32c_unpend_compare ();"
-)
-
;; m32c_conditional_register_usage changes the setcc_gen_code array to
;; point to the _24 variants if needed.
@@ -151,51 +134,54 @@
;; These are the post-split patterns for the conditional sets.
-(define_insn "s<code>_op"
+(define_insn "scc_op"
[(set (match_operand:QI 0 "register_operand" "=Rqi")
- (any_cond:QI (reg:CC FLG_REGNO) (const_int 0)))]
+ (match_operator:QI 1 "ordered_comparison_operator"
+ [(reg:CC FLG_REGNO) (const_int 0)]))]
"TARGET_A16 && reload_completed"
- "* return m32c_scc_pattern(operands, <CODE>);")
+ "* return m32c_scc_pattern(operands, GET_CODE (operands[1]));")
-(define_insn "s<code>_24_op"
+(define_insn "scc_24_op"
[(set (match_operand:HI 0 "mra_operand" "=RhiSd")
- (any_cond:HI (reg:CC FLG_REGNO) (const_int 0)))]
+ (match_operator:HI 1 "ordered_comparison_operator"
+ [(reg:CC FLG_REGNO) (const_int 0)]))]
"TARGET_A24 && reload_completed"
- "sc<code>\t%0"
+ "sc%c1\t%0"
[(set_attr "flags" "n")]
)
-;; These are the pre-split patterns for the conditional sets. Yes,
-;; there are a lot of permutations.
+;; These are the pre-split patterns for the conditional sets.
-(define_insn_and_split "s<code>_<mode>"
+(define_insn_and_split "cstore<mode>4"
[(set (match_operand:QI 0 "register_operand" "=Rqi")
- (any_cond:QI (match_operand:QHPSI 1 "mra_operand" "RraSd")
- (match_operand:QHPSI 2 "mrai_operand" "RraSdi")))]
+ (match_operator:QI 1 "ordered_comparison_operator"
+ [(match_operand:QHPSI 2 "mra_operand" "RraSd")
+ (match_operand:QHPSI 3 "mrai_operand" "RraSdi")]))]
"TARGET_A16"
"#"
"reload_completed"
[(set (reg:CC FLG_REGNO)
- (compare (match_dup 1)
- (match_dup 2)))
+ (compare (match_dup 2)
+ (match_dup 3)))
(set (match_dup 0)
- (any_cond:QI (reg:CC FLG_REGNO) (const_int 0)))]
+ (match_op_dup 1 [(reg:CC FLG_REGNO) (const_int 0)]))]
""
[(set_attr "flags" "x")]
)
-(define_insn_and_split "s<code>_<mode>_24"
+(define_insn_and_split "cstore<mode>4_24"
[(set (match_operand:HI 0 "mra_nopp_operand" "=RhiSd")
- (any_cond:HI (match_operand:QHPSI 1 "mra_operand" "RraSd")
- (match_operand:QHPSI 2 "mrai_operand" "RraSdi")))]
+ (match_operator:HI 1 "ordered_comparison_operator"
+ [(match_operand:QHPSI 2 "mra_operand" "RraSd")
+ (match_operand:QHPSI 3 "mrai_operand" "RraSdi")]))]
"TARGET_A24"
"#"
"reload_completed"
[(set (reg:CC FLG_REGNO)
- (compare (match_dup 1)
- (match_dup 2)))
+ (compare (match_dup 2)
+ (match_dup 3)))
(set (match_dup 0)
- (any_cond:HI (reg:CC FLG_REGNO) (const_int 0)))]
+ (match_op_dup 1 [(reg:CC FLG_REGNO) (const_int 0)]))]
""
[(set_attr "flags" "x")]
)
@@ -240,21 +226,7 @@
[(set_attr "flags" "x")]
)
-;; And these are the expanders, which read the pending compare
-;; operands to build a combined insn.
-
-(define_expand "s<code>"
- [(set (match_operand:QI 0 "register_operand" "=Rqi")
- (any_cond:QI (reg:CC FLG_REGNO) (const_int 0)))]
- "TARGET_A16"
- "m32c_expand_scc (<CODE>, operands); DONE;")
-
-(define_expand "s<code>_24"
- [(set (match_operand:HI 0 "mra_nopp_operand" "=RhiSd")
- (any_cond:HI (reg:CC FLG_REGNO) (const_int 0)))]
- "TARGET_A24"
- "m32c_expand_scc (<CODE>, operands); DONE;")
-
+;; And these are the expanders.
(define_expand "movqicc"
[(set (match_operand:QI 0 "register_operand" "")
diff --git a/gcc/config/m32c/m32c-protos.h b/gcc/config/m32c/m32c-protos.h
index 650c918b44a..d332475784f 100644
--- a/gcc/config/m32c/m32c-protos.h
+++ b/gcc/config/m32c/m32c-protos.h
@@ -45,7 +45,6 @@ void m32c_register_pragmas (void);
int m32c_regno_ok_for_base_p (int);
int m32c_trampoline_alignment (void);
int m32c_trampoline_size (void);
-void m32c_unpend_compare (void);
#if defined(RTX_CODE) && defined(TREE_CODE)
@@ -58,7 +57,6 @@ rtx m32c_function_value (const_tree, const_tree);
int m32c_cannot_change_mode_class (MM, MM, int);
int m32c_class_max_nregs (int, MM);
-rtx m32c_cmp_flg_0 (rtx);
rtx m32c_eh_return_stackadj_rtx (void);
void m32c_emit_eh_epilogue (rtx);
int m32c_expand_cmpstr (rtx *);
@@ -68,7 +66,6 @@ int m32c_expand_movmemhi (rtx *);
int m32c_expand_movstr (rtx *);
void m32c_expand_neg_mulpsi3 (rtx *);
int m32c_expand_setmemhi (rtx *);
-void m32c_expand_scc (int, rtx *);
int m32c_extra_constraint_p (rtx, char, const char *);
int m32c_extra_constraint_p2 (rtx, char, const char *);
int m32c_hard_regno_nregs (int, MM);
@@ -77,7 +74,6 @@ bool m32c_illegal_subreg_p (rtx);
bool m32c_immd_dbl_mov (rtx *, MM);
rtx m32c_incoming_return_addr_rtx (void);
void m32c_initialize_trampoline (rtx, rtx, rtx);
-int m32c_legitimate_address_p (MM, rtx, int);
int m32c_legitimate_constant_p (rtx);
int m32c_legitimize_reload_address (rtx *, MM, int, int, int);
rtx m32c_libcall_value (MM);
@@ -86,7 +82,6 @@ int m32c_memory_move_cost (MM, int, int);
int m32c_modes_tieable_p (MM, MM);
bool m32c_mov_ok (rtx *, MM);
char * m32c_output_compare (rtx, rtx *);
-void m32c_pend_compare (rtx *);
int m32c_preferred_output_reload_class (rtx, int);
int m32c_preferred_reload_class (rtx, int);
int m32c_prepare_move (rtx *, MM);
diff --git a/gcc/config/m32c/m32c.c b/gcc/config/m32c/m32c.c
index d0980dd63a6..989f823df92 100644
--- a/gcc/config/m32c/m32c.c
+++ b/gcc/config/m32c/m32c.c
@@ -68,6 +68,7 @@ static int m32c_comp_type_attributes (const_tree, const_tree);
static bool m32c_fixed_condition_code_regs (unsigned int *, unsigned int *);
static struct machine_function *m32c_init_machine_status (void);
static void m32c_insert_attributes (tree, tree *);
+static bool m32c_legitimate_address_p (enum machine_mode, rtx, bool);
static bool m32c_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
const_tree, bool);
static bool m32c_promote_prototypes (const_tree);
@@ -1746,34 +1747,28 @@ m32c_initialize_trampoline (rtx tramp, rtx function, rtx chainval)
static void
m32c_init_libfuncs (void)
{
+ /* We do this because the M32C has an HImode operand, but the
+ M16C has an 8-bit operand. Since gcc looks at the match data
+ and not the expanded rtl, we have to reset the optab so that
+ the right modes are found. */
if (TARGET_A24)
{
- /* We do this because the M32C has an HImode operand, but the
- M16C has an 8-bit operand. Since gcc looks at the match data
- and not the expanded rtl, we have to reset the array so that
- the right modes are found. */
- setcc_gen_code[EQ] = CODE_FOR_seq_24;
- setcc_gen_code[NE] = CODE_FOR_sne_24;
- setcc_gen_code[GT] = CODE_FOR_sgt_24;
- setcc_gen_code[GE] = CODE_FOR_sge_24;
- setcc_gen_code[LT] = CODE_FOR_slt_24;
- setcc_gen_code[LE] = CODE_FOR_sle_24;
- setcc_gen_code[GTU] = CODE_FOR_sgtu_24;
- setcc_gen_code[GEU] = CODE_FOR_sgeu_24;
- setcc_gen_code[LTU] = CODE_FOR_sltu_24;
- setcc_gen_code[LEU] = CODE_FOR_sleu_24;
+ optab_handler (cstore_optab, QImode)->insn_code = CODE_FOR_cstoreqi4_24;
+ optab_handler (cstore_optab, HImode)->insn_code = CODE_FOR_cstorehi4_24;
+ optab_handler (cstore_optab, PSImode)->insn_code = CODE_FOR_cstorepsi4_24;
}
}
/* Addressing Modes */
-/* Used by GO_IF_LEGITIMATE_ADDRESS. The r8c/m32c family supports a
- wide range of non-orthogonal addressing modes, including the
- ability to double-indirect on *some* of them. Not all insns
- support all modes, either, but we rely on predicates and
- constraints to deal with that. */
-int
-m32c_legitimate_address_p (enum machine_mode mode, rtx x, int strict)
+/* The r8c/m32c family supports a wide range of non-orthogonal
+ addressing modes, including the ability to double-indirect on *some*
+ of them. Not all insns support all modes, either, but we rely on
+ predicates and constraints to deal with that. */
+#undef TARGET_LEGITIMATE_ADDRESS_P
+#define TARGET_LEGITIMATE_ADDRESS_P m32c_legitimate_address_p
+bool
+m32c_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
{
int mode_adjust;
if (CONSTANT_P (x))
@@ -3691,57 +3686,8 @@ m32c_expand_neg_mulpsi3 (rtx * operands)
emit_insn (gen_truncsipsi2 (operands[0], temp2));
}
-static rtx compare_op0, compare_op1;
-
-void
-m32c_pend_compare (rtx *operands)
-{
- compare_op0 = operands[0];
- compare_op1 = operands[1];
-}
-
-void
-m32c_unpend_compare (void)
-{
- switch (GET_MODE (compare_op0))
- {
- case QImode:
- emit_insn (gen_cmpqi_op (compare_op0, compare_op1));
- case HImode:
- emit_insn (gen_cmphi_op (compare_op0, compare_op1));
- case PSImode:
- emit_insn (gen_cmppsi_op (compare_op0, compare_op1));
- default:
- /* Just to silence the "missing case" warnings. */ ;
- }
-}
-
-void
-m32c_expand_scc (int code, rtx *operands)
-{
- enum machine_mode mode = TARGET_A16 ? QImode : HImode;
-
- emit_insn (gen_rtx_SET (mode,
- operands[0],
- gen_rtx_fmt_ee (code,
- mode,
- compare_op0,
- compare_op1)));
-}
-
/* Pattern Output Functions */
-/* Returns a (OP (reg:CC FLG_REGNO) (const_int 0)) from some other
- match_operand rtx's OP. */
-rtx
-m32c_cmp_flg_0 (rtx cmp)
-{
- return gen_rtx_fmt_ee (GET_CODE (cmp),
- GET_MODE (cmp),
- gen_rtx_REG (CCmode, FLG_REGNO),
- GEN_INT (0));
-}
-
int
m32c_expand_movcc (rtx *operands)
{
@@ -3753,22 +3699,17 @@ m32c_expand_movcc (rtx *operands)
if (GET_CODE (operands[2]) != CONST_INT
|| GET_CODE (operands[3]) != CONST_INT)
return 1;
- emit_insn (gen_cmpqi(XEXP (rel, 0), XEXP (rel, 1)));
if (GET_CODE (rel) == NE)
{
rtx tmp = operands[2];
operands[2] = operands[3];
operands[3] = tmp;
+ rel = gen_rtx_EQ (GET_MODE (rel), XEXP (rel, 0), XEXP (rel, 1));
}
- cmp = gen_rtx_fmt_ee (GET_CODE (rel),
- GET_MODE (rel),
- compare_op0,
- compare_op1);
-
emit_move_insn (operands[0],
gen_rtx_IF_THEN_ELSE (GET_MODE (operands[0]),
- cmp,
+ rel,
operands[2],
operands[3]));
return 0;
diff --git a/gcc/config/m32c/m32c.h b/gcc/config/m32c/m32c.h
index cb2b8bea1f0..5c3130534a4 100644
--- a/gcc/config/m32c/m32c.h
+++ b/gcc/config/m32c/m32c.h
@@ -578,10 +578,6 @@ typedef struct m32c_cumulative_args
#define REG_OK_STRICT_V 0
#endif
-#define GO_IF_LEGITIMATE_ADDRESS(MODE,X,LABEL) \
- if (m32c_legitimate_address_p (MODE, X, REG_OK_STRICT_V)) \
- goto LABEL;
-
#define REG_OK_FOR_BASE_P(X) m32c_reg_ok_for_base_p (X, REG_OK_STRICT_V)
#define REG_OK_FOR_INDEX_P(X) 0
diff --git a/gcc/config/m32c/m32c.md b/gcc/config/m32c/m32c.md
index 4bc4d05fbf1..da0f8dd23f9 100644
--- a/gcc/config/m32c/m32c.md
+++ b/gcc/config/m32c/m32c.md
@@ -60,10 +60,7 @@
(define_mode_iterator QHSI [QI HI (SI "TARGET_A24")])
(define_mode_attr bwl [(QI "b") (HI "w") (PSI "l") (SI "l")])
-(define_code_iterator any_cond [eq ne gt ge lt le gtu geu ltu leu])
(define_code_iterator eqne_cond [eq ne])
-(define_code_iterator gl_cond [gt ge lt le gtu geu ltu leu])
-
(define_insn "nop"
diff --git a/gcc/config/m32c/t-m32c b/gcc/config/m32c/t-m32c
index 33454fe3c3e..30b8f6f0b45 100644
--- a/gcc/config/m32c/t-m32c
+++ b/gcc/config/m32c/t-m32c
@@ -1,5 +1,5 @@
# Target Makefile Fragment for R8C/M16C/M32C
-# Copyright (C) 2005, 2007
+# Copyright (C) 2005, 2006, 2007, 2008, 2009
# Free Software Foundation, Inc.
# Contributed by Red Hat.
#
@@ -57,7 +57,7 @@ md : $(MD_FILES:%=$(srcdir)/config/m32c/%.md) $(srcdir)/config/m32c/t-m32c
done > md
m32c-pragma.o: $(srcdir)/config/m32c/m32c-pragma.c $(RTL_H) $(TREE_H) $(CONFIG_H) $(TM_H)
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
# We support four CPU series, but R8C and M16C share one multilib, and
# M32C and M32CM share another.
diff --git a/gcc/config/m32r/m32r-protos.h b/gcc/config/m32r/m32r-protos.h
index 33a9f9dd01f..04533b9b49e 100644
--- a/gcc/config/m32r/m32r-protos.h
+++ b/gcc/config/m32r/m32r-protos.h
@@ -38,6 +38,7 @@ extern enum m32r_function_type m32r_compute_function_type (tree);
extern int easy_di_const (rtx);
extern int easy_df_const (rtx);
extern rtx gen_compare (enum rtx_code, rtx, rtx, int);
+extern bool gen_cond_store (enum rtx_code, rtx, rtx, rtx);
extern rtx gen_split_move_double (rtx *);
extern int m32r_address_code (rtx);
extern void m32r_initialize_trampoline (rtx, rtx, rtx);
diff --git a/gcc/config/m32r/m32r.c b/gcc/config/m32r/m32r.c
index 656c0eae1be..3ee6b6bb5fc 100644
--- a/gcc/config/m32r/m32r.c
+++ b/gcc/config/m32r/m32r.c
@@ -1,6 +1,6 @@
/* Subroutines used for code generation on the Renesas M32R cpu.
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- 2005, 2007, 2008 Free Software Foundation, Inc.
+ 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
This file is part of GCC.
@@ -43,10 +43,6 @@
#include "target-def.h"
#include "tm-constrs.h"
-/* Save the operands last given to a compare for use when we
- generate a scc or bcc insn. */
-rtx m32r_compare_op0, m32r_compare_op1;
-
/* Array of valid operand punctuation characters. */
char m32r_punct_chars[256];
@@ -69,7 +65,7 @@ static bool m32r_handle_option (size_t, const char *, int);
static void init_reg_tables (void);
static void block_move_call (rtx, rtx, rtx);
static int m32r_is_insn (rtx);
-const struct attribute_spec m32r_attribute_table[];
+EXPORTED_CONST struct attribute_spec m32r_attribute_table[];
static rtx m32r_legitimize_address (rtx, rtx, enum machine_mode);
static tree m32r_handle_model_attribute (tree *, tree, tree, int, bool *);
static void m32r_output_function_prologue (FILE *, HOST_WIDE_INT);
@@ -492,7 +488,7 @@ m32r_init_expanders (void)
int
call_operand (rtx op, enum machine_mode mode)
{
- if (GET_CODE (op) != MEM)
+ if (!MEM_P (op))
return 0;
op = XEXP (op, 0);
return call_address_operand (op, mode);
@@ -567,7 +563,7 @@ addr32_operand (rtx op, enum machine_mode mode)
else if (GET_CODE (op) == CONST
&& GET_CODE (XEXP (op, 0)) == PLUS
&& GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF
- && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT
+ && CONST_INT_P (XEXP (XEXP (op, 0), 1))
&& ! flag_pic)
sym = XEXP (XEXP (op, 0), 0);
else
@@ -636,7 +632,7 @@ easy_df_const (rtx op)
int
memreg_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
- return GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) == REG;
+ return MEM_P (op) && REG_P (XEXP (op, 0));
}
/* Return nonzero if TYPE must be passed by indirect reference. */
@@ -738,7 +734,7 @@ gen_compare (enum rtx_code code, rtx x, rtx y, int need_compare)
code = EQ;
break;
case GT:
- if (GET_CODE (y) == CONST_INT)
+ if (CONST_INT_P (y))
tmp = gen_rtx_PLUS (SImode, y, const1_rtx);
else
emit_insn (gen_addsi3 (tmp, y, constm1_rtx));
@@ -778,7 +774,7 @@ gen_compare (enum rtx_code code, rtx x, rtx y, int need_compare)
code = EQ;
break;
case GTU:
- if (GET_CODE (y) == CONST_INT)
+ if (CONST_INT_P (y))
tmp = gen_rtx_PLUS (SImode, y, const1_rtx);
else
emit_insn (gen_addsi3 (tmp, y, constm1_rtx));
@@ -864,6 +860,151 @@ gen_compare (enum rtx_code code, rtx x, rtx y, int need_compare)
return gen_rtx_fmt_ee (branch_code, VOIDmode, cc_reg, CONST0_RTX (CCmode));
}
+
+bool
+gen_cond_store (enum rtx_code code, rtx op0, rtx op1, rtx op2)
+{
+ enum machine_mode mode = GET_MODE (op0);
+
+ gcc_assert (mode == SImode);
+ switch (code)
+ {
+ case EQ:
+ if (!register_operand (op1, mode))
+ op1 = force_reg (mode, op1);
+
+ if (TARGET_M32RX || TARGET_M32R2)
+ {
+ if (!reg_or_zero_operand (op2, mode))
+ op2 = force_reg (mode, op2);
+
+ emit_insn (gen_seq_insn_m32rx (op0, op1, op2));
+ return true;
+ }
+ if (CONST_INT_P (op2) && INTVAL (op2) == 0)
+ {
+ emit_insn (gen_seq_zero_insn (op0, op1));
+ return true;
+ }
+
+ if (!reg_or_eq_int16_operand (op2, mode))
+ op2 = force_reg (mode, op2);
+
+ emit_insn (gen_seq_insn (op0, op1, op2));
+ return true;
+
+ case NE:
+ if (!CONST_INT_P (op2)
+ || (INTVAL (op2) != 0 && satisfies_constraint_K (op2)))
+ {
+ rtx reg;
+
+ if (reload_completed || reload_in_progress)
+ return false;
+
+ reg = gen_reg_rtx (SImode);
+ emit_insn (gen_xorsi3 (reg, op1, op2));
+ op1 = reg;
+
+ if (!register_operand (op1, mode))
+ op1 = force_reg (mode, op1);
+
+ emit_insn (gen_sne_zero_insn (op0, op1));
+ return true;
+ }
+ return false;
+
+ case LT:
+ case GT:
+ if (code == GT)
+ {
+ rtx tmp = op2;
+ op2 = op1;
+ op1 = tmp;
+ code = LT;
+ }
+
+ if (!register_operand (op1, mode))
+ op1 = force_reg (mode, op1);
+
+ if (!reg_or_int16_operand (op2, mode))
+ op2 = force_reg (mode, op2);
+
+ emit_insn (gen_slt_insn (op0, op1, op2));
+ return true;
+
+ case LTU:
+ case GTU:
+ if (code == GTU)
+ {
+ rtx tmp = op2;
+ op2 = op1;
+ op1 = tmp;
+ code = LTU;
+ }
+
+ if (!register_operand (op1, mode))
+ op1 = force_reg (mode, op1);
+
+ if (!reg_or_int16_operand (op2, mode))
+ op2 = force_reg (mode, op2);
+
+ emit_insn (gen_sltu_insn (op0, op1, op2));
+ return true;
+
+ case GE:
+ case GEU:
+ if (!register_operand (op1, mode))
+ op1 = force_reg (mode, op1);
+
+ if (!reg_or_int16_operand (op2, mode))
+ op2 = force_reg (mode, op2);
+
+ if (code == GE)
+ emit_insn (gen_sge_insn (op0, op1, op2));
+ else
+ emit_insn (gen_sgeu_insn (op0, op1, op2));
+ return true;
+
+ case LE:
+ case LEU:
+ if (!register_operand (op1, mode))
+ op1 = force_reg (mode, op1);
+
+ if (CONST_INT_P (op2))
+ {
+ HOST_WIDE_INT value = INTVAL (op2);
+ if (value >= 2147483647)
+ {
+ emit_move_insn (op0, const1_rtx);
+ return true;
+ }
+
+ op2 = GEN_INT (value + 1);
+ if (value < -32768 || value >= 32767)
+ op2 = force_reg (mode, op2);
+
+ if (code == LEU)
+ emit_insn (gen_sltu_insn (op0, op1, op2));
+ else
+ emit_insn (gen_slt_insn (op0, op1, op2));
+ return true;
+ }
+
+ if (!register_operand (op2, mode))
+ op2 = force_reg (mode, op2);
+
+ if (code == LEU)
+ emit_insn (gen_sleu_insn (op0, op1, op2));
+ else
+ emit_insn (gen_sle_insn (op0, op1, op2));
+ return true;
+
+ default:
+ gcc_unreachable ();
+ }
+}
+
/* Split a 2 word move (DI or DF) into component parts. */
@@ -884,12 +1025,12 @@ gen_split_move_double (rtx operands[])
alter_subreg (&src);
start_sequence ();
- if (GET_CODE (dest) == REG)
+ if (REG_P (dest))
{
int dregno = REGNO (dest);
/* Reg = reg. */
- if (GET_CODE (src) == REG)
+ if (REG_P (src))
{
int sregno = REGNO (src);
@@ -908,7 +1049,7 @@ gen_split_move_double (rtx operands[])
}
/* Reg = constant. */
- else if (GET_CODE (src) == CONST_INT || GET_CODE (src) == CONST_DOUBLE)
+ else if (CONST_INT_P (src) || GET_CODE (src) == CONST_DOUBLE)
{
rtx words[2];
split_double (src, &words[0], &words[1]);
@@ -922,7 +1063,7 @@ gen_split_move_double (rtx operands[])
}
/* Reg = mem. */
- else if (GET_CODE (src) == MEM)
+ else if (MEM_P (src))
{
/* If the high-address word is used in the address, we must load it
last. Otherwise, load it first. */
@@ -966,7 +1107,7 @@ gen_split_move_double (rtx operands[])
st r1,r3; st r2,+r3; addi r3,-4
which saves 2 bytes and doesn't force longword alignment. */
- else if (GET_CODE (dest) == MEM && GET_CODE (src) == REG)
+ else if (MEM_P (dest) && REG_P (src))
{
emit_insn (gen_rtx_SET (VOIDmode,
adjust_address (dest, SImode, 0),
@@ -1513,9 +1654,9 @@ m32r_expand_epilogue (void)
/* If the last insn was a BARRIER, we don't have to write any code
because a jump (aka return) was put there. */
- if (insn && GET_CODE (insn) == NOTE)
+ if (insn && NOTE_P (insn))
insn = prev_nonnote_insn (insn);
- if (insn && GET_CODE (insn) == BARRIER)
+ if (insn && BARRIER_P (insn))
noepilogue = TRUE;
}
@@ -1637,7 +1778,7 @@ m32r_legitimate_pic_operand_p (rtx x)
&& GET_CODE (XEXP (x, 0)) == PLUS
&& (GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF
|| GET_CODE (XEXP (XEXP (x, 0), 0)) == LABEL_REF)
- && (GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT))
+ && (CONST_INT_P (XEXP (XEXP (x, 0), 1))))
return 0;
return 1;
@@ -1716,7 +1857,7 @@ m32r_legitimize_pic_address (rtx orig, rtx reg)
else
return orig;
- if (GET_CODE (offset) == CONST_INT)
+ if (CONST_INT_P (offset))
{
if (INT16_P (INTVAL (offset)))
return plus_constant (base, INTVAL (offset));
@@ -1784,14 +1925,14 @@ m32r_print_operand (FILE * file, rtx x, int code)
/* The 's' and 'p' codes are used by output_block_move() to
indicate post-increment 's'tores and 'p're-increment loads. */
case 's':
- if (GET_CODE (x) == REG)
+ if (REG_P (x))
fprintf (file, "@+%s", reg_names [REGNO (x)]);
else
output_operand_lossage ("invalid operand to %%s code");
return;
case 'p':
- if (GET_CODE (x) == REG)
+ if (REG_P (x))
fprintf (file, "@%s+", reg_names [REGNO (x)]);
else
output_operand_lossage ("invalid operand to %%p code");
@@ -1800,9 +1941,9 @@ m32r_print_operand (FILE * file, rtx x, int code)
case 'R' :
/* Write second word of DImode or DFmode reference,
register or memory. */
- if (GET_CODE (x) == REG)
+ if (REG_P (x))
fputs (reg_names[REGNO (x)+1], file);
- else if (GET_CODE (x) == MEM)
+ else if (MEM_P (x))
{
fprintf (file, "@(");
/* Handle possible auto-increment. Since it is pre-increment and
@@ -1822,7 +1963,7 @@ m32r_print_operand (FILE * file, rtx x, int code)
case 'H' : /* High word. */
case 'L' : /* Low word. */
- if (GET_CODE (x) == REG)
+ if (REG_P (x))
{
/* L = least significant word, H = most significant word. */
if ((WORDS_BIG_ENDIAN != 0) ^ (code == 'L'))
@@ -1830,7 +1971,7 @@ m32r_print_operand (FILE * file, rtx x, int code)
else
fputs (reg_names[REGNO (x)+1], file);
}
- else if (GET_CODE (x) == CONST_INT
+ else if (CONST_INT_P (x)
|| GET_CODE (x) == CONST_DOUBLE)
{
rtx first, second;
@@ -1904,7 +2045,7 @@ m32r_print_operand (FILE * file, rtx x, int code)
case 'U' :
/* ??? wip */
/* Output a load/store with update indicator if appropriate. */
- if (GET_CODE (x) == MEM)
+ if (MEM_P (x))
{
if (GET_CODE (XEXP (x, 0)) == PRE_INC
|| GET_CODE (XEXP (x, 0)) == PRE_DEC)
@@ -1916,7 +2057,7 @@ m32r_print_operand (FILE * file, rtx x, int code)
case 'N' :
/* Print a constant value negated. */
- if (GET_CODE (x) == CONST_INT)
+ if (CONST_INT_P (x))
output_addr_const (file, GEN_INT (- INTVAL (x)));
else
output_operand_lossage ("invalid operand to %%N code");
@@ -1924,7 +2065,7 @@ m32r_print_operand (FILE * file, rtx x, int code)
case 'X' :
/* Print a const_int in hex. Used in comments. */
- if (GET_CODE (x) == CONST_INT)
+ if (CONST_INT_P (x))
fprintf (file, HOST_WIDE_INT_PRINT_HEX, INTVAL (x));
return;
@@ -1951,21 +2092,21 @@ m32r_print_operand (FILE * file, rtx x, int code)
addr = XEXP (x, 0);
if (GET_CODE (addr) == PRE_INC)
{
- if (GET_CODE (XEXP (addr, 0)) != REG)
+ if (!REG_P (XEXP (addr, 0)))
fatal_insn ("pre-increment address is not a register", x);
fprintf (file, "@+%s", reg_names[REGNO (XEXP (addr, 0))]);
}
else if (GET_CODE (addr) == PRE_DEC)
{
- if (GET_CODE (XEXP (addr, 0)) != REG)
+ if (!REG_P (XEXP (addr, 0)))
fatal_insn ("pre-decrement address is not a register", x);
fprintf (file, "@-%s", reg_names[REGNO (XEXP (addr, 0))]);
}
else if (GET_CODE (addr) == POST_INC)
{
- if (GET_CODE (XEXP (addr, 0)) != REG)
+ if (!REG_P (XEXP (addr, 0)))
fatal_insn ("post-increment address is not a register", x);
fprintf (file, "@%s+", reg_names[REGNO (XEXP (addr, 0))]);
@@ -2015,13 +2156,13 @@ m32r_print_operand_address (FILE * file, rtx addr)
break;
case PLUS :
- if (GET_CODE (XEXP (addr, 0)) == CONST_INT)
+ if (CONST_INT_P (XEXP (addr, 0)))
offset = INTVAL (XEXP (addr, 0)), base = XEXP (addr, 1);
- else if (GET_CODE (XEXP (addr, 1)) == CONST_INT)
+ else if (CONST_INT_P (XEXP (addr, 1)))
offset = INTVAL (XEXP (addr, 1)), base = XEXP (addr, 0);
else
base = XEXP (addr, 0), index = XEXP (addr, 1);
- if (GET_CODE (base) == REG)
+ if (REG_P (base))
{
/* Print the offset first (if present) to conform to the manual. */
if (index == 0)
@@ -2031,7 +2172,7 @@ m32r_print_operand_address (FILE * file, rtx addr)
fputs (reg_names[REGNO (base)], file);
}
/* The chip doesn't support this, but left in for generality. */
- else if (GET_CODE (index) == REG)
+ else if (REG_P (index))
fprintf (file, "%s,%s",
reg_names[REGNO (base)], reg_names[REGNO (index)]);
/* Not sure this can happen, but leave in for now. */
@@ -2046,7 +2187,7 @@ m32r_print_operand_address (FILE * file, rtx addr)
}
else if (GET_CODE (base) == LO_SUM)
{
- gcc_assert (!index && GET_CODE (XEXP (base, 0)) == REG);
+ gcc_assert (!index && REG_P (XEXP (base, 0)));
if (small_data_operand (XEXP (base, 1), VOIDmode))
fputs ("sda(", file);
else
@@ -2060,7 +2201,7 @@ m32r_print_operand_address (FILE * file, rtx addr)
break;
case LO_SUM :
- if (GET_CODE (XEXP (addr, 0)) != REG)
+ if (!REG_P (XEXP (addr, 0)))
fatal_insn ("lo_sum not of register", addr);
if (small_data_operand (XEXP (addr, 1), VOIDmode))
fputs ("sda(", file);
@@ -2095,8 +2236,8 @@ int
zero_and_one (rtx operand1, rtx operand2)
{
return
- GET_CODE (operand1) == CONST_INT
- && GET_CODE (operand2) == CONST_INT
+ CONST_INT_P (operand1)
+ && CONST_INT_P (operand2)
&& ( ((INTVAL (operand1) == 0) && (INTVAL (operand2) == 1))
||((INTVAL (operand1) == 1) && (INTVAL (operand2) == 0)));
}
@@ -2116,7 +2257,7 @@ emit_cond_move (rtx * operands, rtx insn ATTRIBUTE_UNUSED)
buffer [0] = 0;
/* Destination must be a register. */
- gcc_assert (GET_CODE (operands [0]) == REG);
+ gcc_assert (REG_P (operands [0]));
gcc_assert (conditional_move_operand (operands [2], SImode));
gcc_assert (conditional_move_operand (operands [3], SImode));
@@ -2150,13 +2291,13 @@ m32r_not_same_reg (rtx a, rtx b)
while (GET_CODE (a) == SUBREG)
a = SUBREG_REG (a);
- if (GET_CODE (a) == REG)
+ if (REG_P (a))
reg_a = REGNO (a);
while (GET_CODE (b) == SUBREG)
b = SUBREG_REG (b);
- if (GET_CODE (b) == REG)
+ if (REG_P (b))
reg_b = REGNO (b);
return reg_a != reg_b;
@@ -2220,7 +2361,7 @@ m32r_expand_block_move (rtx operands[])
rtx orig_src = operands[1];
rtx bytes_rtx = operands[2];
rtx align_rtx = operands[3];
- int constp = GET_CODE (bytes_rtx) == CONST_INT;
+ int constp = CONST_INT_P (bytes_rtx);
HOST_WIDE_INT bytes = constp ? INTVAL (bytes_rtx) : 0;
int align = INTVAL (align_rtx);
int leftover;
@@ -2291,8 +2432,8 @@ m32r_expand_block_move (rtx operands[])
if (bytes > MAX_MOVE_BYTES)
{
- emit_insn (gen_cmpsi (src_reg, final_src));
- emit_jump_insn (gen_bne (label));
+ rtx test = gen_rtx_NE (VOIDmode, src_reg, final_src);
+ emit_jump_insn (gen_cbranchsi4 (test, src_reg, final_src, label));
}
}
diff --git a/gcc/config/m32r/m32r.h b/gcc/config/m32r/m32r.h
index 9bc0fa98a0a..61c322048d9 100644
--- a/gcc/config/m32r/m32r.h
+++ b/gcc/config/m32r/m32r.h
@@ -1059,7 +1059,7 @@ L2: .word STATIC
#define CONSTANT_ADDRESS_P(X) \
( GET_CODE (X) == LABEL_REF \
|| GET_CODE (X) == SYMBOL_REF \
- || GET_CODE (X) == CONST_INT \
+ || CONST_INT_P (X) \
|| (GET_CODE (X) == CONST \
&& ! (flag_pic && ! m32r_legitimate_pic_operand_p (X))))
@@ -1073,7 +1073,7 @@ L2: .word STATIC
(! (GET_CODE (X) == CONST \
&& GET_CODE (XEXP (X, 0)) == PLUS \
&& (GET_CODE (XEXP (XEXP (X, 0), 0)) == SYMBOL_REF || GET_CODE (XEXP (XEXP (X, 0), 0)) == LABEL_REF) \
- && GET_CODE (XEXP (XEXP (X, 0), 1)) == CONST_INT \
+ && CONST_INT_P (XEXP (XEXP (X, 0), 1)) \
&& (unsigned HOST_WIDE_INT) INTVAL (XEXP (XEXP (X, 0), 1)) > 32767))
/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
@@ -1120,7 +1120,7 @@ L2: .word STATIC
/* Local to this file. */
#define RTX_OK_FOR_OFFSET_P(X) \
- (GET_CODE (X) == CONST_INT && INT16_P (INTVAL (X)))
+ (CONST_INT_P (X) && INT16_P (INTVAL (X)))
/* Local to this file. */
#define LEGITIMATE_OFFSET_ADDRESS_P(MODE, X) \
@@ -1142,7 +1142,7 @@ L2: .word STATIC
#define LOAD_POSTINC_P(MODE, X) \
(((MODE) == SImode || (MODE) == SFmode) \
&& GET_CODE (X) == POST_INC \
- && GET_CODE (XEXP (X, 0)) == REG \
+ && REG_P (XEXP (X, 0)) \
&& RTX_OK_FOR_BASE_P (XEXP (X, 0)))
/* Local to this file. */
@@ -1150,7 +1150,7 @@ L2: .word STATIC
#define STORE_PREINC_PREDEC_P(MODE, X) \
(((MODE) == SImode || (MODE) == SFmode) \
&& (GET_CODE (X) == PRE_INC || GET_CODE (X) == PRE_DEC) \
- && GET_CODE (XEXP (X, 0)) == REG \
+ && REG_P (XEXP (X, 0)) \
&& RTX_OK_FOR_BASE_P (XEXP (X, 0)))
#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
@@ -1495,12 +1495,6 @@ extern char m32r_punct_chars[256];
/* A function address in a call instruction. */
#define FUNCTION_MODE SImode
-/* Define the information needed to generate branch and scc insns. This is
- stored from the compare operation. Note that we can't use "rtx" here
- since it hasn't been defined! */
-extern struct rtx_def * m32r_compare_op0;
-extern struct rtx_def * m32r_compare_op1;
-
/* M32R function types. */
enum m32r_function_type
{
diff --git a/gcc/config/m32r/m32r.md b/gcc/config/m32r/m32r.md
index d117e1e6928..ec0d61f294c 100644
--- a/gcc/config/m32r/m32r.md
+++ b/gcc/config/m32r/m32r.md
@@ -250,7 +250,7 @@
/* Everything except mem = const or mem = mem can be done easily.
Objects in the small data area are handled too. */
- if (GET_CODE (operands[0]) == MEM)
+ if (MEM_P (operands[0]))
operands[1] = force_reg (QImode, operands[1]);
}")
@@ -289,7 +289,7 @@
/* Everything except mem = const or mem = mem can be done easily. */
- if (GET_CODE (operands[0]) == MEM)
+ if (MEM_P (operands[0]))
operands[1] = force_reg (HImode, operands[1]);
}")
@@ -341,7 +341,7 @@
/* Everything except mem = const or mem = mem can be done easily. */
- if (GET_CODE (operands[0]) == MEM)
+ if (MEM_P (operands[0]))
operands[1] = force_reg (SImode, operands[1]);
/* Small Data Area reference? */
@@ -367,7 +367,7 @@
"register_operand (operands[0], SImode) || register_operand (operands[1], SImode)"
"*
{
- if (GET_CODE (operands[0]) == REG || GET_CODE (operands[1]) == SUBREG)
+ if (REG_P (operands[0]) || GET_CODE (operands[1]) == SUBREG)
{
switch (GET_CODE (operands[1]))
{
@@ -409,8 +409,8 @@
}
}
- else if (GET_CODE (operands[0]) == MEM
- && (GET_CODE (operands[1]) == REG || GET_CODE (operands[1]) == SUBREG))
+ else if (MEM_P (operands[0])
+ && (REG_P (operands[1]) || GET_CODE (operands[1]) == SUBREG))
{
if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
&& XEXP (XEXP (operands[0], 0), 0) == stack_pointer_rtx)
@@ -585,7 +585,7 @@
/* Everything except mem = const or mem = mem can be done easily. */
- if (GET_CODE (operands[0]) == MEM)
+ if (MEM_P (operands[0]))
operands[1] = force_reg (DImode, operands[1]);
}")
@@ -626,7 +626,7 @@
/* Everything except mem = const or mem = mem can be done easily. */
- if (GET_CODE (operands[0]) == MEM)
+ if (MEM_P (operands[0]))
operands[1] = force_reg (SFmode, operands[1]);
}")
@@ -678,7 +678,7 @@
/* Everything except mem = const or mem = mem can be done easily. */
- if (GET_CODE (operands[0]) == MEM)
+ if (MEM_P (operands[0]))
operands[1] = force_reg (DFmode, operands[1]);
}")
@@ -1036,7 +1036,7 @@
&& satisfies_constraint_I (operands[2]))
return \"#\";
- else if (GET_CODE (operands[2]) == CONST_INT)
+ else if (CONST_INT_P (operands[2]))
return \"and3 %0,%1,%#%X2\";
return \"and %0,%2\";
@@ -1067,7 +1067,7 @@
&& satisfies_constraint_I (operands[2]))
return \"#\";
- else if (GET_CODE (operands[2]) == CONST_INT)
+ else if (CONST_INT_P (operands[2]))
return \"or3 %0,%1,%#%X2\";
return \"or %0,%2\";
@@ -1098,7 +1098,7 @@
&& satisfies_constraint_I (operands[2]))
return \"#\";
- else if (GET_CODE (operands[2]) == CONST_INT)
+ else if (CONST_INT_P (operands[2]))
return \"xor3 %0,%1,%#%X2\";
return \"xor %0,%2\";
@@ -1180,18 +1180,6 @@
;; thus merge the compare and branch into one instruction, so they are
;; preferred.
-(define_expand "cmpsi"
- [(set (reg:CC 17)
- (compare:CC (match_operand:SI 0 "register_operand" "")
- (match_operand:SI 1 "reg_or_cmp_int16_operand" "")))]
- ""
- "
-{
- m32r_compare_op0 = operands[0];
- m32r_compare_op1 = operands[1];
- DONE;
-}")
-
(define_insn "cmp_eqsi_zero_insn"
[(set (reg:CC 17)
(eq:CC (match_operand:SI 0 "register_operand" "r,r")
@@ -1256,114 +1244,20 @@
;; These control RTL generation for conditional jump insns.
-(define_expand "beq"
- [(set (pc)
- (if_then_else (match_dup 1)
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- operands[1] = gen_compare (EQ, m32r_compare_op0, m32r_compare_op1, FALSE);
-}")
-
-(define_expand "bne"
- [(set (pc)
- (if_then_else (match_dup 1)
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- operands[1] = gen_compare (NE, m32r_compare_op0, m32r_compare_op1, FALSE);
-}")
-
-(define_expand "bgt"
- [(set (pc)
- (if_then_else (match_dup 1)
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- operands[1] = gen_compare (GT, m32r_compare_op0, m32r_compare_op1, FALSE);
-}")
-
-(define_expand "ble"
- [(set (pc)
- (if_then_else (match_dup 1)
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- operands[1] = gen_compare (LE, m32r_compare_op0, m32r_compare_op1, FALSE);
-}")
-
-(define_expand "bge"
- [(set (pc)
- (if_then_else (match_dup 1)
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- operands[1] = gen_compare (GE, m32r_compare_op0, m32r_compare_op1, FALSE);
-}")
-
-(define_expand "blt"
- [(set (pc)
- (if_then_else (match_dup 1)
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- operands[1] = gen_compare (LT, m32r_compare_op0, m32r_compare_op1, FALSE);
-}")
-
-(define_expand "bgtu"
- [(set (pc)
- (if_then_else (match_dup 1)
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- operands[1] = gen_compare (GTU, m32r_compare_op0, m32r_compare_op1, FALSE);
-}")
-
-(define_expand "bleu"
- [(set (pc)
- (if_then_else (match_dup 1)
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- operands[1] = gen_compare (LEU, m32r_compare_op0, m32r_compare_op1, FALSE);
-}")
-
-(define_expand "bgeu"
- [(set (pc)
- (if_then_else (match_dup 1)
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- operands[1] = gen_compare (GEU, m32r_compare_op0, m32r_compare_op1, FALSE);
-}")
-
-(define_expand "bltu"
+(define_expand "cbranchsi4"
+ ; the comparison is emitted by gen_compare if needed.
[(set (pc)
- (if_then_else (match_dup 1)
- (label_ref (match_operand 0 "" ""))
+ (if_then_else (match_operator 0 "ordered_comparison_operator"
+ [(match_operand:SI 1 "register_operand" "")
+ (match_operand:SI 2 "reg_or_cmp_int16_operand" "")])
+ (label_ref (match_operand 3 "" ""))
(pc)))]
""
"
{
- operands[1] = gen_compare (LTU, m32r_compare_op0, m32r_compare_op1, FALSE);
+ operands[0] = gen_compare (GET_CODE (operands[0]), operands[1], operands[2], FALSE);
+ operands[1] = XEXP (operands[0], 0);
+ operands[2] = XEXP (operands[0], 1);
}")
;; Now match both normal and inverted jump.
@@ -1597,40 +1491,21 @@
;; S<cc> operations to set a register to 1/0 based on a comparison
-(define_expand "seq"
- [(match_operand:SI 0 "register_operand" "")]
+(define_expand "cstoresi4"
+ [(match_operand:SI 0 "register_operand" "")
+ (match_operator:SI 1 "ordered_comparison_operator"
+ [(match_operand:SI 2 "register_operand" "")
+ (match_operand:SI 3 "reg_or_cmp_int16_operand" "")])]
""
"
{
- rtx op0 = operands[0];
- rtx op1 = m32r_compare_op0;
- rtx op2 = m32r_compare_op1;
- enum machine_mode mode = GET_MODE (op0);
-
- if (mode != SImode)
+ if (GET_MODE (operands[0]) != SImode)
FAIL;
- if (! register_operand (op1, mode))
- op1 = force_reg (mode, op1);
-
- if (TARGET_M32RX || TARGET_M32R2)
- {
- if (! reg_or_zero_operand (op2, mode))
- op2 = force_reg (mode, op2);
-
- emit_insn (gen_seq_insn_m32rx (op0, op1, op2));
- DONE;
- }
- if (GET_CODE (op2) == CONST_INT && INTVAL (op2) == 0)
- {
- emit_insn (gen_seq_zero_insn (op0, op1));
- DONE;
- }
-
- if (! reg_or_eq_int16_operand (op2, mode))
- op2 = force_reg (mode, op2);
+ if (!gen_cond_store (GET_CODE (operands[1]),
+ operands[0], operands[2], operands[3]))
+ FAIL;
- emit_insn (gen_seq_insn (op0, op1, op2));
DONE;
}")
@@ -1713,7 +1588,7 @@
rtx op3 = operands[3];
HOST_WIDE_INT value;
- if (GET_CODE (op2) == REG && GET_CODE (op3) == REG
+ if (REG_P (op2) && REG_P (op3)
&& REGNO (op2) == REGNO (op3))
{
op1 = operands[2];
@@ -1721,7 +1596,7 @@
}
start_sequence ();
- if (GET_CODE (op1) == REG && GET_CODE (op3) == REG
+ if (REG_P (op1) && REG_P (op3)
&& REGNO (op1) != REGNO (op3))
{
emit_move_insn (op3, op1);
@@ -1739,41 +1614,6 @@
end_sequence ();
}")
-(define_expand "sne"
- [(match_operand:SI 0 "register_operand" "")]
- ""
- "
-{
- rtx op0 = operands[0];
- rtx op1 = m32r_compare_op0;
- rtx op2 = m32r_compare_op1;
- enum machine_mode mode = GET_MODE (op0);
-
- if (mode != SImode)
- FAIL;
-
- if (GET_CODE (op2) != CONST_INT
- || (INTVAL (op2) != 0 && satisfies_constraint_K (op2)))
- {
- rtx reg;
-
- if (reload_completed || reload_in_progress)
- FAIL;
-
- reg = gen_reg_rtx (SImode);
- emit_insn (gen_xorsi3 (reg, op1, op2));
- op1 = reg;
-
- if (! register_operand (op1, mode))
- op1 = force_reg (mode, op1);
-
- emit_insn (gen_sne_zero_insn (op0, op1));
- DONE;
- }
- else
- FAIL;
-}")
-
(define_insn "sne_zero_insn"
[(set (match_operand:SI 0 "register_operand" "=r")
(ne:SI (match_operand:SI 1 "register_operand" "r")
@@ -1801,29 +1641,6 @@
(ne:SI (reg:CC 17) (const_int 0)))]
"")
-(define_expand "slt"
- [(match_operand:SI 0 "register_operand" "")]
- ""
- "
-{
- rtx op0 = operands[0];
- rtx op1 = m32r_compare_op0;
- rtx op2 = m32r_compare_op1;
- enum machine_mode mode = GET_MODE (op0);
-
- if (mode != SImode)
- FAIL;
-
- if (! register_operand (op1, mode))
- op1 = force_reg (mode, op1);
-
- if (! reg_or_int16_operand (op2, mode))
- op2 = force_reg (mode, op2);
-
- emit_insn (gen_slt_insn (op0, op1, op2));
- DONE;
-}")
-
(define_insn "slt_insn"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(lt:SI (match_operand:SI 1 "register_operand" "r,r")
@@ -1847,46 +1664,6 @@
(ne:SI (reg:CC 17) (const_int 0)))]
"")
-(define_expand "sle"
- [(match_operand:SI 0 "register_operand" "")]
- ""
- "
-{
- rtx op0 = operands[0];
- rtx op1 = m32r_compare_op0;
- rtx op2 = m32r_compare_op1;
- enum machine_mode mode = GET_MODE (op0);
-
- if (mode != SImode)
- FAIL;
-
- if (! register_operand (op1, mode))
- op1 = force_reg (mode, op1);
-
- if (GET_CODE (op2) == CONST_INT)
- {
- HOST_WIDE_INT value = INTVAL (op2);
- if (value >= 2147483647)
- {
- emit_move_insn (op0, const1_rtx);
- DONE;
- }
-
- op2 = GEN_INT (value+1);
- if (value < -32768 || value >= 32767)
- op2 = force_reg (mode, op2);
-
- emit_insn (gen_slt_insn (op0, op1, op2));
- DONE;
- }
-
- if (! register_operand (op2, mode))
- op2 = force_reg (mode, op2);
-
- emit_insn (gen_sle_insn (op0, op1, op2));
- DONE;
-}")
-
(define_insn "sle_insn"
[(set (match_operand:SI 0 "register_operand" "=r")
(le:SI (match_operand:SI 1 "register_operand" "r")
@@ -1933,52 +1710,6 @@
(neg:SI (match_dup 0)))]
"")
-(define_expand "sgt"
- [(match_operand:SI 0 "register_operand" "")]
- ""
- "
-{
- rtx op0 = operands[0];
- rtx op1 = m32r_compare_op0;
- rtx op2 = m32r_compare_op1;
- enum machine_mode mode = GET_MODE (op0);
-
- if (mode != SImode)
- FAIL;
-
- if (! register_operand (op1, mode))
- op1 = force_reg (mode, op1);
-
- if (! register_operand (op2, mode))
- op2 = force_reg (mode, op2);
-
- emit_insn (gen_slt_insn (op0, op2, op1));
- DONE;
-}")
-
-(define_expand "sge"
- [(match_operand:SI 0 "register_operand" "")]
- ""
- "
-{
- rtx op0 = operands[0];
- rtx op1 = m32r_compare_op0;
- rtx op2 = m32r_compare_op1;
- enum machine_mode mode = GET_MODE (op0);
-
- if (mode != SImode)
- FAIL;
-
- if (! register_operand (op1, mode))
- op1 = force_reg (mode, op1);
-
- if (! reg_or_int16_operand (op2, mode))
- op2 = force_reg (mode, op2);
-
- emit_insn (gen_sge_insn (op0, op1, op2));
- DONE;
-}")
-
(define_insn "sge_insn"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(ge:SI (match_operand:SI 1 "register_operand" "r,r")
@@ -2025,29 +1756,6 @@
(neg:SI (match_dup 0)))]
"")
-(define_expand "sltu"
- [(match_operand:SI 0 "register_operand" "")]
- ""
- "
-{
- rtx op0 = operands[0];
- rtx op1 = m32r_compare_op0;
- rtx op2 = m32r_compare_op1;
- enum machine_mode mode = GET_MODE (op0);
-
- if (mode != SImode)
- FAIL;
-
- if (! register_operand (op1, mode))
- op1 = force_reg (mode, op1);
-
- if (! reg_or_int16_operand (op2, mode))
- op2 = force_reg (mode, op2);
-
- emit_insn (gen_sltu_insn (op0, op1, op2));
- DONE;
-}")
-
(define_insn "sltu_insn"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(ltu:SI (match_operand:SI 1 "register_operand" "r,r")
@@ -2071,43 +1779,6 @@
(ne:SI (reg:CC 17) (const_int 0)))]
"")
-(define_expand "sleu"
- [(match_operand:SI 0 "register_operand" "")]
- ""
- "
-{
- rtx op0 = operands[0];
- rtx op1 = m32r_compare_op0;
- rtx op2 = m32r_compare_op1;
- enum machine_mode mode = GET_MODE (op0);
-
- if (mode != SImode)
- FAIL;
-
- if (GET_CODE (op2) == CONST_INT)
- {
- HOST_WIDE_INT value = INTVAL (op2);
- if (value >= 2147483647)
- {
- emit_move_insn (op0, const1_rtx);
- DONE;
- }
-
- op2 = GEN_INT (value+1);
- if (value < 0 || value >= 32767)
- op2 = force_reg (mode, op2);
-
- emit_insn (gen_sltu_insn (op0, op1, op2));
- DONE;
- }
-
- if (! register_operand (op2, mode))
- op2 = force_reg (mode, op2);
-
- emit_insn (gen_sleu_insn (op0, op1, op2));
- DONE;
-}")
-
(define_insn "sleu_insn"
[(set (match_operand:SI 0 "register_operand" "=r")
(leu:SI (match_operand:SI 1 "register_operand" "r")
@@ -2154,52 +1825,6 @@
(neg:SI (match_dup 0)))]
"")
-(define_expand "sgtu"
- [(match_operand:SI 0 "register_operand" "")]
- ""
- "
-{
- rtx op0 = operands[0];
- rtx op1 = m32r_compare_op0;
- rtx op2 = m32r_compare_op1;
- enum machine_mode mode = GET_MODE (op0);
-
- if (mode != SImode)
- FAIL;
-
- if (! register_operand (op1, mode))
- op1 = force_reg (mode, op1);
-
- if (! register_operand (op2, mode))
- op2 = force_reg (mode, op2);
-
- emit_insn (gen_sltu_insn (op0, op2, op1));
- DONE;
-}")
-
-(define_expand "sgeu"
- [(match_operand:SI 0 "register_operand" "")]
- ""
- "
-{
- rtx op0 = operands[0];
- rtx op1 = m32r_compare_op0;
- rtx op2 = m32r_compare_op1;
- enum machine_mode mode = GET_MODE (op0);
-
- if (mode != SImode)
- FAIL;
-
- if (! register_operand (op1, mode))
- op1 = force_reg (mode, op1);
-
- if (! reg_or_int16_operand (op2, mode))
- op2 = force_reg (mode, op2);
-
- emit_insn (gen_sgeu_insn (op0, op1, op2));
- DONE;
-}")
-
(define_insn "sgeu_insn"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(geu:SI (match_operand:SI 1 "register_operand" "r,r")
@@ -2546,8 +2171,8 @@
FAIL;
/* Generate the comparison that will set the carry flag. */
- operands[1] = gen_compare (GET_CODE (operands[1]), m32r_compare_op0,
- m32r_compare_op1, TRUE);
+ operands[1] = gen_compare (GET_CODE (operands[1]), XEXP (operands[1], 0),
+ XEXP (operands[1], 1), TRUE);
/* See other movsicc pattern below for reason why. */
emit_insn (gen_blockage ());
diff --git a/gcc/config/m32r/predicates.md b/gcc/config/m32r/predicates.md
index 5873b6d2ff6..4b3c5fea1e1 100644
--- a/gcc/config/m32r/predicates.md
+++ b/gcc/config/m32r/predicates.md
@@ -22,10 +22,10 @@
(define_predicate "reg_or_zero_operand"
(match_code "reg,subreg,const_int")
{
- if (GET_CODE (op) == REG || GET_CODE (op) == SUBREG)
+ if (REG_P (op) || GET_CODE (op) == SUBREG)
return register_operand (op, mode);
- if (GET_CODE (op) != CONST_INT)
+ if (!CONST_INT_P (op))
return 0;
return INTVAL (op) == 0;
@@ -75,11 +75,11 @@
return FALSE;
x = XEXP (op, 0);
- if (GET_CODE (x) != REG || REGNO (x) != CARRY_REGNUM)
+ if (!REG_P (x) || REGNO (x) != CARRY_REGNUM)
return FALSE;
x = XEXP (op, 1);
- if (GET_CODE (x) != CONST_INT || INTVAL (x) != 0)
+ if (!CONST_INT_P (x) || INTVAL (x) != 0)
return FALSE;
return TRUE;
@@ -119,7 +119,7 @@
case SUBREG :
/* (subreg (mem ...) ...) can occur here if the inner part was once a
pseudo-reg and is now a stack slot. */
- if (GET_CODE (SUBREG_REG (op)) == MEM)
+ if (MEM_P (SUBREG_REG (op)))
return address_operand (XEXP (SUBREG_REG (op), 0), mode);
else
return register_operand (op, mode);
@@ -175,7 +175,7 @@
case SUBREG :
/* (subreg (mem ...) ...) can occur here if the inner part was once a
pseudo-reg and is now a stack slot. */
- if (GET_CODE (SUBREG_REG (op)) == MEM)
+ if (MEM_P (SUBREG_REG (op)))
return address_operand (XEXP (SUBREG_REG (op), 0), mode);
else
return register_operand (op, mode);
@@ -205,7 +205,7 @@
case SUBREG :
/* (subreg (mem ...) ...) can occur here if the inner part was once a
pseudo-reg and is now a stack slot. */
- if (GET_CODE (SUBREG_REG (op)) == MEM)
+ if (MEM_P (SUBREG_REG (op)))
return move_double_src_operand (SUBREG_REG (op), mode);
else
return register_operand (op, mode);
@@ -226,7 +226,7 @@
(define_predicate "two_insn_const_operand"
(match_code "const_int")
{
- if (GET_CODE (op) != CONST_INT)
+ if (!CONST_INT_P (op))
return 0;
if (satisfies_constraint_J (op)
|| satisfies_constraint_M (op)
@@ -257,7 +257,7 @@
(define_predicate "int8_operand"
(match_code "const_int")
{
- if (GET_CODE (op) != CONST_INT)
+ if (!CONST_INT_P (op))
return 0;
return satisfies_constraint_I (op);
})
@@ -267,7 +267,7 @@
(define_predicate "uint16_operand"
(match_code "const_int")
{
- if (GET_CODE (op) != CONST_INT)
+ if (!CONST_INT_P (op))
return 0;
return satisfies_constraint_K (op);
})
@@ -277,9 +277,9 @@
(define_predicate "reg_or_int16_operand"
(match_code "reg,subreg,const_int")
{
- if (GET_CODE (op) == REG || GET_CODE (op) == SUBREG)
+ if (REG_P (op) || GET_CODE (op) == SUBREG)
return register_operand (op, mode);
- if (GET_CODE (op) != CONST_INT)
+ if (!CONST_INT_P (op))
return 0;
return satisfies_constraint_J (op);
})
@@ -289,9 +289,9 @@
(define_predicate "reg_or_uint16_operand"
(match_code "reg,subreg,const_int")
{
- if (GET_CODE (op) == REG || GET_CODE (op) == SUBREG)
+ if (REG_P (op) || GET_CODE (op) == SUBREG)
return register_operand (op, mode);
- if (GET_CODE (op) != CONST_INT)
+ if (!CONST_INT_P (op))
return 0;
return satisfies_constraint_K (op);
})
@@ -302,9 +302,9 @@
(define_predicate "reg_or_cmp_int16_operand"
(match_code "reg,subreg,const_int")
{
- if (GET_CODE (op) == REG || GET_CODE (op) == SUBREG)
+ if (REG_P (op) || GET_CODE (op) == SUBREG)
return register_operand (op, mode);
- if (GET_CODE (op) != CONST_INT)
+ if (!CONST_INT_P (op))
return 0;
return satisfies_constraint_P (op);
})
@@ -319,10 +319,10 @@
{
HOST_WIDE_INT value;
- if (GET_CODE (op) == REG || GET_CODE (op) == SUBREG)
+ if (REG_P (op) || GET_CODE (op) == SUBREG)
return register_operand (op, mode);
- if (GET_CODE (op) != CONST_INT)
+ if (!CONST_INT_P (op))
return 0;
value = INTVAL (op);
@@ -335,7 +335,7 @@
(define_predicate "cmp_int16_operand"
(match_code "const_int")
{
- if (GET_CODE (op) != CONST_INT)
+ if (!CONST_INT_P (op))
return 0;
return satisfies_constraint_P (op);
})
@@ -384,7 +384,7 @@
(define_predicate "small_insn_p"
(match_code "insn,call_insn,jump_insn")
{
- if (GET_CODE (op) == CONST_INT && INTVAL (op) == 0)
+ if (CONST_INT_P (op) && INTVAL (op) == 0)
return 1;
if (! INSN_P (op))
@@ -399,7 +399,7 @@
(define_predicate "m32r_block_immediate_operand"
(match_code "const_int")
{
- if (GET_CODE (op) != CONST_INT
+ if (!CONST_INT_P (op)
|| INTVAL (op) > MAX_MOVE_BYTES
|| INTVAL (op) <= 0)
return 0;
diff --git a/gcc/config/m68hc11/m68hc11-protos.h b/gcc/config/m68hc11/m68hc11-protos.h
index 5412e1d3eea..2f138c724ea 100644
--- a/gcc/config/m68hc11/m68hc11-protos.h
+++ b/gcc/config/m68hc11/m68hc11-protos.h
@@ -48,8 +48,6 @@ extern void m68hc11_initialize_trampoline (rtx, rtx, rtx);
extern rtx m68hc11_expand_compare_and_branch (enum rtx_code, rtx, rtx, rtx);
extern enum reg_class preferred_reload_class (rtx, enum reg_class);
-extern int m68hc11_go_if_legitimate_address (rtx, enum machine_mode, int);
-
extern void m68hc11_notice_update_cc (rtx, rtx);
extern void m68hc11_notice_keep_cc (rtx);
diff --git a/gcc/config/m68hc11/m68hc11.c b/gcc/config/m68hc11/m68hc11.c
index 10bc7a0e66e..a8a8db8ac3e 100644
--- a/gcc/config/m68hc11/m68hc11.c
+++ b/gcc/config/m68hc11/m68hc11.c
@@ -64,7 +64,8 @@ static void emit_move_after_reload (rtx, rtx, rtx);
static rtx simplify_logical (enum machine_mode, int, rtx, rtx *);
static void m68hc11_emit_logical (enum machine_mode, int, rtx *);
static void m68hc11_reorg (void);
-static int go_if_legitimate_address_internal (rtx, enum machine_mode, int);
+static bool m68hc11_legitimate_address_p_1 (enum machine_mode, rtx, bool);
+static bool m68hc11_legitimate_address_p (enum machine_mode, rtx, bool);
static rtx m68hc11_expand_compare (enum rtx_code, rtx, rtx);
static int must_parenthesize (rtx);
static int m68hc11_address_cost (rtx, bool);
@@ -72,7 +73,7 @@ static int m68hc11_shift_cost (enum machine_mode, rtx, int);
static int m68hc11_rtx_costs_1 (rtx, enum rtx_code, enum rtx_code);
static bool m68hc11_rtx_costs (rtx, int, int, int *, bool);
static tree m68hc11_handle_fntype_attribute (tree *, tree, tree, int, bool *);
-const struct attribute_spec m68hc11_attribute_table[];
+EXPORTED_CONST struct attribute_spec m68hc11_attribute_table[];
void create_regs_rtx (void);
@@ -141,10 +142,6 @@ int m68hc11_sp_correction;
int m68hc11_addr_mode;
int m68hc11_mov_addr_mode;
-
-/* Comparison operands saved by the "tstxx" and "cmpxx" expand patterns. */
-rtx m68hc11_compare_op0;
-rtx m68hc11_compare_op1;
const struct processor_costs *m68hc11_cost;
@@ -264,6 +261,9 @@ static const struct processor_costs m6812_cost = {
#undef TARGET_STRIP_NAME_ENCODING
#define TARGET_STRIP_NAME_ENCODING m68hc11_strip_name_encoding
+#undef TARGET_LEGITIMATE_ADDRESS_P
+#define TARGET_LEGITIMATE_ADDRESS_P m68hc11_legitimate_address_p
+
struct gcc_target targetm = TARGET_INITIALIZER;
int
@@ -725,9 +725,9 @@ m68hc11_register_indirect_p (rtx operand, enum machine_mode mode)
return m68hc11_valid_addressing_p (operand, mode, addr_mode);
}
-static int
-go_if_legitimate_address_internal (rtx operand, enum machine_mode mode,
- int strict)
+static bool
+m68hc11_legitimate_address_p_1 (enum machine_mode mode, rtx operand,
+ bool strict)
{
int addr_mode;
@@ -756,9 +756,9 @@ go_if_legitimate_address_internal (rtx operand, enum machine_mode mode,
return 0;
}
-int
-m68hc11_go_if_legitimate_address (rtx operand, enum machine_mode mode,
- int strict)
+bool
+m68hc11_legitimate_address_p (enum machine_mode mode, rtx operand,
+ bool strict)
{
int result;
@@ -769,7 +769,7 @@ m68hc11_go_if_legitimate_address (rtx operand, enum machine_mode mode,
debug_rtx (operand);
}
- result = go_if_legitimate_address_internal (operand, mode, strict);
+ result = m68hc11_legitimate_address_p_1 (mode, operand, strict);
if (debug_m6811)
{
@@ -3877,7 +3877,11 @@ m68hc11_notice_update_cc (rtx exp, rtx insn ATTRIBUTE_UNUSED)
{
cc_status.flags = 0;
cc_status.value1 = XEXP (exp, 0);
- cc_status.value2 = XEXP (exp, 1);
+ if (GET_CODE (XEXP (exp, 1)) == COMPARE
+ && XEXP (XEXP (exp, 1), 1) == CONST0_RTX (GET_MODE (XEXP (XEXP (exp, 1), 0))))
+ cc_status.value2 = XEXP (XEXP (exp, 1), 0);
+ else
+ cc_status.value2 = XEXP (exp, 1);
}
else
{
@@ -5355,6 +5359,7 @@ m68hc11_rtx_costs_1 (rtx x, enum rtx_code code,
case COMPARE:
case ABS:
case ZERO_EXTEND:
+ case ZERO_EXTRACT:
total = extra_cost + rtx_cost (XEXP (x, 0), code, !optimize_size);
if (mode == QImode)
{
@@ -5405,6 +5410,10 @@ m68hc11_rtx_costs (rtx x, int code, int outer_code, int *total,
*total = 0;
return true;
+ case ZERO_EXTRACT:
+ if (outer_code != COMPARE)
+ return false;
+
case ROTATE:
case ROTATERT:
case ASHIFT:
diff --git a/gcc/config/m68hc11/m68hc11.h b/gcc/config/m68hc11/m68hc11.h
index 35176592601..e795485f9c1 100644
--- a/gcc/config/m68hc11/m68hc11.h
+++ b/gcc/config/m68hc11/m68hc11.h
@@ -1132,7 +1132,7 @@ extern unsigned char m68hc11_reg_valid_for_index[FIRST_PSEUDO_REGISTER];
/* Maximum number of registers that can appear in a valid memory address */
#define MAX_REGS_PER_ADDRESS 2
-/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression that is a
+/* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression that is a
valid memory address for an instruction. The MODE argument is the
machine mode for the MEM expression that wants to use this address. */
@@ -1169,19 +1169,6 @@ extern unsigned char m68hc11_reg_valid_for_index[FIRST_PSEUDO_REGISTER];
(((GET_CODE (X) == PRE_DEC) || (GET_CODE (X) == POST_INC)) \
&& SP_REG_P (XEXP (X, 0)))
-/* Go to ADDR if X is a valid address. */
-#ifndef REG_OK_STRICT
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
-{ \
- if (m68hc11_go_if_legitimate_address ((X), (MODE), 0)) goto ADDR; \
-}
-#else
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
-{ \
- if (m68hc11_go_if_legitimate_address ((X), (MODE), 1)) goto ADDR; \
-}
-#endif
-
/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx and check its
validity for a certain class. We have two alternate definitions for each
of them. The usual definition accepts all pseudo regs; the other rejects
@@ -1498,8 +1485,6 @@ extern int current_function_interrupt;
extern int current_function_trap;
extern int current_function_far;
-extern GTY(()) rtx m68hc11_compare_op0;
-extern GTY(()) rtx m68hc11_compare_op1;
extern GTY(()) rtx m68hc11_soft_tmp_reg;
extern GTY(()) rtx ix_reg;
extern GTY(()) rtx iy_reg;
diff --git a/gcc/config/m68hc11/m68hc11.md b/gcc/config/m68hc11/m68hc11.md
index 0d40278cebb..f4ff3ebbb4c 100644
--- a/gcc/config/m68hc11/m68hc11.md
+++ b/gcc/config/m68hc11/m68hc11.md
@@ -162,31 +162,11 @@
;; An offsetable memory operand should be ok. The 'tst_operand' and
;; 'cmp_operand' predicates take care of this rule.
;;
-(define_expand "tstsi"
- [(set (cc0)
- (match_operand:SI 0 "tst_operand" ""))]
- ""
- "
-{
- m68hc11_compare_op0 = operands[0];
- m68hc11_compare_op1 = const0_rtx;
- DONE;
-}")
-
-(define_expand "tsthi"
- [(set (cc0)
- (match_operand:HI 0 "tst_operand" ""))]
- ""
- "
-{
- m68hc11_compare_op0 = operands[0];
- m68hc11_compare_op1 = const0_rtx;
- DONE;
-}")
(define_insn "tsthi_1"
[(set (cc0)
- (match_operand:HI 0 "tst_operand" "dx,*y"))]
+ (compare (match_operand:HI 0 "tst_operand" "dx,*y")
+ (const_int 0)))]
""
"*
{
@@ -196,34 +176,26 @@
return \"cp%0\\t#0\";
}")
-(define_expand "tstqi"
- [(set (cc0)
- (match_operand:QI 0 "tst_operand" ""))]
- ""
- "
-{
- m68hc11_compare_op0 = operands[0];
- m68hc11_compare_op1 = const0_rtx;
- DONE;
-}")
-
;;
;; Split pattern for (tst:QI) on an address register.
;;
(define_split
[(set (cc0)
- (match_operand:QI 0 "hard_addr_reg_operand" ""))]
+ (compare (match_operand:QI 0 "hard_addr_reg_operand" "")
+ (const_int 0)))]
"z_replacement_completed == 2 && GET_MODE (operands[0]) == QImode"
[(parallel [(set (reg:HI D_REGNUM) (match_dup 1))
(set (match_dup 1) (reg:HI D_REGNUM))])
- (set (cc0) (reg:QI D_REGNUM))
+ (set (cc0) (compare (reg:QI D_REGNUM)
+ (const_int 0)))
(parallel [(set (reg:HI D_REGNUM) (match_dup 1))
(set (match_dup 1) (reg:HI D_REGNUM))])]
"operands[1] = gen_rtx_REG (HImode, REGNO (operands[0]));")
(define_insn "tstqi_1"
[(set (cc0)
- (match_operand:QI 0 "tst_operand" "m,d,*A,!u"))]
+ (compare (match_operand:QI 0 "tst_operand" "m,d,*A,!u")
+ (const_int 0)))]
""
"*
{
@@ -252,8 +224,8 @@
;; after Z register replacement.
;;
(define_insn_and_split "tstqi_z_used"
- [(set (cc0)
- (match_operand:QI 0 "tst_operand" "m"))
+ [(set (cc0) (compare (match_operand:QI 0 "tst_operand" "m")
+ (const_int 0)))
(use (match_operand:HI 1 "hard_reg_operand" "dxy"))
(use (reg:HI SOFT_Z_REGNUM))]
""
@@ -261,7 +233,8 @@
"z_replacement_completed == 2"
[(set (mem:HI (pre_dec:HI (reg:HI SP_REGNUM))) (match_dup 1))
(set (match_dup 1) (match_dup 2))
- (set (cc0) (match_dup 0))
+ (set (cc0) (compare (match_dup 0)
+ (const_int 0)))
(set (match_dup 1) (mem:HI (post_inc:HI (reg:HI SP_REGNUM))))]
"operands[2] = gen_rtx_REG (HImode, SOFT_Z_REGNUM);")
@@ -270,21 +243,6 @@
;;- Compare
;;--------------------------------------------------------------------
-(define_expand "cmpsi"
- [(set (cc0)
- (compare (match_operand:SI 0 "tst_operand" "")
- (match_operand:SI 1 "cmp_operand" "")))]
- ""
- "
-{
- if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
- operands[0] = force_reg (SImode, operands[0]);
-
- m68hc11_compare_op0 = operands[0];
- m68hc11_compare_op1 = operands[1];
- DONE;
-}")
-
;;
;; Comparison of a hard register with another one is provided because
;; it helps GCC to avoid to spill a pseudo hard register.
@@ -316,21 +274,6 @@
(compare (match_dup 0) (mem:HI (post_inc:HI (reg:HI SP_REGNUM)))))]
"")
-(define_expand "cmphi"
- [(set (cc0)
- (compare (match_operand:HI 0 "tst_operand" "")
- (match_operand:HI 1 "cmp_operand" "")))]
- ""
- "
-{
- if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
- operands[0] = force_reg (HImode, operands[0]);
-
- m68hc11_compare_op0 = operands[0];
- m68hc11_compare_op1 = operands[1];
- DONE;
-}")
-
(define_insn "cmphi_1_hc12"
[(set (cc0)
(compare (match_operand:HI 0 "tst_operand"
@@ -419,25 +362,11 @@
operands[3] = gen_rtx_REG (HImode, SOFT_TMP_REGNUM);
operands[4] = gen_rtx_REG (HImode, REGNO (operands[1]));")
-(define_expand "cmpqi"
- [(set (cc0)
- (compare (match_operand:QI 0 "tst_operand" "")
- (match_operand:QI 1 "cmp_operand" "")))]
- ""
- "
-{
- if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
- operands[0] = force_reg (QImode, operands[0]);
-
- m68hc11_compare_op0 = operands[0];
- m68hc11_compare_op1 = operands[1];
- DONE;
-}")
-
(define_insn "bitcmpqi"
[(set (cc0)
- (and:QI (match_operand:QI 0 "tst_operand" "d,d,d,m,!u")
- (match_operand:QI 1 "cmp_operand" "im,*B,u,d,d")))]
+ (compare (and:QI (match_operand:QI 0 "tst_operand" "d,d,d,m,!u")
+ (match_operand:QI 1 "cmp_operand" "im,*B,u,d,d"))
+ (const_int 0)))]
""
"@
bitb\\t%b1
@@ -448,8 +377,9 @@
(define_split /* "bitcmpqi" */
[(set (cc0)
- (and:QI (match_operand:QI 0 "tst_operand" "")
- (match_operand:QI 1 "hard_addr_reg_operand" "")))]
+ (compare (and:QI (match_operand:QI 0 "tst_operand" "")
+ (match_operand:QI 1 "hard_addr_reg_operand" ""))
+ (const_int 0)))]
"z_replacement_completed == 2"
[(set (match_dup 3) (match_dup 2))
(set (cc0) (and:QI (match_dup 0) (match_dup 4)))]
@@ -459,8 +389,9 @@
(define_insn_and_split "bitcmpqi_z_used"
[(set (cc0)
- (and:QI (match_operand:QI 0 "tst_operand" "d,m")
- (match_operand:QI 1 "cmp_operand" "m,d")))
+ (compare (and:QI (match_operand:QI 0 "tst_operand" "d,m")
+ (match_operand:QI 1 "cmp_operand" "m,d"))
+ (const_int 0)))
(use (match_operand:HI 2 "hard_reg_operand" "xy,xy"))
(use (reg:HI SOFT_Z_REGNUM))]
""
@@ -474,8 +405,9 @@
(define_insn "bitcmphi"
[(set (cc0)
- (and:HI (match_operand:HI 0 "tst_operand" "d")
- (match_operand:HI 1 "const_int_operand" "i")))]
+ (compare (and:HI (match_operand:HI 0 "tst_operand" "d")
+ (match_operand:HI 1 "const_int_operand" "i"))
+ (const_int 0)))]
"(INTVAL (operands[1]) & 0x0ff) == 0
|| (INTVAL (operands[1]) & 0x0ff00) == 0"
"*
@@ -488,9 +420,10 @@
(define_insn "bitcmpqi_12"
[(set (cc0)
- (zero_extract (match_operand:HI 0 "tst_operand" "d")
- (match_operand:HI 1 "const_int_operand" "i")
- (match_operand:HI 2 "const_int_operand" "i")))]
+ (compare (zero_extract:HI (match_operand:HI 0 "tst_operand" "d")
+ (match_operand:HI 1 "const_int_operand" "i")
+ (match_operand:HI 2 "const_int_operand" "i"))
+ (const_int 0)))]
"(unsigned) (INTVAL (operands[2]) + INTVAL (operands[1])) <= 8
|| (((unsigned) (INTVAL (operands[2]) + INTVAL (operands[1])) <= 16)
&& (unsigned) INTVAL (operands[2]) >= 8)"
@@ -6134,155 +6067,66 @@
""
"bra\\t%l0")
-(define_expand "beq"
- [(set (pc)
- (if_then_else (eq (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- m68hc11_expand_compare_and_branch (EQ, m68hc11_compare_op0,
- m68hc11_compare_op1,
- operands[0]);
- DONE;
-}")
-
-(define_expand "bne"
- [(set (pc)
- (if_then_else (ne (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- m68hc11_expand_compare_and_branch (NE, m68hc11_compare_op0,
- m68hc11_compare_op1,
- operands[0]);
- DONE;
-}")
-
-(define_expand "bgt"
- [(set (pc)
- (if_then_else (gt (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
+(define_expand "cbranchsi4"
+ [(set (cc0)
+ (compare (match_operand:SI 1 "tst_operand" "")
+ (match_operand:SI 2 "cmp_operand" "")))
+ (set (pc)
+ (if_then_else (match_operator 0 "ordered_comparison_operator"
+ [(cc0) (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
(pc)))]
""
"
{
- m68hc11_expand_compare_and_branch (GT, m68hc11_compare_op0,
- m68hc11_compare_op1,
- operands[0]);
- DONE;
-}")
+ if (GET_CODE (operands[1]) == MEM && GET_CODE (operands[2]) == MEM)
+ operands[1] = force_reg (SImode, operands[1]);
-(define_expand "bgtu"
- [(set (pc)
- (if_then_else (gtu (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- m68hc11_expand_compare_and_branch (GTU, m68hc11_compare_op0,
- m68hc11_compare_op1,
- operands[0]);
+ m68hc11_expand_compare_and_branch (GET_CODE (operands[0]), operands[1],
+ operands[2], operands[3]);
DONE;
}")
-(define_expand "blt"
- [(set (pc)
- (if_then_else (lt (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- m68hc11_expand_compare_and_branch (LT, m68hc11_compare_op0,
- m68hc11_compare_op1,
- operands[0]);
- DONE;
-}")
-
-(define_expand "bltu"
- [(set (pc)
- (if_then_else (ltu (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
+(define_expand "cbranchhi4"
+ [(set (cc0)
+ (compare (match_operand:HI 1 "tst_operand" "")
+ (match_operand:HI 2 "cmp_operand" "")))
+ (set (pc)
+ (if_then_else (match_operator 0 "ordered_comparison_operator"
+ [(cc0) (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
(pc)))]
""
"
{
- m68hc11_expand_compare_and_branch (LTU, m68hc11_compare_op0,
- m68hc11_compare_op1,
- operands[0]);
- DONE;
-}")
+ if (GET_CODE (operands[1]) == MEM && GET_CODE (operands[2]) == MEM)
+ operands[1] = force_reg (HImode, operands[1]);
-(define_expand "bge"
- [(set (pc)
- (if_then_else (ge (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- m68hc11_expand_compare_and_branch (GE, m68hc11_compare_op0,
- m68hc11_compare_op1,
- operands[0]);
+ m68hc11_expand_compare_and_branch (GET_CODE (operands[0]), operands[1],
+ operands[2], operands[3]);
DONE;
}")
-(define_expand "bgeu"
- [(set (pc)
- (if_then_else (geu (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
+(define_expand "cbranchqi4"
+ [(set (cc0)
+ (compare (match_operand:QI 1 "tst_operand" "")
+ (match_operand:QI 2 "cmp_operand" "")))
+ (set (pc)
+ (if_then_else (match_operator 0 "ordered_comparison_operator"
+ [(cc0) (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
(pc)))]
""
"
{
- m68hc11_expand_compare_and_branch (GEU, m68hc11_compare_op0,
- m68hc11_compare_op1,
- operands[0]);
- DONE;
-}")
+ if (GET_CODE (operands[1]) == MEM && GET_CODE (operands[2]) == MEM)
+ operands[1] = force_reg (QImode, operands[1]);
-(define_expand "ble"
- [(set (pc)
- (if_then_else (le (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- m68hc11_expand_compare_and_branch (LE, m68hc11_compare_op0,
- m68hc11_compare_op1,
- operands[0]);
+ m68hc11_expand_compare_and_branch (GET_CODE (operands[0]), operands[1],
+ operands[2], operands[3]);
DONE;
}")
-(define_expand "bleu"
- [(set (pc)
- (if_then_else (leu (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- m68hc11_expand_compare_and_branch (LEU, m68hc11_compare_op0,
- m68hc11_compare_op1,
- operands[0]);
- DONE;
-}")
;;
;; Test and branch instructions for 68HC12 for EQ and NE.
@@ -7091,11 +6935,14 @@
(plus:HI (match_dup 0)
(match_operand:HI 1 "const_int_operand" "")))
(set (cc0)
- (match_operand:QI 2 "memory_operand" ""))]
+ (compare (match_operand:QI 2 "memory_operand" "")
+ (const_int 0)))]
"TARGET_AUTO_INC_DEC
&& (INTVAL (operands[1]) == -1 || INTVAL (operands[1]) == 1)
&& reg_mentioned_p (operands[0], operands[2])"
- [(set (cc0) (match_dup 3))]
+ [(set (cc0)
+ (compare (match_dup 3)
+ (const_int 0)))]
"if (INTVAL (operands[1]) == 1)
operands[3] = gen_rtx_MEM (QImode,
gen_rtx_PRE_INC (HImode, operands[0]));
@@ -7326,7 +7173,8 @@
(match_operand:HI 1 "hard_reg_operand" ""))
(set (match_dup 1) (plus:HI (match_dup 1)
(match_operand:HI 2 "const_int_operand" "")))
- (set (cc0) (match_dup 0))]
+ (set (cc0) (compare (match_dup 0)
+ (const_int 0)))]
"peep2_reg_dead_p (3, operands[0]) && !Z_REG_P (operands[1])"
[(set (match_dup 1) (plus:HI (match_dup 1) (match_dup 2)))
(set (cc0) (compare (match_dup 1) (match_dup 2)))]
@@ -7339,7 +7187,8 @@
(plus:HI (match_dup 2)
(match_operand:HI 3 "const_int_operand" "")))
(set (match_operand:HI 4 "memory_operand" "") (match_dup 2))
- (set (cc0) (match_operand:HI 5 "hard_reg_operand" ""))]
+ (set (cc0) (compare (match_operand:HI 5 "hard_reg_operand" "")
+ (const_int 0)))]
"peep2_reg_dead_p (4, operands[5]) && !Z_REG_P (operands[2])
&& !reg_mentioned_p (operands[2], operands[4])
diff --git a/gcc/config/m68k/constraints.md b/gcc/config/m68k/constraints.md
index 592112a155b..a4885cda6ca 100644
--- a/gcc/config/m68k/constraints.md
+++ b/gcc/config/m68k/constraints.md
@@ -78,6 +78,11 @@
(and (match_code "const_double")
(match_test "!(TARGET_68881 && standard_68881_constant_p (op))")))
+(define_constraint "H"
+ "Defines a real zero constant."
+ (and (match_code "const_double")
+ (match_test "op == CONST0_RTX (GET_MODE (op))")))
+
(define_constraint "S"
"Used for operands that satisfy 'm' when -mpcrel is in effect."
(and (match_code "mem")
@@ -124,6 +129,11 @@
(and (match_code "const_int")
(match_test "ival < -0x8000 || ival > 0x7FFF")))
+(define_constraint "Cu"
+ "16-bit offset for wrapped symbols"
+ (and (match_code "const")
+ (match_test "m68k_unwrap_symbol (op, false) != op")))
+
(define_constraint "CQ"
"Integers valid for mvq."
(and (match_code "const_int")
diff --git a/gcc/config/m68k/linux.h b/gcc/config/m68k/linux.h
index 922856cefdf..113f2787fb3 100644
--- a/gcc/config/m68k/linux.h
+++ b/gcc/config/m68k/linux.h
@@ -126,13 +126,6 @@ along with GCC; see the file COPYING3. If not see
if ((LOG) > 0) \
fprintf ((FILE), "%s%u\n", ALIGN_ASM_OP, 1 << (LOG));
-#ifdef HAVE_GAS_BALIGN_AND_P2ALIGN
-/* Use "move.l %a4,%a4" to advance within code. */
-#define ASM_OUTPUT_ALIGN_WITH_NOP(FILE,LOG) \
- if ((LOG) > 0) \
- fprintf ((FILE), "\t.balignw %u,0x284c\n", 1 << (LOG));
-#endif
-
/* If defined, a C expression whose value is a string containing the
assembler operation to identify the following data as uninitialized global
data. */
diff --git a/gcc/config/m68k/m68k-devices.def b/gcc/config/m68k/m68k-devices.def
index b89e7213f3f..6f87ce07613 100644
--- a/gcc/config/m68k/m68k-devices.def
+++ b/gcc/config/m68k/m68k-devices.def
@@ -72,8 +72,8 @@
/* 680x0 series processors. */
M68K_DEVICE ("68000", m68000, "68000", "68000", 68000, isa_00, 0)
M68K_DEVICE ("68010", m68010, "68010", "68000", 68010, isa_10, 0)
-M68K_DEVICE ("68020", m68020, "68020", "68020", 68020, isa_20, FL_MMU)
-M68K_DEVICE ("68030", m68030, "68030", "68020", 68030, isa_20, FL_MMU)
+M68K_DEVICE ("68020", m68020, "68020", "68020", 68020, isa_20, FL_MMU | FL_UCLINUX)
+M68K_DEVICE ("68030", m68030, "68030", "68020", 68030, isa_20, FL_MMU | FL_UCLINUX)
M68K_DEVICE ("68040", m68040, "68040", "68040", 68040, isa_40, FL_MMU)
M68K_DEVICE ("68060", m68060, "68060", "68060", 68060, isa_40, FL_MMU)
M68K_DEVICE ("68302", m68302, "68302", "68000", 68000, isa_00, FL_MMU)
@@ -158,12 +158,12 @@ M68K_DEVICE ("537x", mcf537x, "5373", "5329", cfv3, isa_aplus, FL_CF_HWD
/* CFV4/CFV4e processors. */
M68K_DEVICE ("5407", mcf5407, "5407", "5407", cfv4, isa_b, FL_CF_MAC)
-M68K_DEVICE ("54450", mcf54450, "54455", "54455", cfv4, isa_c, FL_CF_HWDIV | FL_CF_USP | FL_CF_EMAC | FL_MMU)
-M68K_DEVICE ("54451", mcf54451, "54455", "54455", cfv4, isa_c, FL_CF_HWDIV | FL_CF_USP | FL_CF_EMAC | FL_MMU)
-M68K_DEVICE ("54452", mcf54452, "54455", "54455", cfv4, isa_c, FL_CF_HWDIV | FL_CF_USP | FL_CF_EMAC | FL_MMU)
-M68K_DEVICE ("54453", mcf54453, "54455", "54455", cfv4, isa_c, FL_CF_HWDIV | FL_CF_USP | FL_CF_EMAC | FL_MMU)
-M68K_DEVICE ("54454", mcf54454, "54455", "54455", cfv4, isa_c, FL_CF_HWDIV | FL_CF_USP | FL_CF_EMAC | FL_MMU)
-M68K_DEVICE ("54455", mcf54455, "54455", "54455", cfv4, isa_c, FL_CF_HWDIV | FL_CF_USP | FL_CF_EMAC | FL_MMU)
+M68K_DEVICE ("54450", mcf54450, "54455", "54455", cfv4, isa_c, FL_CF_HWDIV | FL_CF_USP | FL_CF_EMAC | FL_MMU | FL_UCLINUX)
+M68K_DEVICE ("54451", mcf54451, "54455", "54455", cfv4, isa_c, FL_CF_HWDIV | FL_CF_USP | FL_CF_EMAC | FL_MMU | FL_UCLINUX)
+M68K_DEVICE ("54452", mcf54452, "54455", "54455", cfv4, isa_c, FL_CF_HWDIV | FL_CF_USP | FL_CF_EMAC | FL_MMU | FL_UCLINUX)
+M68K_DEVICE ("54453", mcf54453, "54455", "54455", cfv4, isa_c, FL_CF_HWDIV | FL_CF_USP | FL_CF_EMAC | FL_MMU | FL_UCLINUX)
+M68K_DEVICE ("54454", mcf54454, "54455", "54455", cfv4, isa_c, FL_CF_HWDIV | FL_CF_USP | FL_CF_EMAC | FL_MMU | FL_UCLINUX)
+M68K_DEVICE ("54455", mcf54455, "54455", "54455", cfv4, isa_c, FL_CF_HWDIV | FL_CF_USP | FL_CF_EMAC | FL_MMU | FL_UCLINUX)
M68K_DEVICE ("5470", mcf5470, "5475", "5475", cfv4e, isa_b, FL_CF_USP | FL_CF_EMAC | FL_CF_FPU | FL_MMU)
M68K_DEVICE ("5471", mcf5471, "5475", "5475", cfv4e, isa_b, FL_CF_USP | FL_CF_EMAC | FL_CF_FPU | FL_MMU)
M68K_DEVICE ("5472", mcf5472, "5475", "5475", cfv4e, isa_b, FL_CF_USP | FL_CF_EMAC | FL_CF_FPU | FL_MMU)
diff --git a/gcc/config/m68k/m68k-protos.h b/gcc/config/m68k/m68k-protos.h
index 43a457fe1d8..08f8a91e691 100644
--- a/gcc/config/m68k/m68k-protos.h
+++ b/gcc/config/m68k/m68k-protos.h
@@ -56,17 +56,23 @@ extern void notice_update_cc (rtx, rtx);
extern bool m68k_legitimate_base_reg_p (rtx, bool);
extern bool m68k_legitimate_index_reg_p (rtx, bool);
extern bool m68k_illegitimate_symbolic_constant_p (rtx);
-extern bool m68k_legitimate_address_p (enum machine_mode, rtx, bool);
extern bool m68k_matches_q_p (rtx);
extern bool m68k_matches_u_p (rtx);
extern rtx legitimize_pic_address (rtx, enum machine_mode, rtx);
+extern rtx m68k_legitimize_tls_address (rtx);
+extern bool m68k_tls_reference_p (rtx, bool);
extern int valid_dbcc_comparison_p_2 (rtx, enum machine_mode);
extern rtx m68k_libcall_value (enum machine_mode);
extern rtx m68k_function_value (const_tree, const_tree);
extern int emit_move_sequence (rtx *, enum machine_mode, rtx);
extern bool m68k_movem_pattern_p (rtx, rtx, HOST_WIDE_INT, bool);
extern const char *m68k_output_movem (rtx *, rtx, HOST_WIDE_INT, bool);
+extern void m68k_final_prescan_insn (rtx, rtx *, int);
+/* Functions from m68k.c used in constraints.md. */
+extern rtx m68k_unwrap_symbol (rtx, bool);
+
+/* Functions from m68k.c used in genattrtab. */
#ifdef HAVE_ATTR_cpu
extern enum attr_cpu m68k_sched_cpu;
extern enum attr_mac m68k_sched_mac;
diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
index d3734efd9cf..ec371e56a01 100644
--- a/gcc/config/m68k/m68k.c
+++ b/gcc/config/m68k/m68k.c
@@ -46,6 +46,7 @@ along with GCC; see the file COPYING3. If not see
/* ??? Need to add a dependency between m68k.o and sched-int.h. */
#include "sched-int.h"
#include "insn-codes.h"
+#include "ggc.h"
enum reg_class regno_reg_class[] =
{
@@ -131,6 +132,7 @@ static void m68k_sched_dfa_pre_advance_cycle (void);
static void m68k_sched_dfa_post_advance_cycle (void);
static int m68k_sched_first_cycle_multipass_dfa_lookahead (void);
+static bool m68k_legitimate_address_p (enum machine_mode, rtx, bool);
static bool m68k_handle_option (size_t, const char *, int);
static rtx find_addr_reg (rtx);
static const char *singlemove_string (rtx *);
@@ -143,20 +145,17 @@ static tree m68k_handle_fndecl_attribute (tree *node, tree name,
static void m68k_compute_frame_layout (void);
static bool m68k_save_reg (unsigned int regno, bool interrupt_handler);
static bool m68k_ok_for_sibcall_p (tree, tree);
+static bool m68k_tls_symbol_p (rtx);
static rtx m68k_legitimize_address (rtx, rtx, enum machine_mode);
static bool m68k_rtx_costs (rtx, int, int, int *, bool);
#if M68K_HONOR_TARGET_STRICT_ALIGNMENT
static bool m68k_return_in_memory (const_tree, const_tree);
#endif
+static void m68k_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
/* Specify the identification number of the library being built */
const char *m68k_library_id_string = "_current_shared_library_a5_offset_";
-
-/* Nonzero if the last compare/test insn had FP operands. The
- sCC expanders peek at this to determine what to do for the
- 68060, which has no fsCC instructions. */
-int m68k_last_compare_had_fp_operands;
/* Initialize the GCC target structure. */
@@ -253,6 +252,17 @@ int m68k_last_compare_had_fp_operands;
#define TARGET_RETURN_IN_MEMORY m68k_return_in_memory
#endif
+#ifdef HAVE_AS_TLS
+#undef TARGET_HAVE_TLS
+#define TARGET_HAVE_TLS (true)
+
+#undef TARGET_ASM_OUTPUT_DWARF_DTPREL
+#define TARGET_ASM_OUTPUT_DWARF_DTPREL m68k_output_dwarf_dtprel
+#endif
+
+#undef TARGET_LEGITIMATE_ADDRESS_P
+#define TARGET_LEGITIMATE_ADDRESS_P m68k_legitimate_address_p
+
static const struct attribute_spec m68k_attribute_table[] =
{
/* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
@@ -1024,10 +1034,10 @@ m68k_expand_prologue (void)
emit_move_insn (gen_rtx_REG (Pmode, D0_REG), limit);
limit = gen_rtx_REG (Pmode, D0_REG);
}
- emit_insn (gen_cmpsi (stack_pointer_rtx, limit));
- emit_insn (gen_conditional_trap (gen_rtx_LTU (VOIDmode,
- cc0_rtx, const0_rtx),
- const1_rtx));
+ emit_insn (gen_ctrapsi4 (gen_rtx_LTU (VOIDmode,
+ stack_pointer_rtx, limit),
+ stack_pointer_rtx, limit,
+ const1_rtx));
}
fsize_with_regs = current_frame.size;
@@ -1110,12 +1120,11 @@ m68k_expand_prologue (void)
if (crtl->limit_stack)
{
if (REG_P (stack_limit_rtx))
- {
- emit_insn (gen_cmpsi (stack_pointer_rtx, stack_limit_rtx));
- emit_insn (gen_conditional_trap (gen_rtx_LTU (VOIDmode,
- cc0_rtx, const0_rtx),
- const1_rtx));
- }
+ emit_insn (gen_ctrapsi4 (gen_rtx_LTU (VOIDmode, stack_pointer_rtx,
+ stack_limit_rtx),
+ stack_pointer_rtx, stack_limit_rtx,
+ const1_rtx));
+
else if (GET_CODE (stack_limit_rtx) != SYMBOL_REF)
warning (0, "stack limit expression is not supported");
}
@@ -1151,8 +1160,7 @@ m68k_expand_prologue (void)
current_frame.reg_mask, true, true));
}
- if (flag_pic
- && !TARGET_SEP_DATA
+ if (!TARGET_SEP_DATA
&& crtl->uses_pic_offset_table)
insn = emit_insn (gen_load_got (pic_offset_table_rtx));
}
@@ -1434,9 +1442,12 @@ m68k_legitimize_sibcall_address (rtx x)
However, if REG is a broken-out memory address or multiplication,
nothing needs to be done because REG can certainly go in an address reg. */
-rtx
+static rtx
m68k_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
{
+ if (m68k_tls_symbol_p (x))
+ return m68k_legitimize_tls_address (x);
+
if (GET_CODE (x) == PLUS)
{
int ch = (x) != (oldx);
@@ -1855,7 +1866,7 @@ m68k_illegitimate_symbolic_constant_p (rtx x)
&& !offset_within_block_p (base, INTVAL (offset)))
return true;
}
- return false;
+ return m68k_tls_reference_p (x, false);
}
/* Return true if X is a legitimate constant address that can reach
@@ -1883,7 +1894,7 @@ m68k_legitimate_constant_address_p (rtx x, unsigned int reach, bool strict_p)
return false;
}
- return true;
+ return !m68k_tls_reference_p (x, false);
}
/* Return true if X is a LABEL_REF for a jump table. Assume that unplaced
@@ -1950,15 +1961,17 @@ m68k_decompose_address (enum machine_mode mode, rtx x,
/* Check for GOT loads. These are (bd,An,Xn) addresses if
TARGET_68020 && flag_pic == 2, otherwise they are (d16,An)
addresses. */
- if (flag_pic
- && GET_CODE (x) == PLUS
- && XEXP (x, 0) == pic_offset_table_rtx
- && (GET_CODE (XEXP (x, 1)) == SYMBOL_REF
- || GET_CODE (XEXP (x, 1)) == LABEL_REF))
+ if (GET_CODE (x) == PLUS
+ && XEXP (x, 0) == pic_offset_table_rtx)
{
- address->base = XEXP (x, 0);
- address->offset = XEXP (x, 1);
- return true;
+ /* As we are processing a PLUS, do not unwrap RELOC32 symbols --
+ they are invalid in this context. */
+ if (m68k_unwrap_symbol (XEXP (x, 1), false) != XEXP (x, 1))
+ {
+ address->base = XEXP (x, 0);
+ address->offset = XEXP (x, 1);
+ return true;
+ }
}
/* The ColdFire FPU only accepts addressing modes 2-5. */
@@ -2103,6 +2116,243 @@ m68k_matches_u_p (rtx x)
&& !address.index);
}
+/* Return GOT pointer. */
+
+static rtx
+m68k_get_gp (void)
+{
+ if (pic_offset_table_rtx == NULL_RTX)
+ pic_offset_table_rtx = gen_rtx_REG (Pmode, PIC_REG);
+
+ crtl->uses_pic_offset_table = 1;
+
+ return pic_offset_table_rtx;
+}
+
+/* M68K relocations, used to distinguish GOT and TLS relocations in UNSPEC
+ wrappers. */
+enum m68k_reloc { RELOC_GOT, RELOC_TLSGD, RELOC_TLSLDM, RELOC_TLSLDO,
+ RELOC_TLSIE, RELOC_TLSLE };
+
+#define TLS_RELOC_P(RELOC) ((RELOC) != RELOC_GOT)
+
+/* Wrap symbol X into unspec representing relocation RELOC.
+ BASE_REG - register that should be added to the result.
+ TEMP_REG - if non-null, temporary register. */
+
+static rtx
+m68k_wrap_symbol (rtx x, enum m68k_reloc reloc, rtx base_reg, rtx temp_reg)
+{
+ bool use_x_p;
+
+ use_x_p = (base_reg == pic_offset_table_rtx) ? TARGET_XGOT : TARGET_XTLS;
+
+ if (TARGET_COLDFIRE && use_x_p)
+ /* When compiling with -mx{got, tls} switch the code will look like this:
+
+ move.l <X>@<RELOC>,<TEMP_REG>
+ add.l <BASE_REG>,<TEMP_REG> */
+ {
+ /* Wrap X in UNSPEC_??? to tip m68k_output_addr_const_extra
+ to put @RELOC after reference. */
+ x = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, x, GEN_INT (reloc)),
+ UNSPEC_RELOC32);
+ x = gen_rtx_CONST (Pmode, x);
+
+ if (temp_reg == NULL)
+ {
+ gcc_assert (can_create_pseudo_p ());
+ temp_reg = gen_reg_rtx (Pmode);
+ }
+
+ emit_move_insn (temp_reg, x);
+ emit_insn (gen_addsi3 (temp_reg, temp_reg, base_reg));
+ x = temp_reg;
+ }
+ else
+ {
+ x = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, x, GEN_INT (reloc)),
+ UNSPEC_RELOC16);
+ x = gen_rtx_CONST (Pmode, x);
+
+ x = gen_rtx_PLUS (Pmode, base_reg, x);
+ }
+
+ return x;
+}
+
+/* Helper for m68k_unwrap_symbol.
+ Also, if unwrapping was successful (that is if (ORIG != <return value>)),
+ sets *RELOC_PTR to relocation type for the symbol. */
+
+static rtx
+m68k_unwrap_symbol_1 (rtx orig, bool unwrap_reloc32_p,
+ enum m68k_reloc *reloc_ptr)
+{
+ if (GET_CODE (orig) == CONST)
+ {
+ rtx x;
+ enum m68k_reloc dummy;
+
+ x = XEXP (orig, 0);
+
+ if (reloc_ptr == NULL)
+ reloc_ptr = &dummy;
+
+ /* Handle an addend. */
+ if ((GET_CODE (x) == PLUS || GET_CODE (x) == MINUS)
+ && CONST_INT_P (XEXP (x, 1)))
+ x = XEXP (x, 0);
+
+ if (GET_CODE (x) == UNSPEC)
+ {
+ switch (XINT (x, 1))
+ {
+ case UNSPEC_RELOC16:
+ orig = XVECEXP (x, 0, 0);
+ *reloc_ptr = (enum m68k_reloc) INTVAL (XVECEXP (x, 0, 1));
+ break;
+
+ case UNSPEC_RELOC32:
+ if (unwrap_reloc32_p)
+ {
+ orig = XVECEXP (x, 0, 0);
+ *reloc_ptr = (enum m68k_reloc) INTVAL (XVECEXP (x, 0, 1));
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+ return orig;
+}
+
+/* Unwrap symbol from UNSPEC_RELOC16 and, if unwrap_reloc32_p,
+ UNSPEC_RELOC32 wrappers. */
+
+rtx
+m68k_unwrap_symbol (rtx orig, bool unwrap_reloc32_p)
+{
+ return m68k_unwrap_symbol_1 (orig, unwrap_reloc32_p, NULL);
+}
+
+/* Helper for m68k_final_prescan_insn. */
+
+static int
+m68k_final_prescan_insn_1 (rtx *x_ptr, void *data ATTRIBUTE_UNUSED)
+{
+ rtx x = *x_ptr;
+
+ if (m68k_unwrap_symbol (x, true) != x)
+ /* For rationale of the below, see comment in m68k_final_prescan_insn. */
+ {
+ rtx plus;
+
+ gcc_assert (GET_CODE (x) == CONST);
+ plus = XEXP (x, 0);
+
+ if (GET_CODE (plus) == PLUS || GET_CODE (plus) == MINUS)
+ {
+ rtx unspec;
+ rtx addend;
+
+ unspec = XEXP (plus, 0);
+ gcc_assert (GET_CODE (unspec) == UNSPEC);
+ addend = XEXP (plus, 1);
+ gcc_assert (CONST_INT_P (addend));
+
+ /* We now have all the pieces, rearrange them. */
+
+ /* Move symbol to plus. */
+ XEXP (plus, 0) = XVECEXP (unspec, 0, 0);
+
+ /* Move plus inside unspec. */
+ XVECEXP (unspec, 0, 0) = plus;
+
+ /* Move unspec to top level of const. */
+ XEXP (x, 0) = unspec;
+ }
+
+ return -1;
+ }
+
+ return 0;
+}
+
+/* Prescan insn before outputing assembler for it. */
+
+void
+m68k_final_prescan_insn (rtx insn ATTRIBUTE_UNUSED,
+ rtx *operands, int n_operands)
+{
+ int i;
+
+ /* Combine and, possibly, other optimizations may do good job
+ converting
+ (const (unspec [(symbol)]))
+ into
+ (const (plus (unspec [(symbol)])
+ (const_int N))).
+ The problem with this is emitting @TLS or @GOT decorations.
+ The decoration is emitted when processing (unspec), so the
+ result would be "#symbol@TLSLE+N" instead of "#symbol+N@TLSLE".
+
+ It seems that the easiest solution to this is to convert such
+ operands to
+ (const (unspec [(plus (symbol)
+ (const_int N))])).
+ Note, that the top level of operand remains intact, so we don't have
+ to patch up anything outside of the operand. */
+
+ for (i = 0; i < n_operands; ++i)
+ {
+ rtx op;
+
+ op = operands[i];
+
+ for_each_rtx (&op, m68k_final_prescan_insn_1, NULL);
+ }
+}
+
+/* Move X to a register and add REG_EQUAL note pointing to ORIG.
+ If REG is non-null, use it; generate new pseudo otherwise. */
+
+static rtx
+m68k_move_to_reg (rtx x, rtx orig, rtx reg)
+{
+ rtx insn;
+
+ if (reg == NULL_RTX)
+ {
+ gcc_assert (can_create_pseudo_p ());
+ reg = gen_reg_rtx (Pmode);
+ }
+
+ insn = emit_move_insn (reg, x);
+ /* Put a REG_EQUAL note on this insn, so that it can be optimized
+ by loop. */
+ set_unique_reg_note (insn, REG_EQUAL, orig);
+
+ return reg;
+}
+
+/* Does the same as m68k_wrap_symbol, but returns a memory reference to
+ GOT slot. */
+
+static rtx
+m68k_wrap_symbol_into_got_ref (rtx x, enum m68k_reloc reloc, rtx temp_reg)
+{
+ x = m68k_wrap_symbol (x, reloc, m68k_get_gp (), temp_reg);
+
+ x = gen_rtx_MEM (Pmode, x);
+ MEM_READONLY_P (x) = 1;
+
+ return x;
+}
+
/* Legitimize PIC addresses. If the address is already
position-independent, we return ORIG. Newly generated
position-independent addresses go to REG. If we need more
@@ -2154,42 +2404,15 @@ legitimize_pic_address (rtx orig, enum machine_mode mode ATTRIBUTE_UNUSED,
{
gcc_assert (reg);
- if (TARGET_COLDFIRE && TARGET_XGOT)
- /* When compiling with -mxgot switch the code for the above
- example will look like this:
-
- movel a5, a0
- addl _foo@GOT, a0
- movel a0@, a0
- movel #12345, a0@ */
- {
- rtx pic_offset;
-
- /* Wrap ORIG in UNSPEC_GOTOFF to tip m68k_output_addr_const_extra
- to put @GOT after reference. */
- pic_offset = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, orig),
- UNSPEC_GOTOFF);
- pic_offset = gen_rtx_CONST (Pmode, pic_offset);
- emit_move_insn (reg, pic_offset);
- emit_insn (gen_addsi3 (reg, reg, pic_offset_table_rtx));
- pic_ref = gen_rtx_MEM (Pmode, reg);
- }
- else
- pic_ref = gen_rtx_MEM (Pmode,
- gen_rtx_PLUS (Pmode,
- pic_offset_table_rtx, orig));
- crtl->uses_pic_offset_table = 1;
- MEM_READONLY_P (pic_ref) = 1;
- emit_move_insn (reg, pic_ref);
- return reg;
+ pic_ref = m68k_wrap_symbol_into_got_ref (orig, RELOC_GOT, reg);
+ pic_ref = m68k_move_to_reg (pic_ref, orig, reg);
}
else if (GET_CODE (orig) == CONST)
{
rtx base;
/* Make sure this has not already been legitimized. */
- if (GET_CODE (XEXP (orig, 0)) == PLUS
- && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
+ if (m68k_unwrap_symbol (orig, true) != orig)
return orig;
gcc_assert (reg);
@@ -2202,13 +2425,257 @@ legitimize_pic_address (rtx orig, enum machine_mode mode ATTRIBUTE_UNUSED,
base == reg ? 0 : reg);
if (GET_CODE (orig) == CONST_INT)
- return plus_constant (base, INTVAL (orig));
- pic_ref = gen_rtx_PLUS (Pmode, base, orig);
- /* Likewise, should we set special REG_NOTEs here? */
+ pic_ref = plus_constant (base, INTVAL (orig));
+ else
+ pic_ref = gen_rtx_PLUS (Pmode, base, orig);
}
+
return pic_ref;
}
+/* The __tls_get_addr symbol. */
+static GTY(()) rtx m68k_tls_get_addr;
+
+/* Return SYMBOL_REF for __tls_get_addr. */
+
+static rtx
+m68k_get_tls_get_addr (void)
+{
+ if (m68k_tls_get_addr == NULL_RTX)
+ m68k_tls_get_addr = init_one_libfunc ("__tls_get_addr");
+
+ return m68k_tls_get_addr;
+}
+
+/* Return libcall result in A0 instead of usual D0. */
+static bool m68k_libcall_value_in_a0_p = false;
+
+/* Emit instruction sequence that calls __tls_get_addr. X is
+ the TLS symbol we are referencing and RELOC is the symbol type to use
+ (either TLSGD or TLSLDM). EQV is the REG_EQUAL note for the sequence
+ emitted. A pseudo register with result of __tls_get_addr call is
+ returned. */
+
+static rtx
+m68k_call_tls_get_addr (rtx x, rtx eqv, enum m68k_reloc reloc)
+{
+ rtx a0;
+ rtx insns;
+ rtx dest;
+
+ /* Emit the call sequence. */
+ start_sequence ();
+
+ /* FIXME: Unfortunately, emit_library_call_value does not
+ consider (plus (%a5) (const (unspec))) to be a good enough
+ operand for push, so it forces it into a register. The bad
+ thing about this is that combiner, due to copy propagation and other
+ optimizations, sometimes can not later fix this. As a consequence,
+ additional register may be allocated resulting in a spill.
+ For reference, see args processing loops in
+ calls.c:emit_library_call_value_1.
+ For testcase, see gcc.target/m68k/tls-{gd, ld}.c */
+ x = m68k_wrap_symbol (x, reloc, m68k_get_gp (), NULL_RTX);
+
+ /* __tls_get_addr() is not a libcall, but emitting a libcall_value
+ is the simpliest way of generating a call. The difference between
+ __tls_get_addr() and libcall is that the result is returned in D0
+ instead of A0. To workaround this, we use m68k_libcall_value_in_a0_p
+ which temporarily switches returning the result to A0. */
+
+ m68k_libcall_value_in_a0_p = true;
+ a0 = emit_library_call_value (m68k_get_tls_get_addr (), NULL_RTX, LCT_PURE,
+ Pmode, 1, x, Pmode);
+ m68k_libcall_value_in_a0_p = false;
+
+ insns = get_insns ();
+ end_sequence ();
+
+ gcc_assert (can_create_pseudo_p ());
+ dest = gen_reg_rtx (Pmode);
+ emit_libcall_block (insns, dest, a0, eqv);
+
+ return dest;
+}
+
+/* The __tls_get_addr symbol. */
+static GTY(()) rtx m68k_read_tp;
+
+/* Return SYMBOL_REF for __m68k_read_tp. */
+
+static rtx
+m68k_get_m68k_read_tp (void)
+{
+ if (m68k_read_tp == NULL_RTX)
+ m68k_read_tp = init_one_libfunc ("__m68k_read_tp");
+
+ return m68k_read_tp;
+}
+
+/* Emit instruction sequence that calls __m68k_read_tp.
+ A pseudo register with result of __m68k_read_tp call is returned. */
+
+static rtx
+m68k_call_m68k_read_tp (void)
+{
+ rtx a0;
+ rtx eqv;
+ rtx insns;
+ rtx dest;
+
+ start_sequence ();
+
+ /* __m68k_read_tp() is not a libcall, but emitting a libcall_value
+ is the simpliest way of generating a call. The difference between
+ __m68k_read_tp() and libcall is that the result is returned in D0
+ instead of A0. To workaround this, we use m68k_libcall_value_in_a0_p
+ which temporarily switches returning the result to A0. */
+
+ /* Emit the call sequence. */
+ m68k_libcall_value_in_a0_p = true;
+ a0 = emit_library_call_value (m68k_get_m68k_read_tp (), NULL_RTX, LCT_PURE,
+ Pmode, 0);
+ m68k_libcall_value_in_a0_p = false;
+ insns = get_insns ();
+ end_sequence ();
+
+ /* Attach a unique REG_EQUIV, to allow the RTL optimizers to
+ share the m68k_read_tp result with other IE/LE model accesses. */
+ eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const1_rtx), UNSPEC_RELOC32);
+
+ gcc_assert (can_create_pseudo_p ());
+ dest = gen_reg_rtx (Pmode);
+ emit_libcall_block (insns, dest, a0, eqv);
+
+ return dest;
+}
+
+/* Return a legitimized address for accessing TLS SYMBOL_REF X.
+ For explanations on instructions sequences see TLS/NPTL ABI for m68k and
+ ColdFire. */
+
+rtx
+m68k_legitimize_tls_address (rtx orig)
+{
+ switch (SYMBOL_REF_TLS_MODEL (orig))
+ {
+ case TLS_MODEL_GLOBAL_DYNAMIC:
+ orig = m68k_call_tls_get_addr (orig, orig, RELOC_TLSGD);
+ break;
+
+ case TLS_MODEL_LOCAL_DYNAMIC:
+ {
+ rtx eqv;
+ rtx a0;
+ rtx x;
+
+ /* Attach a unique REG_EQUIV, to allow the RTL optimizers to
+ share the LDM result with other LD model accesses. */
+ eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
+ UNSPEC_RELOC32);
+
+ a0 = m68k_call_tls_get_addr (orig, eqv, RELOC_TLSLDM);
+
+ x = m68k_wrap_symbol (orig, RELOC_TLSLDO, a0, NULL_RTX);
+
+ if (can_create_pseudo_p ())
+ x = m68k_move_to_reg (x, orig, NULL_RTX);
+
+ orig = x;
+ break;
+ }
+
+ case TLS_MODEL_INITIAL_EXEC:
+ {
+ rtx a0;
+ rtx x;
+
+ a0 = m68k_call_m68k_read_tp ();
+
+ x = m68k_wrap_symbol_into_got_ref (orig, RELOC_TLSIE, NULL_RTX);
+ x = gen_rtx_PLUS (Pmode, x, a0);
+
+ if (can_create_pseudo_p ())
+ x = m68k_move_to_reg (x, orig, NULL_RTX);
+
+ orig = x;
+ break;
+ }
+
+ case TLS_MODEL_LOCAL_EXEC:
+ {
+ rtx a0;
+ rtx x;
+
+ a0 = m68k_call_m68k_read_tp ();
+
+ x = m68k_wrap_symbol (orig, RELOC_TLSLE, a0, NULL_RTX);
+
+ if (can_create_pseudo_p ())
+ x = m68k_move_to_reg (x, orig, NULL_RTX);
+
+ orig = x;
+ break;
+ }
+
+ default:
+ gcc_unreachable ();
+ }
+
+ return orig;
+}
+
+/* Return true if X is a TLS symbol. */
+
+static bool
+m68k_tls_symbol_p (rtx x)
+{
+ if (!TARGET_HAVE_TLS)
+ return false;
+
+ if (GET_CODE (x) != SYMBOL_REF)
+ return false;
+
+ return SYMBOL_REF_TLS_MODEL (x) != 0;
+}
+
+/* Helper for m68k_tls_referenced_p. */
+
+static int
+m68k_tls_reference_p_1 (rtx *x_ptr, void *data ATTRIBUTE_UNUSED)
+{
+ /* Note: this is not the same as m68k_tls_symbol_p. */
+ if (GET_CODE (*x_ptr) == SYMBOL_REF)
+ return SYMBOL_REF_TLS_MODEL (*x_ptr) != 0 ? 1 : 0;
+
+ /* Don't recurse into legitimate TLS references. */
+ if (m68k_tls_reference_p (*x_ptr, true))
+ return -1;
+
+ return 0;
+}
+
+/* If !LEGITIMATE_P, return true if X is a TLS symbol reference,
+ though illegitimate one.
+ If LEGITIMATE_P, return true if X is a legitimate TLS symbol reference. */
+
+bool
+m68k_tls_reference_p (rtx x, bool legitimate_p)
+{
+ if (!TARGET_HAVE_TLS)
+ return false;
+
+ if (!legitimate_p)
+ return for_each_rtx (&x, m68k_tls_reference_p_1, NULL) == 1 ? true : false;
+ else
+ {
+ enum m68k_reloc reloc = RELOC_GOT;
+
+ return (m68k_unwrap_symbol_1 (x, true, &reloc) != x
+ && TLS_RELOC_P (reloc));
+ }
+}
+
#define USE_MOVQ(i) ((unsigned) ((i) + 128) <= 255)
@@ -2418,6 +2885,11 @@ m68k_rtx_costs (rtx x, int code, int outer_code, int *total,
*total = COSTS_N_INSNS (43); /* div.l */
return true;
+ case ZERO_EXTRACT:
+ if (outer_code == COMPARE)
+ *total = 0;
+ return false;
+
default:
return false;
}
@@ -3996,18 +4468,92 @@ print_operand (FILE *file, rtx op, int letter)
}
}
+/* Return string for TLS relocation RELOC. */
+
+static const char *
+m68k_get_reloc_decoration (enum m68k_reloc reloc)
+{
+ /* To my knowledge, !MOTOROLA assemblers don't support TLS. */
+ gcc_assert (MOTOROLA || reloc == RELOC_GOT);
+
+ switch (reloc)
+ {
+ case RELOC_GOT:
+ if (MOTOROLA)
+ {
+ if (flag_pic == 1 && TARGET_68020)
+ return "@GOT.w";
+ else
+ return "@GOT";
+ }
+ else
+ {
+ if (TARGET_68020)
+ {
+ switch (flag_pic)
+ {
+ case 1:
+ return ":w";
+ case 2:
+ return ":l";
+ default:
+ return "";
+ }
+ }
+ }
+
+ case RELOC_TLSGD:
+ return "@TLSGD";
+
+ case RELOC_TLSLDM:
+ return "@TLSLDM";
+
+ case RELOC_TLSLDO:
+ return "@TLSLDO";
+
+ case RELOC_TLSIE:
+ return "@TLSIE";
+
+ case RELOC_TLSLE:
+ return "@TLSLE";
+
+ default:
+ gcc_unreachable ();
+ }
+}
+
/* m68k implementation of OUTPUT_ADDR_CONST_EXTRA. */
bool
m68k_output_addr_const_extra (FILE *file, rtx x)
{
- if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_GOTOFF)
- return false;
+ if (GET_CODE (x) == UNSPEC)
+ {
+ switch (XINT (x, 1))
+ {
+ case UNSPEC_RELOC16:
+ case UNSPEC_RELOC32:
+ output_addr_const (file, XVECEXP (x, 0, 0));
+ fputs (m68k_get_reloc_decoration (INTVAL (XVECEXP (x, 0, 1))), file);
+ return true;
- output_addr_const (file, XVECEXP (x, 0, 0));
- /* ??? What is the non-MOTOROLA syntax? */
- fputs ("@GOT", file);
- return true;
+ default:
+ break;
+ }
+ }
+
+ return false;
+}
+
+/* M68K implementation of TARGET_ASM_OUTPUT_DWARF_DTPREL. */
+
+static void
+m68k_output_dwarf_dtprel (FILE *file, int size, rtx x)
+{
+ gcc_assert (size == 4);
+ fputs ("\t.long\t", file);
+ output_addr_const (file, x);
+ fputs ("@TLSLDO+0x8000", file);
}
@@ -4097,15 +4643,8 @@ print_operand_address (FILE *file, rtx addr)
else
{
if (address.offset)
- {
- output_addr_const (file, address.offset);
- if (flag_pic && address.base == pic_offset_table_rtx)
- {
- fprintf (file, "@GOT");
- if (flag_pic == 1 && TARGET_68020)
- fprintf (file, ".w");
- }
- }
+ output_addr_const (file, address.offset);
+
putc ('(', file);
if (address.base)
fputs (M68K_REGNAME (REGNO (address.base)), file);
@@ -4138,19 +4677,7 @@ print_operand_address (FILE *file, rtx addr)
fputs (M68K_REGNAME (REGNO (address.base)), file);
fprintf (file, "@(");
if (address.offset)
- {
- output_addr_const (file, address.offset);
- if (address.base == pic_offset_table_rtx && TARGET_68020)
- switch (flag_pic)
- {
- case 1:
- fprintf (file, ":w"); break;
- case 2:
- fprintf (file, ":l"); break;
- default:
- break;
- }
- }
+ output_addr_const (file, address.offset);
}
/* Print the ",index" component, if any. */
if (address.index)
@@ -4266,7 +4793,7 @@ strict_low_part_peephole_ok (enum machine_mode mode, rtx first_insn,
simple fact that the m68k does not allow a pc-relative addressing
mode as a destination. gcc does not distinguish between source and
destination addresses. Hence, if we claim that pc-relative address
- modes are valid, e.g. GO_IF_LEGITIMATE_ADDRESS accepts them, then we
+ modes are valid, e.g. TARGET_LEGITIMATE_ADDRESS_P accepts them, then we
end up with invalid code. To get around this problem, we left
pc-relative modes as invalid addresses, and then added special
predicates and constraints to accept them.
@@ -4302,7 +4829,7 @@ output_andsi3 (rtx *operands)
return "and%.w %2,%0";
}
if (GET_CODE (operands[2]) == CONST_INT
- && (logval = exact_log2 (~ INTVAL (operands[2]))) >= 0
+ && (logval = exact_log2 (~ INTVAL (operands[2]) & 0xffffffff)) >= 0
&& (DATA_REG_P (operands[0])
|| offsettable_memref_p (operands[0])))
{
@@ -4339,7 +4866,7 @@ output_iorsi3 (rtx *operands)
return "or%.w %2,%0";
}
if (GET_CODE (operands[2]) == CONST_INT
- && (logval = exact_log2 (INTVAL (operands[2]))) >= 0
+ && (logval = exact_log2 (INTVAL (operands[2]) & 0xffffffff)) >= 0
&& (DATA_REG_P (operands[0])
|| offsettable_memref_p (operands[0])))
{
@@ -4374,7 +4901,7 @@ output_xorsi3 (rtx *operands)
return "eor%.w %2,%0";
}
if (GET_CODE (operands[2]) == CONST_INT
- && (logval = exact_log2 (INTVAL (operands[2]))) >= 0
+ && (logval = exact_log2 (INTVAL (operands[2]) & 0xffffffff)) >= 0
&& (DATA_REG_P (operands[0])
|| offsettable_memref_p (operands[0])))
{
@@ -4638,7 +5165,8 @@ m68k_libcall_value (enum machine_mode mode)
default:
break;
}
- return gen_rtx_REG (mode, D0_REG);
+
+ return gen_rtx_REG (mode, m68k_libcall_value_in_a0_p ? A0_REG : D0_REG);
}
rtx
@@ -4904,9 +5432,8 @@ sched_attr_op_type (rtx insn, bool opx_p, bool address_p)
return OP_TYPE_IMM_L;
default:
- if (GET_CODE (op) == SYMBOL_REF)
- /* ??? Just a guess. Probably we can guess better using length
- attribute of the instructions. */
+ if (symbolic_operand (m68k_unwrap_symbol (op, false), VOIDmode))
+ /* Just a guess. */
return OP_TYPE_IMM_W;
return OP_TYPE_IMM_L;
@@ -5851,3 +6378,5 @@ m68k_sched_indexed_address_bypass_p (rtx pro, rtx con)
return 0;
}
}
+
+#include "gt-m68k.h"
diff --git a/gcc/config/m68k/m68k.h b/gcc/config/m68k/m68k.h
index 875667dc428..24598c5ba07 100644
--- a/gcc/config/m68k/m68k.h
+++ b/gcc/config/m68k/m68k.h
@@ -232,6 +232,7 @@ along with GCC; see the file COPYING3. If not see
#define FL_ISA_C (1 << 16)
#define FL_FIDOA (1 << 17)
#define FL_MMU 0 /* Used by multilib machinery. */
+#define FL_UCLINUX 0 /* Used by multilib machinery. */
#define TARGET_68010 ((m68k_cpu_flags & FL_ISA_68010) != 0)
#define TARGET_68020 ((m68k_cpu_flags & FL_ISA_68020) != 0)
@@ -749,7 +750,8 @@ __transfer_from_trampoline () \
#define LEGITIMATE_PIC_OPERAND_P(X) \
(!symbolic_operand (X, VOIDmode) \
- || (TARGET_PCREL && REG_STRICT_P))
+ || (TARGET_PCREL && REG_STRICT_P) \
+ || m68k_tls_reference_p (X, true))
#define REG_OK_FOR_BASE_P(X) \
m68k_legitimate_base_reg_p (X, REG_STRICT_P)
@@ -757,14 +759,6 @@ __transfer_from_trampoline () \
#define REG_OK_FOR_INDEX_P(X) \
m68k_legitimate_index_reg_p (X, REG_STRICT_P)
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
- do \
- { \
- if (m68k_legitimate_address_p (MODE, X, REG_STRICT_P)) \
- goto ADDR; \
- } \
- while (0)
-
/* This address is OK as it stands. */
#define PIC_CASE_VECTOR_ADDRESS(index) index
@@ -961,6 +955,13 @@ do { if (cc_prev_status.flags & CC_IN_68881) \
if ((LOG) >= 1) \
fprintf (FILE, "\t.even\n");
+#ifdef HAVE_GAS_BALIGN_AND_P2ALIGN
+/* Use "move.l %a4,%a4" to advance within code. */
+#define ASM_OUTPUT_ALIGN_WITH_NOP(FILE,LOG) \
+ if ((LOG) > 0) \
+ fprintf ((FILE), "\t.balignw %u,0x284c\n", 1 << (LOG));
+#endif
+
#define ASM_OUTPUT_SKIP(FILE,SIZE) \
fprintf (FILE, "\t.skip %u\n", (int)(SIZE))
@@ -974,6 +975,9 @@ do { if (cc_prev_status.flags & CC_IN_68881) \
assemble_name ((FILE), (NAME)), \
fprintf ((FILE), ",%u\n", (int)(ROUNDED)))
+#define FINAL_PRESCAN_INSN(INSN, OPVEC, NOPERANDS) \
+ m68k_final_prescan_insn (INSN, OPVEC, NOPERANDS)
+
/* On the 68000, we use several CODE characters:
'.' for dot needed in Motorola-style opcode names.
'-' for an operand pushing on the stack:
@@ -1060,7 +1064,6 @@ enum m68k_function_kind
/* Variables in m68k.c; see there for details. */
extern const char *m68k_library_id_string;
-extern int m68k_last_compare_had_fp_operands;
extern enum target_device m68k_cpu;
extern enum uarch_type m68k_tune;
extern enum fpu_type m68k_fpu;
diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md
index 68442fd5746..037bb372cc9 100644
--- a/gcc/config/m68k/m68k.md
+++ b/gcc/config/m68k/m68k.md
@@ -116,7 +116,8 @@
(UNSPEC_GOT 3)
(UNSPEC_IB 4)
(UNSPEC_TIE 5)
- (UNSPEC_GOTOFF 6)
+ (UNSPEC_RELOC16 6)
+ (UNSPEC_RELOC32 7)
])
;; UNSPEC_VOLATILE usage:
@@ -300,17 +301,10 @@
;; (set (cc0) (const_int foo)) has no mode information. Such insns will
;; be folded while optimizing anyway.
-(define_expand "tstdi"
- [(parallel [(set (cc0)
- (match_operand:DI 0 "nonimmediate_operand" ""))
- (clobber (match_scratch:SI 1 ""))
- (clobber (match_scratch:DI 2 ""))])]
- ""
- "m68k_last_compare_had_fp_operands = 0;")
-
-(define_insn ""
+(define_insn "tstdi"
[(set (cc0)
- (match_operand:DI 0 "nonimmediate_operand" "am,d"))
+ (compare (match_operand:DI 0 "nonimmediate_operand" "am,d")
+ (const_int 0)))
(clobber (match_scratch:SI 1 "=X,d"))
(clobber (match_scratch:DI 2 "=d,X"))]
""
@@ -339,17 +333,12 @@
return "sub%.l %1,%1\;tst%.l %R0\;subx%.l %1,%0";
})
-(define_expand "tstsi"
- [(set (cc0)
- (match_operand:SI 0 "nonimmediate_operand" ""))]
- ""
- "m68k_last_compare_had_fp_operands = 0;")
-
;; If you think that the 68020 does not support tstl a0,
;; reread page B-167 of the 68020 manual more carefully.
(define_insn "*tstsi_internal_68020_cf"
[(set (cc0)
- (match_operand:SI 0 "nonimmediate_operand" "rm"))]
+ (compare (match_operand:SI 0 "nonimmediate_operand" "rm")
+ (const_int 0)))]
"TARGET_68020 || TARGET_COLDFIRE"
"tst%.l %0"
[(set_attr "type" "tst_l")])
@@ -357,7 +346,8 @@
;; On an address reg, cmpw may replace cmpl.
(define_insn "*tstsi_internal"
[(set (cc0)
- (match_operand:SI 0 "nonimmediate_operand" "dm,r"))]
+ (compare (match_operand:SI 0 "nonimmediate_operand" "dm,r")
+ (const_int 0)))]
"!(TARGET_68020 || TARGET_COLDFIRE)"
"@
tst%.l %0
@@ -366,43 +356,26 @@
;; This can't use an address register, because comparisons
;; with address registers as second operand always test the whole word.
-(define_expand "tsthi"
- [(set (cc0)
- (match_operand:HI 0 "nonimmediate_operand" ""))]
- ""
- "m68k_last_compare_had_fp_operands = 0;")
-
(define_insn "*tsthi_internal"
[(set (cc0)
- (match_operand:HI 0 "nonimmediate_operand" "dm"))]
+ (compare (match_operand:HI 0 "nonimmediate_operand" "dm")
+ (const_int 0)))]
""
"tst%.w %0"
[(set_attr "type" "tst")])
-(define_expand "tstqi"
- [(set (cc0)
- (match_operand:QI 0 "nonimmediate_operand" ""))]
- ""
- "m68k_last_compare_had_fp_operands = 0;")
-
(define_insn "*tstqi_internal"
[(set (cc0)
- (match_operand:QI 0 "nonimmediate_operand" "dm"))]
+ (compare (match_operand:QI 0 "nonimmediate_operand" "dm")
+ (const_int 0)))]
""
"tst%.b %0"
[(set_attr "type" "tst")])
-(define_expand "tst<mode>"
- [(set (cc0)
- (match_operand:FP 0 "general_operand" ""))]
- "TARGET_HARD_FLOAT"
-{
- m68k_last_compare_had_fp_operands = 1;
-})
-
(define_insn "tst<mode>_68881"
[(set (cc0)
- (match_operand:FP 0 "general_operand" "f<FP:dreg>m"))]
+ (compare (match_operand:FP 0 "general_operand" "f<FP:dreg>m")
+ (match_operand:FP 1 "const0_operand" "H")))]
"TARGET_68881"
{
cc_status.flags = CC_IN_68881;
@@ -414,7 +387,8 @@
(define_insn "tst<mode>_cf"
[(set (cc0)
- (match_operand:FP 0 "general_operand" "f<FP:dreg><Q>U"))]
+ (compare (match_operand:FP 0 "general_operand" "f<FP:dreg><Q>U")
+ (match_operand:FP 1 "const0_operand" "H")))]
"TARGET_COLDFIRE_FPU"
{
cc_status.flags = CC_IN_68881;
@@ -427,20 +401,11 @@
;; compare instructions.
-(define_expand "cmpdi"
- [(parallel
- [(set (cc0)
- (compare (match_operand:DI 0 "nonimmediate_operand" "")
- (match_operand:DI 1 "general_operand" "")))
- (clobber (match_scratch:DI 2 ""))])]
- ""
- "m68k_last_compare_had_fp_operands = 0;")
-
-(define_insn ""
- [(set (cc0)
- (compare (match_operand:DI 1 "nonimmediate_operand" "0,d")
- (match_operand:DI 2 "general_operand" "d,0")))
- (clobber (match_scratch:DI 0 "=d,d"))]
+(define_insn "*cmpdi_internal"
+ [(set (cc0)
+ (compare (match_operand:DI 1 "nonimmediate_operand" "0,d")
+ (match_operand:DI 2 "general_operand" "d,0")))
+ (clobber (match_scratch:DI 0 "=d,d"))]
""
{
if (rtx_equal_p (operands[0], operands[1]))
@@ -452,15 +417,71 @@
}
})
-(define_expand "cmpsi"
- [(set (cc0)
- (compare (match_operand:SI 0 "nonimmediate_operand" "")
- (match_operand:SI 1 "general_operand" "")))]
+(define_insn "cmpdi"
+ [(set (cc0)
+ (compare (match_operand:DI 0 "nonimmediate_operand")
+ (match_operand:DI 1 "general_operand")))
+ (clobber (match_scratch:DI 2))]
+ ""
+ "")
+
+
+(define_expand "cbranchdi4"
+ [(set (pc)
+ (if_then_else (match_operator 0 "ordered_comparison_operator"
+ [(match_operand:DI 1 "nonimmediate_operand")
+ (match_operand:DI 2 "general_operand")])
+ (label_ref (match_operand 3 ""))
+ (pc)))]
""
{
- m68k_last_compare_had_fp_operands = 0;
+ if (operands[2] == const0_rtx)
+ emit_insn (gen_tstdi (operands[1]));
+ else
+ emit_insn (gen_cmpdi (operands[1], operands[2]));
+ operands[1] = cc0_rtx;
+ operands[2] = const0_rtx;
})
+(define_expand "cstoredi4"
+ [(set (match_operand:QI 0 "register_operand")
+ (match_operator:QI 1 "ordered_comparison_operator"
+ [(match_operand:DI 2 "nonimmediate_operand")
+ (match_operand:DI 3 "general_operand")]))]
+ ""
+{
+ if (operands[3] == const0_rtx)
+ emit_insn (gen_tstdi (operands[2]));
+ else
+ emit_insn (gen_cmpdi (operands[2], operands[3]));
+ operands[2] = cc0_rtx;
+ operands[3] = const0_rtx;
+})
+
+
+(define_expand "cbranchsi4"
+ [(set (cc0)
+ (compare (match_operand:SI 1 "nonimmediate_operand" "")
+ (match_operand:SI 2 "general_operand" "")))
+ (set (pc)
+ (if_then_else (match_operator 0 "ordered_comparison_operator"
+ [(cc0) (const_int 0)])
+ (label_ref (match_operand 3 ""))
+ (pc)))]
+ ""
+ "")
+
+(define_expand "cstoresi4"
+ [(set (cc0)
+ (compare (match_operand:SI 2 "nonimmediate_operand" "")
+ (match_operand:SI 3 "general_operand" "")))
+ (set (match_operand:QI 0 "register_operand")
+ (match_operator:QI 1 "ordered_comparison_operator"
+ [(cc0) (const_int 0)]))]
+ ""
+ "")
+
+
;; A composite of the cmp, cmpa, cmpi & cmpm m68000 op codes.
(define_insn ""
[(set (cc0)
@@ -500,12 +521,27 @@
}
[(set_attr "type" "cmp_l")])
-(define_expand "cmphi"
+(define_expand "cbranchhi4"
[(set (cc0)
- (compare (match_operand:HI 0 "nonimmediate_src_operand" "")
- (match_operand:HI 1 "general_src_operand" "")))]
- "!TARGET_COLDFIRE"
- "m68k_last_compare_had_fp_operands = 0;")
+ (compare (match_operand:HI 1 "nonimmediate_src_operand" "")
+ (match_operand:HI 2 "m68k_subword_comparison_operand" "")))
+ (set (pc)
+ (if_then_else (match_operator 0 "ordered_comparison_operator"
+ [(cc0) (const_int 0)])
+ (label_ref (match_operand 3 ""))
+ (pc)))]
+ ""
+ "")
+
+(define_expand "cstorehi4"
+ [(set (cc0)
+ (compare (match_operand:HI 2 "nonimmediate_operand" "")
+ (match_operand:HI 3 "m68k_subword_comparison_operand" "")))
+ (set (match_operand:QI 0 "register_operand")
+ (match_operator:QI 1 "ordered_comparison_operator"
+ [(cc0) (const_int 0)]))]
+ ""
+ "")
(define_insn ""
[(set (cc0)
@@ -524,12 +560,27 @@
return "cmp%.w %d1,%d0";
})
-(define_expand "cmpqi"
+(define_expand "cbranchqi4"
[(set (cc0)
- (compare (match_operand:QI 0 "nonimmediate_src_operand" "")
- (match_operand:QI 1 "general_src_operand" "")))]
- "!TARGET_COLDFIRE"
- "m68k_last_compare_had_fp_operands = 0;")
+ (compare (match_operand:QI 1 "nonimmediate_src_operand" "")
+ (match_operand:QI 2 "m68k_subword_comparison_operand" "")))
+ (set (pc)
+ (if_then_else (match_operator 0 "ordered_comparison_operator"
+ [(cc0) (const_int 0)])
+ (label_ref (match_operand 3 ""))
+ (pc)))]
+ ""
+ "")
+
+(define_expand "cstoreqi4"
+ [(set (cc0)
+ (compare (match_operand:QI 2 "nonimmediate_src_operand" "")
+ (match_operand:QI 3 "m68k_subword_comparison_operand" "")))
+ (set (match_operand:QI 0 "register_operand")
+ (match_operator:QI 1 "ordered_comparison_operator"
+ [(cc0) (const_int 0)]))]
+ ""
+ "")
(define_insn ""
[(set (cc0)
@@ -548,12 +599,28 @@
return "cmp%.b %d1,%d0";
})
-(define_expand "cmp<mode>"
+(define_expand "cbranch<mode>4"
[(set (cc0)
- (compare (match_operand:FP 0 "register_operand" "")
- (match_operand:FP 1 "fp_src_operand" "")))]
+ (compare (match_operand:FP 1 "register_operand" "")
+ (match_operand:FP 2 "fp_src_operand" "")))
+ (set (pc)
+ (if_then_else (match_operator 0 "comparison_operator"
+ [(cc0) (const_int 0)])
+ (label_ref (match_operand 3 ""))
+ (pc)))]
"TARGET_HARD_FLOAT"
- "m68k_last_compare_had_fp_operands = 1;")
+ "")
+
+(define_expand "cstore<mode>4"
+ [(set (cc0)
+ (compare (match_operand:FP 2 "register_operand" "")
+ (match_operand:FP 3 "fp_src_operand" "")))
+ (set (match_operand:QI 0 "register_operand")
+ (match_operator:QI 1 "m68k_cstore_comparison_operator"
+ [(cc0) (const_int 0)]))]
+ "TARGET_HARD_FLOAT && !(TUNE_68060 || TARGET_COLDFIRE_FPU)"
+ "if (TARGET_COLDFIRE && operands[2] != const0_rtx)
+ FAIL;")
(define_insn "*cmp<mode>_68881"
[(set (cc0)
@@ -588,10 +655,13 @@
;; from a MEM at a constant bit position if we can't use this as a constraint.
(define_insn ""
- [(set (cc0) (zero_extract (match_operand:QI 0 "memory_src_operand" "oS")
- (const_int 1)
- (minus:SI (const_int 7)
- (match_operand:SI 1 "general_operand" "di"))))]
+ [(set
+ (cc0)
+ (compare (zero_extract:SI (match_operand:QI 0 "memory_src_operand" "oS")
+ (const_int 1)
+ (minus:SI (const_int 7)
+ (match_operand:SI 1 "general_operand" "di")))
+ (const_int 0)))]
"!TARGET_COLDFIRE"
{
return output_btst (operands, operands[1], operands[0], insn, 7);
@@ -601,20 +671,26 @@
;; has been deleted.
(define_insn ""
- [(set (cc0) (zero_extract (match_operand:QI 0 "memory_operand" "o")
- (const_int 1)
- (minus:SI (const_int 7)
- (match_operand:SI 1 "general_operand" "d"))))]
+ [(set
+ (cc0)
+ (compare (zero_extract:SI (match_operand:QI 0 "memory_operand" "o")
+ (const_int 1)
+ (minus:SI (const_int 7)
+ (match_operand:SI 1 "general_operand" "d")))
+ (const_int 0)))]
"TARGET_COLDFIRE"
{
return output_btst (operands, operands[1], operands[0], insn, 7);
})
(define_insn ""
- [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "d")
- (const_int 1)
- (minus:SI (const_int 31)
- (match_operand:SI 1 "general_operand" "di"))))]
+ [(set
+ (cc0)
+ (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "d")
+ (const_int 1)
+ (minus:SI (const_int 31)
+ (match_operand:SI 1 "general_operand" "di")))
+ (const_int 0)))]
""
{
return output_btst (operands, operands[1], operands[0], insn, 31);
@@ -625,24 +701,30 @@
;; are automatically masked to 3 or 5 bits.
(define_insn ""
- [(set (cc0) (zero_extract (match_operand:QI 0 "memory_operand" "o")
- (const_int 1)
- (minus:SI (const_int 7)
- (and:SI
- (match_operand:SI 1 "register_operand" "d")
- (const_int 7)))))]
+ [(set
+ (cc0)
+ (compare (zero_extract:SI (match_operand:QI 0 "memory_operand" "o")
+ (const_int 1)
+ (minus:SI (const_int 7)
+ (and:SI
+ (match_operand:SI 1 "register_operand" "d")
+ (const_int 7))))
+ (const_int 0)))]
""
{
return output_btst (operands, operands[1], operands[0], insn, 7);
})
(define_insn ""
- [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "d")
- (const_int 1)
- (minus:SI (const_int 31)
- (and:SI
- (match_operand:SI 1 "register_operand" "d")
- (const_int 31)))))]
+ [(set
+ (cc0)
+ (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "d")
+ (const_int 1)
+ (minus:SI (const_int 31)
+ (and:SI
+ (match_operand:SI 1 "register_operand" "d")
+ (const_int 31))))
+ (const_int 0)))]
""
{
return output_btst (operands, operands[1], operands[0], insn, 31);
@@ -651,9 +733,12 @@
;; Nonoffsettable mem refs are ok in this one pattern
;; since we don't try to adjust them.
(define_insn ""
- [(set (cc0) (zero_extract (match_operand:QI 0 "memory_operand" "m")
- (const_int 1)
- (match_operand:SI 1 "const_int_operand" "n")))]
+ [(set
+ (cc0)
+ (compare (zero_extract:SI (match_operand:QI 0 "memory_operand" "m")
+ (const_int 1)
+ (match_operand:SI 1 "const_int_operand" "n"))
+ (const_int 0)))]
"(unsigned) INTVAL (operands[1]) < 8 && !TARGET_COLDFIRE"
{
operands[1] = GEN_INT (7 - INTVAL (operands[1]));
@@ -661,9 +746,12 @@
})
(define_insn ""
- [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "do")
- (const_int 1)
- (match_operand:SI 1 "const_int_operand" "n")))]
+ [(set
+ (cc0)
+ (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "do")
+ (const_int 1)
+ (match_operand:SI 1 "const_int_operand" "n"))
+ (const_int 0)))]
"!TARGET_COLDFIRE"
{
if (GET_CODE (operands[0]) == MEM)
@@ -681,9 +769,12 @@
;; The 'o' has been replaced with 'Q'.
(define_insn ""
- [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "dQ")
- (const_int 1)
- (match_operand:SI 1 "const_int_operand" "n")))]
+ [(set
+ (cc0)
+ (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "dQ")
+ (const_int 1)
+ (match_operand:SI 1 "const_int_operand" "n"))
+ (const_int 0)))]
"TARGET_COLDFIRE"
{
if (GET_CODE (operands[0]) == MEM)
@@ -779,7 +870,41 @@
{
rtx tmp, base, offset;
- if (flag_pic && !TARGET_PCREL && symbolic_operand (operands[1], SImode))
+ /* Recognize the case where operand[1] is a reference to thread-local
+ data and load its address to a register. */
+ if (!TARGET_PCREL && m68k_tls_reference_p (operands[1], false))
+ {
+ rtx tmp = operands[1];
+ rtx addend = NULL;
+
+ if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
+ {
+ addend = XEXP (XEXP (tmp, 0), 1);
+ tmp = XEXP (XEXP (tmp, 0), 0);
+ }
+
+ gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
+ gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
+
+ tmp = m68k_legitimize_tls_address (tmp);
+
+ if (addend)
+ {
+ if (!REG_P (tmp))
+ {
+ rtx reg;
+
+ reg = gen_reg_rtx (Pmode);
+ emit_move_insn (reg, tmp);
+ tmp = reg;
+ }
+
+ tmp = gen_rtx_PLUS (SImode, tmp, addend);
+ }
+
+ operands[1] = tmp;
+ }
+ else if (flag_pic && !TARGET_PCREL && symbolic_operand (operands[1], SImode))
{
/* The source is an address which requires PIC relocation.
Call legitimize_pic_address with the source, mode, and a relocation
@@ -2338,9 +2463,9 @@
"* return output_addsi3 (operands);")
(define_insn_and_split "*addsi3_5200"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=mr,mr,a,m,r, ?a, ?a,?a,?a")
- (plus:SI (match_operand:SI 1 "general_operand" "%0, 0, 0,0,0, a, a, r, a")
- (match_operand:SI 2 "general_src_operand" " I, L, J,d,mrKi,Cj, r, a, J")))]
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=mr,mr,a, m,r, ?a, ?a,?a,?a")
+ (plus:SI (match_operand:SI 1 "general_operand" "%0, 0, 0, 0,0, a, a, r, a")
+ (match_operand:SI 2 "general_src_operand" " I, L, JCu,d,mrKi,Cj, r, a, JCu")))]
"TARGET_COLDFIRE"
{
switch (which_alternative)
@@ -2382,9 +2507,9 @@
(plus:SI (match_dup 0)
(match_dup 1)))]
""
- [(set_attr "type" "aluq_l,aluq_l,lea,alu_l,alu_l,*,lea,lea,lea")
- (set_attr "opy" "2,2,*,2,2,*,*,*,*")
- (set_attr "opy_type" "*,*,mem5,*,*,*,mem6,mem6,mem5")])
+ [(set_attr "type" "aluq_l,aluq_l,lea, alu_l,alu_l,*,lea, lea, lea")
+ (set_attr "opy" "2, 2, *, 2, 2, *,*, *, *")
+ (set_attr "opy_type" "*, *, mem5,*, *, *,mem6,mem6,mem5")])
(define_insn ""
[(set (match_operand:SI 0 "nonimmediate_operand" "=a")
@@ -5751,9 +5876,10 @@
(define_insn ""
[(set (cc0)
- (zero_extract:SI (match_operand:QI 0 "memory_operand" "o")
- (match_operand:SI 1 "const_int_operand" "n")
- (match_operand:SI 2 "general_operand" "dn")))]
+ (compare (zero_extract:SI (match_operand:QI 0 "memory_operand" "o")
+ (match_operand:SI 1 "const_int_operand" "n")
+ (match_operand:SI 2 "general_operand" "dn"))
+ (const_int 0)))]
"TARGET_68020 && TARGET_BITFIELD"
{
if (operands[1] == const1_rtx
@@ -5776,9 +5902,10 @@
;;; now handle the register cases
(define_insn ""
[(set (cc0)
- (zero_extract:SI (match_operand:SI 0 "register_operand" "d")
- (match_operand:SI 1 "const_int_operand" "n")
- (match_operand:SI 2 "general_operand" "dn")))]
+ (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "d")
+ (match_operand:SI 1 "const_int_operand" "n")
+ (match_operand:SI 2 "general_operand" "dn"))
+ (const_int 0)))]
"TARGET_68020 && TARGET_BITFIELD"
{
if (operands[1] == const1_rtx
@@ -5798,7 +5925,7 @@
(define_insn "scc0_di"
[(set (match_operand:QI 0 "nonimmediate_operand" "=dm")
- (match_operator 1 "valid_dbcc_comparison_p"
+ (match_operator 1 "ordered_comparison_operator"
[(match_operand:DI 2 "general_operand" "ro") (const_int 0)]))]
"! TARGET_COLDFIRE"
{
@@ -5807,7 +5934,7 @@
(define_insn "scc0_di_5200"
[(set (match_operand:QI 0 "nonimmediate_operand" "=d")
- (match_operator 1 "valid_dbcc_comparison_p"
+ (match_operator 1 "ordered_comparison_operator"
[(match_operand:DI 2 "general_operand" "ro") (const_int 0)]))]
"TARGET_COLDFIRE"
{
@@ -5816,7 +5943,7 @@
(define_insn "scc_di"
[(set (match_operand:QI 0 "nonimmediate_operand" "=dm,dm")
- (match_operator 1 "valid_dbcc_comparison_p"
+ (match_operator 1 "ordered_comparison_operator"
[(match_operand:DI 2 "general_operand" "ro,r")
(match_operand:DI 3 "general_operand" "r,ro")]))]
"! TARGET_COLDFIRE"
@@ -5826,7 +5953,7 @@
(define_insn "scc_di_5200"
[(set (match_operand:QI 0 "nonimmediate_operand" "=d,d")
- (match_operator 1 "valid_dbcc_comparison_p"
+ (match_operator 1 "ordered_comparison_operator"
[(match_operand:DI 2 "general_operand" "ro,r")
(match_operand:DI 3 "general_operand" "r,ro")]))]
"TARGET_COLDFIRE"
@@ -5838,19 +5965,6 @@
;; memory, but we cannot allow it to be in memory in case the address
;; needs to be reloaded.
-(define_expand "seq"
- [(set (match_operand:QI 0 "register_operand" "")
- (eq:QI (cc0) (const_int 0)))]
- ""
-{
- if ((TUNE_68060 || TARGET_COLDFIRE_FPU)
- && m68k_last_compare_had_fp_operands)
- {
- m68k_last_compare_had_fp_operands = 0;
- FAIL;
- }
-})
-
(define_insn ""
[(set (match_operand:QI 0 "register_operand" "=d")
(eq:QI (cc0) (const_int 0)))]
@@ -5860,19 +5974,6 @@
OUTPUT_JUMP ("seq %0", "fseq %0", "seq %0");
})
-(define_expand "sne"
- [(set (match_operand:QI 0 "register_operand" "")
- (ne:QI (cc0) (const_int 0)))]
- ""
-{
- if ((TUNE_68060 || TARGET_COLDFIRE_FPU)
- && m68k_last_compare_had_fp_operands)
- {
- m68k_last_compare_had_fp_operands = 0;
- FAIL;
- }
-})
-
(define_insn ""
[(set (match_operand:QI 0 "register_operand" "=d")
(ne:QI (cc0) (const_int 0)))]
@@ -5882,19 +5983,6 @@
OUTPUT_JUMP ("sne %0", "fsne %0", "sne %0");
})
-(define_expand "sgt"
- [(set (match_operand:QI 0 "register_operand" "")
- (gt:QI (cc0) (const_int 0)))]
- ""
-{
- if ((TUNE_68060 || TARGET_COLDFIRE_FPU)
- && m68k_last_compare_had_fp_operands)
- {
- m68k_last_compare_had_fp_operands = 0;
- FAIL;
- }
-})
-
(define_insn ""
[(set (match_operand:QI 0 "register_operand" "=d")
(gt:QI (cc0) (const_int 0)))]
@@ -5904,12 +5992,6 @@
OUTPUT_JUMP ("sgt %0", "fsgt %0", 0);
})
-(define_expand "sgtu"
- [(set (match_operand:QI 0 "register_operand" "")
- (gtu:QI (cc0) (const_int 0)))]
- ""
- "")
-
(define_insn ""
[(set (match_operand:QI 0 "register_operand" "=d")
(gtu:QI (cc0) (const_int 0)))]
@@ -5919,19 +6001,6 @@
return "shi %0";
})
-(define_expand "slt"
- [(set (match_operand:QI 0 "register_operand" "")
- (lt:QI (cc0) (const_int 0)))]
- ""
-{
- if ((TUNE_68060 || TARGET_COLDFIRE_FPU)
- && m68k_last_compare_had_fp_operands)
- {
- m68k_last_compare_had_fp_operands = 0;
- FAIL;
- }
-})
-
(define_insn ""
[(set (match_operand:QI 0 "register_operand" "=d")
(lt:QI (cc0) (const_int 0)))]
@@ -5941,12 +6010,6 @@
OUTPUT_JUMP ("slt %0", "fslt %0", "smi %0");
})
-(define_expand "sltu"
- [(set (match_operand:QI 0 "register_operand" "")
- (ltu:QI (cc0) (const_int 0)))]
- ""
- "")
-
(define_insn ""
[(set (match_operand:QI 0 "register_operand" "=d")
(ltu:QI (cc0) (const_int 0)))]
@@ -5956,19 +6019,6 @@
return "scs %0";
})
-(define_expand "sge"
- [(set (match_operand:QI 0 "register_operand" "")
- (ge:QI (cc0) (const_int 0)))]
- ""
-{
- if ((TUNE_68060 || TARGET_COLDFIRE_FPU)
- && m68k_last_compare_had_fp_operands)
- {
- m68k_last_compare_had_fp_operands = 0;
- FAIL;
- }
-})
-
(define_insn ""
[(set (match_operand:QI 0 "register_operand" "=d")
(ge:QI (cc0) (const_int 0)))]
@@ -5978,12 +6028,6 @@
OUTPUT_JUMP ("sge %0", "fsge %0", "spl %0");
})
-(define_expand "sgeu"
- [(set (match_operand:QI 0 "register_operand" "")
- (geu:QI (cc0) (const_int 0)))]
- ""
- "")
-
(define_insn "*scc"
[(set (match_operand:QI 0 "register_operand" "=d")
(geu:QI (cc0) (const_int 0)))]
@@ -5994,19 +6038,6 @@
}
[(set_attr "type" "scc")])
-(define_expand "sle"
- [(set (match_operand:QI 0 "register_operand" "")
- (le:QI (cc0) (const_int 0)))]
- ""
-{
- if ((TUNE_68060 || TARGET_COLDFIRE_FPU)
- && m68k_last_compare_had_fp_operands)
- {
- m68k_last_compare_had_fp_operands = 0;
- FAIL;
- }
-})
-
(define_insn ""
[(set (match_operand:QI 0 "register_operand" "=d")
(le:QI (cc0) (const_int 0)))]
@@ -6016,12 +6047,6 @@
OUTPUT_JUMP ("sle %0", "fsle %0", 0);
})
-(define_expand "sleu"
- [(set (match_operand:QI 0 "register_operand" "")
- (leu:QI (cc0) (const_int 0)))]
- ""
- "")
-
(define_insn "*sls"
[(set (match_operand:QI 0 "register_operand" "=d")
(leu:QI (cc0) (const_int 0)))]
@@ -6032,15 +6057,6 @@
}
[(set_attr "type" "scc")])
-(define_expand "sordered"
- [(set (match_operand:QI 0 "register_operand" "")
- (ordered:QI (cc0) (const_int 0)))]
- "TARGET_68881 && !TUNE_68060"
-{
- gcc_assert (m68k_last_compare_had_fp_operands);
- m68k_last_compare_had_fp_operands = 0;
-})
-
(define_insn "*sordered_1"
[(set (match_operand:QI 0 "register_operand" "=d")
(ordered:QI (cc0) (const_int 0)))]
@@ -6050,15 +6066,6 @@
return "fsor %0";
})
-(define_expand "sunordered"
- [(set (match_operand:QI 0 "register_operand" "")
- (unordered:QI (cc0) (const_int 0)))]
- "TARGET_68881 && !TUNE_68060"
-{
- gcc_assert (m68k_last_compare_had_fp_operands);
- m68k_last_compare_had_fp_operands = 0;
-})
-
(define_insn "*sunordered_1"
[(set (match_operand:QI 0 "register_operand" "=d")
(unordered:QI (cc0) (const_int 0)))]
@@ -6068,15 +6075,6 @@
return "fsun %0";
})
-(define_expand "suneq"
- [(set (match_operand:QI 0 "register_operand" "")
- (uneq:QI (cc0) (const_int 0)))]
- "TARGET_68881 && !TUNE_68060"
-{
- gcc_assert (m68k_last_compare_had_fp_operands);
- m68k_last_compare_had_fp_operands = 0;
-})
-
(define_insn "*suneq_1"
[(set (match_operand:QI 0 "register_operand" "=d")
(uneq:QI (cc0) (const_int 0)))]
@@ -6086,15 +6084,6 @@
return "fsueq %0";
})
-(define_expand "sunge"
- [(set (match_operand:QI 0 "register_operand" "")
- (unge:QI (cc0) (const_int 0)))]
- "TARGET_68881 && !TUNE_68060"
-{
- gcc_assert (m68k_last_compare_had_fp_operands);
- m68k_last_compare_had_fp_operands = 0;
-})
-
(define_insn "*sunge_1"
[(set (match_operand:QI 0 "register_operand" "=d")
(unge:QI (cc0) (const_int 0)))]
@@ -6104,15 +6093,6 @@
return "fsuge %0";
})
-(define_expand "sungt"
- [(set (match_operand:QI 0 "register_operand" "")
- (ungt:QI (cc0) (const_int 0)))]
- "TARGET_68881 && !TUNE_68060"
-{
- gcc_assert (m68k_last_compare_had_fp_operands);
- m68k_last_compare_had_fp_operands = 0;
-})
-
(define_insn "*sungt_1"
[(set (match_operand:QI 0 "register_operand" "=d")
(ungt:QI (cc0) (const_int 0)))]
@@ -6122,15 +6102,6 @@
return "fsugt %0";
})
-(define_expand "sunle"
- [(set (match_operand:QI 0 "register_operand" "")
- (unle:QI (cc0) (const_int 0)))]
- "TARGET_68881 && !TUNE_68060"
-{
- gcc_assert (m68k_last_compare_had_fp_operands);
- m68k_last_compare_had_fp_operands = 0;
-})
-
(define_insn "*sunle_1"
[(set (match_operand:QI 0 "register_operand" "=d")
(unle:QI (cc0) (const_int 0)))]
@@ -6140,15 +6111,6 @@
return "fsule %0";
})
-(define_expand "sunlt"
- [(set (match_operand:QI 0 "register_operand" "")
- (unlt:QI (cc0) (const_int 0)))]
- "TARGET_68881 && !TUNE_68060"
-{
- gcc_assert (m68k_last_compare_had_fp_operands);
- m68k_last_compare_had_fp_operands = 0;
-})
-
(define_insn "*sunlt_1"
[(set (match_operand:QI 0 "register_operand" "=d")
(unlt:QI (cc0) (const_int 0)))]
@@ -6158,15 +6120,6 @@
return "fsult %0";
})
-(define_expand "sltgt"
- [(set (match_operand:QI 0 "register_operand" "")
- (ltgt:QI (cc0) (const_int 0)))]
- "TARGET_68881 && !TUNE_68060"
-{
- gcc_assert (m68k_last_compare_had_fp_operands);
- m68k_last_compare_had_fp_operands = 0;
-})
-
(define_insn "*sltgt_1"
[(set (match_operand:QI 0 "register_operand" "=d")
(ltgt:QI (cc0) (const_int 0)))]
@@ -7758,23 +7711,54 @@
"trap #7"
[(set_attr "type" "trap")])
-(define_expand "conditional_trap"
- [(trap_if (match_operator 0 "valid_dbcc_comparison_p"
+(define_expand "ctrapdi4"
+ [(trap_if (match_operator 0 "ordered_comparison_operator"
[(cc0) (const_int 0)])
- (match_operand:SI 1 "const_int_operand" "I"))]
+ (match_operand:SI 3 "const1_operand" ""))]
"TARGET_68020"
{
- if (m68k_last_compare_had_fp_operands)
- {
- m68k_last_compare_had_fp_operands = 0;
- FAIL;
- }
+ if (operands[2] == const0_rtx)
+ emit_insn (gen_tstdi (operands[1]));
+ else
+ emit_insn (gen_cmpdi (operands[1], operands[2]));
+ operands[1] = cc0_rtx;
+ operands[2] = const0_rtx;
})
+(define_expand "ctrapsi4"
+ [(set (cc0)
+ (compare (match_operand:SI 1 "nonimmediate_operand" "")
+ (match_operand:SI 2 "general_operand" "")))
+ (trap_if (match_operator 0 "ordered_comparison_operator"
+ [(cc0) (const_int 0)])
+ (match_operand:SI 3 "const1_operand" ""))]
+ "TARGET_68020"
+ "")
+
+(define_expand "ctraphi4"
+ [(set (cc0)
+ (compare (match_operand:HI 1 "nonimmediate_src_operand" "")
+ (match_operand:HI 2 "general_src_operand" "")))
+ (trap_if (match_operator 0 "ordered_comparison_operator"
+ [(cc0) (const_int 0)])
+ (match_operand:SI 3 "const1_operand" ""))]
+ "TARGET_68020"
+ "")
+
+(define_expand "ctrapqi4"
+ [(set (cc0)
+ (compare (match_operand:QI 1 "nonimmediate_src_operand" "")
+ (match_operand:QI 2 "general_src_operand" "")))
+ (trap_if (match_operator 0 "ordered_comparison_operator"
+ [(cc0) (const_int 0)])
+ (match_operand:SI 3 "const1_operand" ""))]
+ "TARGET_68020"
+ "")
+
(define_insn "*conditional_trap"
- [(trap_if (match_operator 0 "valid_dbcc_comparison_p"
+ [(trap_if (match_operator 0 "ordered_comparison_operator"
[(cc0) (const_int 0)])
- (match_operand:SI 1 "const_int_operand" "I"))]
+ (match_operand:SI 1 "const1_operand" "I"))]
"TARGET_68020 && ! flags_in_68881 ()"
{
switch (GET_CODE (operands[0]))
diff --git a/gcc/config/m68k/m68k.opt b/gcc/config/m68k/m68k.opt
index b0d3b3c0d59..d5aa9fa7698 100644
--- a/gcc/config/m68k/m68k.opt
+++ b/gcc/config/m68k/m68k.opt
@@ -182,3 +182,7 @@ Tune for the specified target CPU or architecture
mxgot
Target Report Mask(XGOT)
Support more than 8192 GOT entries on ColdFire
+
+mxtls
+Target Report Mask(XTLS)
+Support TLS segment larger than 64K
diff --git a/gcc/config/m68k/predicates.md b/gcc/config/m68k/predicates.md
index b43e55b8972..6ca261fb92a 100644
--- a/gcc/config/m68k/predicates.md
+++ b/gcc/config/m68k/predicates.md
@@ -124,13 +124,20 @@
(and (match_code "eq,ne,gtu,ltu,geu,leu,gt,lt,ge,le")
(match_test "valid_dbcc_comparison_p_2 (op, mode)")))
+(define_predicate "m68k_cstore_comparison_operator"
+ (if_then_else (match_test "TARGET_68881")
+ (match_operand 0 "comparison_operator")
+ (match_operand 0 "ordered_comparison_operator")))
+
;; Check for sign_extend or zero_extend. Used for bit-count operands.
(define_predicate "extend_operator"
(match_code "sign_extend,zero_extend"))
;; Returns true if OP is either a symbol reference or a sum of a
-;; symbol reference and a constant.
+;; symbol reference and a constant. This predicate is for "raw"
+;; symbol references not yet processed by legitimize*_address,
+;; hence we do not handle UNSPEC_{XGOT, TLS, XTLS} here.
(define_predicate "symbolic_operand"
(match_code "symbol_ref,label_ref,const")
@@ -193,6 +200,24 @@
(and (match_code "mem")
(match_test "GET_CODE (XEXP (op, 0)) == PRE_DEC")))
+;; A zero constant.
+(define_predicate "const0_operand"
+ (and (match_code "const_int,const_double,const_vector")
+ (match_test "op == CONST0_RTX (mode)")))
+
+;; A one constant (operand for conditional_trap).
+(define_predicate "const1_operand"
+ (and (match_code "const_int")
+ (match_test "op == const1_rtx")))
+
+;; A valid operand for a HImode or QImode conditional operation.
+;; ColdFire has tst patterns, but not cmp patterns.
+(define_predicate "m68k_subword_comparison_operand"
+ (if_then_else (match_test "TARGET_COLDFIRE")
+ (and (match_code "const_int")
+ (match_test "op == const0_rtx"))
+ (match_operand 0 "general_src_operand")))
+
;; An operand for movsi_const0 pattern.
(define_predicate "movsi_const0_operand"
(and (match_operand 0 "nonimmediate_operand")
diff --git a/gcc/config/m68k/t-uclinux b/gcc/config/m68k/t-uclinux
index 15d68aa8dd6..e1711a3443e 100644
--- a/gcc/config/m68k/t-uclinux
+++ b/gcc/config/m68k/t-uclinux
@@ -19,8 +19,8 @@
# crti and crtn are provided by uClibc.
EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o
-# Only include multilibs for the 68020 and for CPUs without an MMU.
-M68K_MLIB_CPU += && (MLIB == "68020" || !match(FLAGS, "FL_MMU"))
+# Include multilibs for CPUs without an MMU or with FL_UCLINUX
+M68K_MLIB_CPU += && (!match(FLAGS, "FL_MMU") || match(FLAGS, "FL_UCLINUX"))
# Add multilibs for execute-in-place and shared-library code.
M68K_MLIB_OPTIONS += msep-data/mid-shared-library
diff --git a/gcc/config/mcore/mcore-protos.h b/gcc/config/mcore/mcore-protos.h
index 93c7c11e766..331cf7191d7 100644
--- a/gcc/config/mcore/mcore-protos.h
+++ b/gcc/config/mcore/mcore-protos.h
@@ -46,21 +46,17 @@ extern rtx mcore_function_value (const_tree, const_tree);
#ifdef RTX_CODE
-extern GTY(()) rtx arch_compare_op0;
-extern GTY(()) rtx arch_compare_op1;
-
extern const char * mcore_output_bclri (rtx, int);
extern const char * mcore_output_bseti (rtx, int);
extern const char * mcore_output_cmov (rtx *, int, const char *);
extern char * mcore_output_call (rtx *, int);
extern int mcore_is_dead (rtx, rtx);
extern int mcore_expand_insv (rtx *);
-extern int mcore_modify_comparison (RTX_CODE);
extern bool mcore_expand_block_move (rtx *);
extern const char * mcore_output_andn (rtx, rtx *);
extern void mcore_print_operand_address (FILE *, rtx);
extern void mcore_print_operand (FILE *, rtx, int);
-extern rtx mcore_gen_compare_reg (RTX_CODE);
+extern bool mcore_gen_compare (RTX_CODE, rtx, rtx);
extern int mcore_symbolic_address_p (rtx);
extern bool mcore_r15_operand_p (rtx);
extern enum reg_class mcore_secondary_reload_class (enum reg_class, enum machine_mode, rtx);
diff --git a/gcc/config/mcore/mcore.c b/gcc/config/mcore/mcore.c
index 24cc9406ed7..d03a2839179 100644
--- a/gcc/config/mcore/mcore.c
+++ b/gcc/config/mcore/mcore.c
@@ -57,11 +57,6 @@ long mcore_current_compilation_timestamp = 0;
/* Global variables for machine-dependent things. */
-/* Saved operands from the last compare to use when we generate an scc
- or bcc insn. */
-rtx arch_compare_op0;
-rtx arch_compare_op1;
-
/* Provides the class number of the smallest class containing
reg number. */
const int regno_reg_class[FIRST_PSEUDO_REGISTER] =
@@ -132,7 +127,7 @@ static void mcore_mark_dllexport (tree);
static void mcore_mark_dllimport (tree);
static int mcore_dllexport_p (tree);
static int mcore_dllimport_p (tree);
-const struct attribute_spec mcore_attribute_table[];
+EXPORTED_CONST struct attribute_spec mcore_attribute_table[];
static tree mcore_handle_naked_attribute (tree *, tree, tree, int, bool *);
#ifdef OBJECT_FORMAT_ELF
static void mcore_asm_named_section (const char *,
@@ -519,26 +514,36 @@ mcore_rtx_costs (rtx x, int code, int outer_code, int * total,
}
}
-/* Check to see if a comparison against a constant can be made more efficient
- by incrementing/decrementing the constant to get one that is more efficient
- to load. */
+/* Prepare the operands for a comparison. Return whether the branch/setcc
+ should reverse the operands. */
-int
-mcore_modify_comparison (enum rtx_code code)
+bool
+mcore_gen_compare (enum rtx_code code, rtx op0, rtx op1)
{
- rtx op1 = arch_compare_op1;
-
+ rtx cc_reg = gen_rtx_REG (CCmode, CC_REG);
+ bool invert;
+
if (GET_CODE (op1) == CONST_INT)
{
HOST_WIDE_INT val = INTVAL (op1);
switch (code)
{
+ case GTU:
+ /* Unsigned > 0 is the same as != 0; everything else is converted
+ below to LEU (reversed cmphs). */
+ if (val == 0)
+ code = NE;
+ break;
+
+ /* Check whether (LE A imm) can become (LT A imm + 1),
+ or (GT A imm) can become (GE A imm + 1). */
+ case GT:
case LE:
if (CONST_OK_FOR_J (val + 1))
{
- arch_compare_op1 = GEN_INT (val + 1);
- return 1;
+ op1 = GEN_INT (val + 1);
+ code = code == LE ? LT : GE;
}
break;
@@ -546,28 +551,18 @@ mcore_modify_comparison (enum rtx_code code)
break;
}
}
-
- return 0;
-}
-
-/* Prepare the operands for a comparison. */
-
-rtx
-mcore_gen_compare_reg (enum rtx_code code)
-{
- rtx op0 = arch_compare_op0;
- rtx op1 = arch_compare_op1;
- rtx cc_reg = gen_rtx_REG (CCmode, CC_REG);
-
+
if (CONSTANT_P (op1) && GET_CODE (op1) != CONST_INT)
op1 = force_reg (SImode, op1);
/* cmpnei: 0-31 (K immediate)
cmplti: 1-32 (J immediate, 0 using btsti x,31). */
+ invert = false;
switch (code)
{
case EQ: /* Use inverted condition, cmpne. */
code = NE;
+ invert = true;
/* Drop through. */
case NE: /* Use normal condition, cmpne. */
@@ -577,6 +572,7 @@ mcore_gen_compare_reg (enum rtx_code code)
case LE: /* Use inverted condition, reversed cmplt. */
code = GT;
+ invert = true;
/* Drop through. */
case GT: /* Use normal condition, reversed cmplt. */
@@ -586,6 +582,7 @@ mcore_gen_compare_reg (enum rtx_code code)
case GE: /* Use inverted condition, cmplt. */
code = LT;
+ invert = true;
/* Drop through. */
case LT: /* Use normal condition, cmplt. */
@@ -597,13 +594,10 @@ mcore_gen_compare_reg (enum rtx_code code)
break;
case GTU: /* Use inverted condition, cmple. */
- /* Unsigned > 0 is the same as != 0, but we need to invert the
- condition, so we want to set code = EQ. This cannot be done
- however, as the mcore does not support such a test. Instead
- we cope with this case in the "bgtu" pattern itself so we
- should never reach this point. */
+ /* We coped with unsigned > 0 above. */
gcc_assert (GET_CODE (op1) != CONST_INT || INTVAL (op1) != 0);
code = LEU;
+ invert = true;
/* Drop through. */
case LEU: /* Use normal condition, reversed cmphs. */
@@ -613,6 +607,7 @@ mcore_gen_compare_reg (enum rtx_code code)
case LTU: /* Use inverted condition, cmphs. */
code = GEU;
+ invert = true;
/* Drop through. */
case GEU: /* Use normal condition, cmphs. */
@@ -624,9 +619,10 @@ mcore_gen_compare_reg (enum rtx_code code)
break;
}
- emit_insn (gen_rtx_SET (VOIDmode, cc_reg, gen_rtx_fmt_ee (code, CCmode, op0, op1)));
-
- return cc_reg;
+ emit_insn (gen_rtx_SET (VOIDmode,
+ cc_reg,
+ gen_rtx_fmt_ee (code, CCmode, op0, op1)));
+ return invert;
}
int
diff --git a/gcc/config/mcore/mcore.md b/gcc/config/mcore/mcore.md
index 74906993e20..65b91588fc2 100644
--- a/gcc/config/mcore/mcore.md
+++ b/gcc/config/mcore/mcore.md
@@ -303,22 +303,6 @@
""
"cmphs %1,%0")
-;; We save the compare operands in the cmpxx patterns and use them when
-;; we generate the branch.
-
-;; We accept constants here, in case we can modify them to ones which
-;; are more efficient to load. E.g. change 'x <= 62' to 'x < 63'.
-
-(define_expand "cmpsi"
- [(set (reg:CC 17) (compare:CC (match_operand:SI 0 "mcore_compare_operand" "")
- (match_operand:SI 1 "nonmemory_operand" "")))]
- ""
- "
-{ arch_compare_op0 = operands[0];
- arch_compare_op1 = operands[1];
- DONE;
-}")
-
;; -------------------------------------------------------------------------
;; Logical operations
;; -------------------------------------------------------------------------
@@ -1479,6 +1463,10 @@
;; Define the real conditional branch instructions.
;; ------------------------------------------------------------------------
+;; At top-level, condition test are eq/ne, because we
+;; are comparing against the condition register (which
+;; has the result of the true relational test
+
(define_insn "branch_true"
[(set (pc) (if_then_else (ne (reg:CC 17) (const_int 0))
(label_ref (match_operand 0 "" ""))
@@ -1513,189 +1501,28 @@
;; Conditional branch insns
-;; At top-level, condition test are eq/ne, because we
-;; are comparing against the condition register (which
-;; has the result of the true relational test
-
-; There is no beq compare, so we reverse the branch arms.
-
-(define_expand "beq"
- [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- ""
- "
-{
- operands[1] = mcore_gen_compare_reg (EQ);
-}")
-
-(define_expand "bne"
- [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- operands[1] = mcore_gen_compare_reg (NE);
-}")
-
-; check whether (GT A imm) can become (LE A imm) with the branch reversed.
-; if so, emit a (LT A imm + 1) in place of the (LE A imm). BRC
-
-(define_expand "bgt"
- [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (mcore_modify_comparison (LE))
- {
- emit_jump_insn (gen_reverse_blt (operands[0]));
- DONE;
- }
- operands[1] = mcore_gen_compare_reg (GT);
-}")
-
-; There is no ble compare, so we reverse the branch arms.
-; reversed the condition and branch arms for ble -- the check_dbra_loop()
-; transformation assumes that ble uses a branch-true with the label as
-; as the target. BRC
-
-; check whether (LE A imm) can become (LT A imm + 1).
-
-(define_expand "ble"
- [(set (pc) (if_then_else (eq (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (mcore_modify_comparison (LE))
- {
- emit_jump_insn (gen_blt (operands[0]));
- DONE;
- }
- operands[1] = mcore_gen_compare_reg (LE);
-}")
-
-; make generating a reversed blt simple
-(define_expand "reverse_blt"
- [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- ""
- "
-{
- operands[1] = mcore_gen_compare_reg (LT);
-}")
-
-(define_expand "blt"
- [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- operands[1] = mcore_gen_compare_reg (LT);
-}")
-
-; There is no bge compare, so we reverse the branch arms.
-
-(define_expand "bge"
- [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- ""
- "
-{
- operands[1] = mcore_gen_compare_reg (GE);
-}")
-
-; There is no gtu compare, so we reverse the branch arms
-
-;(define_expand "bgtu"
-; [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
-; (pc)
-; (label_ref (match_operand 0 "" ""))))]
-; ""
-; "
-;{
-; if (GET_CODE (arch_compare_op1) == CONST_INT
-; && INTVAL (arch_compare_op1) == 0)
-; operands[1] = mcore_gen_compare_reg (NE);
-; else
-; { if (mcore_modify_comparison (GTU))
-; {
-; emit_jump_insn (gen_bgeu (operands[0]));
-; DONE;
-; }
-; operands[1] = mcore_gen_compare_reg (LEU);
-; }
-;}")
-
-(define_expand "bgtu"
- [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- ""
- "
-{
- if (GET_CODE (arch_compare_op1) == CONST_INT
- && INTVAL (arch_compare_op1) == 0)
- {
- /* The inverse of '> 0' for an unsigned test is
- '== 0' but we do not have such an instruction available.
- Instead we must reverse the branch (back to the normal
- ordering) and test '!= 0'. */
-
- operands[1] = mcore_gen_compare_reg (NE);
-
- emit_jump_insn (gen_rtx_SET (VOIDmode,
- pc_rtx,
- gen_rtx_IF_THEN_ELSE (VOIDmode,
- gen_rtx_NE (VOIDmode,
- operands[1],
- const0_rtx),
- gen_rtx_LABEL_REF (VOIDmode,operands[0]),
- pc_rtx)));
- DONE;
- }
- operands[1] = mcore_gen_compare_reg (GTU);
-}")
-
-
-(define_expand "bleu"
- [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
+(define_expand "cbranchsi4"
+ [(set (pc)
+ (if_then_else (match_operator:SI 0 "ordered_comparison_operator"
+ [(match_operand:SI 1 "mcore_compare_operand")
+ (match_operand:SI 2 "nonmemory_operand")])
+ (label_ref (match_operand 3 ""))
+ (pc)))]
""
"
{
- operands[1] = mcore_gen_compare_reg (LEU);
-}")
+ bool invert;
+ invert = mcore_gen_compare (GET_CODE (operands[0]),
+ operands[1], operands[2]);
-; There is no bltu compare, so we reverse the branch arms
-(define_expand "bltu"
- [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- ""
- "
-{
- operands[1] = mcore_gen_compare_reg (LTU);
+ if (invert)
+ emit_jump_insn (gen_branch_false (operands[3]));
+ else
+ emit_jump_insn (gen_branch_true (operands[3]));
+ DONE;
}")
-(define_expand "bgeu"
- [(set (pc) (if_then_else (ne (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- operands[1] = mcore_gen_compare_reg (GEU);
-}")
;; ------------------------------------------------------------------------
;; Jump and linkage insns
@@ -1853,118 +1680,23 @@
(set (match_dup 0) (eq:SI (reg:CC 17) (const_int 0)))])
-(define_expand "seq"
- [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
- (eq:SI (match_dup 1) (const_int 0)))]
- ""
- "
-{
- operands[1] = mcore_gen_compare_reg (NE);
-}")
-
-(define_expand "sne"
- [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
- (ne:SI (match_dup 1) (const_int 0)))]
- ""
- "
-{
- operands[1] = mcore_gen_compare_reg (NE);
-}")
-
-(define_expand "slt"
- [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
- (ne:SI (match_dup 1) (const_int 0)))]
- ""
- "
-{
- operands[1] = mcore_gen_compare_reg (LT);
-}")
-
-; make generating a LT with the comparison reversed easy. BRC
-(define_expand "reverse_slt"
- [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
- (eq:SI (match_dup 1) (const_int 0)))]
- ""
- "
-{
- operands[1] = mcore_gen_compare_reg (LT);
-}")
-
-(define_expand "sge"
- [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
- (eq:SI (match_dup 1) (const_int 0)))]
- ""
- "
-{
- operands[1] = mcore_gen_compare_reg (LT);
-}")
-
-; check whether (GT A imm) can become (LE A imm) with the comparison
-; reversed. if so, emit a (LT A imm + 1) in place of the (LE A imm). BRC
-
-(define_expand "sgt"
- [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
- (ne:SI (match_dup 1) (const_int 0)))]
- ""
- "
-{
- if (mcore_modify_comparison (LE))
- {
- emit_insn (gen_reverse_slt (operands[0]));
- DONE;
- }
-
- operands[1] = mcore_gen_compare_reg (GT);
-}")
-
-(define_expand "sle"
- [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
- (eq:SI (match_dup 1) (const_int 0)))]
- ""
- "
-{
- if (mcore_modify_comparison (LE))
- {
- emit_insn (gen_slt (operands[0]));
- DONE;
- }
- operands[1] = mcore_gen_compare_reg (GT);
-}")
-
-(define_expand "sltu"
- [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
- (eq:SI (match_dup 1) (const_int 0)))]
- ""
- "
-{
- operands[1] = mcore_gen_compare_reg (GEU);
-}")
-
-(define_expand "sgeu"
- [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
- (ne:SI (match_dup 1) (const_int 0)))]
- ""
- "
-{
- operands[1] = mcore_gen_compare_reg (GEU);
-}")
-
-(define_expand "sgtu"
+(define_expand "cstoresi4"
[(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
- (eq:SI (match_dup 1) (const_int 0)))]
+ (match_operator:SI 1 "ordered_comparison_operator"
+ [(match_operand:SI 2 "mcore_compare_operand" "")
+ (match_operand:SI 3 "nonmemory_operand" "")]))]
""
"
{
- operands[1] = mcore_gen_compare_reg (LEU);
-}")
+ bool invert;
+ invert = mcore_gen_compare (GET_CODE (operands[1]),
+ operands[2], operands[3]);
-(define_expand "sleu"
- [(set (match_operand:SI 0 "mcore_arith_reg_operand" "")
- (ne:SI (match_dup 1) (const_int 0)))]
- ""
- "
-{
- operands[1] = mcore_gen_compare_reg (LEU);
+ if (invert)
+ emit_insn (gen_mvcv (operands[0]));
+ else
+ emit_insn (gen_mvc (operands[0]));
+ DONE;
}")
(define_insn "incscc"
@@ -3308,7 +3040,7 @@
rtx loop_label = gen_label_rtx ();
rtx step = gen_reg_rtx (Pmode);
rtx tmp = gen_reg_rtx (Pmode);
- rtx memref;
+ rtx test, memref;
#if 1
emit_insn (gen_movsi (tmp, operands[1]));
@@ -3317,8 +3049,8 @@
if (GET_CODE (operands[1]) != CONST_INT)
{
out_label = gen_label_rtx ();
- emit_insn (gen_cmpsi (step, tmp)); /* quick out */
- emit_jump_insn (gen_bgeu (out_label));
+ test = gen_rtx_GEU (VOIDmode, step, tmp); /* quick out */
+ emit_jump_insn (gen_cbranchsi4 (test, step, tmp, out_label));
}
/* Run a loop that steps it incrementally. */
@@ -3332,8 +3064,8 @@
emit_insn(gen_subsi3(tmp, tmp, step));
/* Loop condition -- going back up. */
- emit_insn (gen_cmpsi (step, tmp));
- emit_jump_insn (gen_bltu (loop_label));
+ test = gen_rtx_LTU (VOIDmode, step, tmp);
+ emit_jump_insn (gen_cbranchsi4 (test, step, tmp, loop_label));
if (out_label)
emit_label (out_label);
diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h
index b95461a4c4f..bbae18a13a5 100644
--- a/gcc/config/mips/mips-protos.h
+++ b/gcc/config/mips/mips-protos.h
@@ -184,7 +184,6 @@ enum mips_call_type {
extern bool mips_symbolic_constant_p (rtx, enum mips_symbol_context,
enum mips_symbol_type *);
extern int mips_regno_mode_ok_for_base_p (int, enum machine_mode, bool);
-extern bool mips_legitimate_address_p (enum machine_mode, rtx, bool);
extern bool mips_stack_address_p (rtx, enum machine_mode);
extern int mips_address_insns (rtx, enum machine_mode, bool);
extern int mips_const_insns (rtx);
@@ -222,11 +221,11 @@ extern void mips_split_doubleword_move (rtx, rtx);
extern const char *mips_output_move (rtx, rtx);
extern void mips_restore_gp (rtx);
#ifdef RTX_CODE
-extern bool mips_expand_scc (enum rtx_code, rtx);
-extern void mips_expand_conditional_branch (rtx *, enum rtx_code);
+extern void mips_expand_scc (rtx *);
+extern void mips_expand_conditional_branch (rtx *);
extern void mips_expand_vcondv2sf (rtx, rtx, rtx, enum rtx_code, rtx, rtx);
extern void mips_expand_conditional_move (rtx *);
-extern void mips_expand_conditional_trap (enum rtx_code);
+extern void mips_expand_conditional_trap (rtx);
#endif
extern bool mips_use_pic_fn_addr_reg_p (const_rtx);
extern rtx mips_expand_call (enum mips_call_type, rtx, rtx, rtx, rtx, bool);
diff --git a/gcc/config/mips/mips-ps-3d.md b/gcc/config/mips/mips-ps-3d.md
index d4efe4cbf79..98932d85b11 100644
--- a/gcc/config/mips/mips-ps-3d.md
+++ b/gcc/config/mips/mips-ps-3d.md
@@ -58,7 +58,7 @@
MOVZ.PS. MOVT.PS and MOVF.PS depend on two CC values and move
each item independently. */
- if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) != MODE_INT)
+ if (GET_MODE_CLASS (GET_MODE (XEXP (operands[1], 0))) != MODE_INT)
FAIL;
mips_expand_conditional_move (operands);
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 32c898bcf83..62753a3fea7 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -448,9 +448,6 @@ static int set_noat;
normal branch. */
static bool mips_branch_likely;
-/* The operands passed to the last cmpMM expander. */
-rtx cmp_operands[2];
-
/* The current instruction-set architecture. */
enum processor_type mips_arch;
const struct mips_cpu_info *mips_arch_info;
@@ -568,7 +565,7 @@ const enum reg_class mips_regno_to_class[FIRST_PSEUDO_REGISTER] = {
};
/* The value of TARGET_ATTRIBUTE_TABLE. */
-const struct attribute_spec mips_attribute_table[] = {
+static const struct attribute_spec mips_attribute_table[] = {
/* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
{ "long_call", 0, 0, false, true, true, NULL },
{ "far", 0, 0, false, true, true, NULL },
@@ -1330,7 +1327,7 @@ mips_merge_decl_attributes (tree olddecl, tree newdecl)
static void
mips_split_plus (rtx x, rtx *base_ptr, HOST_WIDE_INT *offset_ptr)
{
- if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
+ if (GET_CODE (x) == PLUS && CONST_INT_P (XEXP (x, 1)))
{
*base_ptr = XEXP (x, 0);
*offset_ptr = INTVAL (XEXP (x, 1));
@@ -1924,7 +1921,7 @@ mips_cannot_force_const_mem (rtx x)
references, reload will consider forcing C into memory and using
one of the instruction's memory alternatives. Returning false
here will force it to use an input reload instead. */
- if (GET_CODE (x) == CONST_INT && LEGITIMATE_CONSTANT_P (x))
+ if (CONST_INT_P (x) && LEGITIMATE_CONSTANT_P (x))
return true;
split_const (x, &base, &offset);
@@ -2119,10 +2116,9 @@ mips_classify_address (struct mips_address_info *info, rtx x,
}
}
-/* Return true if X is a legitimate address for a memory operand of mode
- MODE. STRICT_P is true if REG_OK_STRICT is in effect. */
+/* Implement TARGET_LEGITIMATE_ADDRESS_P. */
-bool
+static bool
mips_legitimate_address_p (enum machine_mode mode, rtx x, bool strict_p)
{
struct mips_address_info addr;
@@ -2144,7 +2140,7 @@ mips_stack_address_p (rtx x, enum machine_mode mode)
/* Return true if ADDR matches the pattern for the LWXS load scaled indexed
address instruction. Note that such addresses are not considered
- legitimate in the GO_IF_LEGITIMATE_ADDRESS sense, because their use
+ legitimate in the TARGET_LEGITIMATE_ADDRESS_P sense, because their use
is so restricted. */
static bool
@@ -2157,7 +2153,7 @@ mips_lwxs_address_p (rtx addr)
rtx offset = XEXP (addr, 0);
if (GET_CODE (offset) == MULT
&& REG_P (XEXP (offset, 0))
- && GET_CODE (XEXP (offset, 1)) == CONST_INT
+ && CONST_INT_P (XEXP (offset, 1))
&& INTVAL (XEXP (offset, 1)) == 4)
return true;
}
@@ -3072,7 +3068,7 @@ mips_rewrite_small_data (rtx pattern)
static int
m16_check_op (rtx op, int low, int high, int mask)
{
- return (GET_CODE (op) == CONST_INT
+ return (CONST_INT_P (op)
&& IN_RANGE (INTVAL (op), low, high)
&& (INTVAL (op) & mask) == 0);
}
@@ -4112,7 +4108,7 @@ mips_canonicalize_int_order_test (enum rtx_code *code, rtx *cmp1,
if (mips_int_order_operand_ok_p (*code, *cmp1))
return true;
- if (GET_CODE (*cmp1) == CONST_INT)
+ if (CONST_INT_P (*cmp1))
switch (*code)
{
case LE:
@@ -4221,8 +4217,8 @@ mips_reversed_fp_cond (enum rtx_code *code)
}
/* Convert a comparison into something that can be used in a branch or
- conditional move. cmp_operands[0] and cmp_operands[1] are the values
- being compared and *CODE is the code used to compare them.
+ conditional move. On entry, *OP0 and *OP1 are the values being
+ compared and *CODE is the code used to compare them.
Update *CODE, *OP0 and *OP1 so that they describe the final comparison.
If NEED_EQ_NE_P, then only EQ or NE comparisons against zero are possible,
@@ -4235,42 +4231,38 @@ mips_reversed_fp_cond (enum rtx_code *code)
static void
mips_emit_compare (enum rtx_code *code, rtx *op0, rtx *op1, bool need_eq_ne_p)
{
- if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) == MODE_INT)
+ rtx cmp_op0 = *op0;
+ rtx cmp_op1 = *op1;
+
+ if (GET_MODE_CLASS (GET_MODE (*op0)) == MODE_INT)
{
- if (!need_eq_ne_p && cmp_operands[1] == const0_rtx)
- {
- *op0 = cmp_operands[0];
- *op1 = cmp_operands[1];
- }
+ if (!need_eq_ne_p && *op1 == const0_rtx)
+ ;
else if (*code == EQ || *code == NE)
{
if (need_eq_ne_p)
{
- *op0 = mips_zero_if_equal (cmp_operands[0], cmp_operands[1]);
+ *op0 = mips_zero_if_equal (cmp_op0, cmp_op1);
*op1 = const0_rtx;
}
else
- {
- *op0 = cmp_operands[0];
- *op1 = force_reg (GET_MODE (*op0), cmp_operands[1]);
- }
+ *op1 = force_reg (GET_MODE (cmp_op0), cmp_op1);
}
else
{
/* The comparison needs a separate scc instruction. Store the
result of the scc in *OP0 and compare it against zero. */
bool invert = false;
- *op0 = gen_reg_rtx (GET_MODE (cmp_operands[0]));
- mips_emit_int_order_test (*code, &invert, *op0,
- cmp_operands[0], cmp_operands[1]);
+ *op0 = gen_reg_rtx (GET_MODE (cmp_op0));
+ mips_emit_int_order_test (*code, &invert, *op0, cmp_op0, cmp_op1);
*code = (invert ? EQ : NE);
*op1 = const0_rtx;
}
}
- else if (ALL_FIXED_POINT_MODE_P (GET_MODE (cmp_operands[0])))
+ else if (ALL_FIXED_POINT_MODE_P (GET_MODE (cmp_op0)))
{
*op0 = gen_rtx_REG (CCDSPmode, CCDSP_CC_REGNUM);
- mips_emit_binary (*code, *op0, cmp_operands[0], cmp_operands[1]);
+ mips_emit_binary (*code, *op0, cmp_op0, cmp_op1);
*code = NE;
*op1 = const0_rtx;
}
@@ -4290,49 +4282,55 @@ mips_emit_compare (enum rtx_code *code, rtx *op0, rtx *op1, bool need_eq_ne_p)
? gen_reg_rtx (CCmode)
: gen_rtx_REG (CCmode, FPSW_REGNUM));
*op1 = const0_rtx;
- mips_emit_binary (cmp_code, *op0, cmp_operands[0], cmp_operands[1]);
+ mips_emit_binary (cmp_code, *op0, cmp_op0, cmp_op1);
}
}
-/* Try comparing cmp_operands[0] and cmp_operands[1] using rtl code CODE.
- Store the result in TARGET and return true if successful.
+/* Try performing the comparison in OPERANDS[1], whose arms are OPERANDS[2]
+ and OPERAND[3]. Store the result in OPERANDS[0].
- On 64-bit targets, TARGET may be narrower than cmp_operands[0]. */
+ On 64-bit targets, the mode of the comparison and target will always be
+ SImode, thus possibly narrower than that of the comparison's operands. */
-bool
-mips_expand_scc (enum rtx_code code, rtx target)
+void
+mips_expand_scc (rtx operands[])
{
- if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) != MODE_INT)
- return false;
+ rtx target = operands[0];
+ enum rtx_code code = GET_CODE (operands[1]);
+ rtx op0 = operands[2];
+ rtx op1 = operands[3];
+
+ gcc_assert (GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT);
if (code == EQ || code == NE)
{
if (ISA_HAS_SEQ_SNE
- && reg_imm10_operand (cmp_operands[1], GET_MODE (cmp_operands[1])))
- mips_emit_binary (code, target, cmp_operands[0], cmp_operands[1]);
+ && reg_imm10_operand (op1, GET_MODE (op1)))
+ mips_emit_binary (code, target, op0, op1);
else
{
- rtx zie = mips_zero_if_equal (cmp_operands[0], cmp_operands[1]);
+ rtx zie = mips_zero_if_equal (op0, op1);
mips_emit_binary (code, target, zie, const0_rtx);
}
}
else
- mips_emit_int_order_test (code, 0, target,
- cmp_operands[0], cmp_operands[1]);
- return true;
+ mips_emit_int_order_test (code, 0, target, op0, op1);
}
-/* Compare cmp_operands[0] with cmp_operands[1] using comparison code
- CODE and jump to OPERANDS[0] if the condition holds. */
+/* Compare OPERANDS[1] with OPERANDS[2] using comparison code
+ CODE and jump to OPERANDS[3] if the condition holds. */
void
-mips_expand_conditional_branch (rtx *operands, enum rtx_code code)
+mips_expand_conditional_branch (rtx *operands)
{
- rtx op0, op1, condition;
+ enum rtx_code code = GET_CODE (operands[0]);
+ rtx op0 = operands[1];
+ rtx op1 = operands[2];
+ rtx condition;
mips_emit_compare (&code, &op0, &op1, TARGET_MIPS16);
condition = gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
- emit_jump_insn (gen_condjump (condition, operands[0]));
+ emit_jump_insn (gen_condjump (condition, operands[3]));
}
/* Implement:
@@ -4359,35 +4357,36 @@ mips_expand_vcondv2sf (rtx dest, rtx true_src, rtx false_src,
cmp_result));
}
-/* Compare cmp_operands[0] with cmp_operands[1] using the code of
- OPERANDS[1]. Move OPERANDS[2] into OPERANDS[0] if the condition
- holds, otherwise move OPERANDS[3] into OPERANDS[0]. */
+/* Perform the comparison in OPERANDS[1]. Move OPERANDS[2] into OPERANDS[0]
+ if the condition holds, otherwise move OPERANDS[3] into OPERANDS[0]. */
void
mips_expand_conditional_move (rtx *operands)
{
- enum rtx_code code;
- rtx cond, op0, op1;
+ rtx cond;
+ enum rtx_code code = GET_CODE (operands[1]);
+ rtx op0 = XEXP (operands[1], 0);
+ rtx op1 = XEXP (operands[1], 1);
- code = GET_CODE (operands[1]);
mips_emit_compare (&code, &op0, &op1, true);
- cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1),
+ cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
emit_insn (gen_rtx_SET (VOIDmode, operands[0],
gen_rtx_IF_THEN_ELSE (GET_MODE (operands[0]), cond,
operands[2], operands[3])));
}
-/* Compare cmp_operands[0] with cmp_operands[1] using rtl code CODE,
- then trap if the condition holds. */
+/* Perform the comparison in COMPARISON, then trap if the condition holds. */
void
-mips_expand_conditional_trap (enum rtx_code code)
+mips_expand_conditional_trap (rtx comparison)
{
rtx op0, op1;
enum machine_mode mode;
+ enum rtx_code code;
/* MIPS conditional trap instructions don't have GT or LE flavors,
so we must swap the operands and convert to LT and GE respectively. */
+ code = GET_CODE (comparison);
switch (code)
{
case GT:
@@ -4395,17 +4394,17 @@ mips_expand_conditional_trap (enum rtx_code code)
case GTU:
case LEU:
code = swap_condition (code);
- op0 = cmp_operands[1];
- op1 = cmp_operands[0];
+ op0 = XEXP (comparison, 1);
+ op1 = XEXP (comparison, 0);
break;
default:
- op0 = cmp_operands[0];
- op1 = cmp_operands[1];
+ op0 = XEXP (comparison, 0);
+ op1 = XEXP (comparison, 1);
break;
}
- mode = GET_MODE (cmp_operands[0]);
+ mode = GET_MODE (XEXP (comparison, 0));
op0 = force_reg (mode, op0);
if (!arith_operand (op1, mode))
op1 = force_reg (mode, op1);
@@ -5161,22 +5160,28 @@ mips_build_builtin_va_list (void)
record = lang_hooks.types.make_type (RECORD_TYPE);
- f_ovfl = build_decl (FIELD_DECL, get_identifier ("__overflow_argptr"),
+ f_ovfl = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, get_identifier ("__overflow_argptr"),
ptr_type_node);
- f_gtop = build_decl (FIELD_DECL, get_identifier ("__gpr_top"),
+ f_gtop = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, get_identifier ("__gpr_top"),
ptr_type_node);
- f_ftop = build_decl (FIELD_DECL, get_identifier ("__fpr_top"),
+ f_ftop = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, get_identifier ("__fpr_top"),
ptr_type_node);
- f_goff = build_decl (FIELD_DECL, get_identifier ("__gpr_offset"),
+ f_goff = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, get_identifier ("__gpr_offset"),
unsigned_char_type_node);
- f_foff = build_decl (FIELD_DECL, get_identifier ("__fpr_offset"),
+ f_foff = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, get_identifier ("__fpr_offset"),
unsigned_char_type_node);
/* Explicitly pad to the size of a pointer, so that -Wpadded won't
warn on every user file. */
index = build_int_cst (NULL_TREE, GET_MODE_SIZE (ptr_mode) - 2 - 1);
array = build_array_type (unsigned_char_type_node,
build_index_type (index));
- f_res = build_decl (FIELD_DECL, get_identifier ("__reserved"), array);
+ f_res = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, get_identifier ("__reserved"), array);
DECL_FIELD_CONTEXT (f_ovfl) = record;
DECL_FIELD_CONTEXT (f_gtop) = record;
@@ -5750,10 +5755,12 @@ mips16_build_function_stub (void)
stubname = ACONCAT (("__fn_stub_", fnname, NULL));
/* Build a decl for the stub. */
- stubdecl = build_decl (FUNCTION_DECL, get_identifier (stubname),
+ stubdecl = build_decl (BUILTINS_LOCATION,
+ FUNCTION_DECL, get_identifier (stubname),
build_function_type (void_type_node, NULL_TREE));
DECL_SECTION_NAME (stubdecl) = build_string (strlen (secname), secname);
- DECL_RESULT (stubdecl) = build_decl (RESULT_DECL, NULL_TREE, void_type_node);
+ DECL_RESULT (stubdecl) = build_decl (BUILTINS_LOCATION,
+ RESULT_DECL, NULL_TREE, void_type_node);
/* Output a comment. */
fprintf (asm_out_file, "\t# Stub function for %s (",
@@ -5994,10 +6001,12 @@ mips16_build_call_stub (rtx retval, rtx *fn_ptr, rtx args_size, int fp_code)
stubname = ACONCAT (("__call_stub_", fp_ret_p ? "fp_" : "",
fnname, NULL));
stubid = get_identifier (stubname);
- stubdecl = build_decl (FUNCTION_DECL, stubid,
+ stubdecl = build_decl (BUILTINS_LOCATION,
+ FUNCTION_DECL, stubid,
build_function_type (void_type_node, NULL_TREE));
DECL_SECTION_NAME (stubdecl) = build_string (strlen (secname), secname);
- DECL_RESULT (stubdecl) = build_decl (RESULT_DECL, NULL_TREE,
+ DECL_RESULT (stubdecl) = build_decl (BUILTINS_LOCATION,
+ RESULT_DECL, NULL_TREE,
void_type_node);
/* Output a comment. */
@@ -6396,7 +6405,7 @@ static void
mips_block_move_loop (rtx dest, rtx src, HOST_WIDE_INT length,
HOST_WIDE_INT bytes_per_iter)
{
- rtx label, src_reg, dest_reg, final_src;
+ rtx label, src_reg, dest_reg, final_src, test;
HOST_WIDE_INT leftover;
leftover = length % bytes_per_iter;
@@ -6423,11 +6432,11 @@ mips_block_move_loop (rtx dest, rtx src, HOST_WIDE_INT length,
mips_emit_move (dest_reg, plus_constant (dest_reg, bytes_per_iter));
/* Emit the loop condition. */
+ test = gen_rtx_NE (VOIDmode, src_reg, final_src);
if (Pmode == DImode)
- emit_insn (gen_cmpdi (src_reg, final_src));
+ emit_jump_insn (gen_cbranchdi4 (test, src_reg, final_src, label));
else
- emit_insn (gen_cmpsi (src_reg, final_src));
- emit_jump_insn (gen_bne (label));
+ emit_jump_insn (gen_cbranchsi4 (test, src_reg, final_src, label));
/* Mop up any left-over bytes. */
if (leftover)
@@ -6440,7 +6449,7 @@ mips_block_move_loop (rtx dest, rtx src, HOST_WIDE_INT length,
bool
mips_expand_block_move (rtx dest, rtx src, rtx length)
{
- if (GET_CODE (length) == CONST_INT)
+ if (CONST_INT_P (length))
{
if (INTVAL (length) <= MIPS_MAX_MOVE_BYTES_STRAIGHT)
{
@@ -7195,28 +7204,28 @@ mips_print_operand (FILE *file, rtx op, int letter)
switch (letter)
{
case 'X':
- if (GET_CODE (op) == CONST_INT)
+ if (CONST_INT_P (op))
fprintf (file, HOST_WIDE_INT_PRINT_HEX, INTVAL (op));
else
output_operand_lossage ("invalid use of '%%%c'", letter);
break;
case 'x':
- if (GET_CODE (op) == CONST_INT)
+ if (CONST_INT_P (op))
fprintf (file, HOST_WIDE_INT_PRINT_HEX, INTVAL (op) & 0xffff);
else
output_operand_lossage ("invalid use of '%%%c'", letter);
break;
case 'd':
- if (GET_CODE (op) == CONST_INT)
+ if (CONST_INT_P (op))
fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (op));
else
output_operand_lossage ("invalid use of '%%%c'", letter);
break;
case 'm':
- if (GET_CODE (op) == CONST_INT)
+ if (CONST_INT_P (op))
fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (op) - 1);
else
output_operand_lossage ("invalid use of '%%%c'", letter);
@@ -7292,6 +7301,8 @@ mips_print_operand (FILE *file, rtx op, int letter)
|| (letter == 'L' && TARGET_BIG_ENDIAN)
|| letter == 'D')
regno++;
+ else if (letter && letter != 'z' && letter != 'M' && letter != 'L')
+ output_operand_lossage ("invalid use of '%%%c'", letter);
/* We need to print $0 .. $31 for COP0 registers. */
if (COP0_REG_P (regno))
fprintf (file, "$%s", &reg_names[regno][4]);
@@ -7303,6 +7314,8 @@ mips_print_operand (FILE *file, rtx op, int letter)
case MEM:
if (letter == 'D')
output_address (plus_constant (XEXP (op, 0), 4));
+ else if (letter && letter != 'z')
+ output_operand_lossage ("invalid use of '%%%c'", letter);
else
output_address (XEXP (op, 0));
break;
@@ -7310,6 +7323,8 @@ mips_print_operand (FILE *file, rtx op, int letter)
default:
if (letter == 'z' && op == CONST0_RTX (GET_MODE (op)))
fputs (reg_names[GP_REG_FIRST], file);
+ else if (letter && letter != 'z')
+ output_operand_lossage ("invalid use of '%%%c'", letter);
else if (CONST_GP_P (op))
fputs (reg_names[GLOBAL_POINTER_REGNUM], file);
else
@@ -9393,7 +9408,7 @@ mips_emit_loadgp (void)
static int
mips_kernel_reg_p (rtx *x, void *data ATTRIBUTE_UNUSED)
{
- return GET_CODE (*x) == REG && KERNEL_REG_P (REGNO (*x));
+ return REG_P (*x) && KERNEL_REG_P (REGNO (*x));
}
/* Expand the "prologue" pattern. */
@@ -13923,6 +13938,8 @@ mips_set_mips16_mode (int mips16_p)
targetm.min_anchor_offset = 0;
targetm.max_anchor_offset = 127;
+ targetm.const_anchor = 0;
+
if (flag_pic && !TARGET_OLDABI)
sorry ("MIPS16 PIC for ABIs other than o32 and o64");
@@ -13950,6 +13967,8 @@ mips_set_mips16_mode (int mips16_p)
targetm.min_anchor_offset = -32768;
targetm.max_anchor_offset = 32767;
+
+ targetm.const_anchor = 0x8000;
}
/* (Re)initialize MIPS target internals for new ISA. */
@@ -14701,7 +14720,7 @@ mips_epilogue_uses (unsigned int regno)
static int
mips_at_reg_p (rtx *x, void *data ATTRIBUTE_UNUSED)
{
- return GET_CODE (*x) == REG && REGNO (*x) == AT_REGNUM;
+ return REG_P (*x) && REGNO (*x) == AT_REGNUM;
}
@@ -14909,6 +14928,9 @@ mips_final_postscan_insn (FILE *file, rtx insn, rtx *opvec, int noperands)
#undef TARGET_ASM_FINAL_POSTSCAN_INSN
#define TARGET_ASM_FINAL_POSTSCAN_INSN mips_final_postscan_insn
+#undef TARGET_LEGITIMATE_ADDRESS_P
+#define TARGET_LEGITIMATE_ADDRESS_P mips_legitimate_address_p
+
struct gcc_target targetm = TARGET_INITIALIZER;
#include "gt-mips.h"
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index 5c68688ccce..3d2fcac45f5 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -668,6 +668,32 @@ enum mips_code_readable_setting {
# endif
#endif
+#ifndef MIPS_ABI_DEFAULT
+#define MIPS_ABI_DEFAULT ABI_32
+#endif
+
+/* Use the most portable ABI flag for the ASM specs. */
+
+#if MIPS_ABI_DEFAULT == ABI_32
+#define MULTILIB_ABI_DEFAULT "mabi=32"
+#endif
+
+#if MIPS_ABI_DEFAULT == ABI_O64
+#define MULTILIB_ABI_DEFAULT "mabi=o64"
+#endif
+
+#if MIPS_ABI_DEFAULT == ABI_N32
+#define MULTILIB_ABI_DEFAULT "mabi=n32"
+#endif
+
+#if MIPS_ABI_DEFAULT == ABI_64
+#define MULTILIB_ABI_DEFAULT "mabi=64"
+#endif
+
+#if MIPS_ABI_DEFAULT == ABI_EABI
+#define MULTILIB_ABI_DEFAULT "mabi=eabi"
+#endif
+
#ifndef MULTILIB_DEFAULTS
#define MULTILIB_DEFAULTS \
{ MULTILIB_ENDIAN_DEFAULT, MULTILIB_ISA_DEFAULT, MULTILIB_ABI_DEFAULT }
@@ -730,10 +756,21 @@ enum mips_code_readable_setting {
#define MIPS_32BIT_OPTION_SPEC \
"mips1|mips2|mips32*|mgp32"
+#if MIPS_ABI_DEFAULT == ABI_O64 \
+ || MIPS_ABI_DEFAULT == ABI_N32 \
+ || MIPS_ABI_DEFAULT == ABI_64
+#define OPT_ARCH64 "mabi=32|mgp32:;"
+#define OPT_ARCH32 "mabi=32|mgp32"
+#else
+#define OPT_ARCH64 "mabi=o64|mabi=n32|mabi=64|mgp64"
+#define OPT_ARCH32 "mabi=o64|mabi=n32|mabi=64|mgp64:;"
+#endif
+
/* Support for a compile-time default CPU, et cetera. The rules are:
--with-arch is ignored if -march is specified or a -mips is specified
- (other than -mips16).
- --with-tune is ignored if -mtune is specified.
+ (other than -mips16); likewise --with-arch-32 and --with-arch-64.
+ --with-tune is ignored if -mtune is specified; likewise
+ --with-tune-32 and --with-tune-64.
--with-abi is ignored if -mabi is specified.
--with-float is ignored if -mhard-float or -msoft-float are
specified.
@@ -741,7 +778,11 @@ enum mips_code_readable_setting {
specified. */
#define OPTION_DEFAULT_SPECS \
{"arch", "%{" MIPS_ARCH_OPTION_SPEC ":;: -march=%(VALUE)}" }, \
+ {"arch_32", "%{" OPT_ARCH32 ":%{" MIPS_ARCH_OPTION_SPEC ":;: -march=%(VALUE)}}" }, \
+ {"arch_64", "%{" OPT_ARCH64 ":%{" MIPS_ARCH_OPTION_SPEC ":;: -march=%(VALUE)}}" }, \
{"tune", "%{!mtune=*:-mtune=%(VALUE)}" }, \
+ {"tune_32", "%{" OPT_ARCH32 ":%{!mtune=*:-mtune=%(VALUE)}}" }, \
+ {"tune_64", "%{" OPT_ARCH64 ":%{!mtune=*:-mtune=%(VALUE)}}" }, \
{"abi", "%{!mabi=*:-mabi=%(VALUE)}" }, \
{"float", "%{!msoft-float:%{!mhard-float:-m%(VALUE)-float}}" }, \
{"divide", "%{!mdivide-traps:%{!mdivide-breaks:-mdivide-%(VALUE)}}" }, \
@@ -1076,32 +1117,6 @@ enum mips_code_readable_setting {
#endif
-#ifndef MIPS_ABI_DEFAULT
-#define MIPS_ABI_DEFAULT ABI_32
-#endif
-
-/* Use the most portable ABI flag for the ASM specs. */
-
-#if MIPS_ABI_DEFAULT == ABI_32
-#define MULTILIB_ABI_DEFAULT "mabi=32"
-#endif
-
-#if MIPS_ABI_DEFAULT == ABI_O64
-#define MULTILIB_ABI_DEFAULT "mabi=o64"
-#endif
-
-#if MIPS_ABI_DEFAULT == ABI_N32
-#define MULTILIB_ABI_DEFAULT "mabi=n32"
-#endif
-
-#if MIPS_ABI_DEFAULT == ABI_64
-#define MULTILIB_ABI_DEFAULT "mabi=64"
-#endif
-
-#if MIPS_ABI_DEFAULT == ABI_EABI
-#define MULTILIB_ABI_DEFAULT "mabi=eabi"
-#endif
-
/* SUBTARGET_ASM_OPTIMIZING_SPEC handles passing optimization options
to the assembler. It may be overridden by subtargets. */
#ifndef SUBTARGET_ASM_OPTIMIZING_SPEC
@@ -2504,25 +2519,11 @@ typedef struct mips_args {
#define MAX_REGS_PER_ADDRESS 1
-#ifdef REG_OK_STRICT
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
-{ \
- if (mips_legitimate_address_p (MODE, X, 1)) \
- goto ADDR; \
-}
-#else
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
-{ \
- if (mips_legitimate_address_p (MODE, X, 0)) \
- goto ADDR; \
-}
-#endif
-
/* Check for constness inline but use mips_legitimate_address_p
to check whether a constant really is an address. */
#define CONSTANT_ADDRESS_P(X) \
- (CONSTANT_P (X) && mips_legitimate_address_p (SImode, X, 0))
+ (CONSTANT_P (X) && memory_address_p (SImode, X))
#define LEGITIMATE_CONSTANT_P(X) (mips_const_insns (X) > 0)
@@ -3432,7 +3433,6 @@ extern int mips_dbx_regno[];
extern int mips_dwarf_regno[];
extern bool mips_split_p[];
extern bool mips_split_hi_p[];
-extern GTY(()) rtx cmp_operands[2];
extern enum processor_type mips_arch; /* which cpu to codegen for */
extern enum processor_type mips_tune; /* which cpu to schedule for */
extern int mips_isa; /* architectural level */
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index 95ba6ba2620..46e7afa9be5 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -727,9 +727,10 @@
;; This attributes gives the mode mask of a SHORT.
(define_mode_attr mask [(QI "0x00ff") (HI "0xffff")])
-;; Mode attributes for GPR loads and stores.
+;; Mode attributes for GPR loads.
(define_mode_attr load [(SI "lw") (DI "ld")])
-(define_mode_attr store [(SI "sw") (DI "sd")])
+;; Instruction names for stores.
+(define_mode_attr store [(QI "sb") (HI "sh") (SI "sw") (DI "sd")])
;; Similarly for MIPS IV indexed FPR loads and stores.
(define_mode_attr loadx [(SF "lwxc1") (DF "ldxc1") (V2SF "ldxc1")])
@@ -791,11 +792,6 @@
(DF "ISA_HAS_FP4 && TARGET_FLOAT64")
(V2SF "TARGET_SB1")])
-;; This code iterator allows all branch instructions to be generated from
-;; a single define_expand template.
-(define_code_iterator any_cond [unordered ordered unlt unge uneq ltgt unle ungt
- eq ne gt ge lt le gtu geu ltu leu])
-
;; This code iterator allows signed and unsigned widening multiplications
;; to use the same template.
(define_code_iterator any_extend [sign_extend zero_extend])
@@ -994,19 +990,15 @@
}
[(set_attr "type" "trap")])
-(define_expand "conditional_trap"
+(define_expand "ctrap<mode>4"
[(trap_if (match_operator 0 "comparison_operator"
- [(match_dup 2) (match_dup 3)])
- (match_operand 1 "const_int_operand"))]
+ [(match_operand:GPR 1 "reg_or_0_operand")
+ (match_operand:GPR 2 "arith_operand")])
+ (match_operand 3 "const_0_operand"))]
"ISA_HAS_COND_TRAP"
{
- if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) == MODE_INT
- && operands[1] == const0_rtx)
- {
- mips_expand_conditional_trap (GET_CODE (operands[0]));
- DONE;
- }
- FAIL;
+ mips_expand_conditional_trap (operands[0]);
+ DONE;
})
(define_insn "*conditional_trap<mode>"
@@ -2701,33 +2693,13 @@
;;
;; Step A needs a real instruction but step B does not.
-(define_insn "truncdisi2"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
- (truncate:SI (match_operand:DI 1 "register_operand" "d,d")))]
- "TARGET_64BIT"
- "@
- sll\t%0,%1,0
- sw\t%1,%0"
- [(set_attr "move_type" "sll0,store")
- (set_attr "mode" "SI")])
-
-(define_insn "truncdihi2"
- [(set (match_operand:HI 0 "nonimmediate_operand" "=d,m")
- (truncate:HI (match_operand:DI 1 "register_operand" "d,d")))]
- "TARGET_64BIT"
- "@
- sll\t%0,%1,0
- sh\t%1,%0"
- [(set_attr "move_type" "sll0,store")
- (set_attr "mode" "SI")])
-
-(define_insn "truncdiqi2"
- [(set (match_operand:QI 0 "nonimmediate_operand" "=d,m")
- (truncate:QI (match_operand:DI 1 "register_operand" "d,d")))]
+(define_insn "truncdi<mode>2"
+ [(set (match_operand:SUBDI 0 "nonimmediate_operand" "=d,m")
+ (truncate:SUBDI (match_operand:DI 1 "register_operand" "d,d")))]
"TARGET_64BIT"
"@
sll\t%0,%1,0
- sb\t%1,%0"
+ <store>\t%1,%0"
[(set_attr "move_type" "sll0,store")
(set_attr "mode" "SI")])
@@ -2764,74 +2736,6 @@
"exts\t%0,%1,%2,31"
[(set_attr "type" "arith")
(set_attr "mode" "<MODE>")])
-
-;; Combiner patterns for truncate/sign_extend combinations. The SI versions
-;; use the shift/truncate patterns above.
-
-(define_insn_and_split "*extenddi_truncate<mode>"
- [(set (match_operand:DI 0 "register_operand" "=d")
- (sign_extend:DI
- (truncate:SHORT (match_operand:DI 1 "register_operand" "d"))))]
- "TARGET_64BIT && !TARGET_MIPS16"
- "#"
- "&& reload_completed"
- [(set (match_dup 2)
- (ashift:DI (match_dup 1)
- (match_dup 3)))
- (set (match_dup 0)
- (ashiftrt:DI (match_dup 2)
- (match_dup 3)))]
-{
- operands[2] = gen_lowpart (DImode, operands[0]);
- operands[3] = GEN_INT (BITS_PER_WORD - GET_MODE_BITSIZE (<MODE>mode));
-})
-
-(define_insn_and_split "*extendsi_truncate<mode>"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (sign_extend:SI
- (truncate:SHORT (match_operand:DI 1 "register_operand" "d"))))]
- "TARGET_64BIT && !TARGET_MIPS16"
- "#"
- "&& reload_completed"
- [(set (match_dup 2)
- (ashift:DI (match_dup 1)
- (match_dup 3)))
- (set (match_dup 0)
- (truncate:SI (ashiftrt:DI (match_dup 2)
- (match_dup 3))))]
-{
- operands[2] = gen_lowpart (DImode, operands[0]);
- operands[3] = GEN_INT (BITS_PER_WORD - GET_MODE_BITSIZE (<MODE>mode));
-})
-
-;; Combiner patterns to optimize truncate/zero_extend combinations.
-
-(define_insn "*zero_extend<mode>_trunchi"
- [(set (match_operand:GPR 0 "register_operand" "=d")
- (zero_extend:GPR
- (truncate:HI (match_operand:DI 1 "register_operand" "d"))))]
- "TARGET_64BIT && !TARGET_MIPS16"
- "andi\t%0,%1,0xffff"
- [(set_attr "type" "logical")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*zero_extend<mode>_truncqi"
- [(set (match_operand:GPR 0 "register_operand" "=d")
- (zero_extend:GPR
- (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
- "TARGET_64BIT && !TARGET_MIPS16"
- "andi\t%0,%1,0xff"
- [(set_attr "type" "logical")
- (set_attr "mode" "<MODE>")])
-
-(define_insn ""
- [(set (match_operand:HI 0 "register_operand" "=d")
- (zero_extend:HI
- (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
- "TARGET_64BIT && !TARGET_MIPS16"
- "andi\t%0,%1,0xff"
- [(set_attr "type" "logical")
- (set_attr "mode" "HI")])
;;
;; ....................
@@ -2956,6 +2860,29 @@
"lbu\t%0,%1"
[(set_attr "move_type" "load")
(set_attr "mode" "HI")])
+
+;; Combiner patterns to optimize truncate/zero_extend combinations.
+
+(define_insn "*zero_extend<GPR:mode>_trunc<SHORT:mode>"
+ [(set (match_operand:GPR 0 "register_operand" "=d")
+ (zero_extend:GPR
+ (truncate:SHORT (match_operand:DI 1 "register_operand" "d"))))]
+ "TARGET_64BIT && !TARGET_MIPS16"
+{
+ operands[2] = GEN_INT (GET_MODE_MASK (<SHORT:MODE>mode));
+ return "andi\t%0,%1,%x2";
+}
+ [(set_attr "type" "logical")
+ (set_attr "mode" "<GPR:MODE>")])
+
+(define_insn "*zero_extendhi_truncqi"
+ [(set (match_operand:HI 0 "register_operand" "=d")
+ (zero_extend:HI
+ (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
+ "TARGET_64BIT && !TARGET_MIPS16"
+ "andi\t%0,%1,0xff"
+ [(set_attr "type" "logical")
+ (set_attr "mode" "HI")])
;;
;; ....................
@@ -3082,6 +3009,80 @@
[(set_attr "move_type" "signext,load")
(set_attr "mode" "SI")])
+;; Combiner patterns for truncate/sign_extend combinations. The SI versions
+;; use the shift/truncate patterns.
+
+(define_insn_and_split "*extenddi_truncate<mode>"
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (sign_extend:DI
+ (truncate:SHORT (match_operand:DI 1 "register_operand" "d"))))]
+ "TARGET_64BIT && !TARGET_MIPS16"
+{
+ if (!ISA_HAS_EXTS)
+ return "#";
+ operands[2] = GEN_INT (GET_MODE_BITSIZE (<SHORT:MODE>mode));
+ return "exts\t%0,%1,0,%m2";
+}
+ "&& reload_completed && !ISA_HAS_EXTS"
+ [(set (match_dup 2)
+ (ashift:DI (match_dup 1)
+ (match_dup 3)))
+ (set (match_dup 0)
+ (ashiftrt:DI (match_dup 2)
+ (match_dup 3)))]
+{
+ operands[2] = gen_lowpart (DImode, operands[0]);
+ operands[3] = GEN_INT (BITS_PER_WORD - GET_MODE_BITSIZE (<MODE>mode));
+}
+ [(set_attr "type" "arith")
+ (set_attr "mode" "DI")])
+
+(define_insn_and_split "*extendsi_truncate<mode>"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (sign_extend:SI
+ (truncate:SHORT (match_operand:DI 1 "register_operand" "d"))))]
+ "TARGET_64BIT && !TARGET_MIPS16"
+{
+ if (!ISA_HAS_EXTS)
+ return "#";
+ operands[2] = GEN_INT (GET_MODE_BITSIZE (<SHORT:MODE>mode));
+ return "exts\t%0,%1,0,%m2";
+}
+ "&& reload_completed && !ISA_HAS_EXTS"
+ [(set (match_dup 2)
+ (ashift:DI (match_dup 1)
+ (match_dup 3)))
+ (set (match_dup 0)
+ (truncate:SI (ashiftrt:DI (match_dup 2)
+ (match_dup 3))))]
+{
+ operands[2] = gen_lowpart (DImode, operands[0]);
+ operands[3] = GEN_INT (BITS_PER_WORD - GET_MODE_BITSIZE (<MODE>mode));
+}
+ [(set_attr "type" "arith")
+ (set_attr "mode" "SI")])
+
+(define_insn_and_split "*extendhi_truncateqi"
+ [(set (match_operand:HI 0 "register_operand" "=d")
+ (sign_extend:HI
+ (truncate:QI (match_operand:DI 1 "register_operand" "d"))))]
+ "TARGET_64BIT && !TARGET_MIPS16"
+{
+ return ISA_HAS_EXTS ? "exts\t%0,%1,0,7" : "#";
+}
+ "&& reload_completed && !ISA_HAS_EXTS"
+ [(set (match_dup 2)
+ (ashift:DI (match_dup 1)
+ (const_int 56)))
+ (set (match_dup 0)
+ (truncate:HI (ashiftrt:DI (match_dup 2)
+ (const_int 56))))]
+{
+ operands[2] = gen_lowpart (DImode, operands[0]);
+}
+ [(set_attr "type" "arith")
+ (set_attr "mode" "SI")])
+
(define_insn "extendsfdf2"
[(set (match_operand:DF 0 "register_operand" "=f")
(float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
@@ -3243,6 +3244,7 @@
rtx reg3 = gen_reg_rtx (SImode);
rtx label1 = gen_label_rtx ();
rtx label2 = gen_label_rtx ();
+ rtx test;
REAL_VALUE_TYPE offset;
real_2expN (&offset, 31, DFmode);
@@ -3252,8 +3254,8 @@
mips_emit_move (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
do_pending_stack_adjust ();
- emit_insn (gen_cmpdf (operands[1], reg1));
- emit_jump_insn (gen_bge (label1));
+ test = gen_rtx_GE (VOIDmode, operands[1], reg1);
+ emit_jump_insn (gen_cbranchdf4 (test, operands[1], reg1, label1));
emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
@@ -3288,6 +3290,7 @@
rtx reg3 = gen_reg_rtx (DImode);
rtx label1 = gen_label_rtx ();
rtx label2 = gen_label_rtx ();
+ rtx test;
REAL_VALUE_TYPE offset;
real_2expN (&offset, 63, DFmode);
@@ -3295,8 +3298,8 @@
mips_emit_move (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode));
do_pending_stack_adjust ();
- emit_insn (gen_cmpdf (operands[1], reg1));
- emit_jump_insn (gen_bge (label1));
+ test = gen_rtx_GE (VOIDmode, operands[1], reg1);
+ emit_jump_insn (gen_cbranchdf4 (test, operands[1], reg1, label1));
emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1]));
emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
@@ -3330,6 +3333,7 @@
rtx reg3 = gen_reg_rtx (SImode);
rtx label1 = gen_label_rtx ();
rtx label2 = gen_label_rtx ();
+ rtx test;
REAL_VALUE_TYPE offset;
real_2expN (&offset, 31, SFmode);
@@ -3337,8 +3341,8 @@
mips_emit_move (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
do_pending_stack_adjust ();
- emit_insn (gen_cmpsf (operands[1], reg1));
- emit_jump_insn (gen_bge (label1));
+ test = gen_rtx_GE (VOIDmode, operands[1], reg1);
+ emit_jump_insn (gen_cbranchsf4 (test, operands[1], reg1, label1));
emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
@@ -3372,6 +3376,7 @@
rtx reg3 = gen_reg_rtx (DImode);
rtx label1 = gen_label_rtx ();
rtx label2 = gen_label_rtx ();
+ rtx test;
REAL_VALUE_TYPE offset;
real_2expN (&offset, 63, SFmode);
@@ -3379,8 +3384,8 @@
mips_emit_move (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode));
do_pending_stack_adjust ();
- emit_insn (gen_cmpsf (operands[1], reg1));
- emit_jump_insn (gen_bge (label1));
+ test = gen_rtx_GE (VOIDmode, operands[1], reg1);
+ emit_jump_insn (gen_cbranchsf4 (test, operands[1], reg1, label1));
emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1]));
emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
@@ -3486,16 +3491,16 @@
[(set_attr "type" "arith")
(set_attr "mode" "<MODE>")])
-(define_insn "*extzv_trunc<mode>_exts"
- [(set (match_operand:GPR 0 "register_operand" "=d")
- (truncate:GPR
+(define_insn "*extzv_truncsi_exts"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (truncate:SI
(zero_extract:DI (match_operand:DI 1 "register_operand" "d")
(match_operand 2 "const_int_operand" "")
(match_operand 3 "const_int_operand" ""))))]
"ISA_HAS_EXTS && TARGET_64BIT && IN_RANGE (INTVAL (operands[2]), 32, 63)"
"exts\t%0,%1,%3,31"
[(set_attr "type" "arith")
- (set_attr "mode" "<MODE>")])
+ (set_attr "mode" "SI")])
(define_expand "insv"
@@ -4105,7 +4110,7 @@
;; instructions will still work correctly.
;; ??? Perhaps it would be better to support these instructions by
-;; modifying GO_IF_LEGITIMATE_ADDRESS and friends. However, since
+;; modifying TARGET_LEGITIMATE_ADDRESS_P and friends. However, since
;; these instructions can only be used to load and store floating
;; point registers, that would probably cause trouble in reload.
@@ -4832,7 +4837,7 @@
reload pass. */
if (TARGET_MIPS16
&& optimize
- && GET_CODE (operands[2]) == CONST_INT
+ && CONST_INT_P (operands[2])
&& INTVAL (operands[2]) > 8
&& INTVAL (operands[2]) <= 16
&& !reload_in_progress
@@ -4853,7 +4858,7 @@
(match_operand:SI 2 "arith_operand" "dI")))]
"!TARGET_MIPS16"
{
- if (GET_CODE (operands[2]) == CONST_INT)
+ if (CONST_INT_P (operands[2]))
operands[2] = GEN_INT (INTVAL (operands[2])
& (GET_MODE_BITSIZE (<MODE>mode) - 1));
@@ -4869,7 +4874,7 @@
(match_operand:SI 2 "arith_operand" "dI"))))]
"TARGET_64BIT && !TARGET_MIPS16"
{
- if (GET_CODE (operands[2]) == CONST_INT)
+ if (CONST_INT_P (operands[2]))
operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
return "<insn>\t%0,%1,%2";
@@ -4925,7 +4930,7 @@
(match_operand:SI 2 "arith_operand" "d,I")))]
"TARGET_64BIT && TARGET_MIPS16"
{
- if (GET_CODE (operands[2]) == CONST_INT)
+ if (CONST_INT_P (operands[2]))
operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
return "dsra\t%0,%2";
@@ -4944,7 +4949,7 @@
(match_operand:SI 2 "arith_operand" "d,I")))]
"TARGET_64BIT && TARGET_MIPS16"
{
- if (GET_CODE (operands[2]) == CONST_INT)
+ if (CONST_INT_P (operands[2]))
operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
return "dsrl\t%0,%2";
@@ -4999,7 +5004,7 @@
(match_operand:SI 2 "arith_operand" "dI")))]
"ISA_HAS_ROR"
{
- if (GET_CODE (operands[2]) == CONST_INT)
+ if (CONST_INT_P (operands[2]))
gcc_assert (INTVAL (operands[2]) >= 0
&& INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode));
@@ -5011,50 +5016,6 @@
;;
;; ....................
;;
-;; COMPARISONS
-;;
-;; ....................
-
-;; Flow here is rather complex:
-;;
-;; 1) The cmp{si,di,sf,df} routine is called. It deposits the arguments
-;; into cmp_operands[] but generates no RTL.
-;;
-;; 2) The appropriate branch define_expand is called, which then
-;; creates the appropriate RTL for the comparison and branch.
-;; Different CC modes are used, based on what type of branch is
-;; done, so that we can constrain things appropriately. There
-;; are assumptions in the rest of GCC that break if we fold the
-;; operands into the branches for integer operations, and use cc0
-;; for floating point, so we use the fp status register instead.
-;; If needed, an appropriate temporary is created to hold the
-;; of the integer compare.
-
-(define_expand "cmp<mode>"
- [(set (cc0)
- (compare:CC (match_operand:GPR 0 "register_operand")
- (match_operand:GPR 1 "nonmemory_operand")))]
- ""
-{
- cmp_operands[0] = operands[0];
- cmp_operands[1] = operands[1];
- DONE;
-})
-
-(define_expand "cmp<mode>"
- [(set (cc0)
- (compare:CC (match_operand:SCALARF 0 "register_operand")
- (match_operand:SCALARF 1 "register_operand")))]
- ""
-{
- cmp_operands[0] = operands[0];
- cmp_operands[1] = operands[1];
- DONE;
-})
-
-;;
-;; ....................
-;;
;; CONDITIONAL BRANCHES
;;
;; ....................
@@ -5189,15 +5150,29 @@
[(set_attr "type" "branch")
(set_attr "mode" "none")])
-(define_expand "b<code>"
+(define_expand "cbranch<mode>4"
[(set (pc)
- (if_then_else (any_cond:CC (cc0)
- (const_int 0))
- (label_ref (match_operand 0 ""))
+ (if_then_else (match_operator 0 "comparison_operator"
+ [(match_operand:GPR 1 "register_operand")
+ (match_operand:GPR 2 "nonmemory_operand")])
+ (label_ref (match_operand 3 ""))
(pc)))]
""
{
- mips_expand_conditional_branch (operands, <CODE>);
+ mips_expand_conditional_branch (operands);
+ DONE;
+})
+
+(define_expand "cbranch<mode>4"
+ [(set (pc)
+ (if_then_else (match_operator 0 "comparison_operator"
+ [(match_operand:SCALARF 1 "register_operand")
+ (match_operand:SCALARF 2 "register_operand")])
+ (label_ref (match_operand 3 ""))
+ (pc)))]
+ ""
+{
+ mips_expand_conditional_branch (operands);
DONE;
})
@@ -5261,12 +5236,16 @@
;; Destination is always set in SI mode.
-(define_expand "seq"
+(define_expand "cstore<mode>4"
[(set (match_operand:SI 0 "register_operand")
- (eq:SI (match_dup 1)
- (match_dup 2)))]
+ (match_operator:SI 1 "mips_cstore_operator"
+ [(match_operand:GPR 2 "register_operand")
+ (match_operand:GPR 3 "nonmemory_operand")]))]
""
- { if (mips_expand_scc (EQ, operands[0])) DONE; else FAIL; })
+{
+ mips_expand_scc (operands);
+ DONE;
+})
(define_insn "*seq_zero_<GPR:mode><GPR2:mode>"
[(set (match_operand:GPR2 0 "register_operand" "=d")
@@ -5299,16 +5278,6 @@
[(set_attr "type" "slt")
(set_attr "mode" "<GPR:MODE>")])
-;; "sne" uses sltu instructions in which the first operand is $0.
-;; This isn't possible in mips16 code.
-
-(define_expand "sne"
- [(set (match_operand:SI 0 "register_operand")
- (ne:SI (match_dup 1)
- (match_dup 2)))]
- "!TARGET_MIPS16"
- { if (mips_expand_scc (NE, operands[0])) DONE; else FAIL; })
-
(define_insn "*sne_zero_<GPR:mode><GPR2:mode>"
[(set (match_operand:GPR2 0 "register_operand" "=d")
(ne:GPR2 (match_operand:GPR 1 "register_operand" "d")
@@ -5331,13 +5300,6 @@
[(set_attr "type" "slt")
(set_attr "mode" "<GPR:MODE>")])
-(define_expand "sgt<u>"
- [(set (match_operand:SI 0 "register_operand")
- (any_gt:SI (match_dup 1)
- (match_dup 2)))]
- ""
- { if (mips_expand_scc (<CODE>, operands[0])) DONE; else FAIL; })
-
(define_insn "*sgt<u>_<GPR:mode><GPR2:mode>"
[(set (match_operand:GPR2 0 "register_operand" "=d")
(any_gt:GPR2 (match_operand:GPR 1 "register_operand" "d")
@@ -5356,13 +5318,6 @@
[(set_attr "type" "slt")
(set_attr "mode" "<GPR:MODE>")])
-(define_expand "sge<u>"
- [(set (match_operand:SI 0 "register_operand")
- (any_ge:SI (match_dup 1)
- (match_dup 2)))]
- ""
- { if (mips_expand_scc (<CODE>, operands[0])) DONE; else FAIL; })
-
(define_insn "*sge<u>_<GPR:mode><GPR2:mode>"
[(set (match_operand:GPR2 0 "register_operand" "=d")
(any_ge:GPR2 (match_operand:GPR 1 "register_operand" "d")
@@ -5372,13 +5327,6 @@
[(set_attr "type" "slt")
(set_attr "mode" "<GPR:MODE>")])
-(define_expand "slt<u>"
- [(set (match_operand:SI 0 "register_operand")
- (any_lt:SI (match_dup 1)
- (match_dup 2)))]
- ""
- { if (mips_expand_scc (<CODE>, operands[0])) DONE; else FAIL; })
-
(define_insn "*slt<u>_<GPR:mode><GPR2:mode>"
[(set (match_operand:GPR2 0 "register_operand" "=d")
(any_lt:GPR2 (match_operand:GPR 1 "register_operand" "d")
@@ -5402,13 +5350,6 @@
(const_int 4)
(const_int 8))])])
-(define_expand "sle<u>"
- [(set (match_operand:SI 0 "register_operand")
- (any_le:SI (match_dup 1)
- (match_dup 2)))]
- ""
- { if (mips_expand_scc (<CODE>, operands[0])) DONE; else FAIL; })
-
(define_insn "*sle<u>_<GPR:mode><GPR2:mode>"
[(set (match_operand:GPR2 0 "register_operand" "=d")
(any_le:GPR2 (match_operand:GPR 1 "register_operand" "d")
diff --git a/gcc/config/mips/predicates.md b/gcc/config/mips/predicates.md
index aaebdded674..d32eaf13f8e 100644
--- a/gcc/config/mips/predicates.md
+++ b/gcc/config/mips/predicates.md
@@ -285,6 +285,12 @@
(define_predicate "order_operator"
(match_code "lt,ltu,le,leu,ge,geu,gt,gtu"))
+;; For NE, cstore uses sltu instructions in which the first operand is $0.
+;; This isn't possible in mips16 code.
+
+(define_predicate "mips_cstore_operator"
+ (ior (match_code "eq,gt,gtu,ge,geu,lt,ltu,le,leu")
+ (and (match_code "ne") (match_test "!TARGET_MIPS16"))))
(define_predicate "small_data_pattern"
(and (match_code "set,parallel,unspec,unspec_volatile,prefetch")
diff --git a/gcc/config/mips/x-native b/gcc/config/mips/x-native
index 6820e73d94b..5e31121ede1 100644
--- a/gcc/config/mips/x-native
+++ b/gcc/config/mips/x-native
@@ -1,3 +1,3 @@
driver-native.o : $(srcdir)/config/mips/driver-native.c \
$(CONFIG_H) $(SYSTEM_H)
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
diff --git a/gcc/config/mmix/mmix-protos.h b/gcc/config/mmix/mmix-protos.h
index d71064aa6d7..e839d864697 100644
--- a/gcc/config/mmix/mmix-protos.h
+++ b/gcc/config/mmix/mmix-protos.h
@@ -82,7 +82,6 @@ extern rtx mmix_eh_return_stackadj_rtx (void);
extern rtx mmix_eh_return_handler_rtx (void);
extern void mmix_initialize_trampoline (rtx, rtx, rtx);
extern int mmix_constant_address_p (rtx);
-extern int mmix_legitimate_address (enum machine_mode, rtx, int);
extern int mmix_legitimate_constant_p (rtx);
extern void mmix_print_operand (FILE *, rtx, int);
extern void mmix_print_operand_address (FILE *, rtx);
@@ -96,7 +95,6 @@ extern void mmix_setup_frame_addresses (void);
/* Needs to be ifdef:d for sake of enum rtx_code. */
extern enum machine_mode mmix_select_cc_mode (enum rtx_code, rtx, rtx);
extern void mmix_canonicalize_comparison (enum rtx_code *, rtx *, rtx *);
-extern int mmix_valid_comparison (enum rtx_code, enum machine_mode, rtx);
extern rtx mmix_gen_compare_reg (enum rtx_code, rtx, rtx);
#endif
diff --git a/gcc/config/mmix/mmix.c b/gcc/config/mmix/mmix.c
index ceed8dbb6db..d2115a5d703 100644
--- a/gcc/config/mmix/mmix.c
+++ b/gcc/config/mmix/mmix.c
@@ -125,6 +125,7 @@ static void mmix_emit_sp_add (HOST_WIDE_INT offset);
static void mmix_target_asm_function_prologue (FILE *, HOST_WIDE_INT);
static void mmix_target_asm_function_end_prologue (FILE *);
static void mmix_target_asm_function_epilogue (FILE *, HOST_WIDE_INT);
+static bool mmix_legitimate_address_p (enum machine_mode, rtx, bool);
static void mmix_reorg (void);
static void mmix_asm_output_mi_thunk
(FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT, tree);
@@ -206,6 +207,9 @@ static bool mmix_pass_by_reference (CUMULATIVE_ARGS *,
#undef TARGET_DEFAULT_TARGET_FLAGS
#define TARGET_DEFAULT_TARGET_FLAGS TARGET_DEFAULT
+#undef TARGET_LEGITIMATE_ADDRESS_P
+#define TARGET_LEGITIMATE_ADDRESS_P mmix_legitimate_address_p
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* Functions that are expansions for target macros.
@@ -985,13 +989,12 @@ mmix_constant_address_p (rtx x)
return constant_ok || (addend & 3) == 0;
}
-/* Return 1 if the address is OK, otherwise 0.
- Used by GO_IF_LEGITIMATE_ADDRESS. */
+/* Return 1 if the address is OK, otherwise 0. */
-int
-mmix_legitimate_address (enum machine_mode mode ATTRIBUTE_UNUSED,
- rtx x,
- int strict_checking)
+bool
+mmix_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED,
+ rtx x,
+ bool strict_checking)
{
#define MMIX_REG_OK(X) \
((strict_checking \
@@ -2359,70 +2362,14 @@ mmix_shiftable_wyde_value (unsigned HOST_WIDEST_INT value)
return 1;
}
-/* Returns zero if code and mode is not a valid condition from a
- compare-type insn. Nonzero if it is. The parameter op, if non-NULL,
- is the comparison of mode is CC-somethingmode. */
-
-int
-mmix_valid_comparison (RTX_CODE code, enum machine_mode mode, rtx op)
-{
- if (mode == VOIDmode && op != NULL_RTX)
- mode = GET_MODE (op);
-
- /* We don't care to look at these, they should always be valid. */
- if (mode == CCmode || mode == CC_UNSmode || mode == DImode)
- return 1;
-
- if ((mode == CC_FPmode || mode == DFmode)
- && (code == GT || code == LT))
- return 1;
-
- if ((mode == CC_FPEQmode || mode == DFmode)
- && (code == EQ || code == NE))
- return 1;
-
- if ((mode == CC_FUNmode || mode == DFmode)
- && (code == ORDERED || code == UNORDERED))
- return 1;
-
- return 0;
-}
-
-/* X and Y are two things to compare using CODE. Emit a compare insn if
- possible and return the rtx for the cc-reg in the proper mode, or
- NULL_RTX if this is not a valid comparison. */
+/* X and Y are two things to compare using CODE. Return the rtx for
+ the cc-reg in the proper mode. */
rtx
mmix_gen_compare_reg (RTX_CODE code, rtx x, rtx y)
{
enum machine_mode ccmode = SELECT_CC_MODE (code, x, y);
- rtx cc_reg;
-
- /* FIXME: Do we get constants here? Of double mode? */
- enum machine_mode mode
- = GET_MODE (x) == VOIDmode
- ? GET_MODE (y)
- : GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT ? DFmode : DImode;
-
- if (! mmix_valid_comparison (code, mode, x))
- return NULL_RTX;
-
- cc_reg = gen_reg_rtx (ccmode);
-
- /* FIXME: Can we avoid emitting a compare insn here? */
- if (! REG_P (x) && ! REG_P (y))
- x = force_reg (mode, x);
-
- /* If it's not quite right yet, put y in a register. */
- if (! REG_P (y)
- && (GET_CODE (y) != CONST_INT
- || ! CONST_OK_FOR_LETTER_P (INTVAL (y), 'I')))
- y = force_reg (mode, y);
-
- emit_insn (gen_rtx_SET (VOIDmode, cc_reg,
- gen_rtx_COMPARE (ccmode, x, y)));
-
- return cc_reg;
+ return gen_reg_rtx (ccmode);
}
/* Local (static) helper functions. */
diff --git a/gcc/config/mmix/mmix.h b/gcc/config/mmix/mmix.h
index a7fb6e5884e..fb3d3019b29 100644
--- a/gcc/config/mmix/mmix.h
+++ b/gcc/config/mmix/mmix.h
@@ -81,11 +81,6 @@ along with GCC; see the file COPYING3. If not see
#define MMIX_FUNCTION_ARG_SIZE(MODE, TYPE) \
((MODE) != BLKmode ? GET_MODE_SIZE (MODE) : int_size_in_bytes (TYPE))
-/* Declarations for helper variables that are not tied to a particular
- target macro. */
-extern GTY(()) rtx mmix_compare_op0;
-extern GTY(()) rtx mmix_compare_op1;
-
/* Per-function machine data. This is normally an opaque type just
defined and used in the tm.c file, but we need to see the definition in
mmix.md too. */
@@ -695,10 +690,6 @@ typedef struct { int regs; int lib; } CUMULATIVE_ARGS;
#define MAX_REGS_PER_ADDRESS 2
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, LABEL) \
- if (mmix_legitimate_address (MODE, X, MMIX_REG_OK_STRICT)) \
- goto LABEL
-
#ifndef REG_OK_STRICT
# define REG_OK_FOR_BASE_P(X) \
(REGNO (X) <= MMIX_LAST_GENERAL_REGISTER \
diff --git a/gcc/config/mmix/mmix.md b/gcc/config/mmix/mmix.md
index aa878af0f82..44263e47f64 100644
--- a/gcc/config/mmix/mmix.md
+++ b/gcc/config/mmix/mmix.md
@@ -440,30 +440,6 @@ DIVU %1,%1,%2\;GET %0,:rR\;NEGU %2,0,%0\;CSNN %0,$255,%2")
""
"NOR %0,%1,0")
-;; Since we don't have cc0, we do what is recommended in the manual;
-;; store away the operands for use in the branch, scc or movcc insn.
-(define_expand "cmpdi"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "mmix_reg_or_8bit_operand" "")]
- ""
- "
-{
- mmix_compare_op0 = operands[0];
- mmix_compare_op1 = operands[1];
- DONE;
-}")
-
-(define_expand "cmpdf"
- [(match_operand:DF 0 "register_operand" "")
- (match_operand:DF 1 "register_operand" "")]
- ""
- "
-{
- mmix_compare_op0 = operands[0];
- mmix_compare_op1 = operands[1];
- DONE;
-}")
-
;; When the user-patterns expand, the resulting insns will match the
;; patterns below.
@@ -474,7 +450,7 @@ DIVU %1,%1,%2\;GET %0,:rR\;NEGU %2,0,%0\;CSNN %0,$255,%2")
;; unsigned, so that has to be done another way.
;; FIXME: Perhaps a peep2 changing CCcode to a new code, that
;; gets folded here.
-(define_insn "*cmpcc_folded"
+(define_insn "*cmpdi_folded"
[(set (match_operand:CC 0 "register_operand" "=r")
(compare:CC
(match_operand:DI 1 "register_operand" "r")
@@ -485,7 +461,7 @@ DIVU %1,%1,%2\;GET %0,:rR\;NEGU %2,0,%0\;CSNN %0,$255,%2")
&& REGNO (operands[1]) == REGNO (operands[0])"
"%% folded: cmp %0,%1,0")
-(define_insn "*cmpcc"
+(define_insn "*cmps"
[(set (match_operand:CC 0 "register_operand" "=r")
(compare:CC
(match_operand:DI 1 "register_operand" "r")
@@ -724,7 +700,8 @@ DIVU %1,%1,%2\;GET %0,:rR\;NEGU %2,0,%0\;CSNN %0,$255,%2")
;; 0 to use in movdfcc.
(define_expand "movdfcc"
- [(set (match_operand:DF 0 "register_operand" "")
+ [(set (match_dup 4) (match_dup 5))
+ (set (match_operand:DF 0 "register_operand" "")
(if_then_else:DF
(match_operand 1 "comparison_operator" "")
(match_operand:DF 2 "mmix_reg_or_0_operand" "")
@@ -733,15 +710,20 @@ DIVU %1,%1,%2\;GET %0,:rR\;NEGU %2,0,%0\;CSNN %0,$255,%2")
"
{
enum rtx_code code = GET_CODE (operands[1]);
- rtx cc_reg = mmix_gen_compare_reg (code, mmix_compare_op0,
- mmix_compare_op1);
- if (cc_reg == NULL_RTX)
+ if (code == LE || code == GE)
FAIL;
- operands[1] = gen_rtx_fmt_ee (code, VOIDmode, cc_reg, const0_rtx);
+
+ operands[4] = mmix_gen_compare_reg (code, XEXP (operands[1], 0),
+ XEXP (operands[1], 1));
+ operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
+ XEXP (operands[1], 0),
+ XEXP (operands[1], 1));
+ operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[4], const0_rtx);
}")
(define_expand "movdicc"
- [(set (match_operand:DI 0 "register_operand" "")
+ [(set (match_dup 4) (match_dup 5))
+ (set (match_operand:DI 0 "register_operand" "")
(if_then_else:DI
(match_operand 1 "comparison_operator" "")
(match_operand:DI 2 "mmix_reg_or_8bit_operand" "")
@@ -750,11 +732,15 @@ DIVU %1,%1,%2\;GET %0,:rR\;NEGU %2,0,%0\;CSNN %0,$255,%2")
"
{
enum rtx_code code = GET_CODE (operands[1]);
- rtx cc_reg = mmix_gen_compare_reg (code, mmix_compare_op0,
- mmix_compare_op1);
- if (cc_reg == NULL_RTX)
+ if (code == LE || code == GE)
FAIL;
- operands[1] = gen_rtx_fmt_ee (code, VOIDmode, cc_reg, const0_rtx);
+
+ operands[4] = mmix_gen_compare_reg (code, XEXP (operands[1], 0),
+ XEXP (operands[1], 1));
+ operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
+ XEXP (operands[1], 0),
+ XEXP (operands[1], 1));
+ operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[4], const0_rtx);
}")
;; FIXME: Is this the right way to do "folding" of CCmode -> DImode?
@@ -854,175 +840,65 @@ DIVU %1,%1,%2\;GET %0,:rR\;NEGU %2,0,%0\;CSNN %0,$255,%2")
CS%d2 %0,%3,%1
ZS%d2 %0,%3,%1")
-;; FIXME: scc patterns will probably help, I just skip them
+;; FIXME: scc insns will probably help, I just skip them
;; right now. Revisit.
-(define_expand "beq"
- [(set (pc)
- (if_then_else (eq (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- operands[1]
- = mmix_gen_compare_reg (EQ, mmix_compare_op0, mmix_compare_op1);
-}")
-
-(define_expand "bne"
- [(set (pc)
- (if_then_else (ne (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
+(define_expand "cbranchdi4"
+ [(set (match_dup 4)
+ (match_op_dup 5
+ [(match_operand:DI 1 "register_operand" "")
+ (match_operand:DI 2 "mmix_reg_or_8bit_operand" "")]))
+ (set (pc)
+ (if_then_else
+ (match_operator 0 "ordered_comparison_operator"
+ [(match_dup 4)
+ (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
""
"
{
- operands[1]
- = mmix_gen_compare_reg (NE, mmix_compare_op0, mmix_compare_op1);
+ operands[4] = mmix_gen_compare_reg (GET_CODE (operands[0]),
+ operands[1], operands[2]);
+ operands[5] = gen_rtx_fmt_ee (COMPARE,
+ GET_MODE (operands[4]),
+ operands[1], operands[2]);
}")
-(define_expand "bgt"
- [(set (pc)
- (if_then_else (gt (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
+(define_expand "cbranchdf4"
+ [(set (match_dup 4)
+ (match_op_dup 5
+ [(match_operand:DF 1 "register_operand" "")
+ (match_operand:DF 2 "register_operand" "")]))
+ (set (pc)
+ (if_then_else
+ (match_operator 0 "float_comparison_operator"
+ [(match_dup 4)
+ (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
""
"
{
- operands[1]
- = mmix_gen_compare_reg (GT, mmix_compare_op0, mmix_compare_op1);
-}")
-
-(define_expand "ble"
- [(set (pc)
- (if_then_else (le (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- operands[1]
- = mmix_gen_compare_reg (LE, mmix_compare_op0, mmix_compare_op1);
-
/* The head comment of optabs.c:can_compare_p says we're required to
implement this, so we have to clean up the mess here. */
- if (operands[1] == NULL_RTX)
+ if (GET_CODE (operands[0]) == LE || GET_CODE (operands[0]) == GE)
{
- /* FIXME: Watch out for sharing/unsharing of rtx:es. */
- emit_jump_insn ((*bcc_gen_fctn[(int) LT]) (operands[0]));
- emit_jump_insn ((*bcc_gen_fctn[(int) EQ]) (operands[0]));
+ enum rtx_code ltgt_code = GET_CODE (operands[0]) == LE ? LT : GT;
+ emit_cmp_and_jump_insns (operands[1], operands[2], ltgt_code, NULL_RTX,
+ DFmode, 0, operands[3]);
+ emit_cmp_and_jump_insns (operands[1], operands[2], EQ, NULL_RTX,
+ DFmode, 0, operands[3]);
DONE;
}
-}")
-
-(define_expand "bge"
- [(set (pc)
- (if_then_else (ge (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- operands[1]
- = mmix_gen_compare_reg (GE, mmix_compare_op0, mmix_compare_op1);
- /* The head comment of optabs.c:can_compare_p says we're required to
- implement this, so we have to clean up the mess here. */
- if (operands[1] == NULL_RTX)
- {
- /* FIXME: Watch out for sharing/unsharing of rtx:es. */
- emit_jump_insn ((*bcc_gen_fctn[(int) GT]) (operands[0]));
- emit_jump_insn ((*bcc_gen_fctn[(int) EQ]) (operands[0]));
- DONE;
- }
+ operands[4] = mmix_gen_compare_reg (GET_CODE (operands[0]),
+ operands[1], operands[2]);
+ operands[5] = gen_rtx_fmt_ee (COMPARE,
+ GET_MODE (operands[4]),
+ operands[1], operands[2]);
}")
-(define_expand "blt"
- [(set (pc)
- (if_then_else (lt (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- operands[1]
- = mmix_gen_compare_reg (LT, mmix_compare_op0, mmix_compare_op1);
-}")
-
-(define_expand "bgtu"
- [(set (pc)
- (if_then_else (gtu (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- operands[1]
- = mmix_gen_compare_reg (GTU, mmix_compare_op0, mmix_compare_op1);
-}")
-
-(define_expand "bleu"
- [(set (pc)
- (if_then_else (leu (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- operands[1]
- = mmix_gen_compare_reg (LEU, mmix_compare_op0, mmix_compare_op1);
-}")
-
-(define_expand "bgeu"
- [(set (pc)
- (if_then_else (geu (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- operands[1]
- = mmix_gen_compare_reg (GEU, mmix_compare_op0, mmix_compare_op1);
-}")
-
-(define_expand "bltu"
- [(set (pc)
- (if_then_else (ltu (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- operands[1]
- = mmix_gen_compare_reg (LTU, mmix_compare_op0, mmix_compare_op1);
-}")
-
-(define_expand "bunordered"
- [(set (pc)
- (if_then_else (unordered (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- operands[1]
- = mmix_gen_compare_reg (UNORDERED, mmix_compare_op0, mmix_compare_op1);
-
- if (operands[1] == NULL_RTX)
- FAIL;
-}")
-
-(define_expand "bordered"
- [(set (pc)
- (if_then_else (ordered (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- operands[1]
- = mmix_gen_compare_reg (ORDERED, mmix_compare_op0, mmix_compare_op1);
-}")
;; FIXME: we can emit an unordered-or-*not*-equal compare in one insn, but
;; there's no RTL code for it. Maybe revisit in future.
diff --git a/gcc/config/mmix/predicates.md b/gcc/config/mmix/predicates.md
index 5c5792e1f6b..b5773b87aee 100644
--- a/gcc/config/mmix/predicates.md
+++ b/gcc/config/mmix/predicates.md
@@ -17,6 +17,11 @@
;; along with GCC; see the file COPYING3. If not see
;; <http://www.gnu.org/licenses/>.
+;; Return 1 if OP is a valid comparison operator for "cbranch" instructions.
+;; LE and GE are further lowered by the cbranchdf4 pattern.
+(define_predicate "float_comparison_operator"
+ (match_code "ne, eq, le, ge, lt, gt, ordered, unordered"))
+
;; True if this is a foldable comparison operator
;; - one where a the result of (compare:CC (reg) (const_int 0)) can be
;; replaced by (reg). */
diff --git a/gcc/config/mn10300/mn10300-protos.h b/gcc/config/mn10300/mn10300-protos.h
index 935cb8f81f6..ae4728ae0cb 100644
--- a/gcc/config/mn10300/mn10300-protos.h
+++ b/gcc/config/mn10300/mn10300-protos.h
@@ -23,7 +23,6 @@ along with GCC; see the file COPYING3. If not see
extern void mn10300_override_options (void);
extern rtx legitimize_pic_address (rtx, rtx);
extern int legitimate_pic_operand_p (rtx);
-extern bool legitimate_address_p (enum machine_mode, rtx, int);
extern void print_operand (FILE *, rtx, int);
extern void print_operand_address (FILE *, rtx);
extern void mn10300_print_reg_list (FILE *, int);
diff --git a/gcc/config/mn10300/mn10300.c b/gcc/config/mn10300/mn10300.c
index ceb77e862c2..608f8a0fa35 100644
--- a/gcc/config/mn10300/mn10300.c
+++ b/gcc/config/mn10300/mn10300.c
@@ -69,6 +69,7 @@ enum processor_type mn10300_processor = PROCESSOR_DEFAULT;
static bool mn10300_handle_option (size_t, const char *, int);
+static bool mn10300_legitimate_address_p (enum machine_mode, rtx, bool);
static int mn10300_address_cost_1 (rtx, int *);
static int mn10300_address_cost (rtx, bool);
static bool mn10300_rtx_costs (rtx, int, int, int *, bool);
@@ -127,6 +128,9 @@ static unsigned int mn10300_case_values_threshold (void);
#undef TARGET_CASE_VALUES_THRESHOLD
#define TARGET_CASE_VALUES_THRESHOLD mn10300_case_values_threshold
+#undef TARGET_LEGITIMATE_ADDRESS_P
+#define TARGET_LEGITIMATE_ADDRESS_P mn10300_legitimate_address_p
+
static void mn10300_encode_section_info (tree, rtx, int);
struct gcc_target targetm = TARGET_INITIALIZER;
@@ -1790,9 +1794,6 @@ symbolic_operand (register rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
OLDX is the address as it was before break_out_memory_refs was called.
In some cases it is useful to look at this to decide what needs to be done.
- MODE and WIN are passed so that this macro can use
- GO_IF_LEGITIMATE_ADDRESS.
-
Normally it is always safe for this macro to do nothing. It exists to
recognize opportunities to optimize the output.
@@ -1900,9 +1901,21 @@ legitimate_pic_operand_p (rtx x)
}
/* Return TRUE if the address X, taken from a (MEM:MODE X) rtx, is
- legitimate, and FALSE otherwise. */
+ legitimate, and FALSE otherwise.
+
+ On the mn10300, the value in the address register must be
+ in the same memory space/segment as the effective address.
+
+ This is problematical for reload since it does not understand
+ that base+index != index+base in a memory reference.
+
+ Note it is still possible to use reg+reg addressing modes,
+ it's just much more difficult. For a discussion of a possible
+ workaround and solution, see the comments in pa.c before the
+ function record_unscaled_index_insn_codes. */
+
bool
-legitimate_address_p (enum machine_mode mode, rtx x, int strict)
+mn10300_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
{
if (CONSTANT_ADDRESS_P (x)
&& (! flag_pic || legitimate_pic_operand_p (x)))
@@ -2030,7 +2043,7 @@ mn10300_rtx_costs (rtx x, int code, int outer_code, int *total, bool speed ATTRI
{
case CONST_INT:
/* Zeros are extremely cheap. */
- if (INTVAL (x) == 0 && outer_code == SET)
+ if (INTVAL (x) == 0 && (outer_code == SET || outer_code == COMPARE))
*total = 0;
/* If it fits in 8 bits, then it's still relatively cheap. */
else if (INT_8_BITS (INTVAL (x)))
@@ -2059,6 +2072,12 @@ mn10300_rtx_costs (rtx x, int code, int outer_code, int *total, bool speed ATTRI
*total = 8;
return true;
+ case ZERO_EXTRACT:
+ /* This is cheap, we can use btst. */
+ if (outer_code == COMPARE)
+ *total = 0;
+ return false;
+
/* ??? This probably needs more work. */
case MOD:
case DIV:
diff --git a/gcc/config/mn10300/mn10300.h b/gcc/config/mn10300/mn10300.h
index b35894435a2..77be9962907 100644
--- a/gcc/config/mn10300/mn10300.h
+++ b/gcc/config/mn10300/mn10300.h
@@ -655,26 +655,6 @@ struct cum_arg {int nbytes; };
#define HAVE_POST_INCREMENT (TARGET_AM33)
-/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
- that is a valid memory address for an instruction.
- The MODE argument is the machine mode for the MEM expression
- that wants to use this address.
-
- The other macros defined here are used only in GO_IF_LEGITIMATE_ADDRESS,
- except for CONSTANT_ADDRESS_P which is actually
- machine-independent.
-
- On the mn10300, the value in the address register must be
- in the same memory space/segment as the effective address.
-
- This is problematical for reload since it does not understand
- that base+index != index+base in a memory reference.
-
- Note it is still possible to use reg+reg addressing modes,
- it's just much more difficult. For a discussion of a possible
- workaround and solution, see the comments in pa.c before the
- function record_unscaled_index_insn_codes. */
-
/* Accept either REG or SUBREG where a register is valid. */
#define RTX_OK_FOR_BASE_P(X, strict) \
@@ -684,14 +664,6 @@ struct cum_arg {int nbytes; };
&& REGNO_STRICT_OK_FOR_BASE_P (REGNO (SUBREG_REG (X)), \
(strict))))
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
-do \
- { \
- if (legitimate_address_p ((MODE), (X), REG_STRICT)) \
- goto ADDR; \
- } \
-while (0)
-
/* Nonzero if the constant value X is a legitimate general operand.
diff --git a/gcc/config/mn10300/mn10300.md b/gcc/config/mn10300/mn10300.md
index 35b0e589cb5..a2b6296912f 100644
--- a/gcc/config/mn10300/mn10300.md
+++ b/gcc/config/mn10300/mn10300.md
@@ -826,34 +826,34 @@
;; TEST INSTRUCTIONS
;; ----------------------------------------------------------------------
-;; Go ahead and define tstsi so we can eliminate redundant tst insns
-;; when we start trying to optimize this port.
-(define_insn "tstsi"
- [(set (cc0) (match_operand:SI 0 "register_operand" "dax"))]
- ""
- "* return output_tst (operands[0], insn);"
- [(set_attr "cc" "set_znv")])
-
-(define_insn ""
- [(set (cc0) (zero_extend:SI (match_operand:QI 0 "memory_operand" "dx,!a")))]
+(define_insn "*tst_extqisi_am33"
+ [(set (cc0) (compare
+ (zero_extend:SI (match_operand:QI 0 "memory_operand" "dx,!a"))
+ (const_int 0)))]
"TARGET_AM33"
"* return output_tst (operands[0], insn);"
[(set_attr "cc" "set_znv")])
-(define_insn ""
- [(set (cc0) (zero_extend:SI (match_operand:QI 0 "memory_operand" "dx")))]
+(define_insn "*tst_extqisi"
+ [(set (cc0) (compare
+ (zero_extend:SI (match_operand:QI 0 "memory_operand" "dx"))
+ (const_int 0)))]
""
"* return output_tst (operands[0], insn);"
[(set_attr "cc" "set_znv")])
-(define_insn ""
- [(set (cc0) (zero_extend:SI (match_operand:HI 0 "memory_operand" "dx,!a")))]
+(define_insn "*tst_exthisi_am33"
+ [(set (cc0) (compare
+ (zero_extend:SI (match_operand:HI 0 "memory_operand" "dx,!a"))
+ (const_int 0)))]
"TARGET_AM33"
"* return output_tst (operands[0], insn);"
[(set_attr "cc" "set_znv")])
-(define_insn ""
- [(set (cc0) (zero_extend:SI (match_operand:HI 0 "memory_operand" "dx")))]
+(define_insn "*tst_exthisi"
+ [(set (cc0) (compare
+ (zero_extend:SI (match_operand:HI 0 "memory_operand" "dx"))
+ (const_int 0)))]
""
"* return output_tst (operands[0], insn);"
[(set_attr "cc" "set_znv")])
@@ -874,17 +874,22 @@
;; possibly satisfied, so just mark the alternative with a `!', so
;; that it is not considered by reload.
-(define_insn "cmpsi"
+(define_insn "*cmpsi"
[(set (cc0)
- (compare (match_operand:SI 0 "register_operand" "!*d*a*x,dax")
- (match_operand:SI 1 "nonmemory_operand" "*0,daxi")))]
+ (compare (match_operand:SI 0 "register_operand" "!*d*a*x,dax,dax")
+ (match_operand:SI 1 "nonmemory_operand" "*0,I,daxi")))]
""
- "@
- btst 0,d0
- cmp %1,%0"
- [(set_attr "cc" "compare,compare")])
+ "*
+{
+ if (which_alternative == 0)
+ return \"btst 0,d0\";
+ if (which_alternative == 1)
+ return output_tst (operands[0], insn);
+ return \"cmp %1,%0\";
+}"
+ [(set_attr "cc" "compare,set_znv,compare")])
-(define_insn "cmpsf"
+(define_insn "*cmpsf"
[(set (cc0)
(compare (match_operand:SF 0 "register_operand" "f,f")
(match_operand:SF 1 "nonmemory_operand" "f,F")))]
@@ -1510,9 +1515,10 @@
(define_insn ""
[(set (cc0)
- (zero_extract:SI (match_operand:SI 0 "register_operand" "dx")
- (match_operand 1 "const_int_operand" "")
- (match_operand 2 "const_int_operand" "")))]
+ (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "dx")
+ (match_operand 1 "const_int_operand" "")
+ (match_operand 2 "const_int_operand" ""))
+ (const_int 0)))]
""
"*
{
@@ -1537,9 +1543,10 @@
(define_insn ""
[(set (cc0)
- (zero_extract:SI (match_operand:QI 0 "general_operand" "R,dx")
- (match_operand 1 "const_int_operand" "")
- (match_operand 2 "const_int_operand" "")))]
+ (compare (zero_extract:SI (match_operand:QI 0 "general_operand" "R,dx")
+ (match_operand 1 "const_int_operand" "")
+ (match_operand 2 "const_int_operand" ""))
+ (const_int 0)))]
"mask_ok_for_mem_btst (INTVAL (operands[1]), INTVAL (operands[2]))"
"*
{
@@ -1581,17 +1588,19 @@
[(set_attr "cc" "clobber")])
(define_insn ""
- [(set (cc0) (and:SI (match_operand:SI 0 "register_operand" "dx")
- (match_operand:SI 1 "const_int_operand" "")))]
+ [(set (cc0) (compare (and:SI (match_operand:SI 0 "register_operand" "dx")
+ (match_operand:SI 1 "const_int_operand" ""))
+ (const_int 0)))]
""
"btst %1,%0"
[(set_attr "cc" "clobber")])
(define_insn ""
[(set (cc0)
- (and:SI
- (subreg:SI (match_operand:QI 0 "general_operand" "R,dx") 0)
- (match_operand:SI 1 "const_8bit_operand" "")))]
+ (compare (and:SI
+ (subreg:SI (match_operand:QI 0 "general_operand" "R,dx") 0)
+ (match_operand:SI 1 "const_8bit_operand" ""))
+ (const_int 0)))]
""
"@
btst %U1,%A0
@@ -1603,97 +1612,34 @@
;; JUMP INSTRUCTIONS
;; ----------------------------------------------------------------------
-;; Conditional jump instructions
-
-(define_expand "ble"
- [(set (pc)
- (if_then_else (le (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "")
-
-(define_expand "bleu"
- [(set (pc)
- (if_then_else (leu (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "")
-
-(define_expand "bge"
- [(set (pc)
- (if_then_else (ge (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "")
-
-(define_expand "bgeu"
- [(set (pc)
- (if_then_else (geu (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "")
-
-(define_expand "blt"
- [(set (pc)
- (if_then_else (lt (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "")
-
-(define_expand "bltu"
- [(set (pc)
- (if_then_else (ltu (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "")
-
-(define_expand "bgt"
- [(set (pc)
- (if_then_else (gt (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
+(define_expand "cbranchsi4"
+ [(set (cc0)
+ (compare (match_operand:SI 1 "register_operand" "")
+ (match_operand:SI 2 "nonmemory_operand" "")))
+ (set (pc)
+ (if_then_else
+ (match_operator 0 "ordered_comparison_operator" [(cc0)
+ (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
""
"")
-(define_expand "bgtu"
- [(set (pc)
- (if_then_else (gtu (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
+(define_expand "cbranchsf4"
+ [(set (cc0)
+ (compare (match_operand:SF 1 "register_operand" "")
+ (match_operand:SF 2 "nonmemory_operand" "")))
+ (set (pc)
+ (if_then_else
+ (match_operator 0 "ordered_comparison_operator" [(cc0)
+ (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
+ "TARGET_AM33_2"
"")
-(define_expand "beq"
- [(set (pc)
- (if_then_else (eq (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "")
-(define_expand "bne"
- [(set (pc)
- (if_then_else (ne (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "")
+;; Conditional jump instructions
(define_insn ""
[(set (pc)
@@ -1774,11 +1720,13 @@
rtx table = gen_reg_rtx (SImode);
rtx index = gen_reg_rtx (SImode);
rtx addr = gen_reg_rtx (Pmode);
+ rtx test;
emit_move_insn (table, gen_rtx_LABEL_REF (VOIDmode, operands[3]));
emit_move_insn (index, plus_constant (operands[0], - INTVAL (operands[1])));
- emit_insn (gen_cmpsi (index, operands[2]));
- emit_jump_insn (gen_bgtu (operands[4]));
+ test = gen_rtx_fmt_ee (GTU, VOIDmode, index, operands[2]);
+ emit_jump_insn (gen_cbranchsi4 (test, index, operands[2], operands[4]));
+
emit_move_insn (index, gen_rtx_ASHIFT (SImode, index, const2_rtx));
emit_move_insn (addr, gen_rtx_MEM (SImode,
gen_rtx_PLUS (SImode, table, index)));
@@ -2518,7 +2466,8 @@
;; This will work on the mn10200 because we can check the ZX flag
;; if the comparison is in HImode.
(define_peephole
- [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
+ [(set (cc0) (compare (match_operand:SI 0 "register_operand" "dx")
+ (const_int 0)))
(set (pc) (if_then_else (ge (cc0) (const_int 0))
(match_operand 1 "" "")
(pc)))]
@@ -2527,7 +2476,8 @@
[(set_attr "cc" "clobber")])
(define_peephole
- [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
+ [(set (cc0) (compare (match_operand:SI 0 "register_operand" "dx")
+ (const_int 0)))
(set (pc) (if_then_else (lt (cc0) (const_int 0))
(match_operand 1 "" "")
(pc)))]
@@ -2536,7 +2486,8 @@
[(set_attr "cc" "clobber")])
(define_peephole
- [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
+ [(set (cc0) (compare (match_operand:SI 0 "register_operand" "dx")
+ (const_int 0)))
(set (pc) (if_then_else (ge (cc0) (const_int 0))
(pc)
(match_operand 1 "" "")))]
@@ -2545,7 +2496,8 @@
[(set_attr "cc" "clobber")])
(define_peephole
- [(set (cc0) (match_operand:SI 0 "register_operand" "dx"))
+ [(set (cc0) (compare (match_operand:SI 0 "register_operand" "dx")
+ (const_int 0)))
(set (pc) (if_then_else (lt (cc0) (const_int 0))
(pc)
(match_operand 1 "" "")))]
diff --git a/gcc/config/moxie/constraints.md b/gcc/config/moxie/constraints.md
new file mode 100644
index 00000000000..038be5d4c6e
--- /dev/null
+++ b/gcc/config/moxie/constraints.md
@@ -0,0 +1,52 @@
+;; Constraint definitions for Moxie
+;; Copyright (C) 2009 Free Software Foundation, Inc.
+;; Contributed by Anthony Green <green@moxielogic.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/>.
+
+;; -------------------------------------------------------------------------
+;; Constraints
+;; -------------------------------------------------------------------------
+
+(define_constraint "A"
+ "An absolute address."
+ (and (match_code "mem")
+ (ior (match_test "GET_CODE (XEXP (op, 0)) == SYMBOL_REF")
+ (match_test "GET_CODE (XEXP (op, 0)) == LABEL_REF")
+ (match_test "GET_CODE (XEXP (op, 0)) == CONST"))))
+
+(define_constraint "B"
+ "An offset address."
+ (and (match_code "mem")
+ (match_test "GET_CODE (XEXP (op, 0)) == PLUS")))
+
+(define_constraint "W"
+ "A register indirect memory operand."
+ (and (match_code "mem")
+ (match_test "REG_P (XEXP (op, 0))
+ && REGNO_OK_FOR_BASE_P (REGNO (XEXP (op, 0)))")))
+
+(define_constraint "I"
+ "An 8-bit constant (0..255)"
+ (and (match_code "const_int")
+ (match_test "ival >= 0 && ival <= 255")))
+
+(define_constraint "N"
+ "A constant -(0..255)"
+ (and (match_code "const_int")
+ (match_test "ival >= -255 && ival <= 0")))
+
diff --git a/gcc/config/moxie/crti.asm b/gcc/config/moxie/crti.asm
new file mode 100644
index 00000000000..f44582799a3
--- /dev/null
+++ b/gcc/config/moxie/crti.asm
@@ -0,0 +1,40 @@
+# crti.asm for moxie
+#
+# Copyright (C) 2009 Free Software Foundation
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3, or (at your option) any
+# later version.
+#
+# This file is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# Under Section 7 of GPL version 3, you are granted additional
+# permissions described in the GCC Runtime Library Exception, version
+# 3.1, as published by the Free Software Foundation.
+#
+# You should have received a copy of the GNU General Public License and
+# a copy of the GCC Runtime Library Exception along with this program;
+# see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+# <http://www.gnu.org/licenses/>.
+
+# This file just make a stack frame for the contents of the .fini and
+# .init sections. Users may put any desired instructions in those
+# sections.
+
+ .file "crti.asm"
+
+ .section ".init"
+ .global _init
+ .type _init, @function
+ .p2align 1
+_init:
+
+ .section ".fini"
+ .global _fini
+ .type _fini,@function
+ .p2align 1
+_fini:
diff --git a/gcc/config/moxie/crtn.asm b/gcc/config/moxie/crtn.asm
new file mode 100644
index 00000000000..3ac9d31eed8
--- /dev/null
+++ b/gcc/config/moxie/crtn.asm
@@ -0,0 +1,34 @@
+# crtn.asm for moxie
+#
+# Copyright (C) 2009 Free Software Foundation
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3, or (at your option) any
+# later version.
+#
+# This file is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# Under Section 7 of GPL version 3, you are granted additional
+# permissions described in the GCC Runtime Library Exception, version
+# 3.1, as published by the Free Software Foundation.
+#
+# You should have received a copy of the GNU General Public License and
+# a copy of the GCC Runtime Library Exception along with this program;
+# see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+# <http://www.gnu.org/licenses/>.
+
+# This file just makes sure that the .fini and .init sections do in
+# fact return. Users may put any desired instructions in those sections.
+# This file is the last thing linked into any executable.
+
+ .file "crtn.asm"
+
+ .section ".init"
+ ret
+
+ .section ".fini"
+ ret
diff --git a/gcc/config/moxie/moxie-protos.h b/gcc/config/moxie/moxie-protos.h
new file mode 100644
index 00000000000..d475aac6a69
--- /dev/null
+++ b/gcc/config/moxie/moxie-protos.h
@@ -0,0 +1,28 @@
+/* Prototypes for moxie.c functions used in the md file & elsewhere.
+ Copyright (C) 2009 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/>. */
+
+extern void moxie_expand_prologue (void);
+extern void moxie_expand_epilogue (void);
+extern int moxie_initial_elimination_offset (int, int);
+extern rtx moxie_function_value (tree, tree, bool ATTRIBUTE_UNUSED);
+extern void moxie_print_operand (FILE *, rtx, int);
+extern void moxie_print_operand_address (FILE *, rtx);
+#ifdef RTX_CODE
+extern rtx moxie_function_arg (CUMULATIVE_ARGS, enum machine_mode, tree, int);
+#endif /* RTX_CODE */
diff --git a/gcc/config/moxie/moxie.c b/gcc/config/moxie/moxie.c
new file mode 100644
index 00000000000..03e9f3f2485
--- /dev/null
+++ b/gcc/config/moxie/moxie.c
@@ -0,0 +1,480 @@
+/* Target Code for moxie
+ Copyright (C) 2008, 2009 Free Software Foundation
+ Contributed by Anthony Green.
+
+ 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 "rtl.h"
+#include "regs.h"
+#include "hard-reg-set.h"
+#include "real.h"
+#include "insn-config.h"
+#include "conditions.h"
+#include "insn-flags.h"
+#include "output.h"
+#include "insn-attr.h"
+#include "flags.h"
+#include "recog.h"
+#include "reload.h"
+#include "toplev.h"
+#include "obstack.h"
+#include "tree.h"
+#include "expr.h"
+#include "optabs.h"
+#include "except.h"
+#include "function.h"
+#include "ggc.h"
+#include "target.h"
+#include "target-def.h"
+#include "tm_p.h"
+#include "langhooks.h"
+#include "df.h"
+
+#define LOSE_AND_RETURN(msgid, x) \
+ do \
+ { \
+ moxie_operand_lossage (msgid, x); \
+ return; \
+ } while (0)
+
+/* Worker function for TARGET_RETURN_IN_MEMORY. */
+
+static bool
+moxie_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
+{
+ const HOST_WIDE_INT size = int_size_in_bytes (type);
+ return (size == -1 || size > 2 * UNITS_PER_WORD);
+}
+
+/* Define how to find the value returned by a function.
+ VALTYPE is the data type of the value (as a tree).
+ If the precise function being called is known, FUNC is its
+ FUNCTION_DECL; otherwise, FUNC is 0.
+
+ We always return values in register $r0 for moxie. */
+
+rtx
+moxie_function_value (tree valtype,
+ tree fntype_or_decl ATTRIBUTE_UNUSED,
+ bool outgoing ATTRIBUTE_UNUSED)
+{
+ return gen_rtx_REG (TYPE_MODE (valtype), MOXIE_R0);
+}
+
+/* Emit an error message when we're in an asm, and a fatal error for
+ "normal" insns. Formatted output isn't easily implemented, since we
+ use output_operand_lossage to output the actual message and handle the
+ categorization of the error. */
+
+static void
+moxie_operand_lossage (const char *msgid, rtx op)
+{
+ debug_rtx (op);
+ output_operand_lossage ("%s", msgid);
+}
+
+/* The PRINT_OPERAND_ADDRESS worker. */
+
+void
+moxie_print_operand_address (FILE *file, rtx x)
+{
+ switch (GET_CODE (x))
+ {
+ case REG:
+ fprintf (file, "(%s)", reg_names[REGNO (x)]);
+ break;
+
+ case PLUS:
+ switch (GET_CODE (XEXP (x, 1)))
+ {
+ case CONST_INT:
+ fprintf (file, "%ld(%s)",
+ INTVAL(XEXP (x, 1)), reg_names[REGNO (XEXP (x, 0))]);
+ break;
+ case SYMBOL_REF:
+ output_addr_const (file, XEXP (x, 1));
+ fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
+ break;
+ case CONST:
+ {
+ rtx plus = XEXP (XEXP (x, 1), 0);
+ if (GET_CODE (XEXP (plus, 0)) == SYMBOL_REF
+ && CONST_INT_P (XEXP (plus, 1)))
+ {
+ output_addr_const(file, XEXP (plus, 0));
+ fprintf (file,"+%ld(%s)", INTVAL (XEXP (plus, 1)),
+ reg_names[REGNO (XEXP (x, 0))]);
+ }
+ else
+ abort();
+ }
+ break;
+ default:
+ abort();
+ }
+ break;
+
+ default:
+ output_addr_const (file, x);
+ break;
+ }
+}
+
+/* The PRINT_OPERAND worker. */
+
+void
+moxie_print_operand (FILE *file, rtx x, int code)
+{
+ rtx operand = x;
+
+ /* New code entries should just be added to the switch below. If
+ handling is finished, just return. If handling was just a
+ modification of the operand, the modified operand should be put in
+ "operand", and then do a break to let default handling
+ (zero-modifier) output the operand. */
+
+ switch (code)
+ {
+ case 0:
+ /* No code, print as usual. */
+ break;
+
+ default:
+ LOSE_AND_RETURN ("invalid operand modifier letter", x);
+ }
+
+ /* Print an operand as without a modifier letter. */
+ switch (GET_CODE (operand))
+ {
+ case REG:
+ if (REGNO (operand) > MOXIE_R13)
+ internal_error ("internal error: bad register: %d", REGNO (operand));
+ fprintf (file, "%s", reg_names[REGNO (operand)]);
+ return;
+
+ case MEM:
+ output_address (XEXP (operand, 0));
+ return;
+
+ default:
+ /* No need to handle all strange variants, let output_addr_const
+ do it for us. */
+ if (CONSTANT_P (operand))
+ {
+ output_addr_const (file, operand);
+ return;
+ }
+
+ LOSE_AND_RETURN ("unexpected operand", x);
+ }
+}
+
+/* Per-function machine data. */
+struct GTY(()) machine_function
+ {
+ /* Number of bytes saved on the stack for callee saved registers. */
+ int callee_saved_reg_size;
+
+ /* Number of bytes saved on the stack for local variables. */
+ int local_vars_size;
+
+ /* The sum of 2 sizes: locals vars and padding byte for saving the
+ * registers. Used in expand_prologue () and expand_epilogue(). */
+ int size_for_adjusting_sp;
+ };
+
+/* Zero initialization is OK for all current fields. */
+
+static struct machine_function *
+moxie_init_machine_status (void)
+{
+ return GGC_CNEW (struct machine_function);
+}
+
+
+/* The OVERRIDE_OPTIONS worker.
+ All this curently does is set init_machine_status. */
+void
+moxie_override_options (void)
+{
+ /* Set the per-function-data initializer. */
+ init_machine_status = moxie_init_machine_status;
+}
+
+/* Compute the size of the local area and the size to be adjusted by the
+ * prologue and epilogue. */
+
+static void
+moxie_compute_frame (void)
+{
+ /* For aligning the local variables. */
+ int stack_alignment = STACK_BOUNDARY / BITS_PER_UNIT;
+ int padding_locals;
+ int regno;
+
+ /* Padding needed for each element of the frame. */
+ cfun->machine->local_vars_size = get_frame_size ();
+
+ /* Align to the stack alignment. */
+ padding_locals = cfun->machine->local_vars_size % stack_alignment;
+ if (padding_locals)
+ padding_locals = stack_alignment - padding_locals;
+
+ cfun->machine->local_vars_size += padding_locals;
+
+ cfun->machine->callee_saved_reg_size = 0;
+
+ /* Save callee-saved registers. */
+ for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
+ if (df_regs_ever_live_p (regno) && (! call_used_regs[regno]))
+ cfun->machine->callee_saved_reg_size += 4;
+
+ cfun->machine->size_for_adjusting_sp =
+ crtl->args.pretend_args_size
+ + cfun->machine->local_vars_size
+ + (ACCUMULATE_OUTGOING_ARGS ? crtl->outgoing_args_size : 0);
+}
+
+void
+moxie_expand_prologue (void)
+{
+ int regno;
+ rtx insn;
+
+ moxie_compute_frame ();
+
+ /* Save callee-saved registers. */
+ for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
+ {
+ if (!fixed_regs[regno] && df_regs_ever_live_p (regno) && !call_used_regs[regno])
+ {
+ insn = emit_insn (gen_movsi_push (gen_rtx_REG (Pmode, regno)));
+ RTX_FRAME_RELATED_P (insn) = 1;
+ }
+ }
+
+ if (cfun->machine->size_for_adjusting_sp > 0)
+ {
+ insn =
+ emit_insn (gen_movsi (gen_rtx_REG (Pmode, MOXIE_R12),
+ GEN_INT (-cfun->machine->size_for_adjusting_sp)));
+ RTX_FRAME_RELATED_P (insn) = 1;
+ insn = emit_insn (gen_addsi3 (stack_pointer_rtx,
+ stack_pointer_rtx,
+ gen_rtx_REG (Pmode, MOXIE_R12)));
+ RTX_FRAME_RELATED_P (insn) = 1;
+ }
+}
+
+void
+moxie_expand_epilogue (void)
+{
+ int regno;
+ rtx insn, reg, cfa_restores = NULL;
+
+ if (cfun->machine->callee_saved_reg_size != 0)
+ {
+ reg = gen_rtx_REG (Pmode, MOXIE_R12);
+ emit_move_insn (reg,
+ GEN_INT (-cfun->machine->callee_saved_reg_size));
+ emit_insn (gen_addsi3 (reg, reg, hard_frame_pointer_rtx));
+ insn = emit_move_insn (stack_pointer_rtx, reg);
+ RTX_FRAME_RELATED_P (insn) = 1;
+ add_reg_note (insn, REG_CFA_DEF_CFA,
+ plus_constant (stack_pointer_rtx,
+ cfun->machine->callee_saved_reg_size));
+ for (regno = FIRST_PSEUDO_REGISTER; regno-- > 0; )
+ if (!fixed_regs[regno] && !call_used_regs[regno]
+ && df_regs_ever_live_p (regno))
+ {
+ reg = gen_rtx_REG (Pmode, regno);
+ insn = emit_insn (gen_movsi_pop (reg));
+ RTX_FRAME_RELATED_P (insn) = 1;
+ add_reg_note (insn, REG_CFA_ADJUST_CFA,
+ gen_rtx_SET (VOIDmode, stack_pointer_rtx,
+ plus_constant (stack_pointer_rtx,
+ UNITS_PER_WORD)));
+ add_reg_note (insn, REG_CFA_RESTORE, reg);
+ }
+ }
+
+ emit_jump_insn (gen_returner ());
+}
+
+/* Implements the macro INITIAL_ELIMINATION_OFFSET, return the OFFSET. */
+
+int
+moxie_initial_elimination_offset (int from, int to)
+{
+ int ret;
+
+ if ((from) == FRAME_POINTER_REGNUM && (to) == HARD_FRAME_POINTER_REGNUM)
+ {
+ /* Compute this since we need to use cfun->machine->local_vars_size. */
+ moxie_compute_frame ();
+ ret = -cfun->machine->callee_saved_reg_size;
+ }
+ else if ((from) == ARG_POINTER_REGNUM && (to) == HARD_FRAME_POINTER_REGNUM)
+ ret = 0x00;
+ else
+ abort ();
+
+ return ret;
+}
+
+/* Worker function for TARGET_SETUP_INCOMING_VARARGS. */
+
+static void
+moxie_setup_incoming_varargs (CUMULATIVE_ARGS *cum,
+ enum machine_mode mode ATTRIBUTE_UNUSED,
+ tree type ATTRIBUTE_UNUSED,
+ int *pretend_size, int no_rtl)
+{
+ int regno;
+ int regs = 4 - *cum;
+
+ *pretend_size = regs < 0 ? 0 : GET_MODE_SIZE (SImode) * regs;
+
+ if (no_rtl)
+ return;
+
+ for (regno = *cum; regno < 4; regno++)
+ {
+ rtx reg = gen_rtx_REG (SImode, regno);
+ rtx slot = gen_rtx_PLUS (Pmode,
+ gen_rtx_REG (SImode, ARG_POINTER_REGNUM),
+ GEN_INT (UNITS_PER_WORD * (3 + (regno-2))));
+
+ emit_move_insn (gen_rtx_MEM (SImode, slot), reg);
+ }
+}
+
+
+/* Return the fixed registers used for condition codes. */
+
+static bool
+moxie_fixed_condition_code_regs (unsigned int *p1, unsigned int *p2)
+{
+ *p1 = CC_REG;
+ *p2 = INVALID_REGNUM;
+ return true;
+}
+
+/* Return the next register to be used to hold a function argument or
+ NULL_RTX if there's no more space. */
+
+rtx
+moxie_function_arg (CUMULATIVE_ARGS cum, enum machine_mode mode,
+ tree type ATTRIBUTE_UNUSED, int named ATTRIBUTE_UNUSED)
+{
+ if (cum < 4)
+ return gen_rtx_REG (mode, cum);
+ else
+ return NULL_RTX;
+}
+
+/* Return non-zero if the function argument described by TYPE is to be
+ passed by reference. */
+
+static bool
+moxie_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
+ enum machine_mode mode, const_tree type,
+ bool named ATTRIBUTE_UNUSED)
+{
+ unsigned HOST_WIDE_INT size;
+
+ if (type)
+ {
+ if (AGGREGATE_TYPE_P (type))
+ return true;
+ size = int_size_in_bytes (type);
+ }
+ else
+ size = GET_MODE_SIZE (mode);
+
+ return size > 8;
+}
+
+/* Some function arguments will only partially fit in the registers
+ that hold arguments. Given a new arg, return the number of bytes
+ that fit in argument passing registers. */
+
+static int
+moxie_arg_partial_bytes (CUMULATIVE_ARGS *cum,
+ enum machine_mode mode,
+ tree type, bool named)
+{
+ int bytes_left, size;
+
+ if (*cum >= 4)
+ return 0;
+
+ if (moxie_pass_by_reference (cum, mode, type, named))
+ size = 4;
+ else if (type)
+ {
+ if (AGGREGATE_TYPE_P (type))
+ return 0;
+ size = int_size_in_bytes (type);
+ }
+ else
+ size = GET_MODE_SIZE (mode);
+
+ bytes_left = 8 - ((*cum - 2) * 4);
+
+ if (size > bytes_left)
+ return bytes_left;
+ else
+ return 0;
+}
+
+/* The Global `targetm' Variable. */
+
+/* Initialize the GCC target structure. */
+
+#undef TARGET_PROMOTE_PROTOTYPES
+#define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
+
+#undef TARGET_RETURN_IN_MEMORY
+#define TARGET_RETURN_IN_MEMORY moxie_return_in_memory
+#undef TARGET_MUST_PASS_IN_STACK
+#define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
+#undef TARGET_PASS_BY_REFERENCE
+#define TARGET_PASS_BY_REFERENCE moxie_pass_by_reference
+#undef TARGET_ARG_PARTIAL_BYTES
+#define TARGET_ARG_PARTIAL_BYTES moxie_arg_partial_bytes
+
+
+#undef TARGET_SETUP_INCOMING_VARARGS
+#define TARGET_SETUP_INCOMING_VARARGS moxie_setup_incoming_varargs
+
+#undef TARGET_FIXED_CONDITION_CODE_REGS
+#define TARGET_FIXED_CONDITION_CODE_REGS moxie_fixed_condition_code_regs
+
+/* Define this to return an RTX representing the place where a
+ function returns or receives a value of data type RET_TYPE, a tree
+ node node representing a data type. */
+#undef TARGET_FUNCTION_VALUE
+#define TARGET_FUNCTION_VALUE moxie_function_value
+
+struct gcc_target targetm = TARGET_INITIALIZER;
+
+#include "gt-moxie.h"
diff --git a/gcc/config/moxie/moxie.h b/gcc/config/moxie/moxie.h
new file mode 100644
index 00000000000..e63190978f0
--- /dev/null
+++ b/gcc/config/moxie/moxie.h
@@ -0,0 +1,576 @@
+/* Target Definitions for moxie.
+ Copyright (C) 2008, 2009 Free Software Foundation, Inc.
+ Contributed by Anthony Green.
+
+ 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_MOXIE_H
+#define GCC_MOXIE_H
+
+/* This is defined by svr4.h, which is included prior to this file.
+ However, we should undefine it for moxie-elf, since we don't provide
+ functions like access() and mkdir() in newlib. This will have to
+ be defined again for a Linux port. */
+#undef TARGET_POSIX_IO
+
+/* Another C string constant used much like `LINK_SPEC'. The difference
+ between the two is that `STARTFILE_SPEC' is used at the very beginning of
+ the command given to the linker.
+
+ If this macro is not defined, a default is provided that loads the standard
+ C startup file from the usual place. See `gcc.c'.
+
+ Defined in svr4.h. */
+#undef STARTFILE_SPEC
+#define STARTFILE_SPEC "crt0%O%s crti.o%s crtbegin.o%s"
+
+/* Provide an ENDFILE_SPEC appropriate for svr4. Here we tack on our own
+ magical crtend.o file (see crtstuff.c) which provides part of the
+ support for getting C++ file-scope static object constructed before
+ entering `main', followed by the normal svr3/svr4 "finalizer" file,
+ which is either `gcrtn.o' or `crtn.o'. */
+
+#undef ENDFILE_SPEC
+#define ENDFILE_SPEC "crtend.o%s crtn.o%s"
+
+/* Provide a LIB_SPEC appropriate for svr4. Here we tack on the default
+ standard C library (unless we are building a shared library) and
+ the simulator BSP code. */
+
+#undef LIB_SPEC
+#define LIB_SPEC "%{!shared:%{!symbolic:-lc}}"
+
+/* Layout of Source Language Data Types */
+
+#define INT_TYPE_SIZE 32
+#define SHORT_TYPE_SIZE 16
+#define LONG_TYPE_SIZE 32
+#define LONG_LONG_TYPE_SIZE 64
+
+#define FLOAT_TYPE_SIZE 32
+#define DOUBLE_TYPE_SIZE 64
+#define LONG_DOUBLE_TYPE_SIZE 64
+
+#define DEFAULT_SIGNED_CHAR 1
+
+/* Registers...
+
+ $fp - frame pointer
+ $sp - stack pointer
+ $r0 - general purpose 32-bit register.
+ $r1 - general purpose 32-bit register.
+ $r2 - general purpose 32-bit register.
+ $r3 - general purpose 32-bit register.
+ $r4 - general purpose 32-bit register.
+ $r5 - general purpose 32-bit register.
+ $r6 - general purpose 32-bit register.
+ $r7 - general purpose 32-bit register.
+ $r8 - general purpose 32-bit register.
+ $r9 - general purpose 32-bit register.
+ $r10 - general purpose 32-bit register.
+ $r11 - general purpose 32-bit register.
+ $r12 - general purpose 32-bit register.
+ $r13 - reserved for execution environment.
+
+ Special Registers...
+
+ $pc - 32-bit program counter.
+
+*/
+
+#define REGISTER_NAMES { \
+ "$fp", "$sp", "$r0", "$r1", \
+ "$r2", "$r3", "$r4", "$r5", \
+ "$r6", "$r7", "$r8", "$r9", \
+ "$r10", "$r11", "$r12", "$r13", \
+ "?fp", "?ap", "$pc", "?cc" }
+
+#define MOXIE_FP 0
+#define MOXIE_SP 1
+#define MOXIE_R0 2
+#define MOXIE_R1 3
+#define MOXIE_R2 4
+#define MOXIE_R3 5
+#define MOXIE_R4 6
+#define MOXIE_R5 7
+#define MOXIE_R6 8
+#define MOXIE_R7 9
+#define MOXIE_R8 10
+#define MOXIE_R9 11
+#define MOXIE_R10 12
+#define MOXIE_R11 13
+#define MOXIE_R12 14
+#define MOXIE_R13 15
+#define MOXIE_QFP 16
+#define MOXIE_QAP 17
+#define MOXIE_PC 18
+#define MOXIE_CC 19
+
+#define FIRST_PSEUDO_REGISTER 20
+
+enum reg_class
+{
+ NO_REGS,
+ GENERAL_REGS,
+ SPECIAL_REGS,
+ CC_REG,
+ ALL_REGS,
+ LIM_REG_CLASSES
+};
+
+
+/* The following macro defines cover classes for Integrated Register
+ Allocator. Cover classes is a set of non-intersected register
+ classes covering all hard registers used for register allocation
+ purpose. Any move between two registers of a cover class should be
+ cheaper than load or store of the registers. The macro value is
+ array of register classes with LIM_REG_CLASSES used as the end
+ marker. */
+#define IRA_COVER_CLASSES { GENERAL_REGS, LIM_REG_CLASSES }
+
+#define REG_CLASS_CONTENTS \
+{ { 0x00000000 }, /* Empty */ \
+ { 0x0003FFFF }, /* $fp, $sp, $r0 to $r5, ?fp */ \
+ { 0x00040000 }, /* $pc */ \
+ { 0x00080000 }, /* ?cc */ \
+ { 0x000FFFFF } /* All registers */ \
+}
+
+#define N_REG_CLASSES LIM_REG_CLASSES
+
+#define REG_CLASS_NAMES {\
+ "NO_REGS", \
+ "GENERAL_REGS", \
+ "SPECIAL_REGS", \
+ "CC_REG", \
+ "ALL_REGS" }
+
+#define FIXED_REGISTERS { 1, 1, 0, 0, \
+ 0, 0, 0, 0, \
+ 0, 0, 0, 0, \
+ 0, 0, 0, 1, \
+ 1, 1, 1, 1 }
+
+#define CALL_USED_REGISTERS { 1, 1, 1, 1, \
+ 0, 0, 0, 0, \
+ 0, 0, 0, 0, \
+ 0, 0, 1, 1, \
+ 1, 1, 1, 1 }
+
+/* We can't copy to or from our CC register. */
+#define AVOID_CCMODE_COPIES 1
+
+/* A C expression that is nonzero if it is permissible to store a
+ value of mode MODE in hard register number REGNO (or in several
+ registers starting with that one). All gstore registers are
+ equivalent, so we can set this to 1. */
+#define HARD_REGNO_MODE_OK(R,M) 1
+
+/* A C expression whose value is a register class containing hard
+ register REGNO. */
+#define REGNO_REG_CLASS(R) ((R < MOXIE_PC) ? GENERAL_REGS : \
+ (R == MOXIE_CC ? CC_REG : SPECIAL_REGS))
+
+/* A C expression for the number of consecutive hard registers,
+ starting at register number REGNO, required to hold a value of mode
+ MODE. */
+#define HARD_REGNO_NREGS(REGNO, MODE) \
+ ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) \
+ / UNITS_PER_WORD)
+
+/* A C expression that is nonzero if a value of mode MODE1 is
+ accessible in mode MODE2 without copying. */
+#define MODES_TIEABLE_P(MODE1, MODE2) 1
+
+/* A C expression for the maximum number of consecutive registers of
+ class CLASS needed to hold a value of mode MODE. */
+#define CLASS_MAX_NREGS(CLASS, MODE) \
+ ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
+
+/* A C expression that places additional restrictions on the register
+ class to use when it is necessary to copy value X into a register
+ in class CLASS. */
+#define PREFERRED_RELOAD_CLASS(X,CLASS) CLASS
+
+/* The Overall Framework of an Assembler File */
+
+#undef ASM_SPEC
+#define ASM_COMMENT_START "#"
+#define ASM_APP_ON ""
+#define ASM_APP_OFF ""
+
+#define FILE_ASM_OP "\t.file\n"
+
+/* Switch to the text or data segment. */
+#define TEXT_SECTION_ASM_OP "\t.text"
+#define DATA_SECTION_ASM_OP "\t.data"
+
+/* Assembler Commands for Alignment */
+
+#define ASM_OUTPUT_ALIGN(STREAM,POWER) \
+ fprintf (STREAM, "\t.p2align\t%d\n", POWER);
+
+/* A C compound statement to output to stdio stream STREAM the
+ assembler syntax for an instruction operand X. */
+#define PRINT_OPERAND(STREAM, X, CODE) moxie_print_operand (STREAM, X, CODE)
+
+#define PRINT_OPERAND_ADDRESS(STREAM ,X) moxie_print_operand_address (STREAM, X)
+
+/* Output and Generation of Labels */
+
+#define GLOBAL_ASM_OP "\t.global\t"
+
+/* Passing Arguments in Registers */
+
+/* A C expression that controls whether a function argument is passed
+ in a register, and which register. */
+#define FUNCTION_ARG(CUM,MODE,TYPE,NAMED) \
+ moxie_function_arg(CUM,MODE,TYPE,NAMED)
+
+/* A C type for declaring a variable that is used as the first
+ argument of `FUNCTION_ARG' and other related values. */
+#define CUMULATIVE_ARGS unsigned int
+
+/* If defined, the maximum amount of space required for outgoing arguments
+ will be computed and placed into the variable
+ `current_function_outgoing_args_size'. No space will be pushed
+ onto the stack for each call; instead, the function prologue should
+ increase the stack frame size by this amount. */
+#define ACCUMULATE_OUTGOING_ARGS 1
+
+/* A C statement (sans semicolon) for initializing the variable CUM
+ for the state at the beginning of the argument list.
+ For moxie, the first arg is passed in register 2 (aka $r0). */
+#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,FNDECL,N_NAMED_ARGS) \
+ (CUM = MOXIE_R0)
+
+#define MOXIE_FUNCTION_ARG_SIZE(MODE, TYPE) \
+ ((MODE) != BLKmode ? GET_MODE_SIZE (MODE) \
+ : (unsigned) int_size_in_bytes (TYPE))
+
+#define FUNCTION_ARG_ADVANCE(CUM,MODE,TYPE,NAMED) \
+ (CUM = (CUM < MOXIE_R2 ? \
+ CUM + ((3 + MOXIE_FUNCTION_ARG_SIZE(MODE,TYPE))/4) : CUM ))
+
+/* How Scalar Function Values Are Returned */
+
+/* These macros are deprecated, but we still need them for now since
+ the version of gcc we're using doesn't fully support
+ TARGET_FUNCTION_VALUE. */
+#define FUNCTION_VALUE(VALTYPE, FUNC) \
+ moxie_function_value (VALTYPE, FUNC, 0)
+#define FUNCTION_OUTGOING_VALUE(VALTYPE, FUNC) \
+ moxie_function_value (VALTYPE, FUNC, 1)
+
+/* A C expression to create an RTX representing the place where a
+ library function returns a value of mode MODE. */
+#define LIBCALL_VALUE(MODE) gen_rtx_REG (MODE, 2)
+
+/* STACK AND CALLING */
+
+/* Define this macro if pushing a word onto the stack moves the stack
+ pointer to a smaller address. */
+#define STACK_GROWS_DOWNWARD
+
+#define INITIAL_FRAME_POINTER_OFFSET(DEPTH) (DEPTH) = 0
+
+/* Offset from the frame pointer to the first local variable slot to
+ be allocated. */
+#define STARTING_FRAME_OFFSET 0
+
+/* Define this if the above stack space is to be considered part of the
+ space allocated by the caller. */
+#define OUTGOING_REG_PARM_STACK_SPACE(FNTYPE) 1
+#define STACK_PARMS_IN_REG_PARM_AREA
+
+/* Define this if it is the responsibility of the caller to allocate
+ the area reserved for arguments passed in registers. */
+#define REG_PARM_STACK_SPACE(FNDECL) (2 * UNITS_PER_WORD)
+
+/* Offset from the argument pointer register to the first argument's
+ address. On some machines it may depend on the data type of the
+ function. */
+#define FIRST_PARM_OFFSET(F) 12
+
+/* Define this macro to nonzero value if the addresses of local variable slots
+ are at negative offsets from the frame pointer. */
+#define FRAME_GROWS_DOWNWARD 1
+
+/* Define this macro as a C expression that is nonzero for registers that are
+ used by the epilogue or the return pattern. The stack and frame
+ pointer registers are already assumed to be used as needed. */
+#define EPILOGUE_USES(R) (R == MOXIE_R5)
+
+#define OVERRIDE_OPTIONS moxie_override_options ()
+
+/* Storage Layout */
+
+#define BITS_BIG_ENDIAN 0
+#define BYTES_BIG_ENDIAN 1
+#define WORDS_BIG_ENDIAN 1
+
+/* Alignment required for a function entry point, in bits. */
+#define FUNCTION_BOUNDARY 16
+
+/* Define this macro as a C expression which is nonzero if accessing
+ less than a word of memory (i.e. a `char' or a `short') is no
+ faster than accessing a word of memory. */
+#define SLOW_BYTE_ACCESS 1
+
+/* Number of storage units in a word; normally the size of a
+ general-purpose register, a power of two from 1 or 8. */
+#define UNITS_PER_WORD 4
+
+/* Define this macro to the minimum alignment enforced by hardware
+ for the stack pointer on this machine. The definition is a C
+ expression for the desired alignment (measured in bits). */
+#define STACK_BOUNDARY 32
+
+/* Normal alignment required for function parameters on the stack, in
+ bits. All stack parameters receive at least this much alignment
+ regardless of data type. */
+#define PARM_BOUNDARY 32
+
+/* Alignment of field after `int : 0' in a structure. */
+#define EMPTY_FIELD_BOUNDARY 32
+
+/* No data type wants to be aligned rounder than this. */
+#define BIGGEST_ALIGNMENT 32
+
+/* The best alignment to use in cases where we have a choice. */
+#define FASTEST_ALIGNMENT 32
+
+/* Every structures size must be a multiple of 8 bits. */
+#define STRUCTURE_SIZE_BOUNDARY 8
+
+/* Look at the fundamental type that is used for a bit-field and use
+ that to impose alignment on the enclosing structure.
+ struct s {int a:8}; should have same alignment as "int", not "char". */
+#define PCC_BITFIELD_TYPE_MATTERS 1
+
+/* Largest integer machine mode for structures. If undefined, the default
+ is GET_MODE_SIZE(DImode). */
+#define MAX_FIXED_MODE_SIZE 32
+
+/* Make strings word-aligned so strcpy from constants will be faster. */
+#define CONSTANT_ALIGNMENT(EXP, ALIGN) \
+ ((TREE_CODE (EXP) == STRING_CST \
+ && (ALIGN) < FASTEST_ALIGNMENT) \
+ ? FASTEST_ALIGNMENT : (ALIGN))
+
+/* Make arrays of chars word-aligned for the same reasons. */
+#define DATA_ALIGNMENT(TYPE, ALIGN) \
+ (TREE_CODE (TYPE) == ARRAY_TYPE \
+ && TYPE_MODE (TREE_TYPE (TYPE)) == QImode \
+ && (ALIGN) < FASTEST_ALIGNMENT ? FASTEST_ALIGNMENT : (ALIGN))
+
+/* Set this nonzero if move instructions will actually fail to work
+ when given unaligned data. */
+#define STRICT_ALIGNMENT 1
+
+/* Generating Code for Profiling */
+#define FUNCTION_PROFILER(FILE,LABELNO) (abort (), 0)
+
+/* Trampolines for Nested Functions. */
+#define TRAMPOLINE_SIZE (2 + 6 + 6 + 2 + 6)
+
+/* Alignment required for trampolines, in bits. */
+#define TRAMPOLINE_ALIGNMENT 16
+
+/* A C statement to initialize the variable parts of a trampoline. ADDR is an
+ RTX for the address of the trampoline; FNADDR is an RTX for the address of
+ the nested function; STATIC_CHAIN is an RTX for the static chain value that
+ should be passed to the function when it is called. */
+#define INITIALIZE_TRAMPOLINE(ADDR, FNADDR, STATIC_CHAIN) \
+do \
+{ \
+ emit_move_insn (gen_rtx_MEM (SImode, \
+ plus_constant (ADDR, 4)), STATIC_CHAIN); \
+ emit_move_insn (gen_rtx_MEM (SImode, plus_constant (ADDR, 18)), FNADDR); \
+} while (0);
+
+/* A C statement to output, on the stream FILE, assembler code for a
+ block of data that contains the constant parts of a trampoline.
+ This code should not include a label--the label is taken care of
+ automatically. */
+#define TRAMPOLINE_TEMPLATE(FILE) \
+{ \
+ fprintf (FILE, "\tpush $sp, $r0\n"); \
+ fprintf (FILE, "\tldi.l $r0, 0x0\n"); \
+ fprintf (FILE, "\tsto.l 0x8($fp), $r0\n"); \
+ fprintf (FILE, "\tpop $sp, $r0\n"); \
+ fprintf (FILE, "\tjmpa 0x0\n"); \
+}
+
+/* An alias for the machine mode for pointers. */
+#define Pmode SImode
+
+/* An alias for the machine mode used for memory references to
+ functions being called, in `call' RTL expressions. */
+#define FUNCTION_MODE QImode
+
+/* The register number of the stack pointer register, which must also
+ be a fixed register according to `FIXED_REGISTERS'. */
+#define STACK_POINTER_REGNUM 1
+
+/* The register number of the frame pointer register, which is used to
+ access automatic variables in the stack frame. */
+#define FRAME_POINTER_REGNUM MOXIE_QFP
+
+/* The register number of the arg pointer register, which is used to
+ access the function's argument list. */
+#define ARG_POINTER_REGNUM MOXIE_QAP
+
+/* If the static chain is passed in memory, these macros provide rtx
+ giving 'mem' expressions that denote where they are stored.
+ 'STATIC_CHAIN' and 'STATIC_CHAIN_INCOMING' give the locations as
+ seen by the calling and called functions, respectively. */
+
+#define STATIC_CHAIN \
+ gen_rtx_MEM (Pmode, plus_constant (stack_pointer_rtx, -UNITS_PER_WORD))
+
+#define STATIC_CHAIN_INCOMING \
+ gen_rtx_MEM (Pmode, plus_constant (arg_pointer_rtx, 2 * UNITS_PER_WORD))
+
+#define HARD_FRAME_POINTER_REGNUM MOXIE_FP
+
+#if 0
+#define ELIMINABLE_REGS \
+{{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM }, \
+ { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM }, \
+ { ARG_POINTER_REGNUM, STACK_POINTER_REGNUM }, \
+ { ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM }}
+#else
+#define ELIMINABLE_REGS \
+{{ FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM }, \
+ { ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM }}
+#endif
+
+/* A C expression that returns nonzero if the compiler is allowed to
+ try to replace register number FROM-REG with register number
+ TO-REG. This macro need only be defined if `ELIMINABLE_REGS' is
+ defined, and will usually be the constant 1, since most of the
+ cases preventing register elimination are things that the compiler
+ already knows about. */
+#define CAN_ELIMINATE(FROM, TO) 1
+
+/* This macro is similar to `INITIAL_FRAME_POINTER_OFFSET'. It
+ specifies the initial difference between the specified pair of
+ registers. This macro must be defined if `ELIMINABLE_REGS' is
+ defined. */
+#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
+ do { \
+ (OFFSET) = moxie_initial_elimination_offset ((FROM), (TO)); \
+ } while (0)
+
+/* A C expression that is nonzero if REGNO is the number of a hard
+ register in which function arguments are sometimes passed. */
+#define FUNCTION_ARG_REGNO_P(r) (r == MOXIE_R0 || r == MOXIE_R1)
+
+/* A C expression that is nonzero if REGNO is the number of a hard
+ register in which the values of called function may come back. */
+#define FUNCTION_VALUE_REGNO_P(r) (r == MOXIE_R0)
+
+/* A macro whose definition is the name of the class to which a valid
+ base register must belong. A base register is one used in an
+ address which is the register value plus a displacement. */
+#define BASE_REG_CLASS GENERAL_REGS
+
+#define INDEX_REG_CLASS NO_REGS
+
+#define HARD_REGNO_OK_FOR_BASE_P(NUM) \
+ ((NUM) >= 0 && (NUM) < FIRST_PSEUDO_REGISTER \
+ && (REGNO_REG_CLASS(NUM) == GENERAL_REGS \
+ || (NUM) == HARD_FRAME_POINTER_REGNUM))
+
+/* A C expression which is nonzero if register number NUM is suitable
+ for use as a base register in operand addresses. */
+#ifdef REG_OK_STRICT
+#define REGNO_OK_FOR_BASE_P(NUM) \
+ (HARD_REGNO_OK_FOR_BASE_P(NUM) \
+ || HARD_REGNO_OK_FOR_BASE_P(reg_renumber[(NUM)]))
+#else
+#define REGNO_OK_FOR_BASE_P(NUM) \
+ ((NUM) >= FIRST_PSEUDO_REGISTER || HARD_REGNO_OK_FOR_BASE_P(NUM))
+#endif
+
+/* A C expression which is nonzero if register number NUM is suitable
+ for use as an index register in operand addresses. */
+#define REGNO_OK_FOR_INDEX_P(NUM) MOXIE_FP
+
+/* The maximum number of bytes that a single instruction can move
+ quickly between memory and registers or between two memory
+ locations. */
+#define MOVE_MAX 4
+#define TRULY_NOOP_TRUNCATION(op,ip) 1
+
+#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, STACK_SIZE) 0
+
+/* A C expression that is nonzero if X is a legitimate constant for
+ an immediate operand on the target machine. */
+#define LEGITIMATE_CONSTANT_P(X) 1
+
+#define FRAME_POINTER_REQUIRED 1
+
+/* A C expression that is 1 if the RTX X is a constant which is a
+ valid address. */
+#define CONSTANT_ADDRESS_P(X) CONSTANT_P(X)
+
+/* A number, the maximum number of registers that can appear in a
+ valid memory address. */
+#define MAX_REGS_PER_ADDRESS 1
+
+#define TRULY_NOOP_TRUNCATION(op,ip) 1
+
+/* An alias for a machine mode name. This is the machine mode that
+ elements of a jump-table should have. */
+#define CASE_VECTOR_MODE SImode
+
+/* A C compound statement with a conditional `goto LABEL;' executed
+ if X (an RTX) is a legitimate memory address on the target machine
+ for a memory operand of mode MODE. */
+#define GO_IF_LEGITIMATE_ADDRESS(MODE,X,LABEL) \
+ do { \
+ if (GET_CODE(X) == PLUS) \
+ { \
+ rtx op1,op2; \
+ op1 = XEXP(X,0); \
+ op2 = XEXP(X,1); \
+ if (GET_CODE(op1) == REG \
+ && CONSTANT_ADDRESS_P(op2) \
+ && REGNO_OK_FOR_BASE_P(REGNO(op1))) \
+ goto LABEL; \
+ } \
+ if (REG_P (X) && REGNO_OK_FOR_BASE_P (REGNO (X))) \
+ goto LABEL; \
+ if (GET_CODE (X) == SYMBOL_REF \
+ || GET_CODE (X) == LABEL_REF \
+ || GET_CODE (X) == CONST) \
+ goto LABEL; \
+ } while (0)
+
+/* Run-time Target Specification */
+
+#define TARGET_CPU_CPP_BUILTINS() \
+ { \
+ builtin_define_std ("moxie"); \
+ builtin_define_std ("MOXIE"); \
+ }
+
+#define HAS_LONG_UNCOND_BRANCH true
+
+#endif /* GCC_MOXIE_H */
diff --git a/gcc/config/moxie/moxie.md b/gcc/config/moxie/moxie.md
new file mode 100644
index 00000000000..7f3729fdad5
--- /dev/null
+++ b/gcc/config/moxie/moxie.md
@@ -0,0 +1,447 @@
+;; Machine description for Moxie
+;; Copyright (C) 2009 Free Software Foundation, Inc.
+;; Contributed by Anthony Green <green@moxielogic.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/>.
+
+;; -------------------------------------------------------------------------
+;; Moxie specific constraints, predicates and attributes
+;; -------------------------------------------------------------------------
+
+(include "constraints.md")
+(include "predicates.md")
+
+; Most instructions are two bytes long.
+(define_attr "length" "" (const_int 2))
+
+;; -------------------------------------------------------------------------
+;; nop instruction
+;; -------------------------------------------------------------------------
+
+(define_insn "nop"
+ [(const_int 0)]
+ ""
+ "nop")
+
+;; -------------------------------------------------------------------------
+;; Arithmetic instructions
+;; -------------------------------------------------------------------------
+
+(define_insn "addsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r,r,r")
+ (plus:SI
+ (match_operand:SI 1 "register_operand" "0,0,0")
+ (match_operand:SI 2 "moxie_add_operand" "I,N,r")))]
+ ""
+ "@
+ inc %0, %2
+ dec %0, -%2
+ add.l %0, %2")
+
+(define_insn "subsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (minus:SI
+ (match_operand:SI 1 "register_operand" "0,0")
+ (match_operand:SI 2 "moxie_sub_operand" "I,r")))]
+ ""
+ "@
+ dec %0, %2
+ sub.l %0, %2")
+
+(define_insn "mulsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (mult:SI
+ (match_operand:SI 1 "register_operand" "0")
+ (match_operand:SI 2 "register_operand" "r")))]
+ ""
+ "mul.l %0, %2")
+
+(define_insn "divsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (div:SI
+ (match_operand:SI 1 "register_operand" "0")
+ (match_operand:SI 2 "register_operand" "r")))]
+ ""
+ "div.l %0, %2")
+
+(define_insn "udivsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (udiv:SI
+ (match_operand:SI 1 "register_operand" "0")
+ (match_operand:SI 2 "register_operand" "r")))]
+ ""
+ "udiv.l %0, %2")
+
+(define_insn "modsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (mod:SI
+ (match_operand:SI 1 "register_operand" "0")
+ (match_operand:SI 2 "register_operand" "r")))]
+ ""
+ "mod.l %0, %2")
+
+(define_insn "umodsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (umod:SI
+ (match_operand:SI 1 "register_operand" "0")
+ (match_operand:SI 2 "register_operand" "r")))]
+ ""
+ "umod.l %0, %2")
+
+;; -------------------------------------------------------------------------
+;; Unary arithmetic instructions
+;; -------------------------------------------------------------------------
+
+(define_insn "negsi2"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (neg:SI (match_operand:SI 1 "register_operand" "r")))]
+ ""
+ "neg %0, %1")
+
+(define_insn "one_cmplsi2"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (not:SI (match_operand:SI 1 "register_operand" "r")))]
+ ""
+ "not %0, %1")
+
+;; -------------------------------------------------------------------------
+;; Logical operators
+;; -------------------------------------------------------------------------
+
+(define_insn "andsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (and:SI (match_operand:SI 1 "register_operand" "0")
+ (match_operand:SI 2 "register_operand" "r")))]
+ ""
+{
+ return "and %0, %2";
+})
+
+(define_insn "xorsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (xor:SI (match_operand:SI 1 "register_operand" "0")
+ (match_operand:SI 2 "register_operand" "r")))]
+ ""
+{
+ return "xor %0, %2";
+})
+
+(define_insn "iorsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ior:SI (match_operand:SI 1 "register_operand" "0")
+ (match_operand:SI 2 "register_operand" "r")))]
+ ""
+{
+ return "or %0, %2";
+})
+
+;; -------------------------------------------------------------------------
+;; Shifters
+;; -------------------------------------------------------------------------
+
+(define_insn "ashlsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ashift:SI (match_operand:SI 1 "register_operand" "0")
+ (match_operand:SI 2 "register_operand" "r")))]
+ ""
+{
+ return "ashl %0, %2";
+})
+
+(define_insn "ashrsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
+ (match_operand:SI 2 "register_operand" "r")))]
+ ""
+{
+ return "ashr %0, %2";
+})
+
+(define_insn "lshrsi3"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
+ (match_operand:SI 2 "register_operand" "r")))]
+ ""
+{
+ return "lshr %0, %2";
+})
+
+;; -------------------------------------------------------------------------
+;; Move instructions
+;; -------------------------------------------------------------------------
+
+;; SImode
+
+;; Push a register onto the stack
+(define_insn "movsi_push"
+ [(set:SI (mem:SI (pre_dec:SI (reg:SI 1)))
+ (match_operand:SI 0 "register_operand" "r"))]
+ ""
+ "push $sp, %0")
+
+;; Pop a register from the stack
+(define_insn "movsi_pop"
+ [(set:SI (match_operand:SI 0 "register_operand" "=r")
+ (mem:SI (post_inc:SI (reg:SI 1))))]
+ ""
+ "pop $sp, %0")
+
+(define_expand "movsi"
+ [(set (match_operand:SI 0 "general_operand" "")
+ (match_operand:SI 1 "general_operand" ""))]
+ ""
+ "
+{
+ /* If this is a store, force the value into a register. */
+ if (! (reload_in_progress || reload_completed))
+ {
+ if (MEM_P (operands[0]))
+ {
+ operands[1] = force_reg (SImode, operands[1]);
+ if (MEM_P (XEXP (operands[0], 0)))
+ operands[0] = gen_rtx_MEM (SImode, force_reg (SImode, XEXP (operands[0], 0)));
+ }
+ else
+ if (MEM_P (operands[1])
+ && MEM_P (XEXP (operands[1], 0)))
+ operands[1] = gen_rtx_MEM (SImode, force_reg (SImode, XEXP (operands[1], 0)));
+ }
+}")
+
+(define_insn "*movsi"
+ [(set (match_operand:SI 0 "general_operand" "=r,r,W,A,r,r,B,r")
+ (match_operand:SI 1 "moxie_general_movsrc_operand" "r,i,r,r,W,A,r,B"))]
+ "register_operand (operands[0], SImode)
+ || register_operand (operands[1], SImode)"
+ "@
+ mov %0, %1
+ ldi.l %0, %1
+ st.l %0, %1
+ sta.l %0, %1
+ ld.l %0, %1
+ lda.l %0, %1
+ sto.l %0, %1
+ ldo.l %0, %1"
+ [(set_attr "length" "2,6,2,6,2,6,6,6")])
+
+(define_expand "movqi"
+ [(set (match_operand:QI 0 "general_operand" "")
+ (match_operand:QI 1 "general_operand" ""))]
+ ""
+ "
+{
+ /* If this is a store, force the value into a register. */
+ if (MEM_P (operands[0]))
+ operands[1] = force_reg (QImode, operands[1]);
+}")
+
+(define_insn "*movqi"
+ [(set (match_operand:QI 0 "general_operand" "=r,r,W,A,r,r,B,r")
+ (match_operand:QI 1 "moxie_general_movsrc_operand" "r,i,r,r,W,A,r,B"))]
+ "register_operand (operands[0], QImode)
+ || register_operand (operands[1], QImode)"
+ "@
+ mov %0, %1
+ ldi.b %0, %1
+ st.b %0, %1
+ sta.b %0, %1
+ ld.b %0, %1
+ lda.b %0, %1
+ sto.b %0, %1
+ ldo.b %0, %1"
+ [(set_attr "length" "2,6,2,6,2,6,6,6")])
+
+(define_expand "movhi"
+ [(set (match_operand:HI 0 "general_operand" "")
+ (match_operand:HI 1 "general_operand" ""))]
+ ""
+ "
+{
+ /* If this is a store, force the value into a register. */
+ if (MEM_P (operands[0]))
+ operands[1] = force_reg (HImode, operands[1]);
+}")
+
+(define_insn "*movhi"
+ [(set (match_operand:HI 0 "general_operand" "=r,r,W,A,r,r,B,r")
+ (match_operand:HI 1 "moxie_general_movsrc_operand" "r,i,r,r,W,A,r,B"))]
+ "(register_operand (operands[0], HImode)
+ || register_operand (operands[1], HImode))"
+ "@
+ mov %0, %1
+ ldi.s %0, %1
+ st.s %0, %1
+ sta.s %0, %1
+ ld.s %0, %1
+ lda.s %0, %1
+ sto.s %0, %1
+ ldo.s %0, %1"
+ [(set_attr "length" "2,6,2,6,2,6,6,6")])
+
+;; -------------------------------------------------------------------------
+;; Compare instructions
+;; -------------------------------------------------------------------------
+
+(define_constants
+ [(CC_REG 11)])
+
+(define_expand "cbranchsi4"
+ [(set (reg:CC CC_REG)
+ (compare:CC
+ (match_operand:SI 1 "general_operand" "")
+ (match_operand:SI 2 "general_operand" "")))
+ (set (pc)
+ (if_then_else (match_operator:CC 0 "comparison_operator"
+ [(reg:CC CC_REG) (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
+ ""
+ "
+ /* Force the compare operands into registers. */
+ if (GET_CODE (operands[1]) != REG)
+ operands[1] = force_reg (SImode, operands[1]);
+ if (GET_CODE (operands[2]) != REG)
+ operands[2] = force_reg (SImode, operands[2]);
+ ")
+
+(define_insn "*cmpsi"
+ [(set (reg:CC CC_REG)
+ (compare
+ (match_operand:SI 0 "register_operand" "r")
+ (match_operand:SI 1 "register_operand" "r")))]
+ ""
+ "cmp %0, %1")
+
+
+;; -------------------------------------------------------------------------
+;; Branch instructions
+;; -------------------------------------------------------------------------
+
+(define_code_iterator cond [ne eq lt ltu gt gtu ge le geu leu])
+(define_code_attr CC [(ne "ne") (eq "eq") (lt "lt") (ltu "ltu")
+ (gt "gt") (gtu "gtu") (ge "ge") (le "le")
+ (geu "geu") (leu "leu") ])
+(define_code_attr rCC [(ne "eq") (eq "ne") (lt "ge") (ltu "geu")
+ (gt "le") (gtu "leu") (ge "lt") (le "gt")
+ (geu "ltu") (leu "gtu") ])
+
+(define_insn "*b<cond:code>"
+ [(set (pc)
+ (if_then_else (cond (reg:CC CC_REG)
+ (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+{
+ if (get_attr_length (insn) == 2)
+ return "b<CC> %l0";
+ else
+ return "b<rCC> .+6\n\tjmpa %l0";
+}
+ [(set (attr "length")
+ (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 1022))
+ (const_int 2) (const_int 8)))])
+
+;; -------------------------------------------------------------------------
+;; Call and Jump instructions
+;; -------------------------------------------------------------------------
+
+(define_expand "call"
+ [(call (match_operand:QI 0 "memory_operand" "")
+ (match_operand 1 "general_operand" ""))]
+ ""
+{
+ gcc_assert (MEM_P (operands[0]));
+})
+
+(define_insn "*call"
+ [(call (mem:QI (match_operand:SI
+ 0 "nonmemory_operand" "i,r"))
+ (match_operand 1 "" ""))]
+ ""
+ "@
+ jsra %0
+ jsr %0"
+ [(set_attr "length" "6,2")])
+
+(define_expand "call_value"
+ [(set (match_operand 0 "" "")
+ (call (match_operand:QI 1 "memory_operand" "")
+ (match_operand 2 "" "")))]
+ ""
+{
+ gcc_assert (MEM_P (operands[1]));
+})
+
+(define_insn "*call_value"
+ [(set (match_operand 0 "register_operand" "=r")
+ (call (mem:QI (match_operand:SI
+ 1 "immediate_operand" "i"))
+ (match_operand 2 "" "")))]
+ ""
+ "jsra %1"
+ [(set_attr "length" "6")])
+
+(define_insn "*call_value_indirect"
+ [(set (match_operand 0 "register_operand" "=r")
+ (call (mem:QI (match_operand:SI
+ 1 "register_operand" "r"))
+ (match_operand 2 "" "")))]
+ ""
+ "jsr %1")
+
+(define_insn "indirect_jump"
+ [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "r"))]
+ ""
+ "jmp %0")
+
+(define_insn "jump"
+ [(set (pc)
+ (label_ref (match_operand 0 "" "")))]
+ ""
+ "jmpa %l0"
+ [(set_attr "length" "6")])
+
+
+;; -------------------------------------------------------------------------
+;; Prologue & Epilogue
+;; -------------------------------------------------------------------------
+
+(define_expand "prologue"
+ [(clobber (const_int 0))]
+ ""
+ "
+{
+ moxie_expand_prologue ();
+ DONE;
+}
+")
+
+(define_expand "epilogue"
+ [(return)]
+ ""
+ "
+{
+ moxie_expand_epilogue ();
+ DONE;
+}
+")
+
+(define_insn "returner"
+ [(return)]
+ "reload_completed"
+ "ret")
diff --git a/gcc/config/moxie/predicates.md b/gcc/config/moxie/predicates.md
new file mode 100644
index 00000000000..f0595c01179
--- /dev/null
+++ b/gcc/config/moxie/predicates.md
@@ -0,0 +1,55 @@
+;; Predicate definitions for Moxie
+;; Copyright (C) 2009 Free Software Foundation, Inc.
+;; Contributed by Anthony Green <green@moxielogic.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/>.
+
+;; -------------------------------------------------------------------------
+;; Predicates
+;; -------------------------------------------------------------------------
+
+;; Nonzero if OP can be source of a simple move operation.
+
+(define_predicate "moxie_general_movsrc_operand"
+ (match_code "mem,const_int,reg,subreg,symbol_ref,label_ref,const")
+{
+ /* Any (MEM LABEL_REF) is OK. That is a pc-relative load. */
+ if (MEM_P (op) && GET_CODE (XEXP (op, 0)) == LABEL_REF)
+ return 1;
+
+ if (MEM_P (op)
+ && GET_CODE (XEXP (op, 0)) == PLUS
+ && GET_CODE (XEXP (XEXP (op, 0), 0)) == REG
+ && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST)
+ return 1;
+
+ return general_operand (op, mode);
+})
+
+;; Nonzero if OP can be an operand to an add/inc/dec instruction.
+
+(define_predicate "moxie_add_operand"
+ (ior (match_code "reg")
+ (and (match_code "const_int")
+ (match_test "IN_RANGE (INTVAL (op), -255, 255)"))))
+
+;; Nonzero if OP can be an operand to an sub/dec instruction.
+
+(define_predicate "moxie_sub_operand"
+ (ior (match_code "reg")
+ (and (match_code "const_int")
+ (match_test "IN_RANGE (INTVAL (op), 0, 255)")))) \ No newline at end of file
diff --git a/gcc/config/moxie/sfp-machine.h b/gcc/config/moxie/sfp-machine.h
new file mode 100644
index 00000000000..57f515e9fc6
--- /dev/null
+++ b/gcc/config/moxie/sfp-machine.h
@@ -0,0 +1,52 @@
+#define _FP_W_TYPE_SIZE 32
+#define _FP_W_TYPE unsigned long
+#define _FP_WS_TYPE signed long
+#define _FP_I_TYPE long
+
+#define _FP_MUL_MEAT_S(R,X,Y) \
+ _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm)
+#define _FP_MUL_MEAT_D(R,X,Y) \
+ _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
+#define _FP_MUL_MEAT_Q(R,X,Y) \
+ _FP_MUL_MEAT_4_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
+
+#define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_loop(S,R,X,Y)
+#define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_2_udiv(D,R,X,Y)
+#define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_4_udiv(Q,R,X,Y)
+
+#define _FP_NANFRAC_S ((_FP_QNANBIT_S << 1) - 1)
+#define _FP_NANFRAC_D ((_FP_QNANBIT_D << 1) - 1), -1
+#define _FP_NANFRAC_Q ((_FP_QNANBIT_Q << 1) - 1), -1, -1, -1
+#define _FP_NANSIGN_S 0
+#define _FP_NANSIGN_D 0
+#define _FP_NANSIGN_Q 0
+
+#define _FP_KEEPNANFRACP 1
+
+/* Someone please check this. */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \
+ do { \
+ if ((_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs) \
+ && !(_FP_FRAC_HIGH_RAW_##fs(Y) & _FP_QNANBIT_##fs)) \
+ { \
+ R##_s = Y##_s; \
+ _FP_FRAC_COPY_##wc(R,Y); \
+ } \
+ else \
+ { \
+ R##_s = X##_s; \
+ _FP_FRAC_COPY_##wc(R,X); \
+ } \
+ R##_c = FP_CLS_NAN; \
+ } while (0)
+
+#define __LITTLE_ENDIAN 1234
+#define __BIG_ENDIAN 4321
+
+# define __BYTE_ORDER __BIG_ENDIAN
+
+/* Define ALIASNAME as a strong alias for NAME. */
+# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
+# define _strong_alias(name, aliasname) \
+ extern __typeof (name) aliasname __attribute__ ((alias (#name)));
+
diff --git a/gcc/config/moxie/t-moxie b/gcc/config/moxie/t-moxie
new file mode 100644
index 00000000000..5498ecbb354
--- /dev/null
+++ b/gcc/config/moxie/t-moxie
@@ -0,0 +1,20 @@
+# Target Makefile Fragment for moxie
+# Copyright (C) 2008 Free Software Foundation, Inc.
+# Contributed by Anthony Green.
+#
+# 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/>.
+
diff --git a/gcc/config/moxie/t-moxie-softfp b/gcc/config/moxie/t-moxie-softfp
new file mode 100644
index 00000000000..61c575132e9
--- /dev/null
+++ b/gcc/config/moxie/t-moxie-softfp
@@ -0,0 +1,9 @@
+softfp_float_modes := sf df
+softfp_int_modes := si di
+softfp_extensions := sfdf
+softfp_truncations := dfsf
+softfp_machine_header := moxie/sfp-machine.h
+softfp_exclude_libgcc2 := y
+
+# softfp seems to be missing a whole bunch of prototypes.
+TARGET_LIBGCC2_CFLAGS += -Wno-missing-prototypes
diff --git a/gcc/config/pa/constraints.md b/gcc/config/pa/constraints.md
index fdf3c988410..c1f3d5cd3f3 100644
--- a/gcc/config/pa/constraints.md
+++ b/gcc/config/pa/constraints.md
@@ -131,7 +131,7 @@
? SFmode : DFmode),
XEXP (op, 0))")))
-;; We could allow short displacements but GO_IF_LEGITIMATE_ADDRESS
+;; We could allow short displacements but TARGET_LEGITIMATE_ADDRESS_P
;; can't tell when a long displacement is valid.
(define_constraint "W"
"A register indirect memory operand."
diff --git a/gcc/config/pa/pa-hpux.h b/gcc/config/pa/pa-hpux.h
index bd12d4fc68e..b600b0e3d4c 100644
--- a/gcc/config/pa/pa-hpux.h
+++ b/gcc/config/pa/pa-hpux.h
@@ -95,12 +95,10 @@ along with GCC; see the file COPYING3. If not see
#undef LINK_SPEC
#if ((TARGET_DEFAULT | TARGET_CPU_DEFAULT) & MASK_PA_11)
#define LINK_SPEC \
- "%<fwhole-program\
- %{!mpa-risc-1-0:%{!march=1.0:%{static:-L/lib/pa1.1 -L/usr/lib/pa1.1 }}}%{mlinker-opt:-O} %{!shared:-u main} %{static:-a archive} %{g*:-a archive} %{shared:-b}"
+ "%{!mpa-risc-1-0:%{!march=1.0:%{static:-L/lib/pa1.1 -L/usr/lib/pa1.1 }}}%{mlinker-opt:-O} %{!shared:-u main} %{static:-a archive} %{g*:-a archive} %{shared:-b}"
#else
#define LINK_SPEC \
- "%<fwhole-program\
- %{mlinker-opt:-O} %{!shared:-u main} %{static:-a archive} %{g*:-a archive} %{shared:-b}"
+ "%{mlinker-opt:-O} %{!shared:-u main} %{static:-a archive} %{g*:-a archive} %{shared:-b}"
#endif
/* hpux8 and later have C++ compatible include files, so do not
diff --git a/gcc/config/pa/pa-hpux10.h b/gcc/config/pa/pa-hpux10.h
index c1294dfff0b..df36ea2e8a9 100644
--- a/gcc/config/pa/pa-hpux10.h
+++ b/gcc/config/pa/pa-hpux10.h
@@ -82,8 +82,7 @@ along with GCC; see the file COPYING3. If not see
#undef LINK_SPEC
#if ((TARGET_DEFAULT | TARGET_CPU_DEFAULT) & MASK_PA_11)
#define LINK_SPEC \
- "%<fwhole-program\
- %{!mpa-risc-1-0:%{!march=1.0:%{static:-L/lib/pa1.1 -L/usr/lib/pa1.1 }}}\
+ "%{!mpa-risc-1-0:%{!march=1.0:%{static:-L/lib/pa1.1 -L/usr/lib/pa1.1 }}}\
%{!shared:%{p:-L/lib/libp %{!static:\
%nWarning: consider linking with `-static' as system libraries with\n\
%n profiling support are only provided in archive format}}}\
@@ -94,8 +93,7 @@ along with GCC; see the file COPYING3. If not see
%{static:-a archive} %{shared:-b}"
#else
#define LINK_SPEC \
- "%<fwhole-program\
- %{!shared:%{p:-L/lib/libp %{!static:\
+ "%{!shared:%{p:-L/lib/libp %{!static:\
%nWarning: consider linking with `-static' as system libraries with\n\
%n profiling support are only provided in archive format}}}\
%{!shared:%{pg:-L/lib/libp %{!static:\
diff --git a/gcc/config/pa/pa-hpux11.h b/gcc/config/pa/pa-hpux11.h
index 06b709c2350..09b414cb00a 100644
--- a/gcc/config/pa/pa-hpux11.h
+++ b/gcc/config/pa/pa-hpux11.h
@@ -104,8 +104,7 @@ along with GCC; see the file COPYING3. If not see
want dereferencing of a NULL pointer to cause a SEGV. */
#undef LINK_SPEC
#define LINK_SPEC \
- "%<fwhole-program\
- %{!shared:%{p:-L/lib/libp -L/usr/lib/libp %{!static:\
+ "%{!shared:%{p:-L/lib/libp -L/usr/lib/libp %{!static:\
%nWarning: consider linking with `-static' as system libraries with\n\
%n profiling support are only provided in archive format}}}\
%{!shared:%{pg:-L/lib/libp -L/usr/lib/libp %{!static:\
diff --git a/gcc/config/pa/pa-protos.h b/gcc/config/pa/pa-protos.h
index 3cd1f8580bc..526081acd52 100644
--- a/gcc/config/pa/pa-protos.h
+++ b/gcc/config/pa/pa-protos.h
@@ -56,7 +56,6 @@ extern void output_arg_descriptor (rtx);
extern void output_global_address (FILE *, rtx, int);
extern void print_operand (FILE *, rtx, int);
extern rtx legitimize_pic_address (rtx, enum machine_mode, rtx);
-extern struct rtx_def *gen_cmp_fp (enum rtx_code, rtx, rtx);
extern void hppa_encode_label (rtx);
extern int arith11_operand (rtx, enum machine_mode);
extern int adddi3_operand (rtx, enum machine_mode);
@@ -96,7 +95,7 @@ extern int fmpyaddoperands (rtx *);
extern int fmpysuboperands (rtx *);
extern int call_operand_address (rtx, enum machine_mode);
extern int ior_operand (rtx, enum machine_mode);
-extern void emit_bcond_fp (enum rtx_code, rtx);
+extern void emit_bcond_fp (rtx[]);
extern int emit_move_sequence (rtx *, enum machine_mode, rtx);
extern int emit_hpdiv_const (rtx *, int);
extern int is_function_label_plus_const (rtx);
diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c
index 80f5fe90bc2..a55f2ec0147 100644
--- a/gcc/config/pa/pa.c
+++ b/gcc/config/pa/pa.c
@@ -165,11 +165,6 @@ static GTY(()) section *som_readonly_data_section;
static GTY(()) section *som_one_only_readonly_data_section;
static GTY(()) section *som_one_only_data_section;
-/* Save the operands last given to a compare for use when we
- generate a scc or bcc insn. */
-rtx hppa_compare_op0, hppa_compare_op1;
-enum cmp_type hppa_branch_type;
-
/* Which cpu we are scheduling for. */
enum processor_type pa_cpu = TARGET_SCHED_DEFAULT;
@@ -876,9 +871,6 @@ legitimize_tls_address (rtx addr)
OLDX is the address as it was before break_out_memory_refs was called.
In some cases it is useful to look at this to decide what needs to be done.
- MODE and WIN are passed so that this macro can use
- GO_IF_LEGITIMATE_ADDRESS.
-
It is always safe for this macro to do nothing. It exists to recognize
opportunities to optimize the output.
@@ -4383,6 +4375,19 @@ return_addr_rtx (int count, rtx frameaddr)
rtx saved_rp;
rtx ins;
+ /* Instruction stream at the normal return address for the export stub:
+
+ 0x4bc23fd1 | stub+8: ldw -18(sr0,sp),rp
+ 0x004010a1 | stub+12: ldsid (sr0,rp),r1
+ 0x00011820 | stub+16: mtsp r1,sr0
+ 0xe0400002 | stub+20: be,n 0(sr0,rp)
+
+ 0xe0400002 must be specified as -532676606 so that it won't be
+ rejected as an invalid immediate operand on 64-bit hosts. */
+
+ HOST_WIDE_INT insns[4] = {0x4bc23fd1, 0x004010a1, 0x00011820, -532676606};
+ int i;
+
if (count != 0)
return NULL_RTX;
@@ -4391,6 +4396,9 @@ return_addr_rtx (int count, rtx frameaddr)
if (TARGET_64BIT || TARGET_NO_SPACE_REGS)
return rp;
+ /* If there is no export stub then just use the value saved from
+ the return pointer register. */
+
saved_rp = gen_reg_rtx (Pmode);
emit_move_insn (saved_rp, rp);
@@ -4402,37 +4410,15 @@ return_addr_rtx (int count, rtx frameaddr)
label = gen_label_rtx ();
/* Check the instruction stream at the normal return address for the
- export stub:
-
- 0x4bc23fd1 | stub+8: ldw -18(sr0,sp),rp
- 0x004010a1 | stub+12: ldsid (sr0,rp),r1
- 0x00011820 | stub+16: mtsp r1,sr0
- 0xe0400002 | stub+20: be,n 0(sr0,rp)
-
- If it is an export stub, than our return address is really in
- -24[frameaddr]. */
-
- emit_cmp_insn (gen_rtx_MEM (SImode, ins), GEN_INT (0x4bc23fd1), NE,
- NULL_RTX, SImode, 1);
- emit_jump_insn (gen_bne (label));
-
- emit_cmp_insn (gen_rtx_MEM (SImode, plus_constant (ins, 4)),
- GEN_INT (0x004010a1), NE, NULL_RTX, SImode, 1);
- emit_jump_insn (gen_bne (label));
-
- emit_cmp_insn (gen_rtx_MEM (SImode, plus_constant (ins, 8)),
- GEN_INT (0x00011820), NE, NULL_RTX, SImode, 1);
- emit_jump_insn (gen_bne (label));
-
- /* 0xe0400002 must be specified as -532676606 so that it won't be
- rejected as an invalid immediate operand on 64-bit hosts. */
- emit_cmp_insn (gen_rtx_MEM (SImode, plus_constant (ins, 12)),
- GEN_INT (-532676606), NE, NULL_RTX, SImode, 1);
-
- /* If there is no export stub then just use the value saved from
- the return pointer register. */
+ export stub. If it is an export stub, than our return address is
+ really in -24[frameaddr]. */
- emit_jump_insn (gen_bne (label));
+ for (i = 0; i < 3; i++)
+ {
+ rtx op0 = gen_rtx_MEM (SImode, plus_constant (ins, i * 4));
+ rtx op1 = GEN_INT (insns[i]);
+ emit_cmp_and_jump_insns (op0, op1, NE, NULL, SImode, 0, label);
+ }
/* Here we know that our return address points to an export
stub. We don't want to return the address of the export stub,
@@ -4446,30 +4432,32 @@ return_addr_rtx (int count, rtx frameaddr)
-24))));
emit_label (label);
+
return saved_rp;
}
void
-emit_bcond_fp (enum rtx_code code, rtx operand0)
+emit_bcond_fp (rtx operands[])
{
+ enum rtx_code code = GET_CODE (operands[0]);
+ rtx operand0 = operands[1];
+ rtx operand1 = operands[2];
+ rtx label = operands[3];
+
+ emit_insn (gen_rtx_SET (VOIDmode, gen_rtx_REG (CCFPmode, 0),
+ gen_rtx_fmt_ee (code, CCFPmode, operand0, operand1)));
+
emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
gen_rtx_IF_THEN_ELSE (VOIDmode,
- gen_rtx_fmt_ee (code,
+ gen_rtx_fmt_ee (NE,
VOIDmode,
gen_rtx_REG (CCFPmode, 0),
const0_rtx),
- gen_rtx_LABEL_REF (VOIDmode, operand0),
+ gen_rtx_LABEL_REF (VOIDmode, label),
pc_rtx)));
}
-rtx
-gen_cmp_fp (enum rtx_code code, rtx operand0, rtx operand1)
-{
- return gen_rtx_SET (VOIDmode, gen_rtx_REG (CCFPmode, 0),
- gen_rtx_fmt_ee (code, CCFPmode, operand0, operand1));
-}
-
/* Adjust the cost of a scheduling dependency. Return the new cost of
a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
diff --git a/gcc/config/pa/pa.h b/gcc/config/pa/pa.h
index 303bdd341df..576916f5b7b 100644
--- a/gcc/config/pa/pa.h
+++ b/gcc/config/pa/pa.h
@@ -21,14 +21,6 @@ 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/>. */
-enum cmp_type /* comparison type */
-{
- CMP_SI, /* compare integers */
- CMP_SF, /* compare single precision floats */
- CMP_DF, /* compare double precision floats */
- CMP_MAX /* max comparison type */
-};
-
/* For long call handling. */
extern unsigned long total_code_bytes;
@@ -755,10 +747,6 @@ struct hppa_args {int words, nargs_prototype, incoming, indirect; };
? PARM_BOUNDARY : MAX_PARM_BOUNDARY)
-extern GTY(()) rtx hppa_compare_op0;
-extern GTY(()) rtx hppa_compare_op1;
-extern enum cmp_type hppa_branch_type;
-
/* On HPPA, we emit profiling code as rtl via PROFILE_HOOK rather than
as assembly via FUNCTION_PROFILER. Just output a local label.
We can't use the function label because the GAS SOM target can't
diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md
index b845182d592..1f5a69b9352 100644
--- a/gcc/config/pa/pa.md
+++ b/gcc/config/pa/pa.md
@@ -653,64 +653,6 @@
;; Compare instructions.
;; This controls RTL generation and register allocation.
-;; We generate RTL for comparisons and branches by having the cmpxx
-;; patterns store away the operands. Then, the scc and bcc patterns
-;; emit RTL for both the compare and the branch.
-;;
-
-(define_expand "cmpdi"
- [(set (reg:CC 0)
- (compare:CC (match_operand:DI 0 "reg_or_0_operand" "")
- (match_operand:DI 1 "register_operand" "")))]
- "TARGET_64BIT"
-
- "
-{
- hppa_compare_op0 = operands[0];
- hppa_compare_op1 = operands[1];
- hppa_branch_type = CMP_SI;
- DONE;
-}")
-
-(define_expand "cmpsi"
- [(set (reg:CC 0)
- (compare:CC (match_operand:SI 0 "reg_or_0_operand" "")
- (match_operand:SI 1 "arith5_operand" "")))]
- ""
- "
-{
- hppa_compare_op0 = operands[0];
- hppa_compare_op1 = operands[1];
- hppa_branch_type = CMP_SI;
- DONE;
-}")
-
-(define_expand "cmpsf"
- [(set (reg:CCFP 0)
- (compare:CCFP (match_operand:SF 0 "reg_or_0_operand" "")
- (match_operand:SF 1 "reg_or_0_operand" "")))]
- "! TARGET_SOFT_FLOAT"
- "
-{
- hppa_compare_op0 = operands[0];
- hppa_compare_op1 = operands[1];
- hppa_branch_type = CMP_SF;
- DONE;
-}")
-
-(define_expand "cmpdf"
- [(set (reg:CCFP 0)
- (compare:CCFP (match_operand:DF 0 "reg_or_0_operand" "")
- (match_operand:DF 1 "reg_or_0_operand" "")))]
- "! TARGET_SOFT_FLOAT"
- "
-{
- hppa_compare_op0 = operands[0];
- hppa_compare_op1 = operands[1];
- hppa_branch_type = CMP_DF;
- DONE;
-}")
-
(define_insn ""
[(set (reg:CCFP 0)
(match_operator:CCFP 2 "comparison_operator"
@@ -767,143 +709,13 @@
;; scc insns.
-(define_expand "seq"
- [(set (match_operand:SI 0 "register_operand" "")
- (eq:SI (match_dup 1)
- (match_dup 2)))]
- "!TARGET_64BIT"
- "
-{
- /* fp scc patterns rarely match, and are not a win on the PA. */
- if (hppa_branch_type != CMP_SI)
- FAIL;
- /* set up operands from compare. */
- operands[1] = hppa_compare_op0;
- operands[2] = hppa_compare_op1;
- /* fall through and generate default code */
-}")
-
-(define_expand "sne"
- [(set (match_operand:SI 0 "register_operand" "")
- (ne:SI (match_dup 1)
- (match_dup 2)))]
- "!TARGET_64BIT"
- "
-{
- /* fp scc patterns rarely match, and are not a win on the PA. */
- if (hppa_branch_type != CMP_SI)
- FAIL;
- operands[1] = hppa_compare_op0;
- operands[2] = hppa_compare_op1;
-}")
-
-(define_expand "slt"
- [(set (match_operand:SI 0 "register_operand" "")
- (lt:SI (match_dup 1)
- (match_dup 2)))]
- "!TARGET_64BIT"
- "
-{
- /* fp scc patterns rarely match, and are not a win on the PA. */
- if (hppa_branch_type != CMP_SI)
- FAIL;
- operands[1] = hppa_compare_op0;
- operands[2] = hppa_compare_op1;
-}")
-
-(define_expand "sgt"
- [(set (match_operand:SI 0 "register_operand" "")
- (gt:SI (match_dup 1)
- (match_dup 2)))]
- "!TARGET_64BIT"
- "
-{
- /* fp scc patterns rarely match, and are not a win on the PA. */
- if (hppa_branch_type != CMP_SI)
- FAIL;
- operands[1] = hppa_compare_op0;
- operands[2] = hppa_compare_op1;
-}")
-
-(define_expand "sle"
- [(set (match_operand:SI 0 "register_operand" "")
- (le:SI (match_dup 1)
- (match_dup 2)))]
- "!TARGET_64BIT"
- "
-{
- /* fp scc patterns rarely match, and are not a win on the PA. */
- if (hppa_branch_type != CMP_SI)
- FAIL;
- operands[1] = hppa_compare_op0;
- operands[2] = hppa_compare_op1;
-}")
-
-(define_expand "sge"
- [(set (match_operand:SI 0 "register_operand" "")
- (ge:SI (match_dup 1)
- (match_dup 2)))]
- "!TARGET_64BIT"
- "
-{
- /* fp scc patterns rarely match, and are not a win on the PA. */
- if (hppa_branch_type != CMP_SI)
- FAIL;
- operands[1] = hppa_compare_op0;
- operands[2] = hppa_compare_op1;
-}")
-
-(define_expand "sltu"
- [(set (match_operand:SI 0 "register_operand" "")
- (ltu:SI (match_dup 1)
- (match_dup 2)))]
+(define_expand "cstoresi4"
+ [(set (match_operand:SI 0 "register_operand")
+ (match_operator:SI 1 "ordered_comparison_operator"
+ [(match_operand:SI 2 "reg_or_0_operand" "")
+ (match_operand:SI 3 "arith5_operand" "")]))]
"!TARGET_64BIT"
- "
-{
- if (hppa_branch_type != CMP_SI)
- FAIL;
- operands[1] = hppa_compare_op0;
- operands[2] = hppa_compare_op1;
-}")
-
-(define_expand "sgtu"
- [(set (match_operand:SI 0 "register_operand" "")
- (gtu:SI (match_dup 1)
- (match_dup 2)))]
- "!TARGET_64BIT"
- "
-{
- if (hppa_branch_type != CMP_SI)
- FAIL;
- operands[1] = hppa_compare_op0;
- operands[2] = hppa_compare_op1;
-}")
-
-(define_expand "sleu"
- [(set (match_operand:SI 0 "register_operand" "")
- (leu:SI (match_dup 1)
- (match_dup 2)))]
- "!TARGET_64BIT"
- "
-{
- if (hppa_branch_type != CMP_SI)
- FAIL;
- operands[1] = hppa_compare_op0;
- operands[2] = hppa_compare_op1;
-}")
-
-(define_expand "sgeu"
- [(set (match_operand:SI 0 "register_operand" "")
- (geu:SI (match_dup 1)
- (match_dup 2)))]
- "!TARGET_64BIT"
- "
-{
- if (hppa_branch_type != CMP_SI)
- FAIL;
- operands[1] = hppa_compare_op0;
- operands[2] = hppa_compare_op1;
-}")
+ "")
;; Instruction canonicalization puts immediate operands second, which
;; is the reverse of what we want.
@@ -1346,28 +1158,15 @@
(define_expand "movsicc"
[(set (match_operand:SI 0 "register_operand" "")
(if_then_else:SI
- (match_operator 1 "comparison_operator"
- [(match_dup 4)
- (match_dup 5)])
+ (match_operand 1 "comparison_operator" "")
(match_operand:SI 2 "reg_or_cint_move_operand" "")
(match_operand:SI 3 "reg_or_cint_move_operand" "")))]
""
"
{
- enum rtx_code code = GET_CODE (operands[1]);
-
- if (hppa_branch_type != CMP_SI)
+ if (GET_MODE (XEXP (operands[1], 0)) != SImode
+ || GET_MODE (XEXP (operands[1], 0)) != GET_MODE (XEXP (operands[1], 1)))
FAIL;
-
- if (GET_MODE (hppa_compare_op0) != GET_MODE (hppa_compare_op1)
- || GET_MODE (hppa_compare_op0) != GET_MODE (operands[0]))
- FAIL;
-
- /* operands[1] is currently the result of compare_from_rtx. We want to
- emit a compare of the original operands. */
- operands[1] = gen_rtx_fmt_ee (code, SImode, hppa_compare_op0, hppa_compare_op1);
- operands[4] = hppa_compare_op0;
- operands[5] = hppa_compare_op1;
}")
;; We used to accept any register for op1.
@@ -1419,28 +1218,15 @@
(define_expand "movdicc"
[(set (match_operand:DI 0 "register_operand" "")
(if_then_else:DI
- (match_operator 1 "comparison_operator"
- [(match_dup 4)
- (match_dup 5)])
+ (match_operand 1 "comparison_operator" "")
(match_operand:DI 2 "reg_or_cint_move_operand" "")
(match_operand:DI 3 "reg_or_cint_move_operand" "")))]
"TARGET_64BIT"
"
{
- enum rtx_code code = GET_CODE (operands[1]);
-
- if (hppa_branch_type != CMP_SI)
+ if (GET_MODE (XEXP (operands[1], 0)) != DImode
+ || GET_MODE (XEXP (operands[1], 0)) != GET_MODE (XEXP (operands[1], 1)))
FAIL;
-
- if (GET_MODE (hppa_compare_op0) != GET_MODE (hppa_compare_op1)
- || GET_MODE (hppa_compare_op0) != GET_MODE (operands[0]))
- FAIL;
-
- /* operands[1] is currently the result of compare_from_rtx. We want to
- emit a compare of the original operands. */
- operands[1] = gen_rtx_fmt_ee (code, DImode, hppa_compare_op0, hppa_compare_op1);
- operands[4] = hppa_compare_op0;
- operands[5] = hppa_compare_op1;
}")
; We need the first constraint alternative in order to avoid
@@ -1486,289 +1272,52 @@
;; Conditional Branches
-(define_expand "beq"
- [(set (pc)
- (if_then_else (eq (match_dup 1) (match_dup 2))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (hppa_branch_type != CMP_SI)
- {
- emit_insn (gen_cmp_fp (EQ, hppa_compare_op0, hppa_compare_op1));
- emit_bcond_fp (NE, operands[0]);
- DONE;
- }
- /* set up operands from compare. */
- operands[1] = hppa_compare_op0;
- operands[2] = hppa_compare_op1;
- /* fall through and generate default code */
-}")
-
-(define_expand "bne"
- [(set (pc)
- (if_then_else (ne (match_dup 1) (match_dup 2))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (hppa_branch_type != CMP_SI)
- {
- emit_insn (gen_cmp_fp (NE, hppa_compare_op0, hppa_compare_op1));
- emit_bcond_fp (NE, operands[0]);
- DONE;
- }
- operands[1] = hppa_compare_op0;
- operands[2] = hppa_compare_op1;
-}")
-
-(define_expand "bgt"
+(define_expand "cbranchdi4"
[(set (pc)
- (if_then_else (gt (match_dup 1) (match_dup 2))
- (label_ref (match_operand 0 "" ""))
+ (if_then_else (match_operator 0 "ordered_comparison_operator"
+ [(match_operand:DI 1 "reg_or_0_operand" "")
+ (match_operand:DI 2 "register_operand" "")])
+ (label_ref (match_operand 3 "" ""))
(pc)))]
- ""
- "
-{
- if (hppa_branch_type != CMP_SI)
- {
- emit_insn (gen_cmp_fp (GT, hppa_compare_op0, hppa_compare_op1));
- emit_bcond_fp (NE, operands[0]);
- DONE;
- }
- operands[1] = hppa_compare_op0;
- operands[2] = hppa_compare_op1;
-}")
-
-(define_expand "blt"
- [(set (pc)
- (if_then_else (lt (match_dup 1) (match_dup 2))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (hppa_branch_type != CMP_SI)
- {
- emit_insn (gen_cmp_fp (LT, hppa_compare_op0, hppa_compare_op1));
- emit_bcond_fp (NE, operands[0]);
- DONE;
- }
- operands[1] = hppa_compare_op0;
- operands[2] = hppa_compare_op1;
-}")
-
-(define_expand "bge"
- [(set (pc)
- (if_then_else (ge (match_dup 1) (match_dup 2))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (hppa_branch_type != CMP_SI)
- {
- emit_insn (gen_cmp_fp (GE, hppa_compare_op0, hppa_compare_op1));
- emit_bcond_fp (NE, operands[0]);
- DONE;
- }
- operands[1] = hppa_compare_op0;
- operands[2] = hppa_compare_op1;
-}")
-
-(define_expand "ble"
- [(set (pc)
- (if_then_else (le (match_dup 1) (match_dup 2))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (hppa_branch_type != CMP_SI)
- {
- emit_insn (gen_cmp_fp (LE, hppa_compare_op0, hppa_compare_op1));
- emit_bcond_fp (NE, operands[0]);
- DONE;
- }
- operands[1] = hppa_compare_op0;
- operands[2] = hppa_compare_op1;
-}")
-
-(define_expand "bgtu"
- [(set (pc)
- (if_then_else (gtu (match_dup 1) (match_dup 2))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (hppa_branch_type != CMP_SI)
- FAIL;
- operands[1] = hppa_compare_op0;
- operands[2] = hppa_compare_op1;
-}")
-
-(define_expand "bltu"
- [(set (pc)
- (if_then_else (ltu (match_dup 1) (match_dup 2))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (hppa_branch_type != CMP_SI)
- FAIL;
- operands[1] = hppa_compare_op0;
- operands[2] = hppa_compare_op1;
-}")
-
-(define_expand "bgeu"
- [(set (pc)
- (if_then_else (geu (match_dup 1) (match_dup 2))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (hppa_branch_type != CMP_SI)
- FAIL;
- operands[1] = hppa_compare_op0;
- operands[2] = hppa_compare_op1;
-}")
-
-(define_expand "bleu"
- [(set (pc)
- (if_then_else (leu (match_dup 1) (match_dup 2))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (hppa_branch_type != CMP_SI)
- FAIL;
- operands[1] = hppa_compare_op0;
- operands[2] = hppa_compare_op1;
-}")
-
-(define_expand "bltgt"
- [(set (pc)
- (if_then_else (ltgt (match_dup 1) (match_dup 2))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (hppa_branch_type == CMP_SI)
- FAIL;
- emit_insn (gen_cmp_fp (LTGT, hppa_compare_op0, hppa_compare_op1));
- emit_bcond_fp (NE, operands[0]);
- DONE;
-}")
-
-(define_expand "bunle"
- [(set (pc)
- (if_then_else (unle (match_dup 1) (match_dup 2))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (hppa_branch_type == CMP_SI)
- FAIL;
- emit_insn (gen_cmp_fp (UNLE, hppa_compare_op0, hppa_compare_op1));
- emit_bcond_fp (NE, operands[0]);
- DONE;
-}")
-
-(define_expand "bunlt"
- [(set (pc)
- (if_then_else (unlt (match_dup 1) (match_dup 2))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (hppa_branch_type == CMP_SI)
- FAIL;
- emit_insn (gen_cmp_fp (UNLT, hppa_compare_op0, hppa_compare_op1));
- emit_bcond_fp (NE, operands[0]);
- DONE;
-}")
-
-(define_expand "bunge"
- [(set (pc)
- (if_then_else (unge (match_dup 1) (match_dup 2))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (hppa_branch_type == CMP_SI)
- FAIL;
- emit_insn (gen_cmp_fp (UNGE, hppa_compare_op0, hppa_compare_op1));
- emit_bcond_fp (NE, operands[0]);
- DONE;
-}")
+ "TARGET_64BIT"
+ "")
-(define_expand "bungt"
+(define_expand "cbranchsi4"
[(set (pc)
- (if_then_else (ungt (match_dup 1) (match_dup 2))
- (label_ref (match_operand 0 "" ""))
+ (if_then_else (match_operator 0 "ordered_comparison_operator"
+ [(match_operand:SI 1 "reg_or_0_operand" "")
+ (match_operand:SI 2 "arith5_operand" "")])
+ (label_ref (match_operand 3 "" ""))
(pc)))]
""
- "
-{
- if (hppa_branch_type == CMP_SI)
- FAIL;
- emit_insn (gen_cmp_fp (UNGT, hppa_compare_op0, hppa_compare_op1));
- emit_bcond_fp (NE, operands[0]);
- DONE;
-}")
+ "")
-(define_expand "buneq"
+(define_expand "cbranchsf4"
[(set (pc)
- (if_then_else (uneq (match_dup 1) (match_dup 2))
- (label_ref (match_operand 0 "" ""))
+ (if_then_else (match_operator 0 "comparison_operator"
+ [(match_operand:SF 1 "reg_or_0_operand" "")
+ (match_operand:SF 2 "reg_or_0_operand" "")])
+ (label_ref (match_operand 3 "" ""))
(pc)))]
""
"
{
- if (hppa_branch_type == CMP_SI)
- FAIL;
- emit_insn (gen_cmp_fp (UNEQ, hppa_compare_op0, hppa_compare_op1));
- emit_bcond_fp (NE, operands[0]);
+ emit_bcond_fp (operands);
DONE;
}")
-(define_expand "bunordered"
- [(set (pc)
- (if_then_else (unordered (match_dup 1) (match_dup 2))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (hppa_branch_type == CMP_SI)
- FAIL;
- emit_insn (gen_cmp_fp (UNORDERED, hppa_compare_op0, hppa_compare_op1));
- emit_bcond_fp (NE, operands[0]);
- DONE;
-}")
-(define_expand "bordered"
+(define_expand "cbranchdf4"
[(set (pc)
- (if_then_else (ordered (match_dup 1) (match_dup 2))
- (label_ref (match_operand 0 "" ""))
+ (if_then_else (match_operator 0 "comparison_operator"
+ [(match_operand:DF 1 "reg_or_0_operand" "")
+ (match_operand:DF 2 "reg_or_0_operand" "")])
+ (label_ref (match_operand 3 "" ""))
(pc)))]
""
"
{
- if (hppa_branch_type == CMP_SI)
- FAIL;
- emit_insn (gen_cmp_fp (ORDERED, hppa_compare_op0, hppa_compare_op1));
- emit_bcond_fp (NE, operands[0]);
+ emit_bcond_fp (operands);
DONE;
}")
@@ -7527,8 +7076,10 @@
then be worthwhile to split the casesi patterns to improve scheduling.
However, it's not clear that all this extra complexity is worth
the effort. */
- emit_insn (gen_cmpsi (operands[0], operands[2]));
- emit_jump_insn (gen_bgtu (operands[4]));
+ {
+ rtx test = gen_rtx_GTU (VOIDmode, operands[0], operands[2]);
+ emit_jump_insn (gen_cbranchsi4 (test, operands[0], operands[2], operands[4]));
+ }
if (TARGET_BIG_SWITCH)
{
diff --git a/gcc/config/pdp11/pdp11-protos.h b/gcc/config/pdp11/pdp11-protos.h
index f493fbc8ab1..2c4bd22fde6 100644
--- a/gcc/config/pdp11/pdp11-protos.h
+++ b/gcc/config/pdp11/pdp11-protos.h
@@ -26,16 +26,15 @@ extern int expand_shift_operand (rtx, enum machine_mode);
extern int immediate15_operand (rtx, enum machine_mode);
extern int simple_memory_operand (rtx, enum machine_mode);
-extern int legitimate_address_p (enum machine_mode, rtx);
extern int legitimate_const_double_p (rtx);
extern void notice_update_cc_on_set (rtx, rtx);
extern void output_addr_const_pdp11 (FILE *, rtx);
extern const char *output_move_double (rtx *);
extern const char *output_move_quad (rtx *);
extern const char *output_block_move (rtx *);
+extern const char *output_jump (enum rtx_code, int, int);
extern void print_operand_address (FILE *, rtx);
extern int register_move_cost (enum reg_class, enum reg_class);
#endif /* RTX_CODE */
extern void output_ascii (FILE *, const char *, int);
-extern const char *output_jump (const char *, const char *, int);
diff --git a/gcc/config/pdp11/pdp11.c b/gcc/config/pdp11/pdp11.c
index 6e8941d75e9..b46760897a5 100644
--- a/gcc/config/pdp11/pdp11.c
+++ b/gcc/config/pdp11/pdp11.c
@@ -1170,11 +1170,27 @@ pdp11_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int *total,
}
const char *
-output_jump (const char *pos, const char *neg, int length)
+output_jump (enum rtx_code code, int inv, int length)
{
static int x = 0;
static char buf[1000];
+ const char *pos, *neg;
+
+ switch (code)
+ {
+ case EQ: pos = "beq", neg = "bne"; break;
+ case NE: pos = "bne", neg = "beq"; break;
+ case GT: pos = "bgt", neg = "ble"; break;
+ case GTU: pos = "bhi", neg = "blos"; break;
+ case LT: pos = "blt", neg = "bge"; break;
+ case LTU: pos = "blo", neg = "bhis"; break;
+ case GE: pos = "bge", neg = "blt"; break;
+ case GEU: pos = "bhis", neg = "blo"; break;
+ case LE: pos = "ble", neg = "bgt"; break;
+ case LEU: pos = "blos", neg = "bhi"; break;
+ default: gcc_unreachable ();
+ }
#if 0
/* currently we don't need this, because the tstdf and cmpdf
@@ -1190,14 +1206,13 @@ output_jump (const char *pos, const char *neg, int length)
{
case 1:
- strcpy(buf, pos);
- strcat(buf, " %l0");
+ sprintf(buf, "%s %%l1", inv ? neg : pos);
return buf;
case 3:
- sprintf(buf, "%s JMP_%d\n\tjmp %%l0\nJMP_%d:", neg, x, x);
+ sprintf(buf, "%s JMP_%d\n\tjmp %%l1\nJMP_%d:", inv ? pos : neg, x, x);
x++;
@@ -1591,20 +1606,6 @@ output_block_move(rtx *operands)
return "";
}
-int
-legitimate_address_p (enum machine_mode mode, rtx address)
-{
-/* #define REG_OK_STRICT */
- GO_IF_LEGITIMATE_ADDRESS(mode, address, win);
-
- return 0;
-
- win:
- return 1;
-
-/* #undef REG_OK_STRICT */
-}
-
/* This function checks whether a real value can be encoded as
a literal, i.e., addressing mode 27. In that mode, real values
are one word values, so the remaining 48 bits have to be zero. */
diff --git a/gcc/config/pdp11/pdp11.h b/gcc/config/pdp11/pdp11.h
index 9dbb41eb7c1..ac678f5cb5b 100644
--- a/gcc/config/pdp11/pdp11.h
+++ b/gcc/config/pdp11/pdp11.h
@@ -371,7 +371,7 @@ enum reg_class { NO_REGS, MUL_REGS, GENERAL_REGS, LOAD_FPU_REGS, NO_LOAD_FPU_REG
#define EXTRA_CONSTRAINT(OP,CODE) \
((GET_CODE (OP) != MEM) ? 0 \
- : !legitimate_address_p (GET_MODE (OP), XEXP (OP, 0)) ? 0 \
+ : !memory_address_p (GET_MODE (OP), XEXP (OP, 0)) ? 0 \
: ((CODE) == 'Q') ? !simple_memory_operand (OP, GET_MODE (OP)) \
: ((CODE) == 'R') ? simple_memory_operand (OP, GET_MODE (OP)) \
: 0)
@@ -1031,6 +1031,9 @@ JMP FUNCTION 0x0058 0x0000 <- FUNCTION
#define OPTIMIZATION_OPTIONS(LEVEL,SIZE) \
{ \
+ flag_finite_math_only = 0; \
+ flag_trapping_math = 0; \
+ flag_signaling_nans = 0; \
if (LEVEL >= 3) \
{ \
flag_omit_frame_pointer = 1; \
diff --git a/gcc/config/pdp11/pdp11.md b/gcc/config/pdp11/pdp11.md
index d5d4396b1c6..64d57e056b3 100644
--- a/gcc/config/pdp11/pdp11.md
+++ b/gcc/config/pdp11/pdp11.md
@@ -19,6 +19,11 @@
;; along with GCC; see the file COPYING3. If not see
;; <http://www.gnu.org/licenses/>.
+;; Match CONST_DOUBLE zero for tstd/tstf.
+(define_predicate "register_or_const0_operand"
+ (ior (match_operand 0 "register_operand")
+ (match_test "op == CONST0_RTX (GET_MODE (op))")))
+
;; HI is 16 bit
;; QI is 8 bit
@@ -81,141 +86,50 @@
;(define_function_unit "fpu" 1 1 (eq_attr "type" "fp") 0 0)
;; compare
-(define_insn "cmpdf"
+(define_insn "*cmpdf"
[(set (cc0)
- (compare (match_operand:DF 0 "general_operand" "fR,Q,F")
- (match_operand:DF 1 "register_operand" "a,a,a")))]
+ (compare (match_operand:DF 0 "general_operand" "fR,fR,Q,Q,F")
+ (match_operand:DF 1 "register_or_const0_operand" "G,a,G,a,a")))]
"TARGET_FPU"
"*
{
cc_status.flags = CC_IN_FPU;
- return \"{cmpd|cmpf} %0, %1\;cfcc\";
-}"
- [(set_attr "length" "2,3,6")])
-
-;; a bit of brain damage, maybe inline later -
-;; problem is - gcc seems to NEED SImode because
-;; of the cmp weirdness - maybe change gcc to handle this?
-
-(define_expand "cmpsi"
- [(set (reg:SI 0)
- (match_operand:SI 0 "general_operand" "g"))
- (set (reg:SI 2)
- (match_operand:SI 1 "general_operand" "g"))
- (parallel [(set (cc0)
- (compare (reg:SI 0)
- (reg:SI 2)))
- (clobber (reg:SI 0))])]
- "0" ;; disable for test
- "")
-
-;; check for next insn for branch code - does this still
-;; work in gcc 2.* ?
-
-(define_insn ""
- [(set (cc0)
- (compare (reg:SI 0)
- (reg:SI 2)))
- (clobber (reg:SI 0))]
- ""
- "*
-{
- rtx br_insn = NEXT_INSN (insn);
- RTX_CODE br_code;
-
- gcc_assert (GET_CODE (br_insn) == JUMP_INSN);
- br_code = GET_CODE (XEXP (XEXP (PATTERN (br_insn), 1), 0));
-
- switch(br_code)
- {
- case GEU:
- case LTU:
- case GTU:
- case LEU:
-
- return \"jsr pc, ___ucmpsi\;cmp $1,r0\";
-
- case GE:
- case LT:
- case GT:
- case LE:
- case EQ:
- case NE:
-
- return \"jsr pc, ___cmpsi\;tst r0\";
-
- default:
-
- gcc_unreachable ();
- }
+ if (which_alternative == 0 || which_alternative == 2)
+ return \"{tstd|tstf} %0, %1\;cfcc\";
+ else
+ return \"{cmpd|cmpf} %0, %1\;cfcc\";
}"
- [(set_attr "length" "4")])
+ [(set_attr "length" "2,2,3,3,6")])
-
-(define_insn "cmphi"
+(define_insn "*cmphi"
[(set (cc0)
- (compare (match_operand:HI 0 "general_operand" "rR,rR,Qi,Qi")
- (match_operand:HI 1 "general_operand" "rR,Qi,rR,Qi")))]
+ (compare (match_operand:HI 0 "general_operand" "rR,rR,rR,Q,Qi,Qi")
+ (match_operand:HI 1 "general_operand" "N,rR,Qi,N,rR,Qi")))]
""
- "cmp %0,%1"
- [(set_attr "length" "1,2,2,3")])
-
-(define_insn "cmpqi"
+ "@
+ tst %0
+ cmp %0,%1
+ cmp %0,%1
+ tst %0
+ cmp %0,%1
+ cmp %0,%1"
+ [(set_attr "length" "1,1,2,2,2,3")])
+
+(define_insn "*cmpqi"
[(set (cc0)
- (compare (match_operand:QI 0 "general_operand" "rR,rR,Qi,Qi")
- (match_operand:QI 1 "general_operand" "rR,Qi,rR,Qi")))]
+ (compare (match_operand:QI 0 "general_operand" "rR,rR,rR,Q,Qi,Qi")
+ (match_operand:QI 1 "general_operand" "N,rR,Qi,N,rR,Qi")))]
""
- "cmpb %0,%1"
- [(set_attr "length" "1,2,2,3")])
+ "@
+ tstb %0
+ cmpb %0,%1
+ cmpb %0,%1
+ tstb %0
+ cmpb %0,%1
+ cmpb %0,%1"
+ [(set_attr "length" "1,1,2,2,2,3")])
-;; We have to have this because cse can optimize the previous pattern
-;; into this one.
-
-(define_insn "tstdf"
- [(set (cc0)
- (match_operand:DF 0 "general_operand" "fR,Q"))]
- "TARGET_FPU"
- "*
-{
- cc_status.flags = CC_IN_FPU;
- return \"{tstd|tstf} %0\;cfcc\";
-}"
- [(set_attr "length" "2,3")])
-
-
-(define_expand "tstsi"
- [(set (reg:SI 0)
- (match_operand:SI 0 "general_operand" "g"))
- (parallel [(set (cc0)
- (reg:SI 0))
- (clobber (reg:SI 0))])]
- "0" ;; disable for test
- "")
-
-(define_insn ""
- [(set (cc0)
- (reg:SI 0))
- (clobber (reg:SI 0))]
- ""
- "jsr pc, ___tstsi\;tst r0"
- [(set_attr "length" "3")])
-
-
-(define_insn "tsthi"
- [(set (cc0)
- (match_operand:HI 0 "general_operand" "rR,Q"))]
- ""
- "tst %0"
- [(set_attr "length" "1,2")])
-
-(define_insn "tstqi"
- [(set (cc0)
- (match_operand:QI 0 "general_operand" "rR,Q"))]
- ""
- "tstb %0"
- [(set_attr "length" "1,2")])
-
;; sob instruction - we need an assembler which can make this instruction
;; valid under _all_ circumstances!
@@ -264,353 +178,81 @@
;; These control RTL generation for conditional jump insns
;; and match them for register allocation.
-;; problem with too short jump distance! we need an assembler which can
-;; make this valid for all jump distances!
-;; e.g. gas!
-
-;; these must be changed to check for CC_IN_FCCR if float is to be
-;; enabled
-
-(define_insn "beq"
- [(set (pc)
- (if_then_else (eq (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "* return output_jump(\"beq\", \"bne\", get_attr_length(insn));"
- [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
- (pc))
- (const_int -128))
- (ge (minus (match_dup 0)
- (pc))
- (const_int 128)))
- (const_int 3)
- (const_int 1)))])
-
-
-(define_insn "bne"
- [(set (pc)
- (if_then_else (ne (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "* return output_jump(\"bne\", \"beq\", get_attr_length(insn));"
- [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
- (pc))
- (const_int -128))
- (ge (minus (match_dup 0)
- (pc))
- (const_int 128)))
- (const_int 3)
- (const_int 1)))])
-
-(define_insn "bgt"
- [(set (pc)
- (if_then_else (gt (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "* return output_jump(\"bgt\", \"ble\", get_attr_length(insn));"
- [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
- (pc))
- (const_int -128))
- (ge (minus (match_dup 0)
- (pc))
- (const_int 128)))
- (const_int 3)
- (const_int 1)))])
-
-(define_insn "bgtu"
- [(set (pc)
- (if_then_else (gtu (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
+(define_expand "cbranchdf4"
+ [(set (cc0)
+ (compare (match_operand:DF 1 "general_operand")
+ (match_operand:DF 2 "general_operand")))
+ (set (pc)
+ (if_then_else (match_operator 0 "ordered_comparison_operator"
+ [(cc0) (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
(pc)))]
""
- "* return output_jump(\"bhi\", \"blos\", get_attr_length(insn));"
- [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
- (pc))
- (const_int -128))
- (ge (minus (match_dup 0)
- (pc))
- (const_int 128)))
- (const_int 3)
- (const_int 1)))])
+ "")
-(define_insn "blt"
- [(set (pc)
- (if_then_else (lt (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
+(define_expand "cbranchhi4"
+ [(set (cc0)
+ (compare (match_operand:HI 1 "general_operand")
+ (match_operand:HI 2 "general_operand")))
+ (set (pc)
+ (if_then_else (match_operator 0 "ordered_comparison_operator"
+ [(cc0) (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
(pc)))]
""
- "* return output_jump(\"blt\", \"bge\", get_attr_length(insn));"
- [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
- (pc))
- (const_int -128))
- (ge (minus (match_dup 0)
- (pc))
- (const_int 128)))
- (const_int 3)
- (const_int 1)))])
-
+ "")
-(define_insn "bltu"
- [(set (pc)
- (if_then_else (ltu (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
+(define_expand "cbranchqi4"
+ [(set (cc0)
+ (compare (match_operand:QI 1 "general_operand")
+ (match_operand:QI 2 "general_operand")))
+ (set (pc)
+ (if_then_else (match_operator 0 "ordered_comparison_operator"
+ [(cc0) (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
(pc)))]
""
- "* return output_jump(\"blo\", \"bhis\", get_attr_length(insn));"
- [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
- (pc))
- (const_int -128))
- (ge (minus (match_dup 0)
- (pc))
- (const_int 128)))
- (const_int 3)
- (const_int 1)))])
+ "")
-(define_insn "bge"
- [(set (pc)
- (if_then_else (ge (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "* return output_jump(\"bge\", \"blt\", get_attr_length(insn));"
- [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
- (pc))
- (const_int -128))
- (ge (minus (match_dup 0)
- (pc))
- (const_int 128)))
- (const_int 3)
- (const_int 1)))])
+;; problem with too short jump distance! we need an assembler which can
+;; make this valid for all jump distances!
+;; e.g. gas!
-(define_insn "bgeu"
- [(set (pc)
- (if_then_else (geu (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "* return output_jump(\"bhis\", \"blo\", get_attr_length(insn));"
- [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
- (pc))
- (const_int -128))
- (ge (minus (match_dup 0)
- (pc))
- (const_int 128)))
- (const_int 3)
- (const_int 1)))])
+;; these must be changed to check for CC_IN_FCCR if float is to be
+;; enabled
-(define_insn "ble"
+(define_insn "*branch"
[(set (pc)
- (if_then_else (le (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
+ (if_then_else (match_operator 0 "ordered_comparison_operator"
+ [(cc0) (const_int 0)])
+ (label_ref (match_operand 1 "" ""))
(pc)))]
""
- "* return output_jump(\"ble\", \"bgt\", get_attr_length(insn));"
- [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
+ "* return output_jump(GET_CODE (operands[0]), 0, get_attr_length(insn));"
+ [(set (attr "length") (if_then_else (ior (le (minus (match_dup 1)
(pc))
(const_int -128))
- (ge (minus (match_dup 0)
+ (ge (minus (match_dup 1)
(pc))
(const_int 128)))
(const_int 3)
(const_int 1)))])
-(define_insn "bleu"
- [(set (pc)
- (if_then_else (leu (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "* return output_jump(\"blos\", \"bhi\", get_attr_length(insn));"
- [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
- (pc))
- (const_int -128))
- (ge (minus (match_dup 0)
- (pc))
- (const_int 128)))
- (const_int 3)
- (const_int 1)))])
-
;; These match inverted jump insns for register allocation.
-(define_insn ""
+(define_insn "*branch_inverted"
[(set (pc)
- (if_then_else (eq (cc0)
- (const_int 0))
+ (if_then_else (match_operator 0 "ordered_comparison_operator"
+ [(cc0) (const_int 0)])
(pc)
- (label_ref (match_operand 0 "" ""))))]
+ (label_ref (match_operand 1 "" ""))))]
""
- "* return output_jump(\"bne\", \"beq\", get_attr_length(insn));"
- [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
+ "* return output_jump(GET_CODE (operands[0]), 1, get_attr_length(insn));"
+ [(set (attr "length") (if_then_else (ior (le (minus (match_dup 1)
(pc))
(const_int -128))
- (ge (minus (match_dup 0)
- (pc))
- (const_int 128)))
- (const_int 3)
- (const_int 1)))])
-
-(define_insn ""
- [(set (pc)
- (if_then_else (ne (cc0)
- (const_int 0))
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- ""
- "* return output_jump(\"beq\", \"bne\", get_attr_length(insn));"
- [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
- (pc))
- (const_int -128))
- (ge (minus (match_dup 0)
- (pc))
- (const_int 128)))
- (const_int 3)
- (const_int 1)))])
-
-(define_insn ""
- [(set (pc)
- (if_then_else (gt (cc0)
- (const_int 0))
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- ""
- "* return output_jump(\"ble\", \"bgt\", get_attr_length(insn));"
- [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
- (pc))
- (const_int -128))
- (ge (minus (match_dup 0)
- (pc))
- (const_int 128)))
- (const_int 3)
- (const_int 1)))])
-
-(define_insn ""
- [(set (pc)
- (if_then_else (gtu (cc0)
- (const_int 0))
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- ""
- "* return output_jump(\"blos\", \"bhi\", get_attr_length(insn));"
- [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
- (pc))
- (const_int -128))
- (ge (minus (match_dup 0)
- (pc))
- (const_int 128)))
- (const_int 3)
- (const_int 1)))])
-
-(define_insn ""
- [(set (pc)
- (if_then_else (lt (cc0)
- (const_int 0))
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- ""
- "* return output_jump(\"bge\", \"blt\", get_attr_length(insn));"
- [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
- (pc))
- (const_int -128))
- (ge (minus (match_dup 0)
- (pc))
- (const_int 128)))
- (const_int 3)
- (const_int 1)))])
-
-(define_insn ""
- [(set (pc)
- (if_then_else (ltu (cc0)
- (const_int 0))
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- ""
- "* return output_jump(\"bhis\", \"blo\", get_attr_length(insn));"
- [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
- (pc))
- (const_int -128))
- (ge (minus (match_dup 0)
- (pc))
- (const_int 128)))
- (const_int 3)
- (const_int 1)))])
-
-(define_insn ""
- [(set (pc)
- (if_then_else (ge (cc0)
- (const_int 0))
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- ""
- "* return output_jump(\"blt\", \"bge\", get_attr_length(insn));"
- [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
- (pc))
- (const_int -128))
- (ge (minus (match_dup 0)
- (pc))
- (const_int 128)))
- (const_int 3)
- (const_int 1)))])
-
-(define_insn ""
- [(set (pc)
- (if_then_else (geu (cc0)
- (const_int 0))
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- ""
- "* return output_jump(\"blo\", \"bhis\", get_attr_length(insn));"
- [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
- (pc))
- (const_int -128))
- (ge (minus (match_dup 0)
- (pc))
- (const_int 128)))
- (const_int 3)
- (const_int 1)))])
-
-(define_insn ""
- [(set (pc)
- (if_then_else (le (cc0)
- (const_int 0))
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- ""
- "* return output_jump(\"bgt\", \"ble\", get_attr_length(insn));"
- [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
- (pc))
- (const_int -128))
- (ge (minus (match_dup 0)
- (pc))
- (const_int 128)))
- (const_int 3)
- (const_int 1)))])
-
-(define_insn ""
- [(set (pc)
- (if_then_else (leu (cc0)
- (const_int 0))
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- ""
- "* return output_jump(\"bhi\", \"blos\", get_attr_length(insn));"
- [(set (attr "length") (if_then_else (ior (le (minus (match_dup 0)
- (pc))
- (const_int -128))
- (ge (minus (match_dup 0)
+ (ge (minus (match_dup 1)
(pc))
(const_int 128)))
(const_int 3)
diff --git a/gcc/config/picochip/picochip-protos.h b/gcc/config/picochip/picochip-protos.h
index 9b2c824ee26..7a2a07b98fa 100644
--- a/gcc/config/picochip/picochip-protos.h
+++ b/gcc/config/picochip/picochip-protos.h
@@ -26,7 +26,6 @@ extern void picochip_function_prologue (FILE *, HOST_WIDE_INT);
extern void picochip_function_epilogue (FILE *, HOST_WIDE_INT);
extern enum reg_class picochip_reg_class_from_letter (unsigned);
-extern int picochip_legitimate_address_p (int, struct rtx_def *, unsigned);
extern int picochip_const_ok_for_letter_p (unsigned HOST_WIDE_INT value, unsigned c);
#ifdef RTX_CODE /* inside TREE_CODE */
diff --git a/gcc/config/picochip/picochip.c b/gcc/config/picochip/picochip.c
index e9b61563153..358ef71e36b 100644
--- a/gcc/config/picochip/picochip.c
+++ b/gcc/config/picochip/picochip.c
@@ -95,6 +95,7 @@ rtx picochip_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
bool picochip_rtx_costs (rtx x, int code, int outer_code, int* total);
bool picochip_return_in_memory(const_tree type,
const_tree fntype ATTRIBUTE_UNUSED);
+bool picochip_legitimate_address_p (enum machine_mode, rtx, bool);
rtx picochip_struct_value_rtx(tree fntype ATTRIBUTE_UNUSED, int incoming ATTRIBUTE_UNUSED);
rtx picochip_function_value (const_tree valtype, const_tree func ATTRIBUTE_UNUSED,
@@ -275,6 +276,9 @@ static char picochip_get_vliw_alu_id (void);
#define TARGET_LIBGCC_CMP_RETURN_MODE picochip_libgcc_cmp_return_mode
*/
+#undef TARGET_LEGITIMATE_ADDRESS_P
+#define TARGET_LEGITIMATE_ADDRESS_P picochip_legitimate_address_p
+
/* Loading and storing QImode values to and from memory
usually requires a scratch register. */
#undef TARGET_SECONDARY_RELOAD
@@ -311,9 +315,6 @@ picochip_override_options (void)
PARAM_VALUE (PARAM_LARGE_STACK_FRAME) = 0;
PARAM_VALUE (PARAM_STACK_FRAME_GROWTH) = 0;
}
- /* The function call overhead on picochip is not very high. Let the
- inliner know so its heuristics become more reasonable. */
- PARAM_VALUE (PARAM_INLINE_CALL_COST) = 2;
/* Turn off the elimination of unused types. The elaborator
generates various interesting types to represent constants,
@@ -1249,8 +1250,8 @@ picochip_const_ok_for_base (enum machine_mode mode, int regno, int offset)
/* Determine whether a given rtx is a legitimate address for machine_mode
MODE. STRICT is non-zero if we're being strict - any pseudo that
is not a hard register must be a memory reference. */
-int
-picochip_legitimate_address_p (int mode, rtx x, unsigned strict)
+bool
+picochip_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
{
int valid = 0;
diff --git a/gcc/config/picochip/picochip.h b/gcc/config/picochip/picochip.h
index a3263d02e02..04400016da2 100644
--- a/gcc/config/picochip/picochip.h
+++ b/gcc/config/picochip/picochip.h
@@ -492,18 +492,6 @@ extern const enum reg_class picochip_regno_reg_class[FIRST_PSEUDO_REGISTER];
#define MAX_REGS_PER_ADDRESS 1
-#ifdef REG_OK_STRICT
-
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, LABEL) \
- if (picochip_legitimate_address_p (MODE, X, 1)) goto LABEL;
-
-#else /* REG_OK_STRICT */
-
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, LABEL) \
- if (picochip_legitimate_address_p (MODE, X, 0)) goto LABEL;
-
-#endif /* !REG_OK_STRICT */
-
/* Legitimize reload address tries machine dependent means of
reloading addresses. There seems to be a strange error in gcc,
which necessitates this macro. Consider:
diff --git a/gcc/config/picochip/picochip.md b/gcc/config/picochip/picochip.md
index 657629c96fa..02f0f14850d 100644
--- a/gcc/config/picochip/picochip.md
+++ b/gcc/config/picochip/picochip.md
@@ -551,7 +551,7 @@
(define_insn_and_split "cbranchhi4"
[(set (pc)
(if_then_else
- (match_operator:CC 0 "comparison_operator"
+ (match_operator:CC 0 "ordered_comparison_operator"
[(match_operand:HI 1 "register_operand" "r")
(match_operand:HI 2 "picochip_comparison_operand" "ri")])
(label_ref (match_operand 3 "" ""))
@@ -2524,117 +2524,6 @@
(set_attr "type" "picoAlu,picoAlu")
(set_attr "longConstant" "false,true")])
-;; cmphi - This needs to be defined, to ensure that the conditional
-;; move works properly (because the if-cvt code uses this pattern to
-;; build the conditional move, even though normally we use cbranch to
-;; directly generate the instructions).
-
-(define_expand "cmphi"
- [(match_operand:HI 0 "general_operand" "g")
- (match_operand:HI 1 "general_operand" "g")]
- ""
- "DONE;")
-
-;;============================================================================
-;; Branch patterns - needed for conditional moves. This is because
-;; they result in the bcc_gen_fctn array being initialised with the
-;; code to define_expand the following, and this in turn means that
-;; when noce_emit_cmove is called, the correct pattern can be
-;; generated, based upon the assumed presence of the following. The
-;; following are never actually used, because the earlier cbranch
-;; patterns take precendence.
-;;============================================================================
-
-(define_expand "bne"
- [(set (pc)
- (if_then_else
- (ne (reg:CC CC_REGNUM) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "gcc_unreachable();")
-
-(define_expand "beq"
- [(set (pc)
- (if_then_else
- (eq (reg:CC CC_REGNUM) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "gcc_unreachable();")
-
-(define_expand "blt"
- [(set (pc)
- (if_then_else
- (lt (reg:CC CC_REGNUM) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "gcc_unreachable();")
-
-(define_expand "bge"
- [(set (pc)
- (if_then_else
- (ge (reg:CC CC_REGNUM) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "gcc_unreachable();")
-
-(define_expand "bgeu"
- [(set (pc)
- (if_then_else
- (geu (reg:CC CC_REGNUM) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "gcc_unreachable();")
-
-(define_expand "bltu"
- [(set (pc)
- (if_then_else
- (ltu (reg:CC CC_REGNUM) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "gcc_unreachable();")
-
-(define_expand "ble"
- [(set (pc)
- (if_then_else
- (le (reg:CC CC_REGNUM) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "gcc_unreachable();")
-
-(define_expand "bgt"
- [(set (pc)
- (if_then_else
- (gt (reg:CC CC_REGNUM) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "gcc_unreachable();")
-
-(define_expand "bleu"
- [(set (pc)
- (if_then_else
- (leu (reg:CC CC_REGNUM) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "gcc_unreachable();")
-
-(define_expand "bgtu"
- [(set (pc)
- (if_then_else
- (gtu (reg:CC CC_REGNUM) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "gcc_unreachable();")
-
;;============================================================================
;; Scheduling, including delay slot scheduling.
;;============================================================================
diff --git a/gcc/config/rs6000/aix.h b/gcc/config/rs6000/aix.h
index 4e736ce3fc2..44015a348b7 100644
--- a/gcc/config/rs6000/aix.h
+++ b/gcc/config/rs6000/aix.h
@@ -120,18 +120,10 @@
/* #define ASM_SPEC "-u %(asm_cpu)" */
/* Default location of syscalls.exp under AIX */
-#ifndef CROSS_DIRECTORY_STRUCTURE
-#define LINK_SYSCALLS_SPEC "-bI:/lib/syscalls.exp"
-#else
-#define LINK_SYSCALLS_SPEC ""
-#endif
+#define LINK_SYSCALLS_SPEC "-bI:%R/lib/syscalls.exp"
/* Default location of libg.exp under AIX */
-#ifndef CROSS_DIRECTORY_STRUCTURE
-#define LINK_LIBG_SPEC "-bexport:/usr/lib/libg.exp"
-#else
-#define LINK_LIBG_SPEC ""
-#endif
+#define LINK_LIBG_SPEC "-bexport:%R/usr/lib/libg.exp"
/* Define the options for the binder: Start text at 512, align all segments
to 512 bytes, and warn if there is text relocation.
@@ -152,11 +144,11 @@
%{!shared:%{g*: %(link_libg) }} %{shared:-bM:SRE}"
/* Profiled library versions are used by linking with special directories. */
-#define LIB_SPEC "%{pg:-L/lib/profiled -L/usr/lib/profiled}\
-%{p:-L/lib/profiled -L/usr/lib/profiled} %{!shared:%{g*:-lg}} -lc"
+#define LIB_SPEC "%{pg:-L%R/lib/profiled -L%R/usr/lib/profiled}\
+%{p:-L%R/lib/profiled -L%R/usr/lib/profiled} %{!shared:%{g*:-lg}} -lc"
/* Static linking with shared libstdc++ requires libsupc++ as well. */
-#define LIBSTDCXX_STATIC "-lstdc++ -lsupc++"
+#define LIBSTDCXX_STATIC "-lsupc++"
/* This now supports a natural alignment mode. */
/* AIX word-aligns FP doubles but doubleword-aligns 64-bit ints. */
diff --git a/gcc/config/rs6000/aix43.h b/gcc/config/rs6000/aix43.h
index 56b24a363c6..bbe23373060 100644
--- a/gcc/config/rs6000/aix43.h
+++ b/gcc/config/rs6000/aix43.h
@@ -104,7 +104,7 @@ do { \
#define CPP_SPEC "%{posix: -D_POSIX_SOURCE}\
%{ansi: -D_ANSI_C_SOURCE}\
%{maix64: -D__64BIT__}\
- %{mpe: -I/usr/lpp/ppe.poe/include}\
+ %{mpe: -I%R/usr/lpp/ppe.poe/include}\
%{pthread: -D_THREAD_SAFE}"
/* The GNU C++ standard library requires that these macros be
@@ -113,7 +113,7 @@ do { \
#define CPLUSPLUS_CPP_SPEC \
"-D_ALL_SOURCE \
%{maix64: -D__64BIT__} \
- %{mpe: -I/usr/lpp/ppe.poe/include} \
+ %{mpe: -I%R/usr/lpp/ppe.poe/include} \
%{pthread: -D_THREAD_SAFE}"
#undef TARGET_DEFAULT
@@ -141,11 +141,11 @@ do { \
#define MULTILIB_DEFAULTS { "mcpu=common" }
#undef LIB_SPEC
-#define LIB_SPEC "%{pg:-L/lib/profiled -L/usr/lib/profiled}\
- %{p:-L/lib/profiled -L/usr/lib/profiled}\
+#define LIB_SPEC "%{pg:-L%R/lib/profiled -L%R/usr/lib/profiled}\
+ %{p:-L%R/lib/profiled -L%R/usr/lib/profiled}\
%{!maix64:%{!shared:%{g*:-lg}}}\
- %{mpe:-L/usr/lpp/ppe.poe/lib -lmpi -lvtd}\
- %{pthread:-L/usr/lib/threads -lpthreads -lc_r /usr/lib/libc.a}\
+ %{mpe:-L%R/usr/lpp/ppe.poe/lib -lmpi -lvtd}\
+ %{pthread:-L%R/usr/lib/threads -lpthreads -lc_r %R/usr/lib/libc.a}\
%{!pthread:-lc}"
#undef LINK_SPEC
@@ -187,3 +187,5 @@ do { \
/* This target uses the aix64.opt file. */
#define TARGET_USES_AIX64_OPT 1
+
+#define TARGET_AIX_VERSION 43
diff --git a/gcc/config/rs6000/aix51.h b/gcc/config/rs6000/aix51.h
index dbec0fb2a3c..32bdbb41f28 100644
--- a/gcc/config/rs6000/aix51.h
+++ b/gcc/config/rs6000/aix51.h
@@ -101,7 +101,7 @@ do { \
#define CPP_SPEC "%{posix: -D_POSIX_SOURCE} \
%{ansi: -D_ANSI_C_SOURCE} \
%{maix64: -D__64BIT__} \
- %{mpe: -I/usr/lpp/ppe.poe/include} \
+ %{mpe: -I%R/usr/lpp/ppe.poe/include} \
%{pthread: -D_THREAD_SAFE}"
/* The GNU C++ standard library requires that these macros be
@@ -110,7 +110,7 @@ do { \
#define CPLUSPLUS_CPP_SPEC \
"-D_ALL_SOURCE \
%{maix64: -D__64BIT__} \
- %{mpe: -I/usr/lpp/ppe.poe/include} \
+ %{mpe: -I%R/usr/lpp/ppe.poe/include} \
%{pthread: -D_THREAD_SAFE}"
#undef TARGET_DEFAULT
@@ -138,10 +138,10 @@ do { \
#define MULTILIB_DEFAULTS { "mcpu=common" }
#undef LIB_SPEC
-#define LIB_SPEC "%{pg:-L/lib/profiled -L/usr/lib/profiled}\
- %{p:-L/lib/profiled -L/usr/lib/profiled}\
+#define LIB_SPEC "%{pg:-L%R/lib/profiled -L%R/usr/lib/profiled}\
+ %{p:-L%R/lib/profiled -L%R/usr/lib/profiled}\
%{!maix64:%{!shared:%{g*:-lg}}}\
- %{mpe:-L/usr/lpp/ppe.poe/lib -lmpi -lvtd}\
+ %{mpe:-L%R/usr/lpp/ppe.poe/lib -lmpi -lvtd}\
%{pthread:-lpthreads} -lc"
#undef LINK_SPEC
@@ -191,3 +191,5 @@ do { \
but does not have crtbegin/end. */
#define TARGET_USE_JCR_SECTION 0
+
+#define TARGET_AIX_VERSION 51
diff --git a/gcc/config/rs6000/aix52.h b/gcc/config/rs6000/aix52.h
index 8fab3f4a263..8d6c2411621 100644
--- a/gcc/config/rs6000/aix52.h
+++ b/gcc/config/rs6000/aix52.h
@@ -99,7 +99,7 @@ do { \
#define CPP_SPEC "%{posix: -D_POSIX_SOURCE} \
%{ansi: -D_ANSI_C_SOURCE} \
%{maix64: -D__64BIT__} \
- %{mpe: -I/usr/lpp/ppe.poe/include} \
+ %{mpe: -I%R/usr/lpp/ppe.poe/include} \
%{pthread: -D_THREAD_SAFE}"
/* The GNU C++ standard library requires that these macros be
@@ -108,7 +108,7 @@ do { \
#define CPLUSPLUS_CPP_SPEC \
"-D_ALL_SOURCE \
%{maix64: -D__64BIT__} \
- %{mpe: -I/usr/lpp/ppe.poe/include} \
+ %{mpe: -I%R/usr/lpp/ppe.poe/include} \
%{pthread: -D_THREAD_SAFE}"
#undef TARGET_DEFAULT
@@ -140,10 +140,10 @@ do { \
#undef MULTILIB_DEFAULTS
#undef LIB_SPEC
-#define LIB_SPEC "%{pg:-L/lib/profiled -L/usr/lib/profiled}\
- %{p:-L/lib/profiled -L/usr/lib/profiled}\
+#define LIB_SPEC "%{pg:-L%R/lib/profiled -L%R/usr/lib/profiled}\
+ %{p:-L%R/lib/profiled -L%R/usr/lib/profiled}\
%{!maix64:%{!shared:%{g*:-lg}}}\
- %{mpe:-L/usr/lpp/ppe.poe/lib -lmpi -lvtd}\
+ %{mpe:-L%R/usr/lpp/ppe.poe/lib -lmpi -lvtd}\
%{pthread:-lpthreads} -lc"
#undef LINK_SPEC
@@ -201,3 +201,5 @@ extern long long int atoll(const char *);
but does not have crtbegin/end. */
#define TARGET_USE_JCR_SECTION 0
+
+#define TARGET_AIX_VERSION 52
diff --git a/gcc/config/rs6000/aix53.h b/gcc/config/rs6000/aix53.h
index 80f1038faa1..6172e76aad2 100644
--- a/gcc/config/rs6000/aix53.h
+++ b/gcc/config/rs6000/aix53.h
@@ -101,7 +101,7 @@ do { \
#define CPP_SPEC "%{posix: -D_POSIX_SOURCE} \
%{ansi: -D_ANSI_C_SOURCE} \
%{maix64: -D__64BIT__} \
- %{mpe: -I/usr/lpp/ppe.poe/include} \
+ %{mpe: -I%R/usr/lpp/ppe.poe/include} \
%{pthread: -D_THREAD_SAFE}"
/* The GNU C++ standard library requires that these macros be
@@ -110,7 +110,7 @@ do { \
#define CPLUSPLUS_CPP_SPEC \
"-D_ALL_SOURCE \
%{maix64: -D__64BIT__} \
- %{mpe: -I/usr/lpp/ppe.poe/include} \
+ %{mpe: -I%R/usr/lpp/ppe.poe/include} \
%{pthread: -D_THREAD_SAFE}"
#undef TARGET_DEFAULT
@@ -136,10 +136,10 @@ do { \
#undef MULTILIB_DEFAULTS
#undef LIB_SPEC
-#define LIB_SPEC "%{pg:-L/lib/profiled -L/usr/lib/profiled}\
- %{p:-L/lib/profiled -L/usr/lib/profiled}\
+#define LIB_SPEC "%{pg:-L%R/lib/profiled -L%R/usr/lib/profiled}\
+ %{p:-L%R/lib/profiled -L%R/usr/lib/profiled}\
%{!maix64:%{!shared:%{g*:-lg}}}\
- %{mpe:-L/usr/lpp/ppe.poe/lib -lmpi -lvtd}\
+ %{mpe:-L%R/usr/lpp/ppe.poe/lib -lmpi -lvtd}\
%{pthread:-lpthreads} -lc"
#undef LINK_SPEC
@@ -197,3 +197,5 @@ extern long long int atoll(const char *);
but does not have crtbegin/end. */
#define TARGET_USE_JCR_SECTION 0
+
+#define TARGET_AIX_VERSION 53
diff --git a/gcc/config/rs6000/aix61.h b/gcc/config/rs6000/aix61.h
index e62a775c745..c0899d8c513 100644
--- a/gcc/config/rs6000/aix61.h
+++ b/gcc/config/rs6000/aix61.h
@@ -102,7 +102,7 @@ do { \
#define CPP_SPEC "%{posix: -D_POSIX_SOURCE} \
%{ansi: -D_ANSI_C_SOURCE} \
%{maix64: -D__64BIT__} \
- %{mpe: -I/usr/lpp/ppe.poe/include} \
+ %{mpe: -I%R/usr/lpp/ppe.poe/include} \
%{pthread: -D_THREAD_SAFE}"
/* The GNU C++ standard library requires that these macros be
@@ -111,7 +111,7 @@ do { \
#define CPLUSPLUS_CPP_SPEC \
"-D_ALL_SOURCE -D__COMPATMATH__ \
%{maix64: -D__64BIT__} \
- %{mpe: -I/usr/lpp/ppe.poe/include} \
+ %{mpe: -I%R/usr/lpp/ppe.poe/include} \
%{pthread: -D_THREAD_SAFE}"
#undef TARGET_DEFAULT
@@ -137,10 +137,10 @@ do { \
#undef MULTILIB_DEFAULTS
#undef LIB_SPEC
-#define LIB_SPEC "%{pg:-L/lib/profiled -L/usr/lib/profiled}\
- %{p:-L/lib/profiled -L/usr/lib/profiled}\
+#define LIB_SPEC "%{pg:-L%R/lib/profiled -L%R/usr/lib/profiled}\
+ %{p:-L%R/lib/profiled -L%R/usr/lib/profiled}\
%{!maix64:%{!shared:%{g*:-lg}}}\
- %{mpe:-L/usr/lpp/ppe.poe/lib -lmpi -lvtd}\
+ %{mpe:-L%R/usr/lpp/ppe.poe/lib -lmpi -lvtd}\
%{pthread:-lpthreads} -lc"
#undef LINK_SPEC
@@ -202,3 +202,5 @@ extern long long int atoll(const char *);
/* Default to 128 bit long double. */
#define RS6000_DEFAULT_LONG_DOUBLE_SIZE 128
+
+#define TARGET_AIX_VERSION 61
diff --git a/gcc/config/rs6000/crtresfpr.asm b/gcc/config/rs6000/crtresfpr.asm
index 7adc9c1e757..9fb228cf458 100644
--- a/gcc/config/rs6000/crtresfpr.asm
+++ b/gcc/config/rs6000/crtresfpr.asm
@@ -38,6 +38,7 @@
/* Called with r11 pointing to the stack header word of the caller of the */
/* function, just beyond the end of the floating point save area. */
+CFI_STARTPROC
HIDDEN_FUNC(_restfpr_14) lfd 14,-144(11) /* restore fp registers */
HIDDEN_FUNC(_restfpr_15) lfd 15,-136(11)
HIDDEN_FUNC(_restfpr_16) lfd 16,-128(11)
@@ -75,5 +76,6 @@ FUNC_END(_restfpr_17)
FUNC_END(_restfpr_16)
FUNC_END(_restfpr_15)
FUNC_END(_restfpr_14)
+CFI_ENDPROC
#endif
diff --git a/gcc/config/rs6000/crtresgpr.asm b/gcc/config/rs6000/crtresgpr.asm
index 4ed3d8e21c5..9f9cec9f9ca 100644
--- a/gcc/config/rs6000/crtresgpr.asm
+++ b/gcc/config/rs6000/crtresgpr.asm
@@ -38,6 +38,7 @@
/* Called with r11 pointing to the stack header word of the caller of the */
/* function, just beyond the end of the integer restore area. */
+CFI_STARTPROC
HIDDEN_FUNC(_restgpr_14) lwz 14,-72(11) /* restore gp registers */
HIDDEN_FUNC(_restgpr_15) lwz 15,-68(11)
HIDDEN_FUNC(_restgpr_16) lwz 16,-64(11)
@@ -75,5 +76,6 @@ FUNC_END(_restgpr_17)
FUNC_END(_restgpr_16)
FUNC_END(_restgpr_15)
FUNC_END(_restgpr_14)
+CFI_ENDPROC
#endif
diff --git a/gcc/config/rs6000/crtresxfpr.asm b/gcc/config/rs6000/crtresxfpr.asm
index 5a87a98052f..633f2db61f0 100644
--- a/gcc/config/rs6000/crtresxfpr.asm
+++ b/gcc/config/rs6000/crtresxfpr.asm
@@ -40,27 +40,68 @@
/* In addition to restoring the fp registers, it will return to the caller's */
/* caller */
+CFI_STARTPROC
+CFI_DEF_CFA_REGISTER (11)
+CFI_OFFSET (65, 4)
+CFI_OFFSET (46, -144)
+CFI_OFFSET (47, -136)
+CFI_OFFSET (48, -128)
+CFI_OFFSET (49, -120)
+CFI_OFFSET (50, -112)
+CFI_OFFSET (51, -104)
+CFI_OFFSET (52, -96)
+CFI_OFFSET (53, -88)
+CFI_OFFSET (54, -80)
+CFI_OFFSET (55, -72)
+CFI_OFFSET (56, -64)
+CFI_OFFSET (57, -56)
+CFI_OFFSET (58, -48)
+CFI_OFFSET (59, -40)
+CFI_OFFSET (60, -32)
+CFI_OFFSET (61, -24)
+CFI_OFFSET (62, -16)
+CFI_OFFSET (63, -8)
HIDDEN_FUNC(_restfpr_14_x) lfd 14,-144(11) /* restore fp registers */
+CFI_RESTORE (46)
HIDDEN_FUNC(_restfpr_15_x) lfd 15,-136(11)
+CFI_RESTORE (47)
HIDDEN_FUNC(_restfpr_16_x) lfd 16,-128(11)
+CFI_RESTORE (48)
HIDDEN_FUNC(_restfpr_17_x) lfd 17,-120(11)
+CFI_RESTORE (49)
HIDDEN_FUNC(_restfpr_18_x) lfd 18,-112(11)
+CFI_RESTORE (50)
HIDDEN_FUNC(_restfpr_19_x) lfd 19,-104(11)
+CFI_RESTORE (51)
HIDDEN_FUNC(_restfpr_20_x) lfd 20,-96(11)
+CFI_RESTORE (52)
HIDDEN_FUNC(_restfpr_21_x) lfd 21,-88(11)
+CFI_RESTORE (53)
HIDDEN_FUNC(_restfpr_22_x) lfd 22,-80(11)
+CFI_RESTORE (54)
HIDDEN_FUNC(_restfpr_23_x) lfd 23,-72(11)
+CFI_RESTORE (55)
HIDDEN_FUNC(_restfpr_24_x) lfd 24,-64(11)
+CFI_RESTORE (56)
HIDDEN_FUNC(_restfpr_25_x) lfd 25,-56(11)
+CFI_RESTORE (57)
HIDDEN_FUNC(_restfpr_26_x) lfd 26,-48(11)
+CFI_RESTORE (58)
HIDDEN_FUNC(_restfpr_27_x) lfd 27,-40(11)
+CFI_RESTORE (59)
HIDDEN_FUNC(_restfpr_28_x) lfd 28,-32(11)
+CFI_RESTORE (60)
HIDDEN_FUNC(_restfpr_29_x) lfd 29,-24(11)
+CFI_RESTORE (61)
HIDDEN_FUNC(_restfpr_30_x) lfd 30,-16(11)
+CFI_RESTORE (62)
HIDDEN_FUNC(_restfpr_31_x) lwz 0,4(11)
lfd 31,-8(11)
+CFI_RESTORE (63)
mtlr 0
+CFI_RESTORE (65)
mr 1,11
+CFI_DEF_CFA_REGISTER (1)
blr
FUNC_END(_restfpr_31_x)
FUNC_END(_restfpr_30_x)
@@ -80,5 +121,6 @@ FUNC_END(_restfpr_17_x)
FUNC_END(_restfpr_16_x)
FUNC_END(_restfpr_15_x)
FUNC_END(_restfpr_14_x)
+CFI_ENDPROC
#endif
diff --git a/gcc/config/rs6000/crtresxgpr.asm b/gcc/config/rs6000/crtresxgpr.asm
index 9317131c8ce..451b2b69d1e 100644
--- a/gcc/config/rs6000/crtresxgpr.asm
+++ b/gcc/config/rs6000/crtresxgpr.asm
@@ -38,27 +38,68 @@
/* Called with r11 pointing to the stack header word of the caller of the */
/* function, just beyond the end of the integer restore area. */
+CFI_STARTPROC
+CFI_DEF_CFA_REGISTER (11)
+CFI_OFFSET (65, 4)
+CFI_OFFSET (14, -72)
+CFI_OFFSET (15, -68)
+CFI_OFFSET (16, -64)
+CFI_OFFSET (17, -60)
+CFI_OFFSET (18, -56)
+CFI_OFFSET (19, -52)
+CFI_OFFSET (20, -48)
+CFI_OFFSET (21, -44)
+CFI_OFFSET (22, -40)
+CFI_OFFSET (23, -36)
+CFI_OFFSET (24, -32)
+CFI_OFFSET (25, -28)
+CFI_OFFSET (26, -24)
+CFI_OFFSET (27, -20)
+CFI_OFFSET (28, -16)
+CFI_OFFSET (29, -12)
+CFI_OFFSET (30, -8)
+CFI_OFFSET (31, -4)
HIDDEN_FUNC(_restgpr_14_x) lwz 14,-72(11) /* restore gp registers */
+CFI_RESTORE (14)
HIDDEN_FUNC(_restgpr_15_x) lwz 15,-68(11)
+CFI_RESTORE (15)
HIDDEN_FUNC(_restgpr_16_x) lwz 16,-64(11)
+CFI_RESTORE (16)
HIDDEN_FUNC(_restgpr_17_x) lwz 17,-60(11)
+CFI_RESTORE (17)
HIDDEN_FUNC(_restgpr_18_x) lwz 18,-56(11)
+CFI_RESTORE (18)
HIDDEN_FUNC(_restgpr_19_x) lwz 19,-52(11)
+CFI_RESTORE (19)
HIDDEN_FUNC(_restgpr_20_x) lwz 20,-48(11)
+CFI_RESTORE (20)
HIDDEN_FUNC(_restgpr_21_x) lwz 21,-44(11)
+CFI_RESTORE (21)
HIDDEN_FUNC(_restgpr_22_x) lwz 22,-40(11)
+CFI_RESTORE (22)
HIDDEN_FUNC(_restgpr_23_x) lwz 23,-36(11)
+CFI_RESTORE (23)
HIDDEN_FUNC(_restgpr_24_x) lwz 24,-32(11)
+CFI_RESTORE (24)
HIDDEN_FUNC(_restgpr_25_x) lwz 25,-28(11)
+CFI_RESTORE (25)
HIDDEN_FUNC(_restgpr_26_x) lwz 26,-24(11)
+CFI_RESTORE (26)
HIDDEN_FUNC(_restgpr_27_x) lwz 27,-20(11)
+CFI_RESTORE (27)
HIDDEN_FUNC(_restgpr_28_x) lwz 28,-16(11)
+CFI_RESTORE (28)
HIDDEN_FUNC(_restgpr_29_x) lwz 29,-12(11)
+CFI_RESTORE (29)
HIDDEN_FUNC(_restgpr_30_x) lwz 30,-8(11)
+CFI_RESTORE (30)
HIDDEN_FUNC(_restgpr_31_x) lwz 0,4(11)
lwz 31,-4(11)
+CFI_RESTORE (31)
mtlr 0
+CFI_RESTORE (65)
mr 1,11
+CFI_DEF_CFA_REGISTER (1)
blr
FUNC_END(_restgpr_31_x)
FUNC_END(_restgpr_30_x)
@@ -78,5 +119,6 @@ FUNC_END(_restgpr_17_x)
FUNC_END(_restgpr_16_x)
FUNC_END(_restgpr_15_x)
FUNC_END(_restgpr_14_x)
+CFI_ENDPROC
#endif
diff --git a/gcc/config/rs6000/crtsavfpr.asm b/gcc/config/rs6000/crtsavfpr.asm
index fe40a9e13d0..3cdb25033ca 100644
--- a/gcc/config/rs6000/crtsavfpr.asm
+++ b/gcc/config/rs6000/crtsavfpr.asm
@@ -38,6 +38,7 @@
/* Called with r11 pointing to the stack header word of the caller of the */
/* function, just beyond the end of the floating point save area. */
+CFI_STARTPROC
HIDDEN_FUNC(_savefpr_14) stfd 14,-144(11) /* save fp registers */
HIDDEN_FUNC(_savefpr_15) stfd 15,-136(11)
HIDDEN_FUNC(_savefpr_16) stfd 16,-128(11)
@@ -75,5 +76,6 @@ FUNC_END(_savefpr_17)
FUNC_END(_savefpr_16)
FUNC_END(_savefpr_15)
FUNC_END(_savefpr_14)
+CFI_ENDPROC
#endif
diff --git a/gcc/config/rs6000/crtsavgpr.asm b/gcc/config/rs6000/crtsavgpr.asm
index 6c5f6720934..6d473963bad 100644
--- a/gcc/config/rs6000/crtsavgpr.asm
+++ b/gcc/config/rs6000/crtsavgpr.asm
@@ -38,6 +38,7 @@
/* Called with r11 pointing to the stack header word of the caller of the */
/* function, just beyond the end of the integer save area. */
+CFI_STARTPROC
HIDDEN_FUNC(_savegpr_14) stw 14,-72(11) /* save gp registers */
HIDDEN_FUNC(_savegpr_15) stw 15,-68(11)
HIDDEN_FUNC(_savegpr_16) stw 16,-64(11)
@@ -75,5 +76,6 @@ FUNC_END(_savegpr_17)
FUNC_END(_savegpr_16)
FUNC_END(_savegpr_15)
FUNC_END(_savegpr_14)
+CFI_ENDPROC
#endif
diff --git a/gcc/config/rs6000/eabi.asm b/gcc/config/rs6000/eabi.asm
index f5581efebf9..292d88e5016 100644
--- a/gcc/config/rs6000/eabi.asm
+++ b/gcc/config/rs6000/eabi.asm
@@ -230,7 +230,7 @@ FUNC_END(__eabi)
r11 has the address of .LCTOC1 in it.
r12 has the value to add to each pointer
r13 .. r31 are unchanged */
-
+#ifdef _RELOCATABLE
FUNC_START(__eabi_convert)
cmplw 1,3,4 /* any pointers to convert? */
subf 5,3,4 /* calculate number of words to convert */
@@ -285,5 +285,5 @@ FUNC_START(__eabi_uconvert)
blr
FUNC_END(__eabi_uconvert)
-
+#endif
#endif
diff --git a/gcc/config/rs6000/linux64.h b/gcc/config/rs6000/linux64.h
index 1b4a36c030d..c3193dcfe0d 100644
--- a/gcc/config/rs6000/linux64.h
+++ b/gcc/config/rs6000/linux64.h
@@ -471,9 +471,8 @@ extern int dot_symbols;
we also do this for floating-point constants. We actually can only
do this if the FP formats of the target and host machines are the
same, but we can't check that since not every file that uses
- GO_IF_LEGITIMATE_ADDRESS_P includes real.h. We also do this when
- we can write the entry into the TOC and the entry is not larger
- than a TOC entry. */
+ the macros includes real.h. We also do this when we can write the
+ entry into the TOC and the entry is not larger than a TOC entry. */
#undef ASM_OUTPUT_SPECIAL_POOL_ENTRY_P
#define ASM_OUTPUT_SPECIAL_POOL_ENTRY_P(X, MODE) \
diff --git a/gcc/config/rs6000/ppc-asm.h b/gcc/config/rs6000/ppc-asm.h
index 3a70a137b55..147f1092753 100644
--- a/gcc/config/rs6000/ppc-asm.h
+++ b/gcc/config/rs6000/ppc-asm.h
@@ -1,6 +1,6 @@
/* PowerPC asm definitions for GNU C.
-Copyright (C) 2002, 2003, 2008 Free Software Foundation, Inc.
+Copyright (C) 2002, 2003, 2008, 2009 Free Software Foundation, Inc.
This file is part of GCC.
@@ -196,6 +196,25 @@ GLUE(.L,name): \
.size FUNC_NAME(name),GLUE(.L,name)-FUNC_NAME(name)
#endif
+#ifdef IN_GCC
+/* For HAVE_GAS_CFI_DIRECTIVE. */
+#include "auto-host.h"
+
+#ifdef HAVE_GAS_CFI_DIRECTIVE
+# define CFI_STARTPROC .cfi_startproc
+# define CFI_ENDPROC .cfi_endproc
+# define CFI_OFFSET(reg, off) .cfi_offset reg, off
+# define CFI_DEF_CFA_REGISTER(reg) .cfi_def_cfa_register reg
+# define CFI_RESTORE(reg) .cfi_restore reg
+#else
+# define CFI_STARTPROC
+# define CFI_ENDPROC
+# define CFI_OFFSET(reg, off)
+# define CFI_DEF_CFA_REGISTER(reg)
+# define CFI_RESTORE(reg)
+#endif
+#endif
+
#if defined __linux__ && !defined __powerpc64__
.section .note.GNU-stack
.previous
diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index af80ef46b6f..dbf78734b17 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -830,6 +830,11 @@
GET_MODE (XEXP (op, 0))),
1"))))
+(define_predicate "rs6000_cbranch_operator"
+ (if_then_else (match_test "TARGET_HARD_FLOAT && !TARGET_FPRS")
+ (match_operand 0 "ordered_comparison_operator")
+ (match_operand 0 "comparison_operator")))
+
;; Return 1 if OP is a comparison operation that is valid for an SCC insn --
;; it must be a positive comparison.
(define_predicate "scc_comparison_operator"
@@ -842,11 +847,6 @@
(and (match_operand 0 "branch_comparison_operator")
(match_code "eq,lt,gt,ltu,gtu,unordered")))
-;; Return 1 is OP is a comparison operation that is valid for a trap insn.
-(define_predicate "trap_comparison_operator"
- (and (match_operand 0 "comparison_operator")
- (match_code "eq,ne,le,lt,ge,gt,leu,ltu,geu,gtu")))
-
;; Return 1 if OP is a load multiple operation, known to be a PARALLEL.
(define_predicate "load_multiple_operation"
(match_code "parallel")
diff --git a/gcc/config/rs6000/rs6000-c.c b/gcc/config/rs6000/rs6000-c.c
index c7adcdb5e04..8a39b9e9f84 100644
--- a/gcc/config/rs6000/rs6000-c.c
+++ b/gcc/config/rs6000/rs6000-c.c
@@ -91,6 +91,7 @@ static GTY(()) tree __pixel_keyword;
static GTY(()) tree pixel_keyword;
static GTY(()) tree __bool_keyword;
static GTY(()) tree bool_keyword;
+static GTY(()) tree _Bool_keyword;
/* Preserved across calls. */
static tree expand_bool_pixel;
@@ -111,6 +112,9 @@ altivec_categorize_keyword (const cpp_token *tok)
if (ident == C_CPP_HASHNODE (bool_keyword))
return C_CPP_HASHNODE (__bool_keyword);
+ if (ident == C_CPP_HASHNODE (_Bool_keyword))
+ return C_CPP_HASHNODE (__bool_keyword);
+
return ident;
}
@@ -141,6 +145,9 @@ init_vector_keywords (void)
bool_keyword = get_identifier ("bool");
C_CPP_HASHNODE (bool_keyword)->flags |= NODE_CONDITIONAL;
+
+ _Bool_keyword = get_identifier ("_Bool");
+ C_CPP_HASHNODE (_Bool_keyword)->flags |= NODE_CONDITIONAL;
}
/* Called to decide whether a conditional macro should be expanded.
@@ -295,6 +302,7 @@ rs6000_cpu_cpp_builtins (cpp_reader *pfile)
builtin_define ("vector=vector");
builtin_define ("pixel=pixel");
builtin_define ("bool=bool");
+ builtin_define ("_Bool=_Bool");
init_vector_keywords ();
/* Enable context-sensitive macros. */
@@ -2993,7 +3001,8 @@ altivec_build_resolved_builtin (tree *args, int n,
support Altivec's overloaded builtins. */
tree
-altivec_resolve_overloaded_builtin (tree fndecl, void *passed_arglist)
+altivec_resolve_overloaded_builtin (location_t loc, tree fndecl,
+ void *passed_arglist)
{
VEC(tree,gc) *arglist = (VEC(tree,gc) *) passed_arglist;
unsigned int nargs = VEC_length (tree, arglist);
@@ -3105,11 +3114,11 @@ altivec_resolve_overloaded_builtin (tree fndecl, void *passed_arglist)
goto bad;
/* Build *(((arg1_inner_type*)&(vector type){arg1})+arg2). */
arg1_inner_type = TREE_TYPE (arg1_type);
- arg2 = build_binary_op (input_location, BIT_AND_EXPR, arg2,
+ arg2 = build_binary_op (loc, BIT_AND_EXPR, arg2,
build_int_cst (TREE_TYPE (arg2),
TYPE_VECTOR_SUBPARTS (arg1_type)
- 1), 0);
- decl = build_decl (VAR_DECL, NULL_TREE, arg1_type);
+ decl = build_decl (loc, VAR_DECL, NULL_TREE, arg1_type);
DECL_EXTERNAL (decl) = 0;
TREE_PUBLIC (decl) = 0;
DECL_CONTEXT (decl) = current_function_decl;
@@ -3119,15 +3128,15 @@ altivec_resolve_overloaded_builtin (tree fndecl, void *passed_arglist)
DECL_INITIAL (decl) = arg1;
stmt = build1 (DECL_EXPR, arg1_type, decl);
TREE_ADDRESSABLE (decl) = 1;
- SET_EXPR_LOCATION (stmt, input_location);
+ SET_EXPR_LOCATION (stmt, loc);
stmt = build1 (COMPOUND_LITERAL_EXPR, arg1_type, stmt);
innerptrtype = build_pointer_type (arg1_inner_type);
- stmt = build_unary_op (input_location, ADDR_EXPR, stmt, 0);
+ stmt = build_unary_op (loc, ADDR_EXPR, stmt, 0);
stmt = convert (innerptrtype, stmt);
- stmt = build_binary_op (input_location, PLUS_EXPR, stmt, arg2, 1);
- stmt = build_indirect_ref (input_location, stmt, NULL);
+ stmt = build_binary_op (loc, PLUS_EXPR, stmt, arg2, 1);
+ stmt = build_indirect_ref (loc, stmt, NULL);
return stmt;
}
@@ -3161,11 +3170,11 @@ altivec_resolve_overloaded_builtin (tree fndecl, void *passed_arglist)
goto bad;
/* Build *(((arg1_inner_type*)&(vector type){arg1})+arg2) = arg0. */
arg1_inner_type = TREE_TYPE (arg1_type);
- arg2 = build_binary_op (input_location, BIT_AND_EXPR, arg2,
+ arg2 = build_binary_op (loc, BIT_AND_EXPR, arg2,
build_int_cst (TREE_TYPE (arg2),
TYPE_VECTOR_SUBPARTS (arg1_type)
- 1), 0);
- decl = build_decl (VAR_DECL, NULL_TREE, arg1_type);
+ decl = build_decl (loc, VAR_DECL, NULL_TREE, arg1_type);
DECL_EXTERNAL (decl) = 0;
TREE_PUBLIC (decl) = 0;
DECL_CONTEXT (decl) = current_function_decl;
@@ -3175,15 +3184,15 @@ altivec_resolve_overloaded_builtin (tree fndecl, void *passed_arglist)
DECL_INITIAL (decl) = arg1;
stmt = build1 (DECL_EXPR, arg1_type, decl);
TREE_ADDRESSABLE (decl) = 1;
- SET_EXPR_LOCATION (stmt, input_location);
+ SET_EXPR_LOCATION (stmt, loc);
stmt = build1 (COMPOUND_LITERAL_EXPR, arg1_type, stmt);
innerptrtype = build_pointer_type (arg1_inner_type);
- stmt = build_unary_op (input_location, ADDR_EXPR, stmt, 0);
+ stmt = build_unary_op (loc, ADDR_EXPR, stmt, 0);
stmt = convert (innerptrtype, stmt);
- stmt = build_binary_op (input_location, PLUS_EXPR, stmt, arg2, 1);
- stmt = build_indirect_ref (input_location, stmt, NULL);
+ stmt = build_binary_op (loc, PLUS_EXPR, stmt, arg2, 1);
+ stmt = build_indirect_ref (loc, stmt, NULL);
stmt = build2 (MODIFY_EXPR, TREE_TYPE (stmt), stmt,
convert (TREE_TYPE (stmt), arg0));
stmt = build2 (COMPOUND_EXPR, arg1_type, stmt, decl);
diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h
index 4b8f5220a51..1b68d440eb8 100644
--- a/gcc/config/rs6000/rs6000-protos.h
+++ b/gcc/config/rs6000/rs6000-protos.h
@@ -81,8 +81,8 @@ extern void print_operand_address (FILE *, rtx);
extern bool rs6000_output_addr_const_extra (FILE *, rtx);
extern enum rtx_code rs6000_reverse_condition (enum machine_mode,
enum rtx_code);
-extern void rs6000_emit_sCOND (enum rtx_code, rtx);
-extern void rs6000_emit_cbranch (enum rtx_code, rtx);
+extern void rs6000_emit_sCOND (enum machine_mode, rtx[]);
+extern void rs6000_emit_cbranch (enum machine_mode, rtx[]);
extern char * output_cbranch (rtx, const char *, int, rtx);
extern char * output_e500_flip_gt_bit (rtx, rtx);
extern rtx rs6000_emit_set_const (rtx, enum machine_mode, rtx, int);
@@ -109,7 +109,6 @@ extern void rs6000_emit_move (rtx, rtx, enum machine_mode);
extern rtx rs6000_secondary_memory_needed_rtx (enum machine_mode);
extern rtx rs6000_legitimize_reload_address (rtx, enum machine_mode,
int, int, int, int *);
-extern int rs6000_legitimate_address (enum machine_mode, rtx, int);
extern bool rs6000_legitimate_offset_address_p (enum machine_mode, rtx, int);
extern bool rs6000_mode_dependent_address (rtx);
extern rtx rs6000_find_base_term (rtx);
@@ -133,7 +132,7 @@ extern void function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode,
tree, int, int);
extern int function_arg_boundary (enum machine_mode, tree);
extern rtx function_arg (CUMULATIVE_ARGS *, enum machine_mode, tree, int);
-extern tree altivec_resolve_overloaded_builtin (tree, void *);
+extern tree altivec_resolve_overloaded_builtin (location_t, tree, void *);
extern rtx rs6000_function_value (const_tree, const_tree);
extern rtx rs6000_libcall_value (enum machine_mode);
extern rtx rs6000_va_arg (tree, tree);
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 92397d6a9f5..78ab6ff2a1a 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -190,11 +190,6 @@ int rs6000_darwin64_abi;
/* Set to nonzero once AIX common-mode calls have been defined. */
static GTY(()) int common_mode_defined;
-/* Save information from a "cmpxx" operation until the branch or scc is
- emitted. */
-rtx rs6000_compare_op0, rs6000_compare_op1;
-int rs6000_compare_fp_p;
-
/* Label number of label created for -mrelocatable, to call to so we can
get the address of the GOT section */
int rs6000_pic_labelno;
@@ -752,7 +747,8 @@ struct processor_costs power6_cost = {
static bool rs6000_function_ok_for_sibcall (tree, tree);
static const char *rs6000_invalid_within_doloop (const_rtx);
-static rtx rs6000_generate_compare (enum rtx_code);
+static bool rs6000_legitimate_address_p (enum machine_mode, rtx, bool);
+static rtx rs6000_generate_compare (rtx, enum machine_mode);
static void rs6000_emit_stack_tie (void);
static void rs6000_frame_related (rtx, rtx, HOST_WIDE_INT, rtx, rtx);
static bool spe_func_has_64bit_regs_p (void);
@@ -779,10 +775,10 @@ static bool rs6000_ms_bitfield_layout_p (const_tree);
static tree rs6000_handle_struct_attribute (tree *, tree, tree, int, bool *);
static void rs6000_eliminate_indexed_memrefs (rtx operands[2]);
static const char *rs6000_mangle_type (const_tree);
-extern const struct attribute_spec rs6000_attribute_table[];
+EXPORTED_CONST struct attribute_spec rs6000_attribute_table[];
static void rs6000_set_default_type_attributes (tree);
static rtx rs6000_savres_routine_sym (rs6000_stack_t *, bool, bool, bool);
-static void rs6000_emit_stack_reset (rs6000_stack_t *, rtx, rtx, int, bool);
+static rtx rs6000_emit_stack_reset (rs6000_stack_t *, rtx, rtx, int, bool);
static rtx rs6000_make_savres_rtx (rs6000_stack_t *, rtx, int,
enum machine_mode, bool, bool, bool);
static bool rs6000_reg_live_or_pic_offset_p (int);
@@ -862,7 +858,7 @@ static tree rs6000_builtin_reciprocal (unsigned int, bool, bool);
static tree rs6000_builtin_mask_for_load (void);
static tree rs6000_builtin_mul_widen_even (tree);
static tree rs6000_builtin_mul_widen_odd (tree);
-static tree rs6000_builtin_conversion (enum tree_code, tree);
+static tree rs6000_builtin_conversion (unsigned int, tree);
static tree rs6000_builtin_vec_perm (tree, tree *);
static void def_builtin (int, const char *, tree, int);
@@ -1300,6 +1296,9 @@ static const char alt_reg_names[][8] =
#undef TARGET_INSTANTIATE_DECLS
#define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
+#undef TARGET_LEGITIMATE_ADDRESS_P
+#define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p
+
struct gcc_target targetm = TARGET_INITIALIZER;
@@ -2018,8 +2017,10 @@ rs6000_builtin_mask_for_load (void)
side of the conversion.
Return NULL_TREE if it is not available. */
static tree
-rs6000_builtin_conversion (enum tree_code code, tree type)
+rs6000_builtin_conversion (unsigned int tcode, tree type)
{
+ enum tree_code code = (enum tree_code) tcode;
+
if (!TARGET_ALTIVEC)
return NULL_TREE;
@@ -3565,7 +3566,7 @@ gpr_or_gpr_p (rtx op0, rtx op1)
}
-/* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address. */
+/* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address_p. */
static bool
constant_pool_expr_p (rtx op)
@@ -3799,8 +3800,6 @@ legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
called. In some cases it is useful to look at this to decide what
needs to be done.
- MODE is passed so that this function can use GO_IF_LEGITIMATE_ADDRESS.
-
It is always safe for this function to do nothing. It exists to
recognize opportunities to optimize the output.
@@ -4244,13 +4243,6 @@ rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
return RS6000_SYMBOL_REF_TLS_P (*x);
}
-/* The convention appears to be to define this wherever it is used.
- With legitimize_reload_address now defined here, REG_MODE_OK_FOR_BASE_P
- is now used here. */
-#ifndef REG_MODE_OK_FOR_BASE_P
-#define REG_MODE_OK_FOR_BASE_P(REGNO, MODE) REG_OK_FOR_BASE_P (REGNO)
-#endif
-
/* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
replace the input X, or the original X if no replacement is called for.
The output parameter *WIN is 1 if the calling macro should goto WIN,
@@ -4307,7 +4299,7 @@ rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
if (GET_CODE (x) == PLUS
&& GET_CODE (XEXP (x, 0)) == REG
&& REGNO (XEXP (x, 0)) < 32
- && REG_MODE_OK_FOR_BASE_P (XEXP (x, 0), mode)
+ && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
&& GET_CODE (XEXP (x, 1)) == CONST_INT
&& (INTVAL (XEXP (x, 1)) & 3) != 0
&& !ALTIVEC_VECTOR_MODE (mode)
@@ -4325,7 +4317,7 @@ rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
if (GET_CODE (x) == PLUS
&& GET_CODE (XEXP (x, 0)) == REG
&& REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
- && REG_MODE_OK_FOR_BASE_P (XEXP (x, 0), mode)
+ && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
&& GET_CODE (XEXP (x, 1)) == CONST_INT
&& !SPE_VECTOR_MODE (mode)
&& !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
@@ -4429,7 +4421,7 @@ rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
return x;
}
-/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
+/* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
that is a valid memory address for an instruction.
The MODE argument is the machine mode for the MEM expression
that wants to use this address.
@@ -4446,8 +4438,8 @@ rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
because adjacent memory cells are accessed by adding word-sized offsets
during assembly output. */
-int
-rs6000_legitimate_address (enum machine_mode mode, rtx x, int reg_ok_strict)
+bool
+rs6000_legitimate_address_p (enum machine_mode mode, rtx x, bool reg_ok_strict)
{
/* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
if (TARGET_ALTIVEC
@@ -5243,14 +5235,6 @@ rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
&& ! legitimate_constant_pool_address_p (operands[1])
&& ! toc_relative_expr_p (operands[1]))
{
- /* Emit a USE operation so that the constant isn't deleted if
- expensive optimizations are turned on because nobody
- references it. This should only be done for operands that
- contain SYMBOL_REFs with CONSTANT_POOL_ADDRESS_P set.
- This should not be done for operands that contain LABEL_REFs.
- For now, we just handle the obvious case. */
- if (GET_CODE (operands[1]) != LABEL_REF)
- emit_use (operands[1]);
#if TARGET_MACHO
/* Darwin uses a special PIC legitimizer. */
@@ -6872,19 +6856,22 @@ rs6000_build_builtin_va_list (void)
return build_pointer_type (char_type_node);
record = (*lang_hooks.types.make_type) (RECORD_TYPE);
- type_decl = build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
+ type_decl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
+ get_identifier ("__va_list_tag"), record);
- f_gpr = build_decl (FIELD_DECL, get_identifier ("gpr"),
+ f_gpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("gpr"),
unsigned_char_type_node);
- f_fpr = build_decl (FIELD_DECL, get_identifier ("fpr"),
+ f_fpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("fpr"),
unsigned_char_type_node);
/* Give the two bytes of padding a name, so that -Wpadded won't warn on
every user file. */
- f_res = build_decl (FIELD_DECL, get_identifier ("reserved"),
- short_unsigned_type_node);
- f_ovf = build_decl (FIELD_DECL, get_identifier ("overflow_arg_area"),
+ f_res = build_decl (BUILTINS_LOCATION, FIELD_DECL,
+ get_identifier ("reserved"), short_unsigned_type_node);
+ f_ovf = build_decl (BUILTINS_LOCATION, FIELD_DECL,
+ get_identifier ("overflow_arg_area"),
ptr_type_node);
- f_sav = build_decl (FIELD_DECL, get_identifier ("reg_save_area"),
+ f_sav = build_decl (BUILTINS_LOCATION, FIELD_DECL,
+ get_identifier ("reg_save_area"),
ptr_type_node);
va_list_gpr_counter_field = f_gpr;
@@ -7105,8 +7092,8 @@ rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
align = 16;
else
{
- lab_false = create_artificial_label ();
- lab_over = create_artificial_label ();
+ lab_false = create_artificial_label (input_location);
+ lab_over = create_artificial_label (input_location);
/* Long long and SPE vectors are aligned in the registers.
As are any other 2 gpr item such as complex int due to a
@@ -9436,19 +9423,22 @@ rs6000_init_builtins (void)
float_type_internal_node = float_type_node;
void_type_internal_node = void_type_node;
- tdecl = build_decl (TYPE_DECL, get_identifier ("__bool char"),
+ tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
+ get_identifier ("__bool char"),
bool_char_type_node);
TYPE_NAME (bool_char_type_node) = tdecl;
(*lang_hooks.decls.pushdecl) (tdecl);
- tdecl = build_decl (TYPE_DECL, get_identifier ("__bool short"),
+ tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
+ get_identifier ("__bool short"),
bool_short_type_node);
TYPE_NAME (bool_short_type_node) = tdecl;
(*lang_hooks.decls.pushdecl) (tdecl);
- tdecl = build_decl (TYPE_DECL, get_identifier ("__bool int"),
+ tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
+ get_identifier ("__bool int"),
bool_int_type_node);
TYPE_NAME (bool_int_type_node) = tdecl;
(*lang_hooks.decls.pushdecl) (tdecl);
- tdecl = build_decl (TYPE_DECL, get_identifier ("__pixel"),
+ tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, get_identifier ("__pixel"),
pixel_type_node);
TYPE_NAME (pixel_type_node) = tdecl;
(*lang_hooks.decls.pushdecl) (tdecl);
@@ -9458,50 +9448,61 @@ rs6000_init_builtins (void)
bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
- tdecl = build_decl (TYPE_DECL, get_identifier ("__vector unsigned char"),
+ tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
+ get_identifier ("__vector unsigned char"),
unsigned_V16QI_type_node);
TYPE_NAME (unsigned_V16QI_type_node) = tdecl;
(*lang_hooks.decls.pushdecl) (tdecl);
- tdecl = build_decl (TYPE_DECL, get_identifier ("__vector signed char"),
+ tdecl = build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier ("__vector signed char"),
V16QI_type_node);
TYPE_NAME (V16QI_type_node) = tdecl;
(*lang_hooks.decls.pushdecl) (tdecl);
- tdecl = build_decl (TYPE_DECL, get_identifier ("__vector __bool char"),
+ tdecl = build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier ("__vector __bool char"),
bool_V16QI_type_node);
TYPE_NAME ( bool_V16QI_type_node) = tdecl;
(*lang_hooks.decls.pushdecl) (tdecl);
- tdecl = build_decl (TYPE_DECL, get_identifier ("__vector unsigned short"),
+ tdecl = build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier ("__vector unsigned short"),
unsigned_V8HI_type_node);
TYPE_NAME (unsigned_V8HI_type_node) = tdecl;
(*lang_hooks.decls.pushdecl) (tdecl);
- tdecl = build_decl (TYPE_DECL, get_identifier ("__vector signed short"),
+ tdecl = build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier ("__vector signed short"),
V8HI_type_node);
TYPE_NAME (V8HI_type_node) = tdecl;
(*lang_hooks.decls.pushdecl) (tdecl);
- tdecl = build_decl (TYPE_DECL, get_identifier ("__vector __bool short"),
+ tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
+ get_identifier ("__vector __bool short"),
bool_V8HI_type_node);
TYPE_NAME (bool_V8HI_type_node) = tdecl;
(*lang_hooks.decls.pushdecl) (tdecl);
- tdecl = build_decl (TYPE_DECL, get_identifier ("__vector unsigned int"),
+ tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
+ get_identifier ("__vector unsigned int"),
unsigned_V4SI_type_node);
TYPE_NAME (unsigned_V4SI_type_node) = tdecl;
(*lang_hooks.decls.pushdecl) (tdecl);
- tdecl = build_decl (TYPE_DECL, get_identifier ("__vector signed int"),
+ tdecl = build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier ("__vector signed int"),
V4SI_type_node);
TYPE_NAME (V4SI_type_node) = tdecl;
(*lang_hooks.decls.pushdecl) (tdecl);
- tdecl = build_decl (TYPE_DECL, get_identifier ("__vector __bool int"),
+ tdecl = build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier ("__vector __bool int"),
bool_V4SI_type_node);
TYPE_NAME (bool_V4SI_type_node) = tdecl;
(*lang_hooks.decls.pushdecl) (tdecl);
- tdecl = build_decl (TYPE_DECL, get_identifier ("__vector float"),
+ tdecl = build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier ("__vector float"),
V4SF_type_node);
TYPE_NAME (V4SF_type_node) = tdecl;
(*lang_hooks.decls.pushdecl) (tdecl);
- tdecl = build_decl (TYPE_DECL, get_identifier ("__vector __pixel"),
+ tdecl = build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier ("__vector __pixel"),
pixel_V8HI_type_node);
TYPE_NAME (pixel_V8HI_type_node) = tdecl;
(*lang_hooks.decls.pushdecl) (tdecl);
@@ -9707,7 +9708,8 @@ spe_init_builtins (void)
SPE_BUILTIN_EVSEL_FSTSTEQ);
(*lang_hooks.decls.pushdecl)
- (build_decl (TYPE_DECL, get_identifier ("__ev64_opaque__"),
+ (build_decl (BUILTINS_LOCATION, TYPE_DECL,
+ get_identifier ("__ev64_opaque__"),
opaque_V2SI_type_node));
/* Initialize irregular SPE builtins. */
@@ -12819,21 +12821,24 @@ rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
represents the result of the compare. */
static rtx
-rs6000_generate_compare (enum rtx_code code)
+rs6000_generate_compare (rtx cmp, enum machine_mode mode)
{
enum machine_mode comp_mode;
rtx compare_result;
+ enum rtx_code code = GET_CODE (cmp);
+ rtx op0 = XEXP (cmp, 0);
+ rtx op1 = XEXP (cmp, 1);
- if (rs6000_compare_fp_p)
+ if (FLOAT_MODE_P (mode))
comp_mode = CCFPmode;
else if (code == GTU || code == LTU
|| code == GEU || code == LEU)
comp_mode = CCUNSmode;
else if ((code == EQ || code == NE)
- && GET_CODE (rs6000_compare_op0) == SUBREG
- && GET_CODE (rs6000_compare_op1) == SUBREG
- && SUBREG_PROMOTED_UNSIGNED_P (rs6000_compare_op0)
- && SUBREG_PROMOTED_UNSIGNED_P (rs6000_compare_op1))
+ && GET_CODE (op0) == SUBREG
+ && GET_CODE (op1) == SUBREG
+ && SUBREG_PROMOTED_UNSIGNED_P (op0)
+ && SUBREG_PROMOTED_UNSIGNED_P (op1))
/* These are unsigned values, perhaps there will be a later
ordering compare that can be shared with this one.
Unfortunately we cannot detect the signedness of the operands
@@ -12847,13 +12852,13 @@ rs6000_generate_compare (enum rtx_code code)
/* E500 FP compare instructions on the GPRs. Yuck! */
if ((!TARGET_FPRS && TARGET_HARD_FLOAT)
- && rs6000_compare_fp_p)
+ && FLOAT_MODE_P (mode))
{
rtx cmp, or_result, compare_result2;
- enum machine_mode op_mode = GET_MODE (rs6000_compare_op0);
+ enum machine_mode op_mode = GET_MODE (op0);
if (op_mode == VOIDmode)
- op_mode = GET_MODE (rs6000_compare_op1);
+ op_mode = GET_MODE (op1);
/* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
This explains the following mess. */
@@ -12865,26 +12870,20 @@ rs6000_generate_compare (enum rtx_code code)
{
case SFmode:
cmp = (flag_finite_math_only && !flag_trapping_math)
- ? gen_tstsfeq_gpr (compare_result, rs6000_compare_op0,
- rs6000_compare_op1)
- : gen_cmpsfeq_gpr (compare_result, rs6000_compare_op0,
- rs6000_compare_op1);
+ ? gen_tstsfeq_gpr (compare_result, op0, op1)
+ : gen_cmpsfeq_gpr (compare_result, op0, op1);
break;
case DFmode:
cmp = (flag_finite_math_only && !flag_trapping_math)
- ? gen_tstdfeq_gpr (compare_result, rs6000_compare_op0,
- rs6000_compare_op1)
- : gen_cmpdfeq_gpr (compare_result, rs6000_compare_op0,
- rs6000_compare_op1);
+ ? gen_tstdfeq_gpr (compare_result, op0, op1)
+ : gen_cmpdfeq_gpr (compare_result, op0, op1);
break;
case TFmode:
cmp = (flag_finite_math_only && !flag_trapping_math)
- ? gen_tsttfeq_gpr (compare_result, rs6000_compare_op0,
- rs6000_compare_op1)
- : gen_cmptfeq_gpr (compare_result, rs6000_compare_op0,
- rs6000_compare_op1);
+ ? gen_tsttfeq_gpr (compare_result, op0, op1)
+ : gen_cmptfeq_gpr (compare_result, op0, op1);
break;
default:
@@ -12897,26 +12896,20 @@ rs6000_generate_compare (enum rtx_code code)
{
case SFmode:
cmp = (flag_finite_math_only && !flag_trapping_math)
- ? gen_tstsfgt_gpr (compare_result, rs6000_compare_op0,
- rs6000_compare_op1)
- : gen_cmpsfgt_gpr (compare_result, rs6000_compare_op0,
- rs6000_compare_op1);
+ ? gen_tstsfgt_gpr (compare_result, op0, op1)
+ : gen_cmpsfgt_gpr (compare_result, op0, op1);
break;
case DFmode:
cmp = (flag_finite_math_only && !flag_trapping_math)
- ? gen_tstdfgt_gpr (compare_result, rs6000_compare_op0,
- rs6000_compare_op1)
- : gen_cmpdfgt_gpr (compare_result, rs6000_compare_op0,
- rs6000_compare_op1);
+ ? gen_tstdfgt_gpr (compare_result, op0, op1)
+ : gen_cmpdfgt_gpr (compare_result, op0, op1);
break;
case TFmode:
cmp = (flag_finite_math_only && !flag_trapping_math)
- ? gen_tsttfgt_gpr (compare_result, rs6000_compare_op0,
- rs6000_compare_op1)
- : gen_cmptfgt_gpr (compare_result, rs6000_compare_op0,
- rs6000_compare_op1);
+ ? gen_tsttfgt_gpr (compare_result, op0, op1)
+ : gen_cmptfgt_gpr (compare_result, op0, op1);
break;
default:
@@ -12929,26 +12922,20 @@ rs6000_generate_compare (enum rtx_code code)
{
case SFmode:
cmp = (flag_finite_math_only && !flag_trapping_math)
- ? gen_tstsflt_gpr (compare_result, rs6000_compare_op0,
- rs6000_compare_op1)
- : gen_cmpsflt_gpr (compare_result, rs6000_compare_op0,
- rs6000_compare_op1);
+ ? gen_tstsflt_gpr (compare_result, op0, op1)
+ : gen_cmpsflt_gpr (compare_result, op0, op1);
break;
case DFmode:
cmp = (flag_finite_math_only && !flag_trapping_math)
- ? gen_tstdflt_gpr (compare_result, rs6000_compare_op0,
- rs6000_compare_op1)
- : gen_cmpdflt_gpr (compare_result, rs6000_compare_op0,
- rs6000_compare_op1);
+ ? gen_tstdflt_gpr (compare_result, op0, op1)
+ : gen_cmpdflt_gpr (compare_result, op0, op1);
break;
case TFmode:
cmp = (flag_finite_math_only && !flag_trapping_math)
- ? gen_tsttflt_gpr (compare_result, rs6000_compare_op0,
- rs6000_compare_op1)
- : gen_cmptflt_gpr (compare_result, rs6000_compare_op0,
- rs6000_compare_op1);
+ ? gen_tsttflt_gpr (compare_result, op0, op1)
+ : gen_cmptflt_gpr (compare_result, op0, op1);
break;
default:
@@ -12980,26 +12967,20 @@ rs6000_generate_compare (enum rtx_code code)
{
case SFmode:
cmp = (flag_finite_math_only && !flag_trapping_math)
- ? gen_tstsfeq_gpr (compare_result2, rs6000_compare_op0,
- rs6000_compare_op1)
- : gen_cmpsfeq_gpr (compare_result2, rs6000_compare_op0,
- rs6000_compare_op1);
+ ? gen_tstsfeq_gpr (compare_result2, op0, op1)
+ : gen_cmpsfeq_gpr (compare_result2, op0, op1);
break;
case DFmode:
cmp = (flag_finite_math_only && !flag_trapping_math)
- ? gen_tstdfeq_gpr (compare_result2, rs6000_compare_op0,
- rs6000_compare_op1)
- : gen_cmpdfeq_gpr (compare_result2, rs6000_compare_op0,
- rs6000_compare_op1);
+ ? gen_tstdfeq_gpr (compare_result2, op0, op1)
+ : gen_cmpdfeq_gpr (compare_result2, op0, op1);
break;
case TFmode:
cmp = (flag_finite_math_only && !flag_trapping_math)
- ? gen_tsttfeq_gpr (compare_result2, rs6000_compare_op0,
- rs6000_compare_op1)
- : gen_cmptfeq_gpr (compare_result2, rs6000_compare_op0,
- rs6000_compare_op1);
+ ? gen_tsttfeq_gpr (compare_result2, op0, op1)
+ : gen_cmptfeq_gpr (compare_result2, op0, op1);
break;
default:
@@ -13029,16 +13010,14 @@ rs6000_generate_compare (enum rtx_code code)
/* Generate XLC-compatible TFmode compare as PARALLEL with extra
CLOBBERs to match cmptf_internal2 pattern. */
if (comp_mode == CCFPmode && TARGET_XL_COMPAT
- && GET_MODE (rs6000_compare_op0) == TFmode
+ && GET_MODE (op0) == TFmode
&& !TARGET_IEEEQUAD
&& TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
emit_insn (gen_rtx_PARALLEL (VOIDmode,
gen_rtvec (9,
gen_rtx_SET (VOIDmode,
compare_result,
- gen_rtx_COMPARE (comp_mode,
- rs6000_compare_op0,
- rs6000_compare_op1)),
+ gen_rtx_COMPARE (comp_mode, op0, op1)),
gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
@@ -13047,29 +13026,25 @@ rs6000_generate_compare (enum rtx_code code)
gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)))));
- else if (GET_CODE (rs6000_compare_op1) == UNSPEC
- && XINT (rs6000_compare_op1, 1) == UNSPEC_SP_TEST)
+ else if (GET_CODE (op1) == UNSPEC
+ && XINT (op1, 1) == UNSPEC_SP_TEST)
{
- rtx op1 = XVECEXP (rs6000_compare_op1, 0, 0);
+ rtx op1b = XVECEXP (op1, 0, 0);
comp_mode = CCEQmode;
compare_result = gen_reg_rtx (CCEQmode);
if (TARGET_64BIT)
- emit_insn (gen_stack_protect_testdi (compare_result,
- rs6000_compare_op0, op1));
+ emit_insn (gen_stack_protect_testdi (compare_result, op0, op1b));
else
- emit_insn (gen_stack_protect_testsi (compare_result,
- rs6000_compare_op0, op1));
+ emit_insn (gen_stack_protect_testsi (compare_result, op0, op1b));
}
else
emit_insn (gen_rtx_SET (VOIDmode, compare_result,
- gen_rtx_COMPARE (comp_mode,
- rs6000_compare_op0,
- rs6000_compare_op1)));
+ gen_rtx_COMPARE (comp_mode, op0, op1)));
}
/* Some kinds of FP comparisons need an OR operation;
under flag_finite_math_only we don't bother. */
- if (rs6000_compare_fp_p
+ if (FLOAT_MODE_P (mode)
&& !flag_finite_math_only
&& !(TARGET_HARD_FLOAT && !TARGET_FPRS)
&& (code == LE || code == GE
@@ -13112,16 +13087,17 @@ rs6000_generate_compare (enum rtx_code code)
/* Emit the RTL for an sCOND pattern. */
void
-rs6000_emit_sCOND (enum rtx_code code, rtx result)
+rs6000_emit_sCOND (enum machine_mode mode, rtx operands[])
{
rtx condition_rtx;
enum machine_mode op_mode;
enum rtx_code cond_code;
+ rtx result = operands[0];
- condition_rtx = rs6000_generate_compare (code);
+ condition_rtx = rs6000_generate_compare (operands[1], mode);
cond_code = GET_CODE (condition_rtx);
- if (rs6000_compare_fp_p
+ if (FLOAT_MODE_P (mode)
&& !TARGET_FPRS && TARGET_HARD_FLOAT)
{
rtx t;
@@ -13156,11 +13132,11 @@ rs6000_emit_sCOND (enum rtx_code code, rtx result)
condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
}
- op_mode = GET_MODE (rs6000_compare_op0);
+ op_mode = GET_MODE (XEXP (operands[1], 0));
if (op_mode == VOIDmode)
- op_mode = GET_MODE (rs6000_compare_op1);
+ op_mode = GET_MODE (XEXP (operands[1], 1));
- if (TARGET_POWERPC64 && (op_mode == DImode || rs6000_compare_fp_p))
+ if (TARGET_POWERPC64 && (op_mode == DImode || FLOAT_MODE_P (mode)))
{
PUT_MODE (condition_rtx, DImode);
convert_move (result, condition_rtx, 0);
@@ -13175,12 +13151,12 @@ rs6000_emit_sCOND (enum rtx_code code, rtx result)
/* Emit a branch of kind CODE to location LOC. */
void
-rs6000_emit_cbranch (enum rtx_code code, rtx loc)
+rs6000_emit_cbranch (enum machine_mode mode, rtx operands[])
{
rtx condition_rtx, loc_ref;
- condition_rtx = rs6000_generate_compare (code);
- loc_ref = gen_rtx_LABEL_REF (VOIDmode, loc);
+ condition_rtx = rs6000_generate_compare (operands[0], mode);
+ loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
loc_ref, pc_rtx)));
@@ -13626,8 +13602,8 @@ int
rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
{
enum rtx_code code = GET_CODE (op);
- rtx op0 = rs6000_compare_op0;
- rtx op1 = rs6000_compare_op1;
+ rtx op0 = XEXP (op, 0);
+ rtx op1 = XEXP (op, 1);
REAL_VALUE_TYPE c1;
enum machine_mode compare_mode = GET_MODE (op0);
enum machine_mode result_mode = GET_MODE (dest);
@@ -13647,7 +13623,7 @@ rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
/* First, work out if the hardware can do this at all, or
if it's too slow.... */
- if (! rs6000_compare_fp_p)
+ if (!FLOAT_MODE_P (compare_mode))
{
if (TARGET_ISEL)
return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
@@ -13812,13 +13788,13 @@ rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
rtx condition_rtx, cr;
/* All isel implementations thus far are 32-bits. */
- if (GET_MODE (rs6000_compare_op0) != SImode)
+ if (GET_MODE (XEXP (op, 0)) != SImode)
return 0;
/* We still have to do the compare, because isel doesn't do a
compare, it just looks at the CRx bits set by a previous compare
instruction. */
- condition_rtx = rs6000_generate_compare (GET_CODE (op));
+ condition_rtx = rs6000_generate_compare (op, SImode);
cr = XEXP (condition_rtx, 0);
if (GET_MODE (cr) == CCmode)
@@ -15959,7 +15935,7 @@ rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep, bool gpr, bool exit
stack pointer, but move the base of the frame into r11 for use by
out-of-line register restore routines. */
-static void
+static rtx
rs6000_emit_stack_reset (rs6000_stack_t *info,
rtx sp_reg_rtx, rtx frame_reg_rtx,
int sp_offset, bool savres)
@@ -15975,10 +15951,10 @@ rs6000_emit_stack_reset (rs6000_stack_t *info,
if (frame_reg_rtx != sp_reg_rtx)
{
if (sp_offset != 0)
- emit_insn (gen_addsi3 (sp_reg_rtx, frame_reg_rtx,
- GEN_INT (sp_offset)));
+ return emit_insn (gen_addsi3 (sp_reg_rtx, frame_reg_rtx,
+ GEN_INT (sp_offset)));
else if (!savres)
- emit_move_insn (sp_reg_rtx, frame_reg_rtx);
+ return emit_move_insn (sp_reg_rtx, frame_reg_rtx);
}
else if (sp_offset != 0)
{
@@ -15990,12 +15966,12 @@ rs6000_emit_stack_reset (rs6000_stack_t *info,
? gen_rtx_REG (Pmode, 11)
: sp_reg_rtx);
- emit_insn (TARGET_32BIT
- ? gen_addsi3 (dest_reg, sp_reg_rtx,
- GEN_INT (sp_offset))
- : gen_adddi3 (dest_reg, sp_reg_rtx,
- GEN_INT (sp_offset)));
+ rtx insn = emit_insn (gen_add3_insn (dest_reg, sp_reg_rtx,
+ GEN_INT (sp_offset)));
+ if (!savres)
+ return insn;
}
+ return NULL_RTX;
}
/* Construct a parallel rtx describing the effect of a call to an
@@ -16905,12 +16881,19 @@ rs6000_restore_saved_cr (rtx reg, int using_mfcr_multiple)
}
}
-/* Emit function epilogue as insns.
+/* Return true if OFFSET from stack pointer can be clobbered by signals.
+ V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
+ below stack pointer not cloberred by signals. */
+
+static inline bool
+offset_below_red_zone_p (HOST_WIDE_INT offset)
+{
+ return offset < (DEFAULT_ABI == ABI_V4
+ ? 0
+ : TARGET_32BIT ? -220 : -288);
+}
- At present, dwarf2out_frame_debug_expr doesn't understand
- register restores, so we don't bother setting RTX_FRAME_RELATED_P
- anywhere in the epilogue. Most of the insns below would in any case
- need special notes to explain where r11 is in relation to the stack. */
+/* Emit function epilogue as insns. */
void
rs6000_emit_epilogue (int sibcall)
@@ -16926,6 +16909,8 @@ rs6000_emit_epilogue (int sibcall)
int sp_offset = 0;
rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
rtx frame_reg_rtx = sp_reg_rtx;
+ rtx cfa_restores = NULL_RTX;
+ rtx insn;
enum machine_mode reg_mode = Pmode;
int reg_size = TARGET_32BIT ? 4 : 8;
int i;
@@ -17066,7 +17051,7 @@ rs6000_emit_epilogue (int sibcall)
&& info->altivec_size != 0
&& (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
|| (DEFAULT_ABI != ABI_V4
- && info->altivec_save_offset < (TARGET_32BIT ? -220 : -288))))
+ && offset_below_red_zone_p (info->altivec_save_offset))))
{
int i;
@@ -17083,7 +17068,7 @@ rs6000_emit_epilogue (int sibcall)
for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
{
- rtx addr, areg, mem;
+ rtx addr, areg, mem, reg;
areg = gen_rtx_REG (Pmode, 0);
emit_move_insn
@@ -17095,7 +17080,13 @@ rs6000_emit_epilogue (int sibcall)
addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
mem = gen_frame_mem (V4SImode, addr);
- emit_move_insn (gen_rtx_REG (V4SImode, i), mem);
+ reg = gen_rtx_REG (V4SImode, i);
+ emit_move_insn (reg, mem);
+ if (offset_below_red_zone_p (info->altivec_save_offset
+ + (i - info->first_altivec_reg_save)
+ * 16))
+ cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
+ cfa_restores);
}
}
@@ -17105,7 +17096,7 @@ rs6000_emit_epilogue (int sibcall)
&& info->vrsave_mask != 0
&& (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
|| (DEFAULT_ABI != ABI_V4
- && info->vrsave_save_offset < (TARGET_32BIT ? -220 : -288))))
+ && offset_below_red_zone_p (info->vrsave_save_offset))))
{
rtx addr, mem, reg;
@@ -17131,6 +17122,7 @@ rs6000_emit_epilogue (int sibcall)
emit_insn (generate_set_vrsave (reg, info, 1));
}
+ insn = NULL_RTX;
/* If we have a large stack frame, restore the old stack pointer
using the backchain. */
if (use_backchain_to_restore_sp)
@@ -17142,8 +17134,8 @@ rs6000_emit_epilogue (int sibcall)
if (DEFAULT_ABI == ABI_V4)
frame_reg_rtx = gen_rtx_REG (Pmode, 11);
- emit_move_insn (frame_reg_rtx,
- gen_rtx_MEM (Pmode, sp_reg_rtx));
+ insn = emit_move_insn (frame_reg_rtx,
+ gen_rtx_MEM (Pmode, sp_reg_rtx));
sp_offset = 0;
}
else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
@@ -17152,7 +17144,7 @@ rs6000_emit_epilogue (int sibcall)
;
else
{
- emit_move_insn (sp_reg_rtx, frame_reg_rtx);
+ insn = emit_move_insn (sp_reg_rtx, frame_reg_rtx);
frame_reg_rtx = sp_reg_rtx;
}
}
@@ -17164,38 +17156,42 @@ rs6000_emit_epilogue (int sibcall)
if (DEFAULT_ABI == ABI_V4)
frame_reg_rtx = gen_rtx_REG (Pmode, 11);
- emit_insn (TARGET_32BIT
- ? gen_addsi3 (frame_reg_rtx, hard_frame_pointer_rtx,
- GEN_INT (info->total_size))
- : gen_adddi3 (frame_reg_rtx, hard_frame_pointer_rtx,
- GEN_INT (info->total_size)));
+ insn = emit_insn (gen_add3_insn (frame_reg_rtx, hard_frame_pointer_rtx,
+ GEN_INT (info->total_size)));
sp_offset = 0;
}
else if (info->push_p
&& DEFAULT_ABI != ABI_V4
&& !crtl->calls_eh_return)
{
- emit_insn (TARGET_32BIT
- ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
- GEN_INT (info->total_size))
- : gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
- GEN_INT (info->total_size)));
+ insn = emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx,
+ GEN_INT (info->total_size)));
sp_offset = 0;
}
+ if (insn && frame_reg_rtx == sp_reg_rtx)
+ {
+ if (cfa_restores)
+ {
+ REG_NOTES (insn) = cfa_restores;
+ cfa_restores = NULL_RTX;
+ }
+ add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
+ RTX_FRAME_RELATED_P (insn) = 1;
+ }
/* Restore AltiVec registers if we have not done so already. */
if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
&& TARGET_ALTIVEC_ABI
&& info->altivec_size != 0
&& (DEFAULT_ABI == ABI_V4
- || info->altivec_save_offset >= (TARGET_32BIT ? -220 : -288)))
+ || !offset_below_red_zone_p (info->altivec_save_offset)))
{
int i;
for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
{
- rtx addr, areg, mem;
+ rtx addr, areg, mem, reg;
areg = gen_rtx_REG (Pmode, 0);
emit_move_insn
@@ -17207,7 +17203,11 @@ rs6000_emit_epilogue (int sibcall)
addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
mem = gen_frame_mem (V4SImode, addr);
- emit_move_insn (gen_rtx_REG (V4SImode, i), mem);
+ reg = gen_rtx_REG (V4SImode, i);
+ emit_move_insn (reg, mem);
+ if (DEFAULT_ABI == ABI_V4)
+ cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
+ cfa_restores);
}
}
@@ -17217,7 +17217,7 @@ rs6000_emit_epilogue (int sibcall)
&& TARGET_ALTIVEC_VRSAVE
&& info->vrsave_mask != 0
&& (DEFAULT_ABI == ABI_V4
- || info->vrsave_save_offset >= (TARGET_32BIT ? -220 : -288)))
+ || !offset_below_red_zone_p (info->vrsave_save_offset)))
{
rtx addr, mem, reg;
@@ -17250,7 +17250,8 @@ rs6000_emit_epilogue (int sibcall)
emit_move_insn (gen_rtx_REG (SImode, 12), mem);
}
- /* Set LR here to try to overlap restores below. */
+ /* Set LR here to try to overlap restores below. LR is always saved
+ above incoming stack, so it never needs REG_CFA_RESTORE. */
if (restore_lr)
emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
gen_rtx_REG (Pmode, 0));
@@ -17332,7 +17333,7 @@ rs6000_emit_epilogue (int sibcall)
for (i = 0; i < 32 - info->first_gp_reg_save; i++)
if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
{
- rtx offset, addr, mem;
+ rtx offset, addr, mem, reg;
/* We're doing all this to ensure that the immediate offset
fits into the immediate field of 'evldd'. */
@@ -17341,9 +17342,24 @@ rs6000_emit_epilogue (int sibcall)
offset = GEN_INT (spe_offset + reg_size * i);
addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset);
mem = gen_rtx_MEM (V2SImode, addr);
+ reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
- emit_move_insn (gen_rtx_REG (reg_mode, info->first_gp_reg_save + i),
- mem);
+ insn = emit_move_insn (reg, mem);
+ if (DEFAULT_ABI == ABI_V4)
+ {
+ if (frame_pointer_needed
+ && info->first_gp_reg_save + i
+ == HARD_FRAME_POINTER_REGNUM)
+ {
+ add_reg_note (insn, REG_CFA_DEF_CFA,
+ plus_constant (frame_reg_rtx,
+ sp_offset));
+ RTX_FRAME_RELATED_P (insn) = 1;
+ }
+
+ cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
+ cfa_restores);
+ }
}
}
else
@@ -17355,7 +17371,6 @@ rs6000_emit_epilogue (int sibcall)
/*savep=*/false, /*gpr=*/true,
/*exitp=*/true);
emit_jump_insn (par);
-
/* We don't want anybody else emitting things after we jumped
back. */
return;
@@ -17384,8 +17399,15 @@ rs6000_emit_epilogue (int sibcall)
if (can_use_exit)
{
if (info->cr_save_p)
- rs6000_restore_saved_cr (gen_rtx_REG (SImode, 12),
- using_mtcr_multiple);
+ {
+ rs6000_restore_saved_cr (gen_rtx_REG (SImode, 12),
+ using_mtcr_multiple);
+ if (DEFAULT_ABI == ABI_V4)
+ cfa_restores
+ = alloc_reg_note (REG_CFA_RESTORE,
+ gen_rtx_REG (SImode, CR2_REGNO),
+ cfa_restores);
+ }
emit_jump_insn (par);
@@ -17393,8 +17415,22 @@ rs6000_emit_epilogue (int sibcall)
back. */
return;
}
- else
- emit_insn (par);
+
+ insn = emit_insn (par);
+ if (DEFAULT_ABI == ABI_V4)
+ {
+ if (frame_pointer_needed)
+ {
+ add_reg_note (insn, REG_CFA_DEF_CFA,
+ plus_constant (frame_reg_rtx, sp_offset));
+ RTX_FRAME_RELATED_P (insn) = 1;
+ }
+
+ for (i = info->first_gp_reg_save; i < 32; i++)
+ cfa_restores
+ = alloc_reg_note (REG_CFA_RESTORE,
+ gen_rtx_REG (reg_mode, i), cfa_restores);
+ }
}
else if (using_load_multiple)
{
@@ -17407,13 +17443,20 @@ rs6000_emit_epilogue (int sibcall)
+ sp_offset
+ reg_size * i));
rtx mem = gen_frame_mem (reg_mode, addr);
+ rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
- RTVEC_ELT (p, i) =
- gen_rtx_SET (VOIDmode,
- gen_rtx_REG (reg_mode, info->first_gp_reg_save + i),
- mem);
+ RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, reg, mem);
+ if (DEFAULT_ABI == ABI_V4)
+ cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
+ cfa_restores);
+ }
+ insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
+ if (DEFAULT_ABI == ABI_V4 && frame_pointer_needed)
+ {
+ add_reg_note (insn, REG_CFA_DEF_CFA,
+ plus_constant (frame_reg_rtx, sp_offset));
+ RTX_FRAME_RELATED_P (insn) = 1;
}
- emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
}
else
{
@@ -17425,9 +17468,23 @@ rs6000_emit_epilogue (int sibcall)
+ sp_offset
+ reg_size * i));
rtx mem = gen_frame_mem (reg_mode, addr);
+ rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
- emit_move_insn (gen_rtx_REG (reg_mode,
- info->first_gp_reg_save + i), mem);
+ insn = emit_move_insn (reg, mem);
+ if (DEFAULT_ABI == ABI_V4)
+ {
+ if (frame_pointer_needed
+ && info->first_gp_reg_save + i
+ == HARD_FRAME_POINTER_REGNUM)
+ {
+ add_reg_note (insn, REG_CFA_DEF_CFA,
+ plus_constant (frame_reg_rtx, sp_offset));
+ RTX_FRAME_RELATED_P (insn) = 1;
+ }
+
+ cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
+ cfa_restores);
+ }
}
}
@@ -17437,36 +17494,52 @@ rs6000_emit_epilogue (int sibcall)
if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
&& ! call_used_regs[info->first_fp_reg_save+i]))
{
- rtx addr, mem;
+ rtx addr, mem, reg;
addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
GEN_INT (info->fp_save_offset
+ sp_offset
+ 8 * i));
mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
? DFmode : SFmode), addr);
+ reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
+ ? DFmode : SFmode),
+ info->first_fp_reg_save + i);
- emit_move_insn (gen_rtx_REG (((TARGET_HARD_FLOAT
- && TARGET_DOUBLE_FLOAT)
- ? DFmode : SFmode),
- info->first_fp_reg_save + i),
- mem);
+ emit_move_insn (reg, mem);
+ if (DEFAULT_ABI == ABI_V4)
+ cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
+ cfa_restores);
}
/* If we saved cr, restore it here. Just those that were used. */
if (info->cr_save_p)
- rs6000_restore_saved_cr (gen_rtx_REG (SImode, 12), using_mtcr_multiple);
+ {
+ rs6000_restore_saved_cr (gen_rtx_REG (SImode, 12), using_mtcr_multiple);
+ if (DEFAULT_ABI == ABI_V4)
+ cfa_restores
+ = alloc_reg_note (REG_CFA_RESTORE, gen_rtx_REG (SImode, CR2_REGNO),
+ cfa_restores);
+ }
/* If this is V.4, unwind the stack pointer after all of the loads
have been done. */
- rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
- sp_offset, !restoring_FPRs_inline);
+ insn = rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
+ sp_offset, !restoring_FPRs_inline);
+ if (insn)
+ {
+ if (cfa_restores)
+ {
+ REG_NOTES (insn) = cfa_restores;
+ cfa_restores = NULL_RTX;
+ }
+ add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
+ RTX_FRAME_RELATED_P (insn) = 1;
+ }
if (crtl->calls_eh_return)
{
rtx sa = EH_RETURN_STACKADJ_RTX;
- emit_insn (TARGET_32BIT
- ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx, sa)
- : gen_adddi3 (sp_reg_rtx, sp_reg_rtx, sa));
+ emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa));
}
if (!sibcall)
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index f11ea1fe249..c50060026c5 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -1722,6 +1722,19 @@ typedef struct rs6000_args
: (reg_renumber[REGNO] > 0 \
&& (reg_renumber[REGNO] <= 31 || reg_renumber[REGNO] == 67 \
|| reg_renumber[REGNO] == FRAME_POINTER_REGNUM)))
+
+/* Nonzero if X is a hard reg that can be used as an index
+ or if it is a pseudo reg in the non-strict case. */
+#define INT_REG_OK_FOR_INDEX_P(X, STRICT) \
+ ((!(STRICT) && REGNO (X) >= FIRST_PSEUDO_REGISTER) \
+ || REGNO_OK_FOR_INDEX_P (REGNO (X)))
+
+/* Nonzero if X is a hard reg that can be used as a base reg
+ or if it is a pseudo reg in the non-strict case. */
+#define INT_REG_OK_FOR_BASE_P(X, STRICT) \
+ ((!(STRICT) && REGNO (X) >= FIRST_PSEUDO_REGISTER) \
+ || REGNO_OK_FOR_BASE_P (REGNO (X)))
+
/* Maximum number of registers that can appear in a valid memory address. */
@@ -1755,62 +1768,6 @@ typedef struct rs6000_args
&& EASY_VECTOR_15((n) >> 1) \
&& ((n) & 1) == 0)
-/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
- and check its validity for a certain class.
- We have two alternate definitions for each of them.
- The usual definition accepts all pseudo regs; the other rejects
- them unless they have been allocated suitable hard regs.
- The symbol REG_OK_STRICT causes the latter definition to be used.
-
- Most source files want to accept pseudo regs in the hope that
- they will get allocated to the class that the insn wants them to be in.
- Source files for reload pass need to be strict.
- After reload, it makes no difference, since pseudo regs have
- been eliminated by then. */
-
-#ifdef REG_OK_STRICT
-# define REG_OK_STRICT_FLAG 1
-#else
-# define REG_OK_STRICT_FLAG 0
-#endif
-
-/* Nonzero if X is a hard reg that can be used as an index
- or if it is a pseudo reg in the non-strict case. */
-#define INT_REG_OK_FOR_INDEX_P(X, STRICT) \
- ((!(STRICT) && REGNO (X) >= FIRST_PSEUDO_REGISTER) \
- || REGNO_OK_FOR_INDEX_P (REGNO (X)))
-
-/* Nonzero if X is a hard reg that can be used as a base reg
- or if it is a pseudo reg in the non-strict case. */
-#define INT_REG_OK_FOR_BASE_P(X, STRICT) \
- ((!(STRICT) && REGNO (X) >= FIRST_PSEUDO_REGISTER) \
- || REGNO_OK_FOR_BASE_P (REGNO (X)))
-
-#define REG_OK_FOR_INDEX_P(X) INT_REG_OK_FOR_INDEX_P (X, REG_OK_STRICT_FLAG)
-#define REG_OK_FOR_BASE_P(X) INT_REG_OK_FOR_BASE_P (X, REG_OK_STRICT_FLAG)
-
-/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
- that is a valid memory address for an instruction.
- The MODE argument is the machine mode for the MEM expression
- that wants to use this address.
-
- On the RS/6000, there are four valid addresses: a SYMBOL_REF that
- refers to a constant pool entry of an address (or the sum of it
- plus a constant), a short (16-bit signed) constant plus a register,
- the sum of two registers, or a register indirect, possibly with an
- auto-increment. For DFmode, DDmode and DImode with a constant plus
- register, we must ensure that both words are addressable or PowerPC64
- with offset word aligned.
-
- For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
- 32-bit DImode, TImode), indexed addressing cannot be used because
- adjacent memory cells are accessed by adding word-sized offsets
- during assembly output. */
-
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
-{ if (rs6000_legitimate_address (MODE, X, REG_OK_STRICT_FLAG)) \
- goto ADDR; \
-}
/* Try a machine-dependent way of reloading an illegitimate address
operand. If we find one, push the reload and jump to WIN. This
@@ -1986,12 +1943,6 @@ do { \
/* Given a condition code and a mode, return the inverse condition. */
#define REVERSE_CONDITION(CODE, MODE) rs6000_reverse_condition (MODE, CODE)
-/* Define the information needed to generate branch and scc insns. This is
- stored from the compare operation. */
-
-extern GTY(()) rtx rs6000_compare_op0;
-extern GTY(()) rtx rs6000_compare_op1;
-extern int rs6000_compare_fp_p;
/* Control the assembler format that we output. */
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index cc37d911dbb..9d4a96051b7 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -11897,262 +11897,90 @@
;; signed & unsigned, and one type of branch.
;;
;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
-;; insns, and branches. We store the operands of compares until we see
-;; how it is used.
-(define_expand "cmp<mode>"
- [(set (cc0)
- (compare (match_operand:GPR 0 "gpc_reg_operand" "")
- (match_operand:GPR 1 "reg_or_short_operand" "")))]
+;; insns, and branches.
+
+(define_expand "cbranch<mode>4"
+ [(use (match_operator 0 "rs6000_cbranch_operator"
+ [(match_operand:GPR 1 "gpc_reg_operand" "")
+ (match_operand:GPR 2 "reg_or_short_operand" "")]))
+ (use (match_operand 3 ""))]
""
"
{
- /* Take care of the possibility that operands[1] might be negative but
+ /* Take care of the possibility that operands[2] might be negative but
this might be a logical operation. That insn doesn't exist. */
- if (GET_CODE (operands[1]) == CONST_INT
- && INTVAL (operands[1]) < 0)
- operands[1] = force_reg (<MODE>mode, operands[1]);
-
- rs6000_compare_op0 = operands[0];
- rs6000_compare_op1 = operands[1];
- rs6000_compare_fp_p = 0;
- DONE;
-}")
+ if (GET_CODE (operands[2]) == CONST_INT
+ && INTVAL (operands[2]) < 0)
+ {
+ operands[2] = force_reg (<MODE>mode, operands[2]);
+ operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
+ GET_MODE (operands[0]),
+ operands[1], operands[2]);
+ }
-(define_expand "cmp<mode>"
- [(set (cc0) (compare (match_operand:FP 0 "gpc_reg_operand" "")
- (match_operand:FP 1 "gpc_reg_operand" "")))]
- ""
- "
-{
- rs6000_compare_op0 = operands[0];
- rs6000_compare_op1 = operands[1];
- rs6000_compare_fp_p = 1;
+ rs6000_emit_cbranch (<MODE>mode, operands);
DONE;
}")
-(define_expand "beq"
- [(use (match_operand 0 "" ""))]
- ""
- "{ rs6000_emit_cbranch (EQ, operands[0]); DONE; }")
-
-(define_expand "bne"
- [(use (match_operand 0 "" ""))]
- ""
- "{ rs6000_emit_cbranch (NE, operands[0]); DONE; }")
-
-(define_expand "bge"
- [(use (match_operand 0 "" ""))]
- ""
- "{ rs6000_emit_cbranch (GE, operands[0]); DONE; }")
-
-(define_expand "bgt"
- [(use (match_operand 0 "" ""))]
- ""
- "{ rs6000_emit_cbranch (GT, operands[0]); DONE; }")
-
-(define_expand "ble"
- [(use (match_operand 0 "" ""))]
- ""
- "{ rs6000_emit_cbranch (LE, operands[0]); DONE; }")
-
-(define_expand "blt"
- [(use (match_operand 0 "" ""))]
- ""
- "{ rs6000_emit_cbranch (LT, operands[0]); DONE; }")
-
-(define_expand "bgeu"
- [(use (match_operand 0 "" ""))]
- ""
- "{ rs6000_emit_cbranch (GEU, operands[0]); DONE; }")
-
-(define_expand "bgtu"
- [(use (match_operand 0 "" ""))]
- ""
- "{ rs6000_emit_cbranch (GTU, operands[0]); DONE; }")
-
-(define_expand "bleu"
- [(use (match_operand 0 "" ""))]
- ""
- "{ rs6000_emit_cbranch (LEU, operands[0]); DONE; }")
-
-(define_expand "bltu"
- [(use (match_operand 0 "" ""))]
- ""
- "{ rs6000_emit_cbranch (LTU, operands[0]); DONE; }")
-
-(define_expand "bunordered"
- [(use (match_operand 0 "" ""))]
- "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
- "{ rs6000_emit_cbranch (UNORDERED, operands[0]); DONE; }")
-
-(define_expand "bordered"
- [(use (match_operand 0 "" ""))]
- "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
- "{ rs6000_emit_cbranch (ORDERED, operands[0]); DONE; }")
-
-(define_expand "buneq"
- [(use (match_operand 0 "" ""))]
- "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
- "{ rs6000_emit_cbranch (UNEQ, operands[0]); DONE; }")
-
-(define_expand "bunge"
- [(use (match_operand 0 "" ""))]
- "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
- "{ rs6000_emit_cbranch (UNGE, operands[0]); DONE; }")
-
-(define_expand "bungt"
- [(use (match_operand 0 "" ""))]
- "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
- "{ rs6000_emit_cbranch (UNGT, operands[0]); DONE; }")
-
-(define_expand "bunle"
- [(use (match_operand 0 "" ""))]
- "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
- "{ rs6000_emit_cbranch (UNLE, operands[0]); DONE; }")
-
-(define_expand "bunlt"
- [(use (match_operand 0 "" ""))]
- "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
- "{ rs6000_emit_cbranch (UNLT, operands[0]); DONE; }")
-
-(define_expand "bltgt"
- [(use (match_operand 0 "" ""))]
- "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
- "{ rs6000_emit_cbranch (LTGT, operands[0]); DONE; }")
-
-;; For SNE, we would prefer that the xor/abs sequence be used for integers.
-;; For SEQ, likewise, except that comparisons with zero should be done
-;; with an scc insns. However, due to the order that combine see the
-;; resulting insns, we must, in fact, allow SEQ for integers. Fail in
-;; the cases we don't want to handle.
-(define_expand "seq"
- [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
- ""
- "{ rs6000_emit_sCOND (EQ, operands[0]); DONE; }")
-
-(define_expand "sne"
- [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
+(define_expand "cbranch<mode>4"
+ [(use (match_operator 0 "rs6000_cbranch_operator"
+ [(match_operand:FP 1 "gpc_reg_operand" "")
+ (match_operand:FP 2 "gpc_reg_operand" "")]))
+ (use (match_operand 3 ""))]
""
"
{
- if (! rs6000_compare_fp_p)
- FAIL;
-
- rs6000_emit_sCOND (NE, operands[0]);
+ rs6000_emit_cbranch (<MODE>mode, operands);
DONE;
}")
-;; A >= 0 is best done the portable way for A an integer.
-(define_expand "sge"
- [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
+(define_expand "cstore<mode>4"
+ [(use (match_operator 1 "rs6000_cbranch_operator"
+ [(match_operand:GPR 2 "gpc_reg_operand" "")
+ (match_operand:GPR 3 "reg_or_short_operand" "")]))
+ (clobber (match_operand:SI 0 "register_operand"))]
""
"
{
- if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
- FAIL;
-
- rs6000_emit_sCOND (GE, operands[0]);
- DONE;
-}")
+ /* Take care of the possibility that operands[3] might be negative but
+ this might be a logical operation. That insn doesn't exist. */
+ if (GET_CODE (operands[3]) == CONST_INT
+ && INTVAL (operands[3]) < 0)
+ {
+ operands[3] = force_reg (<MODE>mode, operands[3]);
+ operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
+ GET_MODE (operands[1]),
+ operands[2], operands[3]);
+ }
-;; A > 0 is best done using the portable sequence, so fail in that case.
-(define_expand "sgt"
- [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
- ""
- "
-{
- if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
+ /* For SNE, we would prefer that the xor/abs sequence be used for integers.
+ For SEQ, likewise, except that comparisons with zero should be done
+ with an scc insns. However, due to the order that combine see the
+ resulting insns, we must, in fact, allow SEQ for integers. Fail in
+ the cases we don't want to handle or are best handled by portable
+ code. */
+ if (GET_CODE (operands[1]) == NE)
FAIL;
-
- rs6000_emit_sCOND (GT, operands[0]);
- DONE;
-}")
-
-;; A <= 0 is best done the portable way for A an integer.
-(define_expand "sle"
- [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
- ""
- "
-{
- if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
+ if ((GET_CODE (operands[1]) == LT || GET_CODE (operands[1]) == LE
+ || GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == GE)
+ && operands[3] == const0_rtx)
FAIL;
-
- rs6000_emit_sCOND (LE, operands[0]);
+ rs6000_emit_sCOND (<MODE>mode, operands);
DONE;
}")
-;; A < 0 is best done in the portable way for A an integer.
-(define_expand "slt"
- [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
+(define_expand "cstore<mode>4"
+ [(use (match_operator 1 "rs6000_cbranch_operator"
+ [(match_operand:FP 2 "gpc_reg_operand" "")
+ (match_operand:FP 3 "gpc_reg_operand" "")]))
+ (clobber (match_operand:SI 0 "register_operand"))]
""
"
{
- if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
- FAIL;
-
- rs6000_emit_sCOND (LT, operands[0]);
+ rs6000_emit_sCOND (<MODE>mode, operands);
DONE;
}")
-(define_expand "sgeu"
- [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
- ""
- "{ rs6000_emit_sCOND (GEU, operands[0]); DONE; }")
-
-(define_expand "sgtu"
- [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
- ""
- "{ rs6000_emit_sCOND (GTU, operands[0]); DONE; }")
-
-(define_expand "sleu"
- [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
- ""
- "{ rs6000_emit_sCOND (LEU, operands[0]); DONE; }")
-
-(define_expand "sltu"
- [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
- ""
- "{ rs6000_emit_sCOND (LTU, operands[0]); DONE; }")
-
-(define_expand "sunordered"
- [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
- "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
- "{ rs6000_emit_sCOND (UNORDERED, operands[0]); DONE; }")
-
-(define_expand "sordered"
- [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
- "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
- "{ rs6000_emit_sCOND (ORDERED, operands[0]); DONE; }")
-
-(define_expand "suneq"
- [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
- "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
- "{ rs6000_emit_sCOND (UNEQ, operands[0]); DONE; }")
-
-(define_expand "sunge"
- [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
- "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
- "{ rs6000_emit_sCOND (UNGE, operands[0]); DONE; }")
-
-(define_expand "sungt"
- [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
- "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
- "{ rs6000_emit_sCOND (UNGT, operands[0]); DONE; }")
-
-(define_expand "sunle"
- [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
- "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
- "{ rs6000_emit_sCOND (UNLE, operands[0]); DONE; }")
-
-(define_expand "sunlt"
- [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
- "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
- "{ rs6000_emit_sCOND (UNLT, operands[0]); DONE; }")
-
-(define_expand "sltgt"
- [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
- "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
- "{ rs6000_emit_sCOND (LTGT, operands[0]); DONE; }")
(define_expand "stack_protect_set"
[(match_operand 0 "memory_operand" "")
@@ -12195,16 +12023,16 @@
(match_operand 2 "" "")]
""
{
+ rtx test, op0, op1;
#ifdef TARGET_THREAD_SSP_OFFSET
rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
operands[1] = gen_rtx_MEM (Pmode, addr);
#endif
- rs6000_compare_op0 = operands[0];
- rs6000_compare_op1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, operands[1]),
- UNSPEC_SP_TEST);
- rs6000_compare_fp_p = 0;
- emit_jump_insn (gen_beq (operands[2]));
+ op0 = operands[0];
+ op1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, operands[1]), UNSPEC_SP_TEST);
+ test = gen_rtx_EQ (VOIDmode, op0, op1);
+ emit_jump_insn (gen_cbranchsi4 (test, op0, op1, operands[2]));
DONE;
})
@@ -14775,17 +14603,16 @@
"{t 31,0,0|trap}"
[(set_attr "type" "trap")])
-(define_expand "conditional_trap"
- [(trap_if (match_operator 0 "trap_comparison_operator"
- [(match_dup 2) (match_dup 3)])
- (match_operand 1 "const_int_operand" ""))]
+(define_expand "ctrap<mode>4"
+ [(trap_if (match_operator 0 "ordered_comparison_operator"
+ [(match_operand:GPR 1 "register_operand")
+ (match_operand:GPR 2 "reg_or_short_operand")])
+ (match_operand 3 "zero_constant" ""))]
""
- "if (rs6000_compare_fp_p || operands[1] != const0_rtx) FAIL;
- operands[2] = rs6000_compare_op0;
- operands[3] = rs6000_compare_op1;")
+ "")
(define_insn ""
- [(trap_if (match_operator 0 "trap_comparison_operator"
+ [(trap_if (match_operator 0 "ordered_comparison_operator"
[(match_operand:GPR 1 "register_operand" "r")
(match_operand:GPR 2 "reg_or_short_operand" "rI")])
(const_int 0))]
diff --git a/gcc/config/rs6000/sysv4.h b/gcc/config/rs6000/sysv4.h
index e8d516268ef..611c0d299c8 100644
--- a/gcc/config/rs6000/sysv4.h
+++ b/gcc/config/rs6000/sysv4.h
@@ -387,8 +387,8 @@ do { \
containing one of them. If -mfp-in-toc (the default), we also do
this for floating-point constants. We actually can only do this
if the FP formats of the target and host machines are the same, but
- we can't check that since not every file that uses
- GO_IF_LEGITIMATE_ADDRESS_P includes real.h.
+ we can't check that since not every file that uses these target macros
+ includes real.h.
Unlike AIX, we don't key off of -mminimal-toc, but instead do not
allow floating point constants in the TOC if -mrelocatable. */
diff --git a/gcc/config/rs6000/t-aix52 b/gcc/config/rs6000/t-aix52
index b22a190096e..0b4540278ce 100644
--- a/gcc/config/rs6000/t-aix52
+++ b/gcc/config/rs6000/t-aix52
@@ -47,7 +47,7 @@ SHLIB_LINK = $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) -shared -nodefaultlibs \
-Wl,-bE:@shlib_map_file@ -o @multilib_dir@/shr.o \
@multilib_flags@ @shlib_objs@ -lc \
`case @multilib_dir@ in \
- *pthread*) echo -L/usr/lib/threads -lpthreads -lc_r /usr/lib/libc.a ;; \
+ *pthread*) echo -L$(TARGET_SYSTEM_ROOT)/usr/lib/threads -lpthreads -lc_r $(TARGET_SYSTEM_ROOT)/usr/lib/libc.a ;; \
*) echo -lc ;; esac` ; \
rm -f @multilib_dir@/tmp-@shlib_base_name@.a ; \
$(AR_CREATE_FOR_TARGET) @multilib_dir@/tmp-@shlib_base_name@.a \
diff --git a/gcc/config/rs6000/t-rs6000 b/gcc/config/rs6000/t-rs6000
index c435bf40324..1a838c54bc3 100644
--- a/gcc/config/rs6000/t-rs6000
+++ b/gcc/config/rs6000/t-rs6000
@@ -1,7 +1,7 @@
# General rules that all rs6000/ targets must have.
#
-# Copyright (C) 1995, 1997, 1998, 1999, 2001, 2002, 2003, 2004,
-# 2008 Free Software Foundation, Inc.
+# Copyright (C) 1995, 1997, 1998, 1999, 2001, 2002, 2003, 2004, 2008, 2009
+# Free Software Foundation, Inc.
#
# This file is part of GCC.
#
@@ -31,7 +31,8 @@ rs6000-c.o: $(srcdir)/config/rs6000/rs6000-c.c \
$(srcdir)/config/rs6000/rs6000-protos.h \
$(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(CPPLIB_H) \
$(TM_P_H) c-pragma.h errors.h coretypes.h $(TM_H)
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/config/rs6000/rs6000-c.c
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $(srcdir)/config/rs6000/rs6000-c.c
# The rs6000 backend doesn't cause warnings in these files.
insn-conditions.o-warn =
diff --git a/gcc/config/rs6000/x-darwin b/gcc/config/rs6000/x-darwin
index 033ab6bf54c..5672c698b1e 100644
--- a/gcc/config/rs6000/x-darwin
+++ b/gcc/config/rs6000/x-darwin
@@ -1,4 +1,5 @@
host-ppc-darwin.o : $(srcdir)/config/rs6000/host-darwin.c \
$(CONFIG_H) $(SYSTEM_H) coretypes.h hosthooks.h $(HOSTHOOKS_DEF_H) toplev.h \
config/host-darwin.h $(DIAGNOSTIC_H)
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< -o $@
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) \
+ $(INCLUDES) $< -o $@
diff --git a/gcc/config/rs6000/x-darwin64 b/gcc/config/rs6000/x-darwin64
index 3cb423db35e..921d555ba01 100644
--- a/gcc/config/rs6000/x-darwin64
+++ b/gcc/config/rs6000/x-darwin64
@@ -1,4 +1,5 @@
host-ppc64-darwin.o : $(srcdir)/config/rs6000/host-ppc64-darwin.c \
$(CONFIG_H) $(SYSTEM_H) coretypes.h hosthooks.h $(HOSTHOOKS_DEF_H) toplev.h \
config/host-darwin.h $(DIAGNOSTIC_H)
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< -o $@
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) \
+ $(INCLUDES) $< -o $@
diff --git a/gcc/config/rs6000/x-rs6000 b/gcc/config/rs6000/x-rs6000
index 8246c377630..9e31f24cd64 100644
--- a/gcc/config/rs6000/x-rs6000
+++ b/gcc/config/rs6000/x-rs6000
@@ -1,3 +1,3 @@
driver-rs6000.o : $(srcdir)/config/rs6000/driver-rs6000.c \
$(CONFIG_H) $(SYSTEM_H) $(TM_H) coretypes.h
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
diff --git a/gcc/config/rs6000/xcoff.h b/gcc/config/rs6000/xcoff.h
index 76bbf4044d2..6560f319a25 100644
--- a/gcc/config/rs6000/xcoff.h
+++ b/gcc/config/rs6000/xcoff.h
@@ -70,10 +70,9 @@
or a CONST containing one of them. If -mfp-in-toc (the default),
we also do this for floating-point constants. We actually can only
do this if the FP formats of the target and host machines are the
- same, but we can't check that since not every file that uses
- GO_IF_LEGITIMATE_ADDRESS_P includes real.h. We also do this when
- we can write the entry into the TOC and the entry is not larger
- than a TOC entry. */
+ same, but we can't check that since not every file that uses these
+ target macros includes real.h. We also do this when we can write the
+ entry into the TOC and the entry is not larger than a TOC entry. */
#define ASM_OUTPUT_SPECIAL_POOL_ENTRY_P(X, MODE) \
(TARGET_TOC \
diff --git a/gcc/config/s390/2064.md b/gcc/config/s390/2064.md
index 573826a7549..143978334a3 100644
--- a/gcc/config/s390/2064.md
+++ b/gcc/config/s390/2064.md
@@ -21,22 +21,22 @@
;;
;; References:
-;; The microarchitecture of the IBM eServer z900 processor.
+;; The microarchitecture of the IBM eServer z900 processor.
;; E.M. Schwarz et al.
;; IBM Journal of Research and Development Vol. 46 No 4/5, 2002.
-;;
+;;
;; z900 (cpu 2064) pipeline
-;;
+;;
;; dec
;; --> | <---
;; LA bypass | agen |
-;; | | |
+;; | | |
;; --- c1 | Load bypass
-;; | |
+;; | |
;; c2----
;; |
-;; e1
-;; |
+;; e1
+;; |
;; wr
;; This scheduler description is also used for the g5 and g6.
@@ -46,12 +46,12 @@
(define_cpu_unit "z_wr" "z_ipu")
-(define_insn_reservation "z_la" 1
+(define_insn_reservation "z_la" 1
(and (eq_attr "cpu" "z900,g5,g6")
(eq_attr "type" "la"))
"z_e1,z_wr")
-(define_insn_reservation "z_larl" 1
+(define_insn_reservation "z_larl" 1
(and (eq_attr "cpu" "z900,g5,g6")
(eq_attr "type" "larl"))
"z_e1,z_wr")
@@ -101,32 +101,32 @@
"z_e1,z_wr")
;;
-;; s390_agen_dep_p returns 1, if a register is set in the
+;; s390_agen_dep_p returns 1, if a register is set in the
;; first insn and used in the dependent insn to form a address.
;;
;;
;; If an instruction uses a register to address memory, it needs
;; to be set 5 cycles in advance.
-;;
+;;
-(define_bypass 5 "z_int,z_agen"
+(define_bypass 5 "z_int,z_agen"
"z_agen,z_la,z_call,z_load,z_store" "s390_agen_dep_p")
;;
-;; A load type instruction uses a bypass to feed the result back
-;; to the address generation pipeline stage.
+;; A load type instruction uses a bypass to feed the result back
+;; to the address generation pipeline stage.
;;
-(define_bypass 3 "z_load"
+(define_bypass 3 "z_load"
"z_agen,z_la,z_call,z_load,z_store" "s390_agen_dep_p")
;;
-;; A load address type instruction uses a bypass to feed the
-;; result back to the address generation pipeline stage.
+;; A load address type instruction uses a bypass to feed the
+;; result back to the address generation pipeline stage.
;;
-(define_bypass 2 "z_larl,z_la"
+(define_bypass 2 "z_larl,z_la"
"z_agen,z_la,z_call,z_load,z_store" "s390_agen_dep_p")
diff --git a/gcc/config/s390/2084.md b/gcc/config/s390/2084.md
index a72ae365734..38669c23a97 100644
--- a/gcc/config/s390/2084.md
+++ b/gcc/config/s390/2084.md
@@ -76,38 +76,38 @@
(define_insn_reservation "x_lr" 1
(and (eq_attr "cpu" "z990,z9_109")
(eq_attr "type" "lr"))
- "x-e1-st,x-wr-st")
+ "x-e1-st,x-wr-st")
-(define_insn_reservation "x_la" 1
+(define_insn_reservation "x_la" 1
(and (eq_attr "cpu" "z990,z9_109")
(eq_attr "type" "la"))
- "x-e1-st,x-wr-st")
+ "x-e1-st,x-wr-st")
-(define_insn_reservation "x_larl" 1
+(define_insn_reservation "x_larl" 1
(and (eq_attr "cpu" "z990,z9_109")
(eq_attr "type" "larl"))
- "x-e1-st,x-wr-st")
+ "x-e1-st,x-wr-st")
-(define_insn_reservation "x_load" 1
+(define_insn_reservation "x_load" 1
(and (eq_attr "cpu" "z990,z9_109")
(eq_attr "type" "load"))
- "x-e1-st+x-mem,x-wr-st")
+ "x-e1-st+x-mem,x-wr-st")
-(define_insn_reservation "x_store" 1
+(define_insn_reservation "x_store" 1
(and (eq_attr "cpu" "z990,z9_109")
(eq_attr "type" "store"))
- "x-e1-st+x_store_tok,x-wr-st")
+ "x-e1-st+x_store_tok,x-wr-st")
-(define_insn_reservation "x_branch" 1
+(define_insn_reservation "x_branch" 1
(and (eq_attr "cpu" "z990,z9_109")
(eq_attr "type" "branch"))
- "x_e1_r,x_wr_r")
+ "x_e1_r,x_wr_r")
-(define_insn_reservation "x_call" 5
+(define_insn_reservation "x_call" 5
(and (eq_attr "cpu" "z990,z9_109")
(eq_attr "type" "jsr"))
"x-e1-np*5,x-wr-np")
-
+
(define_insn_reservation "x_mul_hi" 2
(and (eq_attr "cpu" "z990,z9_109")
(eq_attr "type" "imulhi"))
@@ -123,162 +123,162 @@
(eq_attr "type" "idiv"))
"x-e1-np*10,x-wr-np")
-(define_insn_reservation "x_sem" 17
+(define_insn_reservation "x_sem" 17
(and (eq_attr "cpu" "z990,z9_109")
(eq_attr "type" "sem"))
- "x-e1-np+x-mem,x-e1-np*16,x-wr-st")
+ "x-e1-np+x-mem,x-e1-np*16,x-wr-st")
;;
;; Multicycle insns
;;
-(define_insn_reservation "x_cs" 1
+(define_insn_reservation "x_cs" 1
(and (eq_attr "cpu" "z990,z9_109")
(eq_attr "type" "cs"))
- "x-e1-np,x-wr-np")
+ "x-e1-np,x-wr-np")
-(define_insn_reservation "x_vs" 1
+(define_insn_reservation "x_vs" 1
(and (eq_attr "cpu" "z990,z9_109")
(eq_attr "type" "vs"))
- "x-e1-np*10,x-wr-np")
+ "x-e1-np*10,x-wr-np")
-(define_insn_reservation "x_stm" 1
+(define_insn_reservation "x_stm" 1
(and (eq_attr "cpu" "z990,z9_109")
(eq_attr "type" "stm"))
- "(x-e1-np+x_store_tok)*10,x-wr-np")
+ "(x-e1-np+x_store_tok)*10,x-wr-np")
-(define_insn_reservation "x_lm" 1
+(define_insn_reservation "x_lm" 1
(and (eq_attr "cpu" "z990,z9_109")
(eq_attr "type" "lm"))
- "x-e1-np*10,x-wr-np")
+ "x-e1-np*10,x-wr-np")
-(define_insn_reservation "x_other" 1
+(define_insn_reservation "x_other" 1
(and (eq_attr "cpu" "z990,z9_109")
(eq_attr "type" "other"))
- "x-e1-np,x-wr-np")
+ "x-e1-np,x-wr-np")
;;
;; Floating point insns
;;
-(define_insn_reservation "x_fsimptf" 7
+(define_insn_reservation "x_fsimptf" 7
(and (eq_attr "cpu" "z990,z9_109")
(eq_attr "type" "fsimptf"))
- "x_e1_t*2,x-wr-fp")
+ "x_e1_t*2,x-wr-fp")
-(define_insn_reservation "x_fsimpdf" 6
+(define_insn_reservation "x_fsimpdf" 6
(and (eq_attr "cpu" "z990,z9_109")
(eq_attr "type" "fsimpdf,fmuldf"))
- "x_e1_t,x-wr-fp")
+ "x_e1_t,x-wr-fp")
-(define_insn_reservation "x_fsimpsf" 6
+(define_insn_reservation "x_fsimpsf" 6
(and (eq_attr "cpu" "z990,z9_109")
(eq_attr "type" "fsimpsf,fmulsf"))
- "x_e1_t,x-wr-fp")
+ "x_e1_t,x-wr-fp")
(define_insn_reservation "x_fmultf" 33
(and (eq_attr "cpu" "z990,z9_109")
(eq_attr "type" "fmultf"))
- "x_e1_t*27,x-wr-fp")
+ "x_e1_t*27,x-wr-fp")
(define_insn_reservation "x_fdivtf" 82
(and (eq_attr "cpu" "z990,z9_109")
(eq_attr "type" "fdivtf,fsqrttf"))
- "x_e1_t*76,x-wr-fp")
+ "x_e1_t*76,x-wr-fp")
(define_insn_reservation "x_fdivdf" 36
(and (eq_attr "cpu" "z990,z9_109")
(eq_attr "type" "fdivdf,fsqrtdf"))
- "x_e1_t*30,x-wr-fp")
+ "x_e1_t*30,x-wr-fp")
-(define_insn_reservation "x_fdivsf" 36
+(define_insn_reservation "x_fdivsf" 36
(and (eq_attr "cpu" "z990,z9_109")
(eq_attr "type" "fdivsf,fsqrtsf"))
- "x_e1_t*30,x-wr-fp")
+ "x_e1_t*30,x-wr-fp")
-(define_insn_reservation "x_floadtf" 6
+(define_insn_reservation "x_floadtf" 6
(and (eq_attr "cpu" "z990,z9_109")
(eq_attr "type" "floadtf"))
- "x_e1_t,x-wr-fp")
+ "x_e1_t,x-wr-fp")
-(define_insn_reservation "x_floaddf" 6
+(define_insn_reservation "x_floaddf" 6
(and (eq_attr "cpu" "z990,z9_109")
(eq_attr "type" "floaddf"))
- "x_e1_t,x-wr-fp")
+ "x_e1_t,x-wr-fp")
-(define_insn_reservation "x_floadsf" 6
+(define_insn_reservation "x_floadsf" 6
(and (eq_attr "cpu" "z990,z9_109")
(eq_attr "type" "floadsf"))
- "x_e1_t,x-wr-fp")
+ "x_e1_t,x-wr-fp")
-(define_insn_reservation "x_fstoredf" 1
+(define_insn_reservation "x_fstoredf" 1
(and (eq_attr "cpu" "z990,z9_109")
(eq_attr "type" "fstoredf"))
- "x_e1_t,x-wr-fp")
+ "x_e1_t,x-wr-fp")
-(define_insn_reservation "x_fstoresf" 1
+(define_insn_reservation "x_fstoresf" 1
(and (eq_attr "cpu" "z990,z9_109")
(eq_attr "type" "fstoresf"))
- "x_e1_t,x-wr-fp")
+ "x_e1_t,x-wr-fp")
(define_insn_reservation "x_ftrunctf" 16
(and (eq_attr "cpu" "z990,z9_109")
(eq_attr "type" "ftrunctf"))
- "x_e1_t*10,x-wr-fp")
+ "x_e1_t*10,x-wr-fp")
(define_insn_reservation "x_ftruncdf" 11
(and (eq_attr "cpu" "z990,z9_109")
(eq_attr "type" "ftruncdf"))
- "x_e1_t*5,x-wr-fp")
+ "x_e1_t*5,x-wr-fp")
-(define_insn_reservation "x_ftoi" 1
+(define_insn_reservation "x_ftoi" 1
(and (eq_attr "cpu" "z990,z9_109")
(eq_attr "type" "ftoi"))
- "x_e1_t*3,x-wr-fp")
+ "x_e1_t*3,x-wr-fp")
-(define_insn_reservation "x_itof" 7
+(define_insn_reservation "x_itof" 7
(and (eq_attr "cpu" "z990,z9_109")
(eq_attr "type" "itoftf,itofdf,itofsf"))
- "x_e1_t*3,x-wr-fp")
+ "x_e1_t*3,x-wr-fp")
(define_bypass 1 "x_fsimpdf" "x_fstoredf")
(define_bypass 1 "x_fsimpsf" "x_fstoresf")
(define_bypass 1 "x_floaddf" "x_fsimpdf,x_fstoredf,x_floaddf")
-
+
(define_bypass 1 "x_floadsf" "x_fsimpsf,x_fstoresf,x_floadsf")
;;
-;; s390_agen_dep_p returns 1, if a register is set in the
+;; s390_agen_dep_p returns 1, if a register is set in the
;; first insn and used in the dependent insn to form a address.
;;
;;
;; If an instruction uses a register to address memory, it needs
;; to be set 5 cycles in advance.
-;;
+;;
-(define_bypass 5 "x_int,x_agen,x_lr"
+(define_bypass 5 "x_int,x_agen,x_lr"
"x_agen,x_la,x_branch,x_call,x_load,x_store,x_cs,x_stm,x_lm,x_other"
"s390_agen_dep_p")
-(define_bypass 9 "x_int,x_agen,x_lr"
+(define_bypass 9 "x_int,x_agen,x_lr"
"x_floadtf, x_floaddf, x_floadsf, x_fstoredf, x_fstoresf,\
x_fsimpdf, x_fsimpsf, x_fdivdf, x_fdivsf"
"s390_agen_dep_p")
;;
-;; A load type instruction uses a bypass to feed the result back
-;; to the address generation pipeline stage.
+;; A load type instruction uses a bypass to feed the result back
+;; to the address generation pipeline stage.
;;
-(define_bypass 4 "x_load"
+(define_bypass 4 "x_load"
"x_agen,x_la,x_branch,x_call,x_load,x_store,x_cs,x_stm,x_lm,x_other"
"s390_agen_dep_p")
@@ -288,11 +288,11 @@
"s390_agen_dep_p")
;;
-;; A load address type instruction uses a bypass to feed the
-;; result back to the address generation pipeline stage.
+;; A load address type instruction uses a bypass to feed the
+;; result back to the address generation pipeline stage.
;;
-(define_bypass 3 "x_larl,x_la"
+(define_bypass 3 "x_larl,x_la"
"x_agen,x_la,x_branch,x_call,x_load,x_store,x_cs,x_stm,x_lm,x_other"
"s390_agen_dep_p")
diff --git a/gcc/config/s390/constraints.md b/gcc/config/s390/constraints.md
index 4d37094e2cf..8fec7e124a6 100644
--- a/gcc/config/s390/constraints.md
+++ b/gcc/config/s390/constraints.md
@@ -76,27 +76,27 @@
;; Register constraints.
;;
-(define_register_constraint "a"
+(define_register_constraint "a"
"ADDR_REGS"
"Any address register from 1 to 15.")
-(define_register_constraint "c"
+(define_register_constraint "c"
"CC_REGS"
"Condition code register 33")
-(define_register_constraint "d"
+(define_register_constraint "d"
"GENERAL_REGS"
"Any register from 0 to 15")
-(define_register_constraint "f"
+(define_register_constraint "f"
"FP_REGS"
"Floating point registers")
-(define_register_constraint "t"
+(define_register_constraint "t"
"ACCESS_REGS"
"@internal
Access registers 36 and 37")
@@ -187,9 +187,9 @@
;; is specified instead of a part number, the constraint matches
;; if there is any single part with non-default value.
;;
-;; The following patterns define only those constraints that are actually
-;; used in s390.md. If you need an additional one, simply add it in the
-;; obvious way. Function s390_N_constraint_str is ready to handle all
+;; The following patterns define only those constraints that are actually
+;; used in s390.md. If you need an additional one, simply add it in the
+;; obvious way. Function s390_N_constraint_str is ready to handle all
;; combinations.
;;
@@ -398,7 +398,7 @@ level. This constraint will never be used and using it in an inline
assembly is *always* a bug since there is no instruction accepting all
those addresses. It just serves as a placeholder for a generic memory
constraint."
- (match_test "legitimate_address_p (GET_MODE (op), op, 1)"))
+ (match_test "strict_memory_address_p (GET_MODE (op), op)"))
; This defines 'm' as normal memory constraint. This is only possible
; since the standard memory constraint is re-defined in s390.h using
@@ -409,53 +409,53 @@ constraint."
|| s390_mem_constraint (\"T\", op)"))
(define_memory_constraint "AQ"
- "@internal
+ "@internal
Offsettable memory reference without index register and with short displacement"
(match_test "s390_mem_constraint (\"AQ\", op)"))
(define_memory_constraint "AR"
- "@internal
+ "@internal
Offsettable memory reference with index register and short displacement"
(match_test "s390_mem_constraint (\"AR\", op)"))
(define_memory_constraint "AS"
- "@internal
+ "@internal
Offsettable memory reference without index register but with long displacement"
(match_test "s390_mem_constraint (\"AS\", op)"))
(define_memory_constraint "AT"
- "@internal
+ "@internal
Offsettable memory reference with index register and long displacement"
(match_test "s390_mem_constraint (\"AT\", op)"))
(define_constraint "BQ"
- "@internal
- Memory reference without index register and with short
+ "@internal
+ Memory reference without index register and with short
displacement that does *not* refer to a literal pool entry."
(match_test "s390_mem_constraint (\"BQ\", op)"))
(define_constraint "BR"
- "@internal
+ "@internal
Memory reference with index register and short displacement that
does *not* refer to a literal pool entry. "
(match_test "s390_mem_constraint (\"BR\", op)"))
(define_constraint "BS"
- "@internal
+ "@internal
Memory reference without index register but with long displacement
that does *not* refer to a literal pool entry. "
(match_test "s390_mem_constraint (\"BS\", op)"))
(define_constraint "BT"
- "@internal
+ "@internal
Memory reference with index register and long displacement that
does *not* refer to a literal pool entry. "
(match_test "s390_mem_constraint (\"BT\", op)"))
diff --git a/gcc/config/s390/fixdfdi.h b/gcc/config/s390/fixdfdi.h
index b6fb833e5d0..ddddf3a7c9c 100644
--- a/gcc/config/s390/fixdfdi.h
+++ b/gcc/config/s390/fixdfdi.h
@@ -63,12 +63,12 @@ __fixunstfdi (long double a1)
if (!EXPD (dl1) || SIGND(dl1))
return 0;
- /* The exponent - considered the binary point at the right end of
+ /* The exponent - considered the binary point at the right end of
the mantissa. */
exp = EXPD (dl1) - EXPONENT_BIAS - MANTISSA_BITS;
/* number < 1: If the mantissa would need to be right-shifted more bits than
- its size (plus the implied one bit on the left) the result would be
+ its size (plus the implied one bit on the left) the result would be
zero. */
if (exp <= -PRECISION)
return 0;
@@ -238,7 +238,7 @@ __fixunsdfdi (double a1)
/* shift down until exp < 12 or l = 0 */
if (exp > 0)
l <<= exp;
- else
+ else
l >>= -exp;
return l;
@@ -313,7 +313,7 @@ __fixdfdi (double a1)
/* shift down until exp < 12 or l = 0 */
if (exp > 0)
l <<= exp;
- else
+ else
l >>= -exp;
return (SIGND (dl1) ? -l : l);
@@ -381,7 +381,7 @@ __fixunssfdi (float a1)
if (exp > 0)
l <<= exp;
- else
+ else
l >>= -exp;
return l;
@@ -452,7 +452,7 @@ __fixsfdi (float a1)
if (exp > 0)
l <<= exp;
- else
+ else
l >>= -exp;
return (SIGN (fl1) ? -l : l);
diff --git a/gcc/config/s390/libgcc-glibc.ver b/gcc/config/s390/libgcc-glibc.ver
index 4832ba78ee3..6fc52e40d78 100644
--- a/gcc/config/s390/libgcc-glibc.ver
+++ b/gcc/config/s390/libgcc-glibc.ver
@@ -23,7 +23,7 @@
# to defer implementation of these routines to libgcc.so via DT_AUXILIARY.
# Note that we cannot use the default libgcc-glibc.ver file on s390x,
-# because GLIBC_2.0 does not exist on this architecture, as the first
+# because GLIBC_2.0 does not exist on this architecture, as the first
# ever glibc release on the platform was GLIBC_2.2.
%ifndef __s390x__
diff --git a/gcc/config/s390/predicates.md b/gcc/config/s390/predicates.md
index bb8fdf261d5..d09c9b3e161 100644
--- a/gcc/config/s390/predicates.md
+++ b/gcc/config/s390/predicates.md
@@ -189,6 +189,14 @@
return (s390_compare_and_branch_condition_mask (op) >= 0);
})
+;; Return nonzero if OP is a valid comparison operator for the
+;; cstore expanders -- respectively cstorecc4 and integer cstore.
+(define_predicate "s390_eqne_operator"
+ (match_code "eq, ne"))
+
+(define_predicate "s390_scond_operator"
+ (match_code "ltu, gtu, leu, geu"))
+
;; Return nonzero if OP is a valid comparison operator
;; for an ALC condition.
diff --git a/gcc/config/s390/s390-modes.def b/gcc/config/s390/s390-modes.def
index b701a550e8f..be2bf6ea798 100644
--- a/gcc/config/s390/s390-modes.def
+++ b/gcc/config/s390/s390-modes.def
@@ -45,8 +45,8 @@ Signed compares
CCS: EQ LT GT UNORDERED (LTGFR, LTGR, LTR, ICM/Y,
LTDBR, LTDR, LTEBR, LTER,
- CG/R, C/R/Y, CGHI, CHI,
- CDB/R, CD/R, CEB/R, CE/R,
+ CG/R, C/R/Y, CGHI, CHI,
+ CDB/R, CD/R, CEB/R, CE/R,
ADB/R, AEB/R, SDB/R, SEB/R,
SRAG, SRA, SRDA)
CCSR: EQ GT LT UNORDERED (CGF/R, CH/Y)
@@ -60,7 +60,7 @@ CCAN: EQ LT GT GT (AGHI, AHI)
Condition codes of unsigned adds and subs
CCL: EQ NE EQ NE (ALGF/R, ALG/R, AL/R/Y,
- ALCG/R, ALC/R,
+ ALCG/R, ALC/R,
SLGF/R, SLG/R, SL/R/Y,
SLBG/R, SLB/R)
CCL1: GEU GEU LTU LTU (ALG/R, AL/R/Y)
@@ -69,14 +69,14 @@ CCL3: EQ LTU EQ GTU (SLG/R, SL/R/Y)
Test under mask checks
-CCT: EQ NE NE NE (ICM/Y, TML, CG/R, CGHI,
+CCT: EQ NE NE NE (ICM/Y, TML, CG/R, CGHI,
C/R/Y, CHI, NG/R, N/R/Y,
OG/R, O/R/Y, XG/R, X/R/Y)
CCT1: NE EQ NE NE (TMH, TML)
CCT2: NE NE EQ NE (TMH, TML)
CCT3: NE NE NE EQ (TMH, TML)
-CCA and CCT modes are request only modes. These modes are never returned by
+CCA and CCT modes are request only modes. These modes are never returned by
s390_select_cc_mode. They are only intended to match other modes.
Requested mode -> Destination CC register mode
@@ -89,11 +89,11 @@ CCA -> CCAP, CCAN
CCAP, CCAN
-The CC obtained from add instruction usually can't be used for comparisons
+The CC obtained from add instruction usually can't be used for comparisons
because its coupling with overflow flag. In case of an overflow the
less than/greater than data are lost. Nevertheless a comparison can be done
whenever immediate values are involved because they are known at compile time.
-If you know whether the used constant is positive or negative you can predict
+If you know whether the used constant is positive or negative you can predict
the sign of the result even in case of an overflow.
@@ -103,7 +103,7 @@ If bits of an integer masked with an AND instruction are checked, the test under
mask instructions turn out to be very handy for a set of special cases.
The simple cases are checks whether all masked bits are zero or ones:
- int a;
+ int a;
if ((a & (16 + 128)) == 0) -> CCT/CCZ
if ((a & (16 + 128)) == 16 + 128) -> CCT3
@@ -120,15 +120,15 @@ CCSR, CCUR
There are several instructions comparing 32 bit with 64-bit unsigned/signed
values. Such instructions can be considered to have a builtin zero/sign_extend.
-The problem is that in the RTL (to be canonical) the zero/sign extended operand
-has to be the first one but the machine instructions like it the other way
-around. The following both modes can be considered as CCS and CCU modes with
+The problem is that in the RTL (to be canonical) the zero/sign extended operand
+has to be the first one but the machine instructions like it the other way
+around. The following both modes can be considered as CCS and CCU modes with
exchanged operands.
CCL1, CCL2
-These modes represent the result of overflow checks.
+These modes represent the result of overflow checks.
if (a + b < a) -> CCL1 state of the carry bit (CC2 | CC3)
if (a - b > a) -> CCL2 state of the borrow bit (CC0 | CC1)
@@ -142,7 +142,7 @@ CCL3
A logical subtract instruction sets the borrow bit in case of an overflow.
The resulting condition code of those instructions is represented by the
-CCL3 mode. Together with the CCU mode this mode is used for jumpless
+CCL3 mode. Together with the CCU mode this mode is used for jumpless
implementations of several if-constructs - see s390_expand_addcc for more
details.
@@ -152,7 +152,7 @@ The compare and swap instructions sets the condition code to 0/1 if the
operands were equal/unequal. The CCZ1 mode ensures the result can be
effectively placed into a register.
-*/
+*/
CC_MODE (CCZ);
diff --git a/gcc/config/s390/s390-protos.h b/gcc/config/s390/s390-protos.h
index 3bde1c14b48..2329138cf1f 100644
--- a/gcc/config/s390/s390-protos.h
+++ b/gcc/config/s390/s390-protos.h
@@ -22,7 +22,7 @@ along with GCC; see the file COPYING3. If not see
-/* Prototypes of functions used for constraint evaluation in
+/* Prototypes of functions used for constraint evaluation in
constraints.c. */
extern int s390_mem_constraint (const char *str, rtx op);
@@ -72,7 +72,6 @@ extern bool preferred_la_operand_p (rtx, rtx);
extern int legitimate_pic_operand_p (rtx);
extern int legitimate_constant_p (rtx);
extern bool legitimate_reload_constant_p (rtx);
-extern bool legitimate_address_p (enum machine_mode, rtx, int);
extern rtx legitimize_pic_address (rtx, rtx);
extern rtx legitimize_reload_address (rtx, enum machine_mode, int, int);
extern enum reg_class s390_preferred_reload_class (rtx, enum reg_class);
@@ -93,7 +92,7 @@ extern void s390_expand_cmpmem (rtx, rtx, rtx, rtx);
extern bool s390_expand_addcc (enum rtx_code, rtx, rtx, rtx, rtx, rtx);
extern bool s390_expand_insv (rtx, rtx, rtx, rtx);
extern void s390_expand_cs_hqi (enum machine_mode, rtx, rtx, rtx, rtx);
-extern void s390_expand_atomic (enum machine_mode, enum rtx_code,
+extern void s390_expand_atomic (enum machine_mode, enum rtx_code,
rtx, rtx, rtx, bool);
extern rtx s390_return_addr_rtx (int, rtx);
extern rtx s390_back_chain_rtx (void);
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index e2ed4a0d407..fd81bbac467 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -56,7 +56,7 @@ along with GCC; see the file COPYING3. If not see
/* Define the specific costs for a given cpu. */
-struct processor_costs
+struct processor_costs
{
/* multiplication */
const int m; /* cost of an M instruction. */
@@ -94,7 +94,7 @@ struct processor_costs
const struct processor_costs *s390_cost;
static const
-struct processor_costs z900_cost =
+struct processor_costs z900_cost =
{
COSTS_N_INSNS (5), /* M */
COSTS_N_INSNS (10), /* MGHI */
@@ -126,7 +126,7 @@ struct processor_costs z900_cost =
};
static const
-struct processor_costs z990_cost =
+struct processor_costs z990_cost =
{
COSTS_N_INSNS (4), /* M */
COSTS_N_INSNS (2), /* MGHI */
@@ -158,7 +158,7 @@ struct processor_costs z990_cost =
};
static const
-struct processor_costs z9_109_cost =
+struct processor_costs z9_109_cost =
{
COSTS_N_INSNS (4), /* M */
COSTS_N_INSNS (2), /* MGHI */
@@ -223,11 +223,6 @@ struct processor_costs z10_cost =
extern int reload_completed;
-/* Save information from a "cmpxx" operation until the branch or scc is
- emitted. A pair of a MODE_CC register and a const0_rtx if a compare
- has been emitted already. */
-rtx s390_compare_op0, s390_compare_op1;
-
/* Structure used to hold the components of a S/390 memory
address. A legitimate address on S/390 is of the general
form
@@ -257,7 +252,7 @@ HOST_WIDE_INT s390_warn_framesize = 0;
HOST_WIDE_INT s390_stack_size = 0;
HOST_WIDE_INT s390_stack_guard = 0;
-/* The following structure is embedded in the machine
+/* The following structure is embedded in the machine
specific part of struct function. */
struct GTY (()) s390_frame_layout
@@ -280,8 +275,8 @@ struct GTY (()) s390_frame_layout
int last_save_gpr;
int last_restore_gpr;
- /* Bits standing for floating point registers. Set, if the
- respective register has to be saved. Starting with reg 16 (f0)
+ /* Bits standing for floating point registers. Set, if the
+ respective register has to be saved. Starting with reg 16 (f0)
at the rightmost bit.
Bit 15 - 8 7 6 5 4 3 2 1 0
fpr 15 - 8 7 5 3 1 6 4 2 0
@@ -405,7 +400,7 @@ s390_cc_modes_compatible (enum machine_mode m1, enum machine_mode m2)
case CCZ1mode:
if (m2 == CCZmode)
return m1;
-
+
return VOIDmode;
default:
@@ -515,7 +510,7 @@ s390_tm_ccmode (rtx op1, rtx op2, bool mixed)
if (INTVAL (op2) == 0)
return CCTmode;
- /* Selected bits all one: CC3.
+ /* Selected bits all one: CC3.
e.g.: int a; if ((a & (16 + 128)) == 16 + 128) */
if (INTVAL (op2) == INTVAL (op1))
return CCT3mode;
@@ -587,7 +582,7 @@ s390_select_ccmode (enum rtx_code code, rtx op0, rtx op1)
case GT:
/* The only overflow condition of NEG and ABS happens when
-INT_MAX is used as parameter, which stays negative. So
- we have an overflow from a positive value to a negative.
+ we have an overflow from a positive value to a negative.
Using CCAP mode the resulting cc can be used for comparisons. */
if ((GET_CODE (op0) == NEG || GET_CODE (op0) == ABS)
&& GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
@@ -596,7 +591,7 @@ s390_select_ccmode (enum rtx_code code, rtx op0, rtx op1)
/* If constants are involved in an add instruction it is possible to use
the resulting cc for comparisons with zero. Knowing the sign of the
constant the overflow behavior gets predictable. e.g.:
- int a, b; if ((b = a + c) > 0)
+ int a, b; if ((b = a + c) > 0)
with c as a constant value: c < 0 -> CCAN and c >= 0 -> CCAP */
if (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 1)) == CONST_INT
&& CONST_OK_FOR_K (INTVAL (XEXP (op0, 1))))
@@ -719,7 +714,7 @@ s390_canonicalize_comparison (enum rtx_code *code, rtx *op0, rtx *op1)
&& GET_CODE (*op1) == CONST_INT
&& INTVAL (*op1) == 0xffff
&& SCALAR_INT_MODE_P (GET_MODE (*op0))
- && (nonzero_bits (*op0, GET_MODE (*op0))
+ && (nonzero_bits (*op0, GET_MODE (*op0))
& ~(unsigned HOST_WIDE_INT) 0xffff) == 0)
{
*op0 = gen_lowpart (HImode, *op0);
@@ -827,7 +822,7 @@ s390_emit_compare (enum rtx_code code, rtx op0, rtx op1)
emit_insn (gen_rtx_SET (VOIDmode, cc, gen_rtx_COMPARE (mode, op0, op1)));
}
- return gen_rtx_fmt_ee (code, VOIDmode, cc, const0_rtx);
+ return gen_rtx_fmt_ee (code, VOIDmode, cc, const0_rtx);
}
/* Emit a SImode compare and swap instruction setting MEM to NEW_RTX if OLD
@@ -1301,9 +1296,9 @@ s390_overlap_p (rtx mem1, rtx mem2, HOST_WIDE_INT size)
/* This overlapping check is used by peepholes merging memory block operations.
Overlapping operations would otherwise be recognized by the S/390 hardware
- and would fall back to a slower implementation. Allowing overlapping
+ and would fall back to a slower implementation. Allowing overlapping
operations would lead to slow code but not to wrong code. Therefore we are
- somewhat optimistic if we cannot prove that the memory blocks are
+ somewhat optimistic if we cannot prove that the memory blocks are
overlapping.
That's why we return false here although this may accept operations on
overlapping memory areas. */
@@ -1626,7 +1621,7 @@ override_options (void)
error ("stack size must not be greater than 64k");
}
else if (s390_stack_guard)
- error ("-mstack-guard implies use of -mstack-size");
+ error ("-mstack-guard implies use of -mstack-size");
#ifdef TARGET_DEFAULT_LONG_DOUBLE_128
if (!(target_flags_explicit & MASK_LONG_DOUBLE_128))
@@ -1809,7 +1804,7 @@ s390_decompose_address (rtx addr, struct s390_address *out)
{
case UNSPEC_LTREF:
if (!disp)
- disp = gen_rtx_UNSPEC (Pmode,
+ disp = gen_rtx_UNSPEC (Pmode,
gen_rtvec (1, XVECEXP (base, 0, 0)),
UNSPEC_LTREL_OFFSET);
else
@@ -1829,8 +1824,8 @@ s390_decompose_address (rtx addr, struct s390_address *out)
return false;
}
- if (!REG_P (base)
- || (GET_MODE (base) != SImode
+ if (!REG_P (base)
+ || (GET_MODE (base) != SImode
&& GET_MODE (base) != Pmode))
return false;
@@ -1857,7 +1852,7 @@ s390_decompose_address (rtx addr, struct s390_address *out)
{
case UNSPEC_LTREF:
if (!disp)
- disp = gen_rtx_UNSPEC (Pmode,
+ disp = gen_rtx_UNSPEC (Pmode,
gen_rtvec (1, XVECEXP (indx, 0, 0)),
UNSPEC_LTREL_OFFSET);
else
@@ -1877,7 +1872,7 @@ s390_decompose_address (rtx addr, struct s390_address *out)
return false;
}
- if (!REG_P (indx)
+ if (!REG_P (indx)
|| (GET_MODE (indx) != SImode
&& GET_MODE (indx) != Pmode))
return false;
@@ -1909,21 +1904,21 @@ s390_decompose_address (rtx addr, struct s390_address *out)
/* Validate displacement. */
if (!disp)
{
- /* If virtual registers are involved, the displacement will change later
- anyway as the virtual registers get eliminated. This could make a
- valid displacement invalid, but it is more likely to make an invalid
- displacement valid, because we sometimes access the register save area
+ /* If virtual registers are involved, the displacement will change later
+ anyway as the virtual registers get eliminated. This could make a
+ valid displacement invalid, but it is more likely to make an invalid
+ displacement valid, because we sometimes access the register save area
via negative offsets to one of those registers.
Thus we don't check the displacement for validity here. If after
elimination the displacement turns out to be invalid after all,
this is fixed up by reload in any case. */
- if (base != arg_pointer_rtx
- && indx != arg_pointer_rtx
- && base != return_address_pointer_rtx
+ if (base != arg_pointer_rtx
+ && indx != arg_pointer_rtx
+ && base != return_address_pointer_rtx
&& indx != return_address_pointer_rtx
- && base != frame_pointer_rtx
+ && base != frame_pointer_rtx
&& indx != frame_pointer_rtx
- && base != virtual_stack_vars_rtx
+ && base != virtual_stack_vars_rtx
&& indx != virtual_stack_vars_rtx)
if (!DISP_IN_RANGE (offset))
return false;
@@ -2276,8 +2271,8 @@ s390_float_const_zero_p (rtx value)
/* Compute a (partial) cost for rtx X. Return true if the complete
cost has been computed, and false if subexpressions should be
- scanned. In either case, *TOTAL contains the cost result.
- CODE contains GET_CODE (x), OUTER_CODE contains the code
+ scanned. In either case, *TOTAL contains the cost result.
+ CODE contains GET_CODE (x), OUTER_CODE contains the code
of the superexpression of x. */
static bool
@@ -2328,7 +2323,7 @@ s390_rtx_costs (rtx x, int code, int outer_code, int *total,
*total = COSTS_N_INSNS (1);
return false;
- case MULT:
+ case MULT:
switch (GET_MODE (x))
{
case SImode:
@@ -3085,8 +3080,8 @@ s390_expand_plus_operand (rtx target, rtx src,
/* Return true if ADDR is a valid memory address.
STRICT specifies whether strict register checking applies. */
-bool
-legitimate_address_p (enum machine_mode mode, rtx addr, int strict)
+static bool
+s390_legitimate_address_p (enum machine_mode mode, rtx addr, bool strict)
{
struct s390_address ad;
@@ -3109,11 +3104,11 @@ legitimate_address_p (enum machine_mode mode, rtx addr, int strict)
}
else
{
- if (ad.base
+ if (ad.base
&& !(REGNO (ad.base) >= FIRST_PSEUDO_REGISTER
|| REGNO_REG_CLASS (REGNO (ad.base)) == ADDR_REGS))
return false;
-
+
if (ad.indx
&& !(REGNO (ad.indx) >= FIRST_PSEUDO_REGISTER
|| REGNO_REG_CLASS (REGNO (ad.indx)) == ADDR_REGS))
@@ -3195,7 +3190,7 @@ s390_load_address (rtx dst, rtx src)
differentiate them from global data objects. The returned
address is the PIC reg + an unspec constant.
- GO_IF_LEGITIMATE_ADDRESS rejects symbolic references unless the PIC
+ TARGET_LEGITIMIZE_ADDRESS_P rejects symbolic references unless the PIC
reg also appears in the address. */
rtx
@@ -3359,7 +3354,7 @@ legitimize_pic_address (rtx orig, rtx reg)
gcc_unreachable ();
}
}
- else
+ else
gcc_assert (GET_CODE (addr) == PLUS);
}
if (GET_CODE (addr) == PLUS)
@@ -3744,11 +3739,11 @@ s390_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
{
x = legitimize_tls_address (x, 0);
- if (legitimate_address_p (mode, x, FALSE))
+ if (s390_legitimate_address_p (mode, x, FALSE))
return x;
}
else if (GET_CODE (x) == PLUS
- && (TLS_SYMBOLIC_CONST (XEXP (x, 0))
+ && (TLS_SYMBOLIC_CONST (XEXP (x, 0))
|| TLS_SYMBOLIC_CONST (XEXP (x, 1))))
{
return x;
@@ -3761,7 +3756,7 @@ s390_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
|| SYMBOLIC_CONST (XEXP (x, 1)))))
x = legitimize_pic_address (x, 0);
- if (legitimate_address_p (mode, x, FALSE))
+ if (s390_legitimate_address_p (mode, x, FALSE))
return x;
}
@@ -3827,7 +3822,7 @@ s390_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
MODE is the mode of the enclosing MEM. OPNUM is the operand number
and TYPE is the reload type of the current reload. */
-rtx
+rtx
legitimize_reload_address (rtx ad, enum machine_mode mode ATTRIBUTE_UNUSED,
int opnum, int type)
{
@@ -3859,7 +3854,7 @@ legitimize_reload_address (rtx ad, enum machine_mode mode ATTRIBUTE_UNUSED,
new_rtx = gen_rtx_PLUS (Pmode, tem, GEN_INT (lower));
push_reload (XEXP (tem, 1), 0, &XEXP (tem, 1), 0,
- BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
+ BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
opnum, (enum reload_type) type);
return new_rtx;
}
@@ -3957,7 +3952,7 @@ s390_expand_setmem (rtx dst, rtx len, rtx val)
return;
gcc_assert (GET_CODE (val) == CONST_INT || GET_MODE (val) == QImode);
-
+
if (GET_CODE (len) == CONST_INT && INTVAL (len) > 0 && INTVAL (len) <= 257)
{
if (val == const0_rtx && INTVAL (len) <= 256)
@@ -3966,7 +3961,7 @@ s390_expand_setmem (rtx dst, rtx len, rtx val)
{
/* Initialize memory by storing the first byte. */
emit_move_insn (adjust_address (dst, QImode, 0), val);
-
+
if (INTVAL (len) > 1)
{
/* Initiate 1 byte overlap move.
@@ -3977,7 +3972,7 @@ s390_expand_setmem (rtx dst, rtx len, rtx val)
rtx dstp1 = adjust_address (dst, VOIDmode, 1);
set_mem_size (dst, const1_rtx);
- emit_insn (gen_movmem_short (dstp1, dst,
+ emit_insn (gen_movmem_short (dstp1, dst,
GEN_INT (INTVAL (len) - 2)));
}
}
@@ -4023,7 +4018,7 @@ s390_expand_setmem (rtx dst, rtx len, rtx val)
/* Initialize memory by storing the first byte. */
emit_move_insn (adjust_address (dst, QImode, 0), val);
-
+
/* If count is 1 we are done. */
emit_cmp_and_jump_insns (count, const1_rtx,
EQ, NULL_RTX, mode, 1, end_label);
@@ -4273,9 +4268,9 @@ s390_expand_addcc (enum rtx_code cmp_code, rtx cmp_op0, rtx cmp_op1,
}
p = rtvec_alloc (2);
- RTVEC_ELT (p, 0) =
+ RTVEC_ELT (p, 0) =
gen_rtx_SET (VOIDmode, dst, op_res);
- RTVEC_ELT (p, 1) =
+ RTVEC_ELT (p, 1) =
gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM));
emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
@@ -4334,15 +4329,15 @@ s390_expand_addcc (enum rtx_code cmp_code, rtx cmp_op0, rtx cmp_op1,
if (!register_operand (src, GET_MODE (dst)))
src = force_reg (GET_MODE (dst), src);
- op_res = gen_rtx_MINUS (GET_MODE (dst),
- gen_rtx_MINUS (GET_MODE (dst), src, const0_rtx),
- gen_rtx_fmt_ee (cmp_code, GET_MODE (dst),
- gen_rtx_REG (cc_mode, CC_REGNUM),
+ op_res = gen_rtx_MINUS (GET_MODE (dst),
+ gen_rtx_MINUS (GET_MODE (dst), src, const0_rtx),
+ gen_rtx_fmt_ee (cmp_code, GET_MODE (dst),
+ gen_rtx_REG (cc_mode, CC_REGNUM),
const0_rtx));
p = rtvec_alloc (2);
- RTVEC_ELT (p, 0) =
+ RTVEC_ELT (p, 0) =
gen_rtx_SET (VOIDmode, dst, op_res);
- RTVEC_ELT (p, 1) =
+ RTVEC_ELT (p, 1) =
gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM));
emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
@@ -4402,7 +4397,7 @@ s390_expand_insv (rtx dest, rtx op1, rtx op2, rtx src)
set_mem_size (dest, GEN_INT (size));
s390_expand_movmem (dest, src_mem, GEN_INT (size));
}
-
+
/* (set (ze (mem)) (reg)). */
else if (register_operand (src, word_mode))
{
@@ -4415,7 +4410,7 @@ s390_expand_insv (rtx dest, rtx op1, rtx op2, rtx src)
int stcmh_width = bitsize - GET_MODE_BITSIZE (SImode);
int size = stcmh_width / BITS_PER_UNIT;
- emit_move_insn (adjust_address (dest, SImode, size),
+ emit_move_insn (adjust_address (dest, SImode, size),
gen_lowpart (SImode, src));
set_mem_size (dest, GEN_INT (size));
emit_move_insn (gen_rtx_ZERO_EXTRACT (word_mode, dest, GEN_INT
@@ -4432,7 +4427,7 @@ s390_expand_insv (rtx dest, rtx op1, rtx op2, rtx src)
/* (set (ze (reg)) (const_int)). */
if (TARGET_ZARCH
- && register_operand (dest, word_mode)
+ && register_operand (dest, word_mode)
&& (bitpos % 16) == 0
&& (bitsize % 16) == 0
&& const_int_operand (src, VOIDmode))
@@ -4452,9 +4447,9 @@ s390_expand_insv (rtx dest, rtx op1, rtx op2, rtx src)
putsize = GET_MODE_BITSIZE (putmode);
regpos -= putsize;
- emit_move_insn (gen_rtx_ZERO_EXTRACT (word_mode, dest,
+ emit_move_insn (gen_rtx_ZERO_EXTRACT (word_mode, dest,
GEN_INT (putsize),
- GEN_INT (regpos)),
+ GEN_INT (regpos)),
gen_int_mode (val, putmode));
val >>= putsize;
}
@@ -4473,16 +4468,16 @@ s390_expand_mask_and_shift (rtx val, enum machine_mode mode, rtx count)
{
val = expand_simple_binop (SImode, AND, val, GEN_INT (GET_MODE_MASK (mode)),
NULL_RTX, 1, OPTAB_DIRECT);
- return expand_simple_binop (SImode, ASHIFT, val, count,
+ return expand_simple_binop (SImode, ASHIFT, val, count,
NULL_RTX, 1, OPTAB_DIRECT);
}
/* Structure to hold the initial parameters for a compare_and_swap operation
- in HImode and QImode. */
+ in HImode and QImode. */
struct alignment_context
{
- rtx memsi; /* SI aligned memory location. */
+ rtx memsi; /* SI aligned memory location. */
rtx shift; /* Bit offset with regard to lsb. */
rtx modemask; /* Mask of the HQImode shifted by SHIFT bits. */
rtx modemaski; /* ~modemask */
@@ -4534,7 +4529,7 @@ init_alignment_context (struct alignment_context *ac, rtx mem,
ac->shift = expand_simple_binop (SImode, MULT, ac->shift, GEN_INT (BITS_PER_UNIT),
NULL_RTX, 1, OPTAB_DIRECT);
/* Calculate masks. */
- ac->modemask = expand_simple_binop (SImode, ASHIFT,
+ ac->modemask = expand_simple_binop (SImode, ASHIFT,
GEN_INT (GET_MODE_MASK (mode)), ac->shift,
NULL_RTX, 1, OPTAB_DIRECT);
ac->modemaski = expand_simple_unop (SImode, NOT, ac->modemask, NULL_RTX, 1);
@@ -4572,9 +4567,9 @@ s390_expand_cs_hqi (enum machine_mode mode, rtx target, rtx mem, rtx cmp, rtx ne
/* Start CS loop. */
emit_label (csloop);
- /* val = "<mem>00..0<mem>"
+ /* val = "<mem>00..0<mem>"
* cmp = "00..0<cmp>00..0"
- * new = "00..0<new>00..0"
+ * new = "00..0<new>00..0"
*/
/* Patch cmp and new with val at correct position. */
@@ -4600,17 +4595,17 @@ s390_expand_cs_hqi (enum machine_mode mode, rtx target, rtx mem, rtx cmp, rtx ne
cmpv, newv));
/* Check for changes outside mode. */
- resv = expand_simple_binop (SImode, AND, res, ac.modemaski,
+ resv = expand_simple_binop (SImode, AND, res, ac.modemaski,
NULL_RTX, 1, OPTAB_DIRECT);
- cc = s390_emit_compare (NE, resv, val);
+ cc = s390_emit_compare (NE, resv, val);
emit_move_insn (val, resv);
/* Loop internal if so. */
s390_emit_jump (csloop, cc);
emit_label (csend);
-
+
/* Return the correct part of the bitfield. */
- convert_move (target, expand_simple_binop (SImode, LSHIFTRT, res, ac.shift,
+ convert_move (target, expand_simple_binop (SImode, LSHIFTRT, res, ac.shift,
NULL_RTX, 1, OPTAB_DIRECT), 1);
}
@@ -4664,7 +4659,7 @@ s390_expand_atomic (enum machine_mode mode, enum rtx_code code,
val = expand_simple_binop (SImode, AND, val, ac.modemask,
NULL_RTX, 1, OPTAB_DIRECT);
/* FALLTHRU */
- case SET:
+ case SET:
if (ac.aligned && MEM_P (val))
store_bit_field (new_rtx, GET_MODE_BITSIZE (mode), 0, SImode, val);
else
@@ -5516,8 +5511,8 @@ s390_split_branches (void)
}
-/* Find an annotated literal pool symbol referenced in RTX X,
- and store it at REF. Will abort if X contains references to
+/* Find an annotated literal pool symbol referenced in RTX X,
+ and store it at REF. Will abort if X contains references to
more than one such pool symbol; multiple references to the same
symbol are allowed, however.
@@ -5550,7 +5545,7 @@ find_constant_pool_ref (rtx x, rtx *ref)
if (*ref == NULL_RTX)
*ref = sym;
- else
+ else
gcc_assert (*ref == sym);
return;
@@ -5571,7 +5566,7 @@ find_constant_pool_ref (rtx x, rtx *ref)
}
}
-/* Replace every reference to the annotated literal pool
+/* Replace every reference to the annotated literal pool
symbol REF in X by its base plus OFFSET. */
static void
@@ -6516,7 +6511,7 @@ s390_chunkify_start (void)
for (curr_pool = pool_list; curr_pool; curr_pool = curr_pool->next)
{
- rtx new_insn = gen_reload_base (cfun->machine->base_reg,
+ rtx new_insn = gen_reload_base (cfun->machine->base_reg,
curr_pool->label);
rtx insn = curr_pool->first_insn;
INSN_ADDRESSES_NEW (emit_insn_before (new_insn, insn), -1);
@@ -6531,7 +6526,7 @@ s390_chunkify_start (void)
struct constant_pool *pool = s390_find_pool (pool_list, insn);
if (pool)
{
- rtx new_insn = gen_reload_base (cfun->machine->base_reg,
+ rtx new_insn = gen_reload_base (cfun->machine->base_reg,
pool->label);
INSN_ADDRESSES_NEW (emit_insn_after (new_insn, insn), -1);
}
@@ -6768,7 +6763,7 @@ find_unused_clobbered_reg (void)
}
-/* Helper function for s390_regs_ever_clobbered. Sets the fields in DATA for all
+/* Helper function for s390_regs_ever_clobbered. Sets the fields in DATA for all
clobbered hard regs in SETREG. */
static void
@@ -6826,8 +6821,8 @@ s390_regs_ever_clobbered (int *regs_ever_clobbered)
deal with this automatically. */
if (crtl->calls_eh_return || cfun->machine->has_landing_pad_p)
for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM ; i++)
- if (crtl->calls_eh_return
- || (cfun->machine->has_landing_pad_p
+ if (crtl->calls_eh_return
+ || (cfun->machine->has_landing_pad_p
&& df_regs_ever_live_p (EH_RETURN_DATA_REGNO (i))))
regs_ever_clobbered[EH_RETURN_DATA_REGNO (i)] = 1;
@@ -6846,16 +6841,16 @@ s390_regs_ever_clobbered (int *regs_ever_clobbered)
{
if (INSN_P (cur_insn))
note_stores (PATTERN (cur_insn),
- s390_reg_clobbered_rtx,
+ s390_reg_clobbered_rtx,
regs_ever_clobbered);
}
}
}
-/* Determine the frame area which actually has to be accessed
- in the function epilogue. The values are stored at the
+/* Determine the frame area which actually has to be accessed
+ in the function epilogue. The values are stored at the
given pointers AREA_BOTTOM (address of the lowest used stack
- address) and AREA_TOP (address of the first item which does
+ address) and AREA_TOP (address of the first item which does
not belong to the stack frame). */
static void
@@ -6889,7 +6884,7 @@ s390_frame_area (int *area_bottom, int *area_top)
b = MIN (b, cfun_frame_layout.f4_offset + (i - 2) * 8);
t = MAX (t, cfun_frame_layout.f4_offset + (i - 1) * 8);
}
-
+
*area_bottom = b;
*area_top = t;
}
@@ -6928,10 +6923,10 @@ s390_register_info (int clobbered_regs[])
clobbered_regs[HARD_FRAME_POINTER_REGNUM] = 1;
if (flag_pic)
- clobbered_regs[PIC_OFFSET_TABLE_REGNUM]
+ clobbered_regs[PIC_OFFSET_TABLE_REGNUM]
|= df_regs_ever_live_p (PIC_OFFSET_TABLE_REGNUM);
- clobbered_regs[BASE_REGNUM]
+ clobbered_regs[BASE_REGNUM]
|= (cfun->machine->base_reg
&& REGNO (cfun->machine->base_reg) == BASE_REGNUM);
@@ -6974,8 +6969,8 @@ s390_register_info (int clobbered_regs[])
cfun_frame_layout.first_save_gpr_slot = i;
cfun_frame_layout.last_save_gpr_slot = j;
- for (i = cfun_frame_layout.first_save_gpr_slot;
- i < cfun_frame_layout.last_save_gpr_slot + 1;
+ for (i = cfun_frame_layout.first_save_gpr_slot;
+ i < cfun_frame_layout.last_save_gpr_slot + 1;
i++)
if (clobbered_regs[i])
break;
@@ -6983,7 +6978,7 @@ s390_register_info (int clobbered_regs[])
for (j = cfun_frame_layout.last_save_gpr_slot; j > i; j--)
if (clobbered_regs[j])
break;
-
+
if (i == cfun_frame_layout.last_save_gpr_slot + 1)
{
/* Nothing to save/restore. */
@@ -7063,7 +7058,7 @@ s390_frame_info (void)
cfun_frame_layout.frame_size = get_frame_size ();
if (!TARGET_64BIT && cfun_frame_layout.frame_size > 0x7fff0000)
fatal_error ("total size of local variables exceeds architecture limit");
-
+
if (!TARGET_PACKED_STACK)
{
cfun_frame_layout.backchain_offset = 0;
@@ -7077,46 +7072,46 @@ s390_frame_info (void)
{
cfun_frame_layout.backchain_offset = (STACK_POINTER_OFFSET
- UNITS_PER_WORD);
- cfun_frame_layout.gprs_offset
- = (cfun_frame_layout.backchain_offset
+ cfun_frame_layout.gprs_offset
+ = (cfun_frame_layout.backchain_offset
- (STACK_POINTER_REGNUM - cfun_frame_layout.first_save_gpr_slot + 1)
* UNITS_PER_WORD);
-
+
if (TARGET_64BIT)
{
- cfun_frame_layout.f4_offset
+ cfun_frame_layout.f4_offset
= (cfun_frame_layout.gprs_offset
- 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
-
- cfun_frame_layout.f0_offset
- = (cfun_frame_layout.f4_offset
+
+ cfun_frame_layout.f0_offset
+ = (cfun_frame_layout.f4_offset
- 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
}
else
{
/* On 31 bit we have to care about alignment of the
floating point regs to provide fastest access. */
- cfun_frame_layout.f0_offset
- = ((cfun_frame_layout.gprs_offset
+ cfun_frame_layout.f0_offset
+ = ((cfun_frame_layout.gprs_offset
& ~(STACK_BOUNDARY / BITS_PER_UNIT - 1))
- 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
-
- cfun_frame_layout.f4_offset
+
+ cfun_frame_layout.f4_offset
= (cfun_frame_layout.f0_offset
- 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
}
}
else /* no backchain */
{
- cfun_frame_layout.f4_offset
+ cfun_frame_layout.f4_offset
= (STACK_POINTER_OFFSET
- 8 * (cfun_fpr_bit_p (2) + cfun_fpr_bit_p (3)));
-
- cfun_frame_layout.f0_offset
+
+ cfun_frame_layout.f0_offset
= (cfun_frame_layout.f4_offset
- 8 * (cfun_fpr_bit_p (0) + cfun_fpr_bit_p (1)));
-
- cfun_frame_layout.gprs_offset
+
+ cfun_frame_layout.gprs_offset
= cfun_frame_layout.f0_offset - cfun_gprs_save_area_size;
}
@@ -7137,7 +7132,7 @@ s390_frame_info (void)
if (TARGET_BACKCHAIN)
cfun_frame_layout.frame_size += UNITS_PER_WORD;
- /* No alignment trouble here because f8-f15 are only saved under
+ /* No alignment trouble here because f8-f15 are only saved under
64 bit. */
cfun_frame_layout.f8_offset = (MIN (MIN (cfun_frame_layout.f0_offset,
cfun_frame_layout.f4_offset),
@@ -7149,9 +7144,9 @@ s390_frame_info (void)
for (i = 0; i < 8; i++)
if (cfun_fpr_bit_p (i))
cfun_frame_layout.frame_size += 8;
-
+
cfun_frame_layout.frame_size += cfun_gprs_save_area_size;
-
+
/* If under 31 bit an odd number of gprs has to be saved we have to adjust
the frame size to sustain 8 byte alignment of stack frames. */
cfun_frame_layout.frame_size = ((cfun_frame_layout.frame_size +
@@ -7218,11 +7213,11 @@ s390_update_frame_layout (void)
s390_register_info (clobbered_regs);
- df_set_regs_ever_live (BASE_REGNUM,
+ df_set_regs_ever_live (BASE_REGNUM,
clobbered_regs[BASE_REGNUM] ? true : false);
- df_set_regs_ever_live (RETURN_REGNUM,
+ df_set_regs_ever_live (RETURN_REGNUM,
clobbered_regs[RETURN_REGNUM] ? true : false);
- df_set_regs_ever_live (STACK_POINTER_REGNUM,
+ df_set_regs_ever_live (STACK_POINTER_REGNUM,
clobbered_regs[STACK_POINTER_REGNUM] ? true : false);
if (cfun->machine->base_reg)
@@ -7254,10 +7249,10 @@ s390_hard_regno_mode_ok (unsigned int regno, enum machine_mode mode)
case GENERAL_REGS:
if (REGNO_PAIR_OK (regno, mode))
{
- if (TARGET_64BIT
+ if (TARGET_64BIT
|| (mode != TFmode && mode != TCmode && mode != TDmode))
return true;
- }
+ }
break;
case CC_REGS:
if (GET_MODE_CLASS (mode) == MODE_CC)
@@ -7273,7 +7268,7 @@ s390_hard_regno_mode_ok (unsigned int regno, enum machine_mode mode)
default:
return false;
}
-
+
return false;
}
@@ -7370,7 +7365,7 @@ s390_initial_elimination_offset (int from, int to)
switch (from)
{
case FRAME_POINTER_REGNUM:
- offset = (get_frame_size()
+ offset = (get_frame_size()
+ STACK_POINTER_OFFSET
+ crtl->outgoing_args_size);
break;
@@ -7429,6 +7424,21 @@ restore_fpr (rtx base, int offset, int regnum)
return emit_move_insn (gen_rtx_REG (DFmode, regnum), addr);
}
+/* Return true if REGNO is a global register, but not one
+ of the special ones that need to be saved/restored in anyway. */
+
+static inline bool
+global_not_special_regno_p (int regno)
+{
+ return (global_regs[regno]
+ /* These registers are special and need to be
+ restored in any case. */
+ && !(regno == STACK_POINTER_REGNUM
+ || regno == RETURN_REGNUM
+ || regno == BASE_REGNUM
+ || (flag_pic && regno == (int)PIC_OFFSET_TABLE_REGNUM)));
+}
+
/* Generate insn to save registers FIRST to LAST into
the register save area located at offset OFFSET
relative to register BASE. */
@@ -7452,7 +7462,8 @@ save_gprs (rtx base, int offset, int first, int last)
else
insn = gen_movsi (addr, gen_rtx_REG (Pmode, first));
- RTX_FRAME_RELATED_P (insn) = 1;
+ if (!global_not_special_regno_p (first))
+ RTX_FRAME_RELATED_P (insn) = 1;
return insn;
}
@@ -7465,7 +7476,7 @@ save_gprs (rtx base, int offset, int first, int last)
for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
{
rtx mem = XEXP (XVECEXP (PATTERN (insn), 0, i), 0);
-
+
if (first + i <= 6)
set_mem_alias_set (mem, get_varargs_alias_set ());
}
@@ -7482,28 +7493,41 @@ save_gprs (rtx base, int offset, int first, int last)
set, even if it does not. Therefore we emit a new pattern
without those registers as REG_FRAME_RELATED_EXPR note. */
- if (first >= 6)
+ if (first >= 6 && !global_not_special_regno_p (first))
{
rtx pat = PATTERN (insn);
for (i = 0; i < XVECLEN (pat, 0); i++)
- if (GET_CODE (XVECEXP (pat, 0, i)) == SET)
+ if (GET_CODE (XVECEXP (pat, 0, i)) == SET
+ && !global_not_special_regno_p (REGNO (SET_SRC (XVECEXP (pat,
+ 0, i)))))
RTX_FRAME_RELATED_P (XVECEXP (pat, 0, i)) = 1;
RTX_FRAME_RELATED_P (insn) = 1;
}
else if (last >= 6)
{
- addr = plus_constant (base, offset + (6 - first) * UNITS_PER_WORD);
+ int start;
+
+ for (start = first >= 6 ? first : 6; start <= last; start++)
+ if (!global_not_special_regno_p (start))
+ break;
+
+ if (start > last)
+ return insn;
+
+ addr = plus_constant (base, offset + (start - first) * UNITS_PER_WORD);
note = gen_store_multiple (gen_rtx_MEM (Pmode, addr),
- gen_rtx_REG (Pmode, 6),
- GEN_INT (last - 6 + 1));
+ gen_rtx_REG (Pmode, start),
+ GEN_INT (last - start + 1));
note = PATTERN (note);
add_reg_note (insn, REG_FRAME_RELATED_EXPR, note);
for (i = 0; i < XVECLEN (note, 0); i++)
- if (GET_CODE (XVECEXP (note, 0, i)) == SET)
+ if (GET_CODE (XVECEXP (note, 0, i)) == SET
+ && !global_not_special_regno_p (REGNO (SET_SRC (XVECEXP (note,
+ 0, i)))))
RTX_FRAME_RELATED_P (XVECEXP (note, 0, i)) = 1;
RTX_FRAME_RELATED_P (insn) = 1;
@@ -7629,8 +7653,8 @@ s390_emit_prologue (void)
/* Choose best register to use for temp use within prologue.
See below for why TPF must use the register 1. */
- if (!has_hard_reg_initial_val (Pmode, RETURN_REGNUM)
- && !current_function_is_leaf
+ if (!has_hard_reg_initial_val (Pmode, RETURN_REGNUM)
+ && !current_function_is_leaf
&& !TARGET_TPF_PROFILING)
temp_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
else
@@ -7639,11 +7663,11 @@ s390_emit_prologue (void)
/* Save call saved gprs. */
if (cfun_frame_layout.first_save_gpr != -1)
{
- insn = save_gprs (stack_pointer_rtx,
- cfun_frame_layout.gprs_offset +
- UNITS_PER_WORD * (cfun_frame_layout.first_save_gpr
+ insn = save_gprs (stack_pointer_rtx,
+ cfun_frame_layout.gprs_offset +
+ UNITS_PER_WORD * (cfun_frame_layout.first_save_gpr
- cfun_frame_layout.first_save_gpr_slot),
- cfun_frame_layout.first_save_gpr,
+ cfun_frame_layout.first_save_gpr,
cfun_frame_layout.last_save_gpr);
emit_insn (insn);
}
@@ -7696,14 +7720,14 @@ s390_emit_prologue (void)
if (cfun_fpr_bit_p (i))
{
insn = save_fpr (stack_pointer_rtx, offset, i + 16);
-
+
RTX_FRAME_RELATED_P (insn) = 1;
offset -= 8;
}
if (offset >= cfun_frame_layout.f8_offset)
next_fpr = i + 16;
}
-
+
if (!TARGET_PACKED_STACK)
next_fpr = cfun_save_high_fprs_p ? 31 : 0;
@@ -7747,21 +7771,17 @@ s390_emit_prologue (void)
rtx t = gen_rtx_AND (Pmode, stack_pointer_rtx,
GEN_INT (stack_check_mask));
if (TARGET_64BIT)
- gen_cmpdi (t, const0_rtx);
+ emit_insn (gen_ctrapdi4 (gen_rtx_EQ (VOIDmode, t, const0_rtx),
+ t, const0_rtx, const0_rtx));
else
- gen_cmpsi (t, const0_rtx);
-
- emit_insn (gen_conditional_trap (gen_rtx_EQ (CCmode,
- gen_rtx_REG (CCmode,
- CC_REGNUM),
- const0_rtx),
- const0_rtx));
+ emit_insn (gen_ctrapsi4 (gen_rtx_EQ (VOIDmode, t, const0_rtx),
+ t, const0_rtx, const0_rtx));
}
}
- if (s390_warn_framesize > 0
+ if (s390_warn_framesize > 0
&& cfun_frame_layout.frame_size >= s390_warn_framesize)
- warning (0, "frame size of %qs is " HOST_WIDE_INT_PRINT_DEC " bytes",
+ warning (0, "frame size of %qs is " HOST_WIDE_INT_PRINT_DEC " bytes",
current_function_name (), cfun_frame_layout.frame_size);
if (s390_warn_dynamicstack_p && cfun->calls_alloca)
@@ -7776,7 +7796,7 @@ s390_emit_prologue (void)
if (DISP_IN_RANGE (INTVAL (frame_off)))
{
insn = gen_rtx_SET (VOIDmode, stack_pointer_rtx,
- gen_rtx_PLUS (Pmode, stack_pointer_rtx,
+ gen_rtx_PLUS (Pmode, stack_pointer_rtx,
frame_off));
insn = emit_insn (insn);
}
@@ -7801,11 +7821,11 @@ s390_emit_prologue (void)
if (TARGET_BACKCHAIN)
{
if (cfun_frame_layout.backchain_offset)
- addr = gen_rtx_MEM (Pmode,
- plus_constant (stack_pointer_rtx,
+ addr = gen_rtx_MEM (Pmode,
+ plus_constant (stack_pointer_rtx,
cfun_frame_layout.backchain_offset));
else
- addr = gen_rtx_MEM (Pmode, stack_pointer_rtx);
+ addr = gen_rtx_MEM (Pmode, stack_pointer_rtx);
set_mem_alias_set (addr, get_frame_alias_set ());
insn = emit_insn (gen_move_insn (addr, temp_reg));
}
@@ -7830,7 +7850,7 @@ s390_emit_prologue (void)
moved below the use of the stack slots. */
s390_emit_stack_tie ();
- insn = emit_insn (gen_add2_insn (temp_reg,
+ insn = emit_insn (gen_add2_insn (temp_reg,
GEN_INT (cfun_frame_layout.f8_offset)));
offset = 0;
@@ -7842,7 +7862,7 @@ s390_emit_prologue (void)
cfun_frame_layout.frame_size
+ cfun_frame_layout.f8_offset
+ offset);
-
+
insn = save_fpr (temp_reg, offset, i);
offset += 8;
RTX_FRAME_RELATED_P (insn) = 1;
@@ -7891,7 +7911,7 @@ s390_emit_prologue (void)
void
s390_emit_epilogue (bool sibcall)
{
- rtx frame_pointer, return_reg;
+ rtx frame_pointer, return_reg, cfa_restores = NULL_RTX;
int area_bottom, area_top, offset = 0;
int next_offset;
rtvec p;
@@ -7913,7 +7933,7 @@ s390_emit_epilogue (bool sibcall)
/* Check whether to use frame or stack pointer for restore. */
- frame_pointer = (frame_pointer_needed
+ frame_pointer = (frame_pointer_needed
? hard_frame_pointer_rtx : stack_pointer_rtx);
s390_frame_area (&area_bottom, &area_top);
@@ -7933,11 +7953,13 @@ s390_emit_epilogue (bool sibcall)
}
else
{
- rtx insn, frame_off;
+ rtx insn, frame_off, cfa;
offset = area_bottom < 0 ? -area_bottom : 0;
frame_off = GEN_INT (cfun_frame_layout.frame_size - offset);
+ cfa = gen_rtx_SET (VOIDmode, frame_pointer,
+ gen_rtx_PLUS (Pmode, frame_pointer, frame_off));
if (DISP_IN_RANGE (INTVAL (frame_off)))
{
insn = gen_rtx_SET (VOIDmode, frame_pointer,
@@ -7952,6 +7974,8 @@ s390_emit_epilogue (bool sibcall)
insn = emit_insn (gen_add2_insn (frame_pointer, frame_off));
annotate_constant_pool_refs (&PATTERN (insn));
}
+ add_reg_note (insn, REG_CFA_ADJUST_CFA, cfa);
+ RTX_FRAME_RELATED_P (insn) = 1;
}
/* Restore call saved fprs. */
@@ -7967,11 +7991,14 @@ s390_emit_epilogue (bool sibcall)
{
restore_fpr (frame_pointer,
offset + next_offset, i);
+ cfa_restores
+ = alloc_reg_note (REG_CFA_RESTORE,
+ gen_rtx_REG (DFmode, i), cfa_restores);
next_offset += 8;
}
}
}
-
+
}
else
{
@@ -7982,12 +8009,15 @@ s390_emit_epilogue (bool sibcall)
{
restore_fpr (frame_pointer,
offset + next_offset, i);
+ cfa_restores
+ = alloc_reg_note (REG_CFA_RESTORE,
+ gen_rtx_REG (DFmode, i), cfa_restores);
next_offset += 8;
}
else if (!TARGET_PACKED_STACK)
next_offset += 8;
}
-
+
}
/* Return register. */
@@ -8008,24 +8038,20 @@ s390_emit_epilogue (bool sibcall)
i <= cfun_frame_layout.last_restore_gpr;
i++)
{
- /* These registers are special and need to be
- restored in any case. */
- if (i == STACK_POINTER_REGNUM
- || i == RETURN_REGNUM
- || i == BASE_REGNUM
- || (flag_pic && i == (int)PIC_OFFSET_TABLE_REGNUM))
- continue;
-
- if (global_regs[i])
+ if (global_not_special_regno_p (i))
{
addr = plus_constant (frame_pointer,
- offset + cfun_frame_layout.gprs_offset
+ offset + cfun_frame_layout.gprs_offset
+ (i - cfun_frame_layout.first_save_gpr_slot)
* UNITS_PER_WORD);
addr = gen_rtx_MEM (Pmode, addr);
set_mem_alias_set (addr, get_frame_alias_set ());
emit_move_insn (addr, gen_rtx_REG (Pmode, i));
}
+ else
+ cfa_restores
+ = alloc_reg_note (REG_CFA_RESTORE,
+ gen_rtx_REG (Pmode, i), cfa_restores);
}
if (! sibcall)
@@ -8044,7 +8070,7 @@ s390_emit_epilogue (bool sibcall)
addr = plus_constant (frame_pointer,
offset + cfun_frame_layout.gprs_offset
- + (RETURN_REGNUM
+ + (RETURN_REGNUM
- cfun_frame_layout.first_save_gpr_slot)
* UNITS_PER_WORD);
addr = gen_rtx_MEM (Pmode, addr);
@@ -8055,12 +8081,16 @@ s390_emit_epilogue (bool sibcall)
insn = restore_gprs (frame_pointer,
offset + cfun_frame_layout.gprs_offset
- + (cfun_frame_layout.first_restore_gpr
+ + (cfun_frame_layout.first_restore_gpr
- cfun_frame_layout.first_save_gpr_slot)
* UNITS_PER_WORD,
cfun_frame_layout.first_restore_gpr,
cfun_frame_layout.last_restore_gpr);
- emit_insn (insn);
+ insn = emit_insn (insn);
+ REG_NOTES (insn) = cfa_restores;
+ add_reg_note (insn, REG_CFA_DEF_CFA,
+ plus_constant (stack_pointer_rtx, STACK_POINTER_OFFSET));
+ RTX_FRAME_RELATED_P (insn) = 1;
}
if (! sibcall)
@@ -8354,15 +8384,20 @@ s390_build_builtin_va_list (void)
record = lang_hooks.types.make_type (RECORD_TYPE);
type_decl =
- build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
+ build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier ("__va_list_tag"), record);
- f_gpr = build_decl (FIELD_DECL, get_identifier ("__gpr"),
+ f_gpr = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, get_identifier ("__gpr"),
long_integer_type_node);
- f_fpr = build_decl (FIELD_DECL, get_identifier ("__fpr"),
+ f_fpr = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, get_identifier ("__fpr"),
long_integer_type_node);
- f_ovf = build_decl (FIELD_DECL, get_identifier ("__overflow_arg_area"),
+ f_ovf = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, get_identifier ("__overflow_arg_area"),
ptr_type_node);
- f_sav = build_decl (FIELD_DECL, get_identifier ("__reg_save_area"),
+ f_sav = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, get_identifier ("__reg_save_area"),
ptr_type_node);
va_list_gpr_counter_field = f_gpr;
@@ -8465,7 +8500,7 @@ s390_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
t = make_tree (TREE_TYPE (sav), return_address_pointer_rtx);
t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (sav), t,
size_int (-RETURN_REGNUM * UNITS_PER_WORD));
-
+
t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
TREE_SIDE_EFFECTS (t) = 1;
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
@@ -8497,7 +8532,7 @@ s390_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
} */
static tree
-s390_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
+s390_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
gimple_seq *post_p ATTRIBUTE_UNUSED)
{
tree f_gpr, f_fpr, f_ovf, f_sav;
@@ -8586,8 +8621,8 @@ s390_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
/* Pull the value out of the saved registers ... */
- lab_false = create_artificial_label ();
- lab_over = create_artificial_label ();
+ lab_false = create_artificial_label (UNKNOWN_LOCATION);
+ lab_over = create_artificial_label (UNKNOWN_LOCATION);
addr = create_tmp_var (ptr_type_node, "addr");
DECL_POINTER_ALIAS_SET (addr) = get_varargs_alias_set ();
@@ -8597,9 +8632,9 @@ s390_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
gimplify_and_add (t, pre_p);
- t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav,
+ t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav,
size_int (sav_ofs));
- u = build2 (MULT_EXPR, TREE_TYPE (reg), reg,
+ u = build2 (MULT_EXPR, TREE_TYPE (reg), reg,
fold_convert (TREE_TYPE (reg), size_int (sav_scale)));
t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t, fold_convert (sizetype, u));
@@ -8614,14 +8649,14 @@ s390_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
t = ovf;
if (size < UNITS_PER_WORD)
- t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t,
+ t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t,
size_int (UNITS_PER_WORD - size));
gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
gimplify_assign (addr, t, pre_p);
- t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t,
+ t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t,
size_int (size));
gimplify_assign (ovf, t, pre_p);
@@ -9277,7 +9312,7 @@ s390_fixed_condition_code_regs (unsigned int *p1, unsigned int *p2)
{
*p1 = CC_REGNUM;
*p2 = INVALID_REGNUM;
-
+
return true;
}
@@ -9443,10 +9478,10 @@ s390_optimize_prologue (void)
/* If all special registers are in fact used, there's nothing we
can do, so no point in walking the insn list. */
- if (cfun_frame_layout.first_save_gpr <= BASE_REGNUM
+ if (cfun_frame_layout.first_save_gpr <= BASE_REGNUM
&& cfun_frame_layout.last_save_gpr >= BASE_REGNUM
- && (TARGET_CPU_ZARCH
- || (cfun_frame_layout.first_save_gpr <= RETURN_REGNUM
+ && (TARGET_CPU_ZARCH
+ || (cfun_frame_layout.first_save_gpr <= RETURN_REGNUM
&& cfun_frame_layout.last_save_gpr >= RETURN_REGNUM)))
return;
@@ -9486,9 +9521,9 @@ s390_optimize_prologue (void)
if (cfun_frame_layout.first_save_gpr != -1)
{
- new_insn = save_gprs (base,
+ new_insn = save_gprs (base,
off + (cfun_frame_layout.first_save_gpr
- - first) * UNITS_PER_WORD,
+ - first) * UNITS_PER_WORD,
cfun_frame_layout.first_save_gpr,
cfun_frame_layout.last_save_gpr);
new_insn = emit_insn_before (new_insn, insn);
@@ -9547,9 +9582,9 @@ s390_optimize_prologue (void)
if (cfun_frame_layout.first_restore_gpr != -1)
{
- new_insn = restore_gprs (base,
+ new_insn = restore_gprs (base,
off + (cfun_frame_layout.first_restore_gpr
- - first) * UNITS_PER_WORD,
+ - first) * UNITS_PER_WORD,
cfun_frame_layout.first_restore_gpr,
cfun_frame_layout.last_restore_gpr);
new_insn = emit_insn_before (new_insn, insn);
@@ -9993,6 +10028,9 @@ s390_reorg (void)
#undef TARGET_LIBGCC_SHIFT_COUNT_MODE
#define TARGET_LIBGCC_SHIFT_COUNT_MODE s390_libgcc_shift_count_mode
+#undef TARGET_LEGITIMATE_ADDRESS_P
+#define TARGET_LEGITIMATE_ADDRESS_P s390_legitimate_address_p
+
struct gcc_target targetm = TARGET_INITIALIZER;
#include "gt-s390.h"
diff --git a/gcc/config/s390/s390.h b/gcc/config/s390/s390.h
index 2b4d7ce72ca..f34b7f22567 100644
--- a/gcc/config/s390/s390.h
+++ b/gcc/config/s390/s390.h
@@ -180,7 +180,7 @@ extern int s390_arch_flags;
#define S390_TDC_POSITIVE_NORMALIZED_DFP_NUMBER (1 << 7)
#define S390_TDC_NEGATIVE_NORMALIZED_DFP_NUMBER (1 << 6)
-/* For signbit, the BFP-DFP-difference makes no difference. */
+/* For signbit, the BFP-DFP-difference makes no difference. */
#define S390_TDC_SIGNBIT_SET (S390_TDC_NEGATIVE_ZERO \
| S390_TDC_NEGATIVE_NORMALIZED_BFP_NUMBER \
| S390_TDC_NEGATIVE_DENORMALIZED_BFP_NUMBER\
@@ -298,10 +298,10 @@ if (INTEGRAL_MODE_P (MODE) && \
correspond to actual hardware:
Reg 32: Argument pointer
Reg 33: Condition code
- Reg 34: Frame pointer
+ Reg 34: Frame pointer
Reg 35: Return address pointer
- Registers 36 and 37 are mapped to access registers
+ Registers 36 and 37 are mapped to access registers
0 and 1, used to implement thread-local storage. */
#define FIRST_PSEUDO_REGISTER 38
@@ -455,7 +455,7 @@ if (INTEGRAL_MODE_P (MODE) && \
enum reg_class
{
NO_REGS, CC_REGS, ADDR_REGS, GENERAL_REGS, ACCESS_REGS,
- ADDR_CC_REGS, GENERAL_CC_REGS,
+ ADDR_CC_REGS, GENERAL_CC_REGS,
FP_REGS, ADDR_FP_REGS, GENERAL_FP_REGS,
ALL_REGS, LIM_REG_CLASSES
};
@@ -575,7 +575,7 @@ extern const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER];
the argument area. */
#define FIRST_PARM_OFFSET(FNDECL) 0
-/* Defining this macro makes __builtin_frame_address(0) and
+/* Defining this macro makes __builtin_frame_address(0) and
__builtin_return_address(0) work with -fomit-frame-pointer. */
#define INITIAL_FRAME_ADDRESS_RTX \
(plus_constant (arg_pointer_rtx, -STACK_POINTER_OFFSET))
@@ -615,7 +615,7 @@ extern const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER];
/* Describe how we implement __builtin_eh_return. */
#define EH_RETURN_DATA_REGNO(N) ((N) < 4 ? (N) + 6 : INVALID_REGNUM)
#define EH_RETURN_HANDLER_RTX gen_rtx_MEM (Pmode, return_address_pointer_rtx)
-
+
/* Select a format to encode pointers in exception handling data. */
#define ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL) \
(flag_pic \
@@ -740,30 +740,12 @@ CUMULATIVE_ARGS;
#define MAX_REGS_PER_ADDRESS 2
/* This definition replaces the formerly used 'm' constraint with a
-different constraint letter in order to avoid changing semantics of
-the 'm' constraint when accepting new address formats in
-legitimate_address_p. The constraint letter defined here must not be
-used in insn definitions or inline assemblies. */
+ different constraint letter in order to avoid changing semantics of
+ the 'm' constraint when accepting new address formats in
+ TARGET_LEGITIMATE_ADDRESS_P. The constraint letter defined here
+ must not be used in insn definitions or inline assemblies. */
#define TARGET_MEM_CONSTRAINT 'e'
-/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression that is a
- valid memory address for an instruction.
- The MODE argument is the machine mode for the MEM expression
- that wants to use this address. */
-#ifdef REG_OK_STRICT
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
-{ \
- if (legitimate_address_p (MODE, X, 1)) \
- goto ADDR; \
-}
-#else
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
-{ \
- if (legitimate_address_p (MODE, X, 0)) \
- goto ADDR; \
-}
-#endif
-
/* Try a machine-dependent way of reloading an illegitimate address
operand. If we find one, push the reload and jump to WIN. This
macro is used in only one place: `find_reloads_address' in reload.c. */
@@ -803,12 +785,6 @@ do { \
#define CANONICALIZE_COMPARISON(CODE, OP0, OP1) \
s390_canonicalize_comparison (&(CODE), &(OP0), &(OP1))
-/* Define the information needed to generate branch and scc insns. This is
- stored from the compare operation. Note that we can't use "rtx" here
- since it hasn't been defined! */
-extern struct rtx_def *s390_compare_op0, *s390_compare_op1;
-
-
/* Relative costs of operations. */
/* On s390, copy between fprs and gprs is expensive. */
@@ -831,7 +807,7 @@ extern struct rtx_def *s390_compare_op0, *s390_compare_op1;
#define SLOW_BYTE_ACCESS 1
/* An integer expression for the size in bits of the largest integer machine
- mode that should actually be used. We allow pairs of registers. */
+ mode that should actually be used. We allow pairs of registers. */
#define MAX_FIXED_MODE_SIZE GET_MODE_BITSIZE (TARGET_64BIT ? TImode : DImode)
/* The maximum number of bytes that a single instruction can move quickly
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index c3d181f0aac..ed08f6ee6a6 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -37,7 +37,7 @@
;; %N: print the second word of a DImode operand.
;; %M: print the second word of a TImode operand.
;; %Y: print shift count operand.
-;;
+;;
;; %b: print integer X as if it's an unsigned byte.
;; %c: print integer X as if it's an signed byte.
;; %x: print integer X as if it's an unsigned halfword.
@@ -154,7 +154,7 @@
(RETURN_REGNUM 14)
; Condition code register.
(CC_REGNUM 33)
- ; Thread local storage pointer register.
+ ; Thread local storage pointer register.
(TP_REGNUM 36)
])
@@ -220,7 +220,7 @@
;; reg: Instruction does not use the agen unit
(define_attr "atype" "agen,reg"
- (if_then_else (eq_attr "op_type" "E,RR,RI,RRE")
+ (if_then_else (eq_attr "op_type" "E,RR,RI,RRE")
(const_string "reg")
(const_string "agen")))
@@ -319,7 +319,7 @@
;; These mode iterators allow floating point patterns to be generated from the
;; same template.
-(define_mode_iterator FP_ALL [TF DF SF (TD "TARGET_HARD_DFP") (DD "TARGET_HARD_DFP")
+(define_mode_iterator FP_ALL [TF DF SF (TD "TARGET_HARD_DFP") (DD "TARGET_HARD_DFP")
(SD "TARGET_HARD_DFP")])
(define_mode_iterator FP [TF DF SF (TD "TARGET_HARD_DFP") (DD "TARGET_HARD_DFP")])
(define_mode_iterator FPALL [TF DF SF TD DD SD])
@@ -354,28 +354,21 @@
(define_mode_iterator INT [(DI "TARGET_64BIT") SI HI QI])
(define_mode_iterator INTALL [TI DI SI HI QI])
-;; This iterator allows to unify all 'bCOND' expander patterns.
-(define_code_iterator COMPARE [eq ne gt gtu lt ltu ge geu le leu unordered
- ordered uneq unlt ungt unle unge ltgt])
-
-;; This iterator allows to unify all 'sCOND' patterns.
-(define_code_iterator SCOND [ltu gtu leu geu])
-
;; This iterator allows some 'ashift' and 'lshiftrt' pattern to be defined from
;; the same template.
(define_code_iterator SHIFT [ashift lshiftrt])
;; This iterator and attribute allow to combine most atomic operations.
(define_code_iterator ATOMIC [and ior xor plus minus mult])
-(define_code_attr atomic [(and "and") (ior "ior") (xor "xor")
+(define_code_attr atomic [(and "and") (ior "ior") (xor "xor")
(plus "add") (minus "sub") (mult "nand")])
-;; In FP templates, a string like "lt<de>br" will expand to "ltxbr" in
+;; In FP templates, a string like "lt<de>br" will expand to "ltxbr" in
;; TF/TDmode, "ltdbr" in DF/DDmode, and "ltebr" in SF/SDmode.
(define_mode_attr xde [(TF "x") (DF "d") (SF "e") (TD "x") (DD "d") (SD "e")])
-;; In FP templates, a <dee> in "m<dee><bt>r" will expand to "mx<bt>r" in
-;; TF/TDmode, "md<bt>r" in DF/DDmode, "mee<bt>r" in SFmode and "me<bt>r in
+;; In FP templates, a <dee> in "m<dee><bt>r" will expand to "mx<bt>r" in
+;; TF/TDmode, "md<bt>r" in DF/DDmode, "mee<bt>r" in SFmode and "me<bt>r in
;; SDmode.
(define_mode_attr xdee [(TF "x") (DF "d") (SF "ee") (TD "x") (DD "d") (SD "e")])
@@ -389,14 +382,14 @@
;; dfp variants in a single insn definition.
;; This attribute is used to set op_type accordingly.
-(define_mode_attr RRer [(TF "RRE") (DF "RRE") (SF "RRE") (TD "RRR")
+(define_mode_attr RRer [(TF "RRE") (DF "RRE") (SF "RRE") (TD "RRR")
(DD "RRR") (SD "RRR")])
-;; This attribute is used in the operand constraint list in order to have the
+;; This attribute is used in the operand constraint list in order to have the
;; first and the second operand match for bfp modes.
(define_mode_attr f0 [(TF "0") (DF "0") (SF "0") (TD "f") (DD "f") (DD "f")])
-;; This attribute is used in the operand list of the instruction to have an
+;; This attribute is used in the operand list of the instruction to have an
;; additional operand for the dfp instructions.
(define_mode_attr op1 [(TF "") (DF "") (SF "")
(TD "%1,") (DD "%1,") (SD "%1,")])
@@ -493,39 +486,6 @@
;;- Compare instructions.
;;
-(define_expand "cmp<mode>"
- [(set (reg:CC CC_REGNUM)
- (compare:CC (match_operand:GPR 0 "register_operand" "")
- (match_operand:GPR 1 "general_operand" "")))]
- ""
-{
- s390_compare_op0 = operands[0];
- s390_compare_op1 = operands[1];
- DONE;
-})
-
-(define_expand "cmp<mode>"
- [(set (reg:CC CC_REGNUM)
- (compare:CC (match_operand:FP 0 "register_operand" "")
- (match_operand:FP 1 "general_operand" "")))]
- "TARGET_HARD_FLOAT"
-{
- s390_compare_op0 = operands[0];
- s390_compare_op1 = operands[1];
- DONE;
-})
-
-(define_expand "cmpcc"
- [(set (reg:CC CC_REGNUM)
- (compare:CC (match_operand 0 "cc_reg_operand" "")
- (match_operand 1 "general_operand" "")))]
- ""
-{
- s390_compare_op0 = operands[0];
- s390_compare_op1 = operands[1];
- DONE;
-})
-
; Test-under-Mask instructions
(define_insn "*tmqi_mem"
@@ -3812,9 +3772,9 @@
TD -> DI convert afterwards. */
emit_insn (gen_extendddtd2 (temp, operands[1]));
temp = force_reg (TDmode, temp);
- emit_insn (gen_cmptd (temp,
- CONST_DOUBLE_FROM_REAL_VALUE (cmp, TDmode)));
- emit_jump_insn (gen_blt (label1));
+ emit_cmp_and_jump_insns (temp,
+ CONST_DOUBLE_FROM_REAL_VALUE (cmp, TDmode),
+ LT, NULL_RTX, VOIDmode, 0, label1);
emit_insn (gen_subtd3 (temp, temp,
CONST_DOUBLE_FROM_REAL_VALUE (sub, TDmode)));
emit_insn (gen_fix_trunctddi2_dfp (operands[0], temp, GEN_INT (11)));
@@ -3840,9 +3800,9 @@
decimal_real_from_string (&cmp, "9223372036854775808.0"); /* 2^63 */
decimal_real_from_string (&sub, "18446744073709551616.0"); /* 2^64 */
- emit_insn (gen_cmptd (operands[1],
- CONST_DOUBLE_FROM_REAL_VALUE (cmp, TDmode)));
- emit_jump_insn (gen_blt (label1));
+ emit_cmp_and_jump_insns (operands[1],
+ CONST_DOUBLE_FROM_REAL_VALUE (cmp, TDmode),
+ LT, NULL_RTX, VOIDmode, 0, label1);
emit_insn (gen_subtd3 (temp, operands[1],
CONST_DOUBLE_FROM_REAL_VALUE (sub, TDmode)));
emit_insn (gen_fix_trunctddi2_dfp (operands[0], temp, GEN_INT (11)));
@@ -3873,9 +3833,9 @@
real_2expN (&cmp, GET_MODE_BITSIZE(<GPR:MODE>mode) - 1, <BFP:MODE>mode);
real_2expN (&sub, GET_MODE_BITSIZE(<GPR:MODE>mode), <BFP:MODE>mode);
- emit_insn (gen_cmp<BFP:mode> (operands[1],
- CONST_DOUBLE_FROM_REAL_VALUE (cmp, <BFP:MODE>mode)));
- emit_jump_insn (gen_blt (label1));
+ emit_cmp_and_jump_insns (operands[1],
+ CONST_DOUBLE_FROM_REAL_VALUE (cmp, <BFP:MODE>mode),
+ LT, NULL_RTX, VOIDmode, 0, label1);
emit_insn (gen_sub<BFP:mode>3 (temp, operands[1],
CONST_DOUBLE_FROM_REAL_VALUE (sub, <BFP:MODE>mode)));
emit_insn (gen_fix_trunc<BFP:mode><GPR:mode>2_bfp (operands[0], temp,
@@ -5074,7 +5034,7 @@
(match_operand:GPR 3 "const_int_operand" "")]
"TARGET_CPU_ZARCH"
"if (!s390_expand_addcc (GET_CODE (operands[1]),
- s390_compare_op0, s390_compare_op1,
+ XEXP (operands[1], 0), XEXP (operands[1], 1),
operands[0], operands[2],
operands[3])) FAIL; DONE;")
@@ -5114,31 +5074,29 @@
"")
-(define_expand "s<code>"
+(define_expand "cstore<mode>4"
[(set (match_operand:SI 0 "register_operand" "")
- (SCOND (match_dup 0)
- (match_dup 0)))]
+ (match_operator:SI 1 "s390_scond_operator"
+ [(match_operand:GPR 2 "register_operand" "")
+ (match_operand:GPR 3 "general_operand" "")]))]
"TARGET_CPU_ZARCH"
- "if (!s390_expand_addcc (<CODE>, s390_compare_op0, s390_compare_op1,
+ "if (!s390_expand_addcc (GET_CODE (operands[1]), operands[2], operands[3],
operands[0], const0_rtx, const1_rtx)) FAIL; DONE;")
-(define_expand "seq"
+(define_expand "cstorecc4"
[(parallel
- [(set (match_operand:SI 0 "register_operand" "=d")
- (match_dup 1))
- (clobber (reg:CC CC_REGNUM))])
- (parallel
- [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 1)))
+ [(set (match_operand:SI 0 "register_operand" "")
+ (match_operator:SI 1 "s390_eqne_operator"
+ [(match_operand:CCZ1 2 "register_operand")
+ (match_operand 3 "const0_operand")]))
(clobber (reg:CC CC_REGNUM))])]
""
-{
- if (GET_MODE (s390_compare_op0) != CCZ1mode)
- FAIL;
- operands[1] = s390_emit_compare (NE, s390_compare_op0, s390_compare_op1);
- PUT_MODE (operands[1], SImode);
-})
+ "emit_insn (gen_sne (operands[0], operands[2]));
+ if (GET_CODE (operands[1]) == EQ)
+ emit_insn (gen_xorsi3 (operands[0], operands[0], const1_rtx));
+ DONE;")
-(define_insn_and_split "*sne"
+(define_insn_and_split "sne"
[(set (match_operand:SI 0 "register_operand" "=d")
(ne:SI (match_operand:CCZ1 1 "register_operand" "0")
(const_int 0)))
@@ -5566,8 +5524,8 @@
operands[1] = make_safe_from (operands[1], operands[0]);
emit_move_insn (operands[0], const0_rtx);
- emit_insn (gen_cmpsi (operands[1], operands[2]));
- emit_jump_insn (gen_bltu (label1));
+ emit_cmp_and_jump_insns (operands[1], operands[2], LT, NULL_RTX,
+ SImode, 1, label1);
emit_move_insn (operands[0], const1_rtx);
emit_label (label1);
}
@@ -5598,12 +5556,12 @@
operands[2] = make_safe_from (operands[2], operands[0]);
emit_move_insn (operands[0], const0_rtx);
- emit_insn (gen_cmpsi (operands[2], operands[1]));
- emit_jump_insn (gen_bgtu (label3));
- emit_insn (gen_cmpsi (operands[2], const0_rtx));
- emit_jump_insn (gen_blt (label2));
- emit_insn (gen_cmpsi (operands[2], const1_rtx));
- emit_jump_insn (gen_beq (label1));
+ emit_cmp_and_jump_insns (operands[2], operands[1], GT, NULL_RTX,
+ SImode, 1, label3);
+ emit_cmp_and_jump_insns (operands[2], const0_rtx, LT, NULL_RTX,
+ SImode, 0, label2);
+ emit_cmp_and_jump_insns (operands[2], const1_rtx, EQ, NULL_RTX,
+ SImode, 0, label1);
emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
operands[2]));
@@ -5652,8 +5610,8 @@
operands[1] = make_safe_from (operands[1], operands[0]);
emit_move_insn (operands[0], operands[1]);
- emit_insn (gen_cmpsi (operands[0], operands[2]));
- emit_jump_insn (gen_bltu (label1));
+ emit_cmp_and_jump_insns (operands[0], operands[2], LT, NULL_RTX,
+ SImode, 1, label1);
emit_insn (gen_abssi2 (operands[0], operands[2]));
emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
emit_label (label1);
@@ -5685,12 +5643,12 @@
operands[2] = make_safe_from (operands[2], operands[0]);
emit_move_insn(operands[0], operands[1]);
- emit_insn (gen_cmpsi (operands[2], operands[1]));
- emit_jump_insn (gen_bgtu (label3));
- emit_insn (gen_cmpsi (operands[2], const0_rtx));
- emit_jump_insn (gen_blt (label2));
- emit_insn (gen_cmpsi (operands[2], const1_rtx));
- emit_jump_insn (gen_beq (label1));
+ emit_cmp_and_jump_insns (operands[2], operands[1], GT, NULL_RTX,
+ SImode, 1, label3);
+ emit_cmp_and_jump_insns (operands[2], const0_rtx, LT, NULL_RTX,
+ SImode, 0, label2);
+ emit_cmp_and_jump_insns (operands[2], const1_rtx, EQ, NULL_RTX,
+ SImode, 0, label1);
emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
operands[2]));
@@ -7359,15 +7317,42 @@
;; Branch instruction patterns.
;;
-(define_expand "b<code>"
+(define_expand "cbranch<mode>4"
[(set (pc)
- (if_then_else (COMPARE (match_operand 0 "" "")
- (const_int 0))
- (match_dup 0)
+ (if_then_else (match_operator 0 "comparison_operator"
+ [(match_operand:GPR 1 "register_operand" "")
+ (match_operand:GPR 2 "general_operand" "")])
+ (label_ref (match_operand 3 "" ""))
(pc)))]
""
- "s390_emit_jump (operands[0],
- s390_emit_compare (<CODE>, s390_compare_op0, s390_compare_op1)); DONE;")
+ "s390_emit_jump (operands[3],
+ s390_emit_compare (GET_CODE (operands[0]), operands[1], operands[2]));
+ DONE;")
+
+(define_expand "cbranch<mode>4"
+ [(set (pc)
+ (if_then_else (match_operator 0 "comparison_operator"
+ [(match_operand:FP 1 "register_operand" "")
+ (match_operand:FP 2 "general_operand" "")])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
+ "TARGET_HARD_FLOAT"
+ "s390_emit_jump (operands[3],
+ s390_emit_compare (GET_CODE (operands[0]), operands[1], operands[2]));
+ DONE;")
+
+(define_expand "cbranchcc4"
+ [(set (pc)
+ (if_then_else (match_operator 0 "s390_eqne_operator"
+ [(match_operand 1 "cc_reg_operand" "")
+ (match_operand 2 "const0_operand" "")])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
+ "TARGET_HARD_FLOAT"
+ "s390_emit_jump (operands[3],
+ s390_emit_compare (GET_CODE (operands[0]), operands[1], operands[2]));
+ DONE;")
+
;;
@@ -7506,18 +7491,36 @@
[(set_attr "op_type" "RI")
(set_attr "type" "branch")])
-(define_expand "conditional_trap"
- [(trap_if (match_operand 0 "comparison_operator" "")
- (match_operand 1 "general_operand" ""))]
+(define_expand "ctrap<mode>4"
+ [(trap_if (match_operator 0 "comparison_operator"
+ [(match_operand:GPR 1 "register_operand" "")
+ (match_operand:GPR 2 "general_operand" "")])
+ (match_operand 3 "const0_operand" ""))]
""
-{
- if (operands[1] != const0_rtx) FAIL;
- operands[0] = s390_emit_compare (GET_CODE (operands[0]),
- s390_compare_op0, s390_compare_op1);
-})
+ {
+ rtx cond = s390_emit_compare (GET_CODE (operands[0]),
+ operands[1], operands[2]);
+ emit_insn (gen_condtrap (cond, XEXP (cond, 0)));
+ DONE;
+ })
+
+(define_expand "ctrap<mode>4"
+ [(trap_if (match_operator 0 "comparison_operator"
+ [(match_operand:FP 1 "register_operand" "")
+ (match_operand:FP 2 "general_operand" "")])
+ (match_operand 3 "const0_operand" ""))]
+ ""
+ {
+ rtx cond = s390_emit_compare (GET_CODE (operands[0]),
+ operands[1], operands[2]);
+ emit_insn (gen_condtrap (cond, XEXP (cond, 0)));
+ DONE;
+ })
-(define_insn "*trap"
- [(trap_if (match_operator 0 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
+(define_insn "condtrap"
+ [(trap_if (match_operator 0 "s390_comparison"
+ [(match_operand 1 "cc_reg_operand" "c")
+ (const_int 0)])
(const_int 0))]
""
"j%C0\t.+2";
@@ -8665,6 +8668,7 @@
(match_operand 2 "" "")]
""
{
+ rtx cc_reg, test;
#ifdef TARGET_THREAD_SSP_OFFSET
operands[1]
= gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, s390_get_thread_pointer (),
@@ -8675,9 +8679,9 @@
else
emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
- s390_compare_op0 = gen_rtx_REG (CCZmode, CC_REGNUM);
- s390_compare_op1 = const0_rtx;
- emit_jump_insn (gen_beq (operands[2]));
+ cc_reg = gen_rtx_REG (CCZmode, CC_REGNUM);
+ test = gen_rtx_EQ (VOIDmode, cc_reg, const0_rtx);
+ emit_jump_insn (gen_cbranchcc4 (test, cc_reg, const0_rtx, operands[2]));
DONE;
})
@@ -8735,7 +8739,7 @@
(define_insn "bswap<mode>2"
[(set (match_operand:GPR 0 "register_operand" "=d, d")
(bswap:GPR (match_operand:GPR 1 "nonimmediate_operand" " d,RT")))]
- ""
+ "TARGET_CPU_ZARCH"
"@
lrv<g>r\t%0,%1
lrv<g>\t%0,%1"
diff --git a/gcc/config/s390/tpf-unwind.h b/gcc/config/s390/tpf-unwind.h
index 4fd9ffaa103..33fd5f5c8c5 100644
--- a/gcc/config/s390/tpf-unwind.h
+++ b/gcc/config/s390/tpf-unwind.h
@@ -46,7 +46,7 @@ __isPATrange (void *addr)
/* TPF return address offset from start of stack frame. */
#define TPFRA_OFFSET 168
-/* Exceptions macro defined for TPF so that functions without
+/* Exceptions macro defined for TPF so that functions without
dwarf frame information can be used with exceptions. */
#define MD_FALLBACK_FRAME_STATE_FOR s390_fallback_frame_state
@@ -165,20 +165,20 @@ __tpf_eh_return (void *target)
/* Begin looping through stack frames. Stop if invalid
code information is retrieved or if a match between the
- current stack frame iteration shared object's address
+ current stack frame iteration shared object's address
matches that of the target, calculated above. */
do
{
/* Get return address based on our stackptr iterator. */
- current = (void *) *((unsigned long int *)
+ current = (void *) *((unsigned long int *)
(stackptr+RA_OFFSET));
/* Is it a Pat Stub? */
- if (__isPATrange (current))
+ if (__isPATrange (current))
{
- /* Yes it was, get real return address
+ /* Yes it was, get real return address
in TPF stack area. */
- current = (void *) *((unsigned long int *)
+ current = (void *) *((unsigned long int *)
(stackptr+TPFRA_OFFSET));
is_a_stub = 1;
}
@@ -198,7 +198,7 @@ __tpf_eh_return (void *target)
/* Yes! They are in the same module.
Force copy of TPF private stack area to
destination stack frame TPF private area. */
- destination_frame = (void *) *((unsigned long int *)
+ destination_frame = (void *) *((unsigned long int *)
(*PREVIOUS_STACK_PTR() + R15_OFFSET));
/* Copy TPF linkage area from current frame to
@@ -209,24 +209,24 @@ __tpf_eh_return (void *target)
/* Now overlay the
real target address into the TPF stack area of
the target frame we are jumping to. */
- *((unsigned long int *) (destination_frame +
+ *((unsigned long int *) (destination_frame +
TPFRA_OFFSET)) = (unsigned long int) target;
/* Before returning the desired pat stub address to
- the exception handling unwinder so that it can
- actually do the "leap" shift out the low order
+ the exception handling unwinder so that it can
+ actually do the "leap" shift out the low order
bit designated to determine if we are in 64BIT mode.
This is necessary for CTOA stubs.
- Otherwise we leap one byte past where we want to
+ Otherwise we leap one byte past where we want to
go to in the TPF pat stub linkage code. */
- shifter = *((unsigned long int *)
+ shifter = *((unsigned long int *)
(stackptr + RA_OFFSET));
shifter &= ~1ul;
/* Store Pat Stub Address in destination Stack Frame. */
*((unsigned long int *) (destination_frame +
- RA_OFFSET)) = shifter;
+ RA_OFFSET)) = shifter;
/* Re-adjust pat stub address to go to correct place
in linkage. */
diff --git a/gcc/config/score/score-conv.h b/gcc/config/score/score-conv.h
index 67855da895e..e042dc1b7d3 100644
--- a/gcc/config/score/score-conv.h
+++ b/gcc/config/score/score-conv.h
@@ -22,11 +22,6 @@
extern int target_flags;
-/* Define the information needed to generate branch insns. This is
- stored from the compare operation. */
-extern GTY(()) rtx cmp_op0;
-extern GTY(()) rtx cmp_op1;
-
#define GP_REG_FIRST 0U
#define GP_REG_LAST 31U
#define GP_REG_NUM (GP_REG_LAST - GP_REG_FIRST + 1U)
diff --git a/gcc/config/score/score-protos.h b/gcc/config/score/score-protos.h
index d6739b8cf4c..204dc1876a4 100644
--- a/gcc/config/score/score-protos.h
+++ b/gcc/config/score/score-protos.h
@@ -25,7 +25,6 @@ enum score_mem_unit {SCORE_BYTE = 0, SCORE_HWORD = 1, SCORE_WORD = 2};
#define SCORE_ALIGN_UNIT(V, UNIT) !(V & ((1 << UNIT) - 1))
-extern void score_gen_cmp (enum machine_mode mode);
extern void score_prologue (void);
extern void score_epilogue (int sibcall_p);
extern void score_call (rtx *ops, bool sib);
diff --git a/gcc/config/score/score.c b/gcc/config/score/score.c
index 2ac3021bf5e..b75f3cfaebf 100644
--- a/gcc/config/score/score.c
+++ b/gcc/config/score/score.c
@@ -116,8 +116,10 @@
#undef TARGET_ADDRESS_COST
#define TARGET_ADDRESS_COST score_address_cost
+#undef TARGET_LEGITIMATE_ADDRESS_P
+#define TARGET_LEGITIMATE_ADDRESS_P score_legitimate_address_p
+
struct extern_list *extern_head = 0;
-rtx cmp_op0, cmp_op1;
/* default 0 = NO_REGS */
enum reg_class score_char_to_class[256];
@@ -531,14 +533,14 @@ score_regno_mode_ok_for_base_p (int regno, int strict)
gcc_unreachable ();
}
-/* Implement GO_IF_LEGITIMATE_ADDRESS macro. */
-int
-score_address_p (enum machine_mode mode, rtx x, int strict)
+/* Implement TARGET_LEGITIMIZE_ADDRESS_P. */
+bool
+score_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
{
if (TARGET_SCORE5 || TARGET_SCORE5U || TARGET_SCORE7 || TARGET_SCORE7D)
- return score7_address_p (mode, x, strict);
+ return score7_legitimate_address_p (mode, x, strict);
else if (TARGET_SCORE3)
- return score3_address_p (mode, x, strict);
+ return score3_legitimate_address_p (mode, x, strict);
gcc_unreachable ();
}
@@ -698,17 +700,6 @@ score_epilogue (int sibcall_p)
gcc_unreachable ();
}
-void
-score_gen_cmp (enum machine_mode mode)
-{
- if (TARGET_SCORE5 || TARGET_SCORE5U || TARGET_SCORE7 || TARGET_SCORE7D)
- return score7_gen_cmp (mode);
- else if (TARGET_SCORE3)
- return score3_gen_cmp (mode);
-
- gcc_unreachable ();
-}
-
/* Call and sibcall pattern all need call this function. */
void
score_call (rtx *ops, bool sib)
@@ -1118,7 +1109,7 @@ score_block_move_loop (rtx dst, rtx src, HOST_WIDE_INT length)
HOST_WIDE_INT loop_mov_bytes;
HOST_WIDE_INT iteration = 0;
HOST_WIDE_INT head_length = 0, leftover;
- rtx label, src_reg, dst_reg, final_dst;
+ rtx label, src_reg, dst_reg, final_dst, test;
bool gen_loop_head = (src_align < BITS_PER_WORD
|| dst_align < BITS_PER_WORD);
@@ -1158,8 +1149,8 @@ score_block_move_loop (rtx dst, rtx src, HOST_WIDE_INT length)
score_block_move_loop_body (dst_reg, dst_align,
src_reg, src_align, loop_mov_bytes);
- emit_insn (gen_cmpsi (dst_reg, final_dst));
- emit_jump_insn (gen_bne (label));
+ test = gen_rtx_NE (VOIDmode, dst_reg, final_dst);
+ emit_jump_insn (gen_cbranchsi4 (test, dst_reg, final_dst, label));
score_block_move_loop_foot (dst_reg, dst_align,
src_reg, src_align, leftover);
diff --git a/gcc/config/score/score.h b/gcc/config/score/score.h
index d9fe8e65625..e6c8b7504ba 100644
--- a/gcc/config/score/score.h
+++ b/gcc/config/score/score.h
@@ -748,16 +748,6 @@ typedef struct score_args
/* Maximum number of registers that can appear in a valid memory address. */
#define MAX_REGS_PER_ADDRESS 1
-#ifdef REG_OK_STRICT
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, LABEL) \
- if (score_address_p (MODE, X, 1)) \
- goto LABEL;
-#else
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, LABEL) \
- if (score_address_p (MODE, X, 0)) \
- goto LABEL;
-#endif
-
/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
and check its validity for a certain class.
We have two alternate definitions for each of them.
diff --git a/gcc/config/score/score.md b/gcc/config/score/score.md
index e616c57aa7e..b426e14e0ac 100644
--- a/gcc/config/score/score.md
+++ b/gcc/config/score/score.md
@@ -2175,6 +2175,20 @@
(set_attr "length" "4,4")
(set_attr "mode" "SI")])
+(define_expand "cbranchsi4"
+ [(set (reg:CC CC_REGNUM)
+ (compare:CC (match_operand:SI 1 "score_register_operand" "")
+ (match_operand:SI 2 "arith_operand" "")))
+ (set (pc)
+ (if_then_else
+ (match_operator 0 "ordered_comparison_operator"
+ [(reg:CC CC_REGNUM)
+ (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
+ ""
+ "")
+
(define_insn "cbrancheqz"
[(set (pc) (if_then_else
(eq (match_operand:SI 0 "score_register_operand" "d")
@@ -2259,16 +2273,6 @@
(const_int 4)
(const_int 6)))])
-(define_expand "cmpsi"
- [(match_operand:SI 0 "score_register_operand")
- (match_operand:SI 1 "arith_operand")]
- ""
-{
- cmp_op0 = operands[0];
- cmp_op1 = operands[1];
- DONE;
-})
-
(define_insn "cmpsi_nz_score7"
[(set (reg:CC_NZ CC_REGNUM)
(compare:CC_NZ (match_operand:SI 0 "register_operand" "d,e,d")
@@ -2375,106 +2379,6 @@
(set_attr "up_c" "yes")
(set_attr "mode" "SI")])
-(define_expand "beq"
- [(set (pc)
- (if_then_else (eq (reg:CC CC_REGNUM) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
-{
- score_gen_cmp (CCmode);
-})
-
-(define_expand "bne"
- [(set (pc)
- (if_then_else (ne (reg:CC CC_REGNUM) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
-{
- score_gen_cmp (CCmode);
-})
-
-(define_expand "bgt"
- [(set (pc)
- (if_then_else (gt (reg:CC CC_REGNUM) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
-{
- score_gen_cmp (CCmode);
-})
-
-(define_expand "ble"
- [(set (pc)
- (if_then_else (le (reg:CC CC_REGNUM) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
-{
- score_gen_cmp (CCmode);
-})
-
-(define_expand "bge"
- [(set (pc)
- (if_then_else (ge (reg:CC CC_REGNUM) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
-{
- score_gen_cmp (CCmode);
-})
-
-(define_expand "blt"
- [(set (pc)
- (if_then_else (lt (reg:CC CC_REGNUM) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
-{
- score_gen_cmp (CCmode);
-})
-
-(define_expand "bgtu"
- [(set (pc)
- (if_then_else (gtu (reg:CC CC_REGNUM) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
-{
- score_gen_cmp (CCmode);
-})
-
-(define_expand "bleu"
- [(set (pc)
- (if_then_else (leu (reg:CC CC_REGNUM) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
-{
- score_gen_cmp (CCmode);
-})
-
-(define_expand "bgeu"
- [(set (pc)
- (if_then_else (geu (reg:CC CC_REGNUM) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
-{
- score_gen_cmp (CCmode);
-})
-
-(define_expand "bltu"
- [(set (pc)
- (if_then_else (ltu (reg:CC CC_REGNUM) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
-{
- score_gen_cmp (CCmode);
-})
-
(define_insn "*branch_n_score7"
[(set (pc)
(if_then_else
diff --git a/gcc/config/score/score3.c b/gcc/config/score/score3.c
index 9e41452c03d..4258d29e525 100644
--- a/gcc/config/score/score3.c
+++ b/gcc/config/score/score3.c
@@ -54,9 +54,6 @@
#define BITSET_P(VALUE, BIT) (((VALUE) & (1L << (BIT))) != 0)
#define INS_BUF_SZ 128
-/* Define the information needed to generate branch insns. This is
- stored from the compare operation. */
-extern rtx cmp_op0, cmp_op1;
extern enum reg_class score_char_to_class[256];
static int score3_sdata_max;
@@ -913,9 +910,9 @@ score3_regno_mode_ok_for_base_p (int regno, int strict)
return GP_REG_P (regno);
}
-/* Implement GO_IF_LEGITIMATE_ADDRESS macro. */
-int
-score3_address_p (enum machine_mode mode, rtx x, int strict)
+/* Implement TARGET_LEGITIMATE_ADDRESS_P macro. */
+bool
+score3_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
{
struct score3_address_info addr;
@@ -1647,13 +1644,6 @@ score3_epilogue (int sibcall_p)
emit_jump_insn (gen_return_internal_score3 (gen_rtx_REG (Pmode, RA_REGNUM)));
}
-void
-score3_gen_cmp (enum machine_mode mode)
-{
- emit_insn (gen_rtx_SET (VOIDmode, gen_rtx_REG (mode, CC_REGNUM),
- gen_rtx_COMPARE (mode, cmp_op0, cmp_op1)));
-}
-
/* Return true if X is a symbolic constant that can be calculated in
the same way as a bare symbol. If it is, store the type of the
symbol in *SYMBOL_TYPE. */
@@ -1692,7 +1682,8 @@ score3_movsicc (rtx *ops)
mode = score3_select_cc_mode (GET_CODE (ops[1]), ops[2], ops[3]);
emit_insn (gen_rtx_SET (VOIDmode, gen_rtx_REG (mode, CC_REGNUM),
- gen_rtx_COMPARE (mode, cmp_op0, cmp_op1)));
+ gen_rtx_COMPARE (mode, XEXP (ops[1], 0),
+ XEXP (ops[1], 1))));
}
/* Call and sibcall pattern all need call this function. */
diff --git a/gcc/config/score/score3.h b/gcc/config/score/score3.h
index c46a8e694d9..001b2f0c2ee 100644
--- a/gcc/config/score/score3.h
+++ b/gcc/config/score/score3.h
@@ -122,7 +122,8 @@ extern rtx score3_function_value (tree valtype,
enum machine_mode mode);
extern void score3_initialize_trampoline (rtx ADDR, rtx FUNC, rtx CHAIN);
extern int score3_regno_mode_ok_for_base_p (int regno, int strict);
-extern int score3_address_p (enum machine_mode mode, rtx x, int strict);
+extern bool score3_legitimate_address_p (enum machine_mode mode, rtx x,
+ bool strict);
extern int score3_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
enum reg_class from,
enum reg_class to);
@@ -138,7 +139,6 @@ extern enum machine_mode
score3_select_cc_mode (enum rtx_code op, rtx x, rtx y);
extern void score3_prologue (void);
extern void score3_epilogue (int sibcall_p);
-extern void score3_gen_cmp (enum machine_mode mode);
extern void score3_call (rtx *ops, bool sib);
extern void score3_call_value (rtx *ops, bool sib);
extern void score3_movsicc (rtx *ops);
diff --git a/gcc/config/score/score7.c b/gcc/config/score/score7.c
index dc532764edd..9ab6ebd3004 100644
--- a/gcc/config/score/score7.c
+++ b/gcc/config/score/score7.c
@@ -54,9 +54,6 @@
#define BITSET_P(VALUE, BIT) (((VALUE) & (1L << (BIT))) != 0)
#define INS_BUF_SZ 128
-/* Define the information needed to generate branch insns. This is
- stored from the compare operation. */
-extern rtx cmp_op0, cmp_op1;
extern enum reg_class score_char_to_class[256];
static int score7_sdata_max;
@@ -904,9 +901,9 @@ score7_regno_mode_ok_for_base_p (int regno, int strict)
return GP_REG_P (regno);
}
-/* Implement GO_IF_LEGITIMATE_ADDRESS macro. */
-int
-score7_address_p (enum machine_mode mode, rtx x, int strict)
+/* Implement TARGET_LEGITIMATE_ADDRESS_P macro. */
+bool
+score7_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
{
struct score7_address_info addr;
@@ -1531,13 +1528,6 @@ score7_epilogue (int sibcall_p)
emit_jump_insn (gen_return_internal_score7 (gen_rtx_REG (Pmode, RA_REGNUM)));
}
-void
-score7_gen_cmp (enum machine_mode mode)
-{
- emit_insn (gen_rtx_SET (VOIDmode, gen_rtx_REG (mode, CC_REGNUM),
- gen_rtx_COMPARE (mode, cmp_op0, cmp_op1)));
-}
-
/* Return true if X is a symbolic constant that can be calculated in
the same way as a bare symbol. If it is, store the type of the
symbol in *SYMBOL_TYPE. */
@@ -1576,7 +1566,8 @@ score7_movsicc (rtx *ops)
mode = score7_select_cc_mode (GET_CODE (ops[1]), ops[2], ops[3]);
emit_insn (gen_rtx_SET (VOIDmode, gen_rtx_REG (mode, CC_REGNUM),
- gen_rtx_COMPARE (mode, cmp_op0, cmp_op1)));
+ gen_rtx_COMPARE (mode, XEXP (ops[1], 0),
+ XEXP (ops[1], 1))));
}
/* Call and sibcall pattern all need call this function. */
diff --git a/gcc/config/score/score7.h b/gcc/config/score/score7.h
index e2033c74498..ae3f4e837cb 100644
--- a/gcc/config/score/score7.h
+++ b/gcc/config/score/score7.h
@@ -122,7 +122,8 @@ extern rtx score7_function_value (tree valtype,
enum machine_mode mode);
extern void score7_initialize_trampoline (rtx ADDR, rtx FUNC, rtx CHAIN);
extern int score7_regno_mode_ok_for_base_p (int regno, int strict);
-extern int score7_address_p (enum machine_mode mode, rtx x, int strict);
+extern bool score7_legitimate_address_p (enum machine_mode mode, rtx x,
+ bool strict);
extern int score7_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
enum reg_class from,
enum reg_class to);
@@ -139,7 +140,6 @@ extern enum machine_mode score7_select_cc_mode (enum rtx_code op,
rtx y);
extern void score7_prologue (void);
extern void score7_epilogue (int sibcall_p);
-extern void score7_gen_cmp (enum machine_mode mode);
extern void score7_call (rtx *ops, bool sib);
extern void score7_call_value (rtx *ops, bool sib);
extern void score7_movsicc (rtx *ops);
diff --git a/gcc/config/score/t-score-elf b/gcc/config/score/t-score-elf
index c2db527a25b..e30a5a1000f 100644
--- a/gcc/config/score/t-score-elf
+++ b/gcc/config/score/t-score-elf
@@ -1,4 +1,4 @@
-# Copyright (C) 2006, 2007, 2008 Free Software Foundation, Inc.
+# Copyright (C) 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
#
# This file is part of GCC.
#
@@ -20,13 +20,13 @@
score7.o: $(srcdir)/config/score/score7.c $(CONFIG_H) $(SYSTEM_H) \
coretypes.h $(TM_H) $(RTL_H) output.h flags.h $(TREE_H) \
expr.h toplev.h $(TM_P_H)
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
$(srcdir)/config/score/score7.c
score3.o: $(srcdir)/config/score/score3.c $(CONFIG_H) $(SYSTEM_H) \
coretypes.h $(TM_H) $(RTL_H) output.h flags.h $(TREE_H) \
expr.h toplev.h $(TM_P_H)
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
$(srcdir)/config/score/score3.c
diff --git a/gcc/config/sh/predicates.md b/gcc/config/sh/predicates.md
index da9962c9984..3295f64865e 100644
--- a/gcc/config/sh/predicates.md
+++ b/gcc/config/sh/predicates.md
@@ -29,7 +29,7 @@
cond = XEXP (op, 0);
mem = XEXP (op, 1);
res = XEXP (op, 2);
- if (GET_CODE (mem) != MEM
+ if (!MEM_P (mem)
|| (GET_CODE (res) != SIGN_EXTEND && GET_CODE (res) != TRUNCATE))
return 0;
tar = XEXP (res, 0);
@@ -52,8 +52,8 @@
and = XEXP (cond, 0);
return (GET_CODE (and) == AND
&& rtx_equal_p (XEXP (and, 0), tar)
- && GET_CODE (XEXP (and, 1)) == CONST_INT
- && GET_CODE (XEXP (cond, 1)) == CONST_INT
+ && CONST_INT_P (XEXP (and, 1))
+ && CONST_INT_P (XEXP (cond, 1))
&& INTVAL (XEXP (and, 1)) == 3
&& INTVAL (XEXP (cond, 1)) == 3);
})
@@ -108,11 +108,11 @@
attempting to transform a sequence of two 64-bit sets of the
same register from literal constants into a set and an add,
when the difference is too wide for an add. */
- if (GET_CODE (op) == CONST_INT
+ if (CONST_INT_P (op)
|| satisfies_constraint_Css (op))
return 1;
else if (GET_CODE (op) == TRUNCATE
- && GET_CODE (XEXP (op, 0)) == REG
+ && REG_P (XEXP (op, 0))
&& ! system_reg_operand (XEXP (op, 0), VOIDmode)
&& (mode == VOIDmode || mode == GET_MODE (op))
&& (GET_MODE_SIZE (GET_MODE (op))
@@ -152,9 +152,9 @@
{
int regno;
- if (GET_CODE (op) == REG)
+ if (REG_P (op))
regno = REGNO (op);
- else if (GET_CODE (op) == SUBREG && GET_CODE (SUBREG_REG (op)) == REG)
+ else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
regno = REGNO (SUBREG_REG (op));
else
return 1;
@@ -175,7 +175,7 @@
#if 0 /* Can't do this because of PROMOTE_MODE for unsigned vars. */
if (GET_MODE (op) == SImode && GET_CODE (op) == SIGN_EXTEND
&& GET_MODE (XEXP (op, 0)) == HImode
- && GET_CODE (XEXP (op, 0)) == REG
+ && REG_P (XEXP (op, 0))
&& REGNO (XEXP (op, 0)) <= LAST_GENERAL_REG)
return register_operand (XEXP (op, 0), VOIDmode);
#endif
@@ -223,13 +223,13 @@
{
if (GET_CODE (op) == PLUS)
{
- if (GET_CODE (XEXP (op, 0)) != REG)
+ if (!REG_P (XEXP (op, 0)))
return 0;
- if (GET_CODE (XEXP (op, 1)) != CONST_INT
+ if (!CONST_INT_P (XEXP (op, 1))
|| (INTVAL (XEXP (op, 1)) & 31))
return 0;
}
- else if (GET_CODE (op) != REG)
+ else if (!REG_P (op))
return 0;
return address_operand (op, mode);
})
@@ -253,7 +253,7 @@
(define_predicate "cmpsi_operand"
(match_code "subreg,reg,const_int")
{
- if (GET_CODE (op) == REG && REGNO (op) == T_REG
+ if (REG_P (op) && REGNO (op) == T_REG
&& GET_MODE (op) == SImode
&& TARGET_SH1)
return 1;
@@ -319,9 +319,9 @@
{
int regno;
- if (GET_CODE (op) == REG)
+ if (REG_P (op))
regno = REGNO (op);
- else if (GET_CODE (op) == SUBREG && GET_CODE (SUBREG_REG (op)) == REG)
+ else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
regno = REGNO (SUBREG_REG (op));
else
return 1;
@@ -337,7 +337,7 @@
(define_predicate "fpscr_operand"
(match_code "reg")
{
- return (GET_CODE (op) == REG
+ return (REG_P (op)
&& (REGNO (op) == FPSCR_REG
|| (REGNO (op) >= FIRST_PSEUDO_REGISTER
&& !(reload_in_progress || reload_completed)))
@@ -352,7 +352,7 @@
if (TARGET_SHMEDIA)
return fp_arith_reg_operand (op, mode);
- return (GET_CODE (op) == REG
+ return (REG_P (op)
&& (REGNO (op) == FPUL_REG || REGNO (op) >= FIRST_PSEUDO_REGISTER)
&& GET_MODE (op) == mode);
})
@@ -374,7 +374,7 @@
(define_predicate "general_movsrc_operand"
(match_code "subreg,reg,const_int,const_double,mem,symbol_ref,label_ref,const,const_vector")
{
- if (GET_CODE (op) == MEM)
+ if (MEM_P (op))
{
rtx inside = XEXP (op, 0);
if (GET_CODE (inside) == CONST)
@@ -385,7 +385,7 @@
if (GET_CODE (inside) == PLUS
&& GET_CODE (XEXP (inside, 0)) == LABEL_REF
- && GET_CODE (XEXP (inside, 1)) == CONST_INT)
+ && CONST_INT_P (XEXP (inside, 1)))
return 1;
/* Only post inc allowed. */
@@ -411,7 +411,7 @@
(match_code "subreg,reg,mem")
{
/* Only pre dec allowed. */
- if (GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) == POST_INC)
+ if (MEM_P (op) && GET_CODE (XEXP (op, 0)) == POST_INC)
return 0;
if (mode == DImode && TARGET_SHMEDIA && GET_CODE (op) == SUBREG
&& GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) < 8
@@ -428,7 +428,7 @@
{
rtx inside;
- if (GET_CODE (op) != MEM || GET_MODE (op) != mode)
+ if (!MEM_P (op) || GET_MODE (op) != mode)
return 0;
inside = XEXP (op, 0);
@@ -436,7 +436,7 @@
if (GET_CODE (inside) == POST_INC)
inside = XEXP (inside, 0);
- if (GET_CODE (inside) == REG)
+ if (REG_P (inside))
return 1;
return 0;
@@ -457,7 +457,7 @@
op = XEXP (op, 0);
/* Can't use true_regnum here because copy_cost wants to know about
SECONDARY_INPUT_RELOAD_CLASS. */
- return GET_CODE (op) == REG && FP_REGISTER_P (REGNO (op));
+ return REG_P (op) && FP_REGISTER_P (REGNO (op));
})
;; TODO: Add a comment here.
@@ -532,7 +532,7 @@
{
HOST_WIDE_INT i;
- if (GET_CODE (op) != CONST_INT)
+ if (!CONST_INT_P (op))
return 0;
i = INTVAL (op);
return i >= 1 * 8 && i <= 7 * 8 && (i & 7) == 0;
@@ -552,6 +552,17 @@
(and (match_code "minus,div")
(match_test "GET_MODE (op) == mode")))
+;; UNORDERED is only supported on SHMEDIA.
+
+(define_predicate "sh_float_comparison_operator"
+ (ior (match_operand 0 "ordered_comparison_operator")
+ (and (match_test "TARGET_SHMEDIA")
+ (match_code "unordered"))))
+
+(define_predicate "shmedia_cbranch_comparison_operator"
+ (ior (match_operand 0 "equality_comparison_operator")
+ (match_operand 0 "greater_comparison_operator")))
+
;; TODO: Add a comment here.
(define_predicate "sh_const_vec"
@@ -564,7 +575,7 @@
return 0;
i = XVECLEN (op, 0) - 1;
for (; i >= 0; i--)
- if (GET_CODE (XVECEXP (op, 0, i)) != CONST_INT)
+ if (!CONST_INT_P (XVECEXP (op, 0, i)))
return 0;
return 1;
})
@@ -586,12 +597,12 @@
/* Determine numbers of last and of least significant elements. */
last = XVECLEN (op, 0) - 1;
least = TARGET_LITTLE_ENDIAN ? 0 : last;
- if (GET_CODE (XVECEXP (op, 0, least)) != CONST_INT)
+ if (!CONST_INT_P (XVECEXP (op, 0, least)))
return 0;
sign_ix = least;
if (GET_MODE_UNIT_SIZE (mode) == 1)
sign_ix = TARGET_LITTLE_ENDIAN ? 1 : last - 1;
- if (GET_CODE (XVECEXP (op, 0, sign_ix)) != CONST_INT)
+ if (!CONST_INT_P (XVECEXP (op, 0, sign_ix)))
return 0;
unit_size = GET_MODE_UNIT_SIZE (GET_MODE (op));
sign = (INTVAL (XVECEXP (op, 0, sign_ix)) >> (unit_size * BITS_PER_UNIT - 1)
@@ -649,7 +660,7 @@
(match_code "const_int,const_double,const,symbol_ref,label_ref,subreg,reg,zero_extend,sign_extend")
{
return (CONSTANT_P (op)
- ? (GET_CODE (op) == CONST_INT
+ ? (CONST_INT_P (op)
? (unsigned) INTVAL (op) < GET_MODE_BITSIZE (mode)
: nonmemory_operand (op, mode))
: shift_count_reg_operand (op, mode));
@@ -717,7 +728,7 @@
if (GET_CODE (op) == SUBREG)
op = XEXP (op, 0);
- if (GET_CODE (op) != REG)
+ if (!REG_P (op))
return 0;
/* We must protect ourselves from matching pseudos that are virtual
@@ -773,7 +784,7 @@
(define_predicate "xor_operand"
(match_code "subreg,reg,const_int")
{
- if (GET_CODE (op) == CONST_INT)
+ if (CONST_INT_P (op))
return (TARGET_SHMEDIA
? (satisfies_constraint_I06 (op)
|| (!can_create_pseudo_p () && INTVAL (op) == 0xff))
@@ -788,13 +799,13 @@
(define_predicate "bitwise_memory_operand"
(match_code "mem")
{
- if (GET_CODE (op) == MEM)
+ if (MEM_P (op))
{
if (REG_P (XEXP (op, 0)))
return 1;
if (GET_CODE (XEXP (op, 0)) == PLUS
- && GET_CODE (XEXP (XEXP (op, 0), 0)) == REG
+ && REG_P (XEXP (XEXP (op, 0), 0))
&& satisfies_constraint_K12 (XEXP (XEXP (op, 0), 1)))
return 1;
}
diff --git a/gcc/config/sh/sh-protos.h b/gcc/config/sh/sh-protos.h
index a484b9c5d05..35cd73021b9 100644
--- a/gcc/config/sh/sh-protos.h
+++ b/gcc/config/sh/sh-protos.h
@@ -41,7 +41,6 @@ enum sh_function_kind {
extern rtx sh_fsca_sf2int (void);
extern rtx sh_fsca_df2int (void);
extern rtx sh_fsca_int2sf (void);
-extern struct rtx_def *prepare_scc_operands (enum rtx_code);
/* Declare functions defined in sh.c and used in templates. */
@@ -59,6 +58,7 @@ extern int fp_zero_operand (rtx);
extern int fp_one_operand (rtx);
extern int fp_int_operand (rtx);
extern rtx get_fpscr_rtx (void);
+extern bool sh_legitimate_index_p (enum machine_mode, rtx);
extern rtx legitimize_pic_address (rtx, enum machine_mode, rtx);
extern int nonpic_symbol_mentioned_p (rtx);
extern void emit_sf_insn (rtx);
@@ -72,7 +72,10 @@ extern enum rtx_code prepare_cbranch_operands (rtx *, enum machine_mode mode,
enum rtx_code comparison);
extern void expand_cbranchsi4 (rtx *operands, enum rtx_code comparison, int);
extern bool expand_cbranchdi4 (rtx *operands, enum rtx_code comparison);
-extern void from_compare (rtx *, int);
+extern void sh_emit_scc_to_t (enum rtx_code, rtx, rtx);
+extern rtx sh_emit_cheap_store_flag (enum machine_mode, enum rtx_code, rtx, rtx);
+extern void sh_emit_compare_and_branch (rtx *, enum machine_mode);
+extern void sh_emit_compare_and_set (rtx *, enum machine_mode);
extern int shift_insns_rtx (rtx);
extern void gen_ashift (int, int, rtx);
extern void gen_ashift_hi (int, int, rtx);
@@ -117,11 +120,13 @@ extern int sh_insn_length_adjustment (rtx);
extern int sh_can_redirect_branch (rtx, rtx);
extern void sh_expand_unop_v2sf (enum rtx_code, rtx, rtx);
extern void sh_expand_binop_v2sf (enum rtx_code, rtx, rtx, rtx);
-extern int sh_expand_t_scc (enum rtx_code code, rtx target);
+extern int sh_expand_t_scc (rtx *);
extern rtx sh_gen_truncate (enum machine_mode, rtx, int);
extern bool sh_vector_mode_supported_p (enum machine_mode);
#endif /* RTX_CODE */
+extern void sh_optimization_options (int, int);
+extern void sh_override_options (void);
extern const char *output_jump_label_table (void);
extern int sh_handle_pragma (int (*)(void), void (*)(int), const char *);
extern struct rtx_def *get_fpscr_rtx (void);
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index d23a45a2289..527cd7f791d 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 "cfglayout.h"
#include "intl.h"
#include "sched-int.h"
+#include "params.h"
#include "ggc.h"
#include "gimple.h"
#include "cfgloop.h"
@@ -105,12 +106,6 @@ static int skip_cycles = 0;
and returned from sh_reorder2. */
static short cached_can_issue_more;
-/* Saved operands from the last compare to use when we generate an scc
- or bcc insn. */
-
-rtx sh_compare_op0;
-rtx sh_compare_op1;
-
/* Provides the class number of the smallest class containing
reg number. */
@@ -190,7 +185,7 @@ static void push_regs (HARD_REG_SET *, int);
static int calc_live_regs (HARD_REG_SET *);
static HOST_WIDE_INT rounded_frame_size (int);
static rtx mark_constant_pool_use (rtx);
-const struct attribute_spec sh_attribute_table[];
+EXPORTED_CONST struct attribute_spec sh_attribute_table[];
static tree sh_handle_interrupt_handler_attribute (tree *, tree, tree, int, bool *);
static tree sh_handle_resbank_handler_attribute (tree *, tree,
tree, int, bool *);
@@ -244,6 +239,7 @@ static bool sh_rtx_costs (rtx, int, int, int *, bool);
static int sh_address_cost (rtx, bool);
static int sh_pr_n_sets (void);
static rtx sh_allocate_initial_value (rtx);
+static bool sh_legitimate_address_p (enum machine_mode, rtx, bool);
static rtx sh_legitimize_address (rtx, rtx, enum machine_mode);
static int shmedia_target_regs_stack_space (HARD_REG_SET *);
static int shmedia_reserve_space_for_target_registers_p (int, HARD_REG_SET *);
@@ -486,6 +482,9 @@ static int sh2a_function_vector_p (tree);
#undef TARGET_SECONDARY_RELOAD
#define TARGET_SECONDARY_RELOAD sh_secondary_reload
+#undef TARGET_LEGITIMATE_ADDRESS_P
+#define TARGET_LEGITIMATE_ADDRESS_P sh_legitimate_address_p
+
/* Machine-specific symbol_ref flags. */
#define SYMBOL_FLAG_FUNCVEC_FUNCTION (SYMBOL_FLAG_MACH_DEP << 0)
@@ -612,6 +611,280 @@ sh_handle_option (size_t code, const char *arg ATTRIBUTE_UNUSED,
}
}
+/* Set default optimization options. */
+void
+sh_optimization_options (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED)
+{
+ if (level)
+ {
+ flag_omit_frame_pointer = 2;
+ if (!size)
+ sh_div_str = "inv:minlat";
+ }
+ if (size)
+ {
+ target_flags |= MASK_SMALLCODE;
+ sh_div_str = SH_DIV_STR_FOR_SIZE ;
+ }
+ else
+ TARGET_CBRANCHDI4 = 1;
+ /* We can't meaningfully test TARGET_SHMEDIA here, because -m options
+ haven't been parsed yet, hence we'd read only the default.
+ sh_target_reg_class will return NO_REGS if this is not SHMEDIA, so
+ it's OK to always set flag_branch_target_load_optimize. */
+ if (level > 1)
+ {
+ flag_branch_target_load_optimize = 1;
+ if (!size)
+ target_flags |= MASK_SAVE_ALL_TARGET_REGS;
+ }
+ /* Likewise, we can't meaningfully test TARGET_SH2E / TARGET_IEEE
+ here, so leave it to OVERRIDE_OPTIONS to set
+ flag_finite_math_only. We set it to 2 here so we know if the user
+ explicitly requested this to be on or off. */
+ flag_finite_math_only = 2;
+ /* If flag_schedule_insns is 1, we set it to 2 here so we know if
+ the user explicitly requested this to be on or off. */
+ if (flag_schedule_insns > 0)
+ flag_schedule_insns = 2;
+
+ set_param_value ("simultaneous-prefetches", 2);
+}
+
+/* Implement OVERRIDE_OPTIONS macro. Validate and override various
+ options, and do some machine dependent initialization. */
+void
+sh_override_options (void)
+{
+ int regno;
+
+ SUBTARGET_OVERRIDE_OPTIONS;
+ if (flag_finite_math_only == 2)
+ flag_finite_math_only
+ = !flag_signaling_nans && TARGET_SH2E && ! TARGET_IEEE;
+ if (TARGET_SH2E && !flag_finite_math_only)
+ target_flags |= MASK_IEEE;
+ sh_cpu = PROCESSOR_SH1;
+ assembler_dialect = 0;
+ if (TARGET_SH2)
+ sh_cpu = PROCESSOR_SH2;
+ if (TARGET_SH2E)
+ sh_cpu = PROCESSOR_SH2E;
+ if (TARGET_SH2A)
+ {
+ sh_cpu = PROCESSOR_SH2A;
+ if (TARGET_SH2A_DOUBLE)
+ target_flags |= MASK_FMOVD;
+ }
+ if (TARGET_SH3)
+ sh_cpu = PROCESSOR_SH3;
+ if (TARGET_SH3E)
+ sh_cpu = PROCESSOR_SH3E;
+ if (TARGET_SH4)
+ {
+ assembler_dialect = 1;
+ sh_cpu = PROCESSOR_SH4;
+ }
+ if (TARGET_SH4A_ARCH)
+ {
+ assembler_dialect = 1;
+ sh_cpu = PROCESSOR_SH4A;
+ }
+ if (TARGET_SH5)
+ {
+ sh_cpu = PROCESSOR_SH5;
+ target_flags |= MASK_ALIGN_DOUBLE;
+ if (TARGET_SHMEDIA_FPU)
+ target_flags |= MASK_FMOVD;
+ if (TARGET_SHMEDIA)
+ {
+ /* There are no delay slots on SHmedia. */
+ flag_delayed_branch = 0;
+ /* Relaxation isn't yet supported for SHmedia */
+ target_flags &= ~MASK_RELAX;
+ /* After reload, if conversion does little good but can cause
+ ICEs:
+ - find_if_block doesn't do anything for SH because we don't
+ have conditional execution patterns. (We use conditional
+ move patterns, which are handled differently, and only
+ before reload).
+ - find_cond_trap doesn't do anything for the SH because we
+ don't have conditional traps.
+ - find_if_case_1 uses redirect_edge_and_branch_force in
+ the only path that does an optimization, and this causes
+ an ICE when branch targets are in registers.
+ - find_if_case_2 doesn't do anything for the SHmedia after
+ reload except when it can redirect a tablejump - and
+ that's rather rare. */
+ flag_if_conversion2 = 0;
+ if (! strcmp (sh_div_str, "call"))
+ sh_div_strategy = SH_DIV_CALL;
+ else if (! strcmp (sh_div_str, "call2"))
+ sh_div_strategy = SH_DIV_CALL2;
+ if (! strcmp (sh_div_str, "fp") && TARGET_FPU_ANY)
+ sh_div_strategy = SH_DIV_FP;
+ else if (! strcmp (sh_div_str, "inv"))
+ sh_div_strategy = SH_DIV_INV;
+ else if (! strcmp (sh_div_str, "inv:minlat"))
+ sh_div_strategy = SH_DIV_INV_MINLAT;
+ else if (! strcmp (sh_div_str, "inv20u"))
+ sh_div_strategy = SH_DIV_INV20U;
+ else if (! strcmp (sh_div_str, "inv20l"))
+ sh_div_strategy = SH_DIV_INV20L;
+ else if (! strcmp (sh_div_str, "inv:call2"))
+ sh_div_strategy = SH_DIV_INV_CALL2;
+ else if (! strcmp (sh_div_str, "inv:call"))
+ sh_div_strategy = SH_DIV_INV_CALL;
+ else if (! strcmp (sh_div_str, "inv:fp"))
+ {
+ if (TARGET_FPU_ANY)
+ sh_div_strategy = SH_DIV_INV_FP;
+ else
+ sh_div_strategy = SH_DIV_INV;
+ }
+ TARGET_CBRANCHDI4 = 0;
+ /* Assembler CFI isn't yet fully supported for SHmedia. */
+ flag_dwarf2_cfi_asm = 0;
+ }
+ }
+ else
+ {
+ /* Only the sh64-elf assembler fully supports .quad properly. */
+ targetm.asm_out.aligned_op.di = NULL;
+ targetm.asm_out.unaligned_op.di = NULL;
+ }
+ if (TARGET_SH1)
+ {
+ if (! strcmp (sh_div_str, "call-div1"))
+ sh_div_strategy = SH_DIV_CALL_DIV1;
+ else if (! strcmp (sh_div_str, "call-fp")
+ && (TARGET_FPU_DOUBLE
+ || (TARGET_HARD_SH4 && TARGET_SH2E)
+ || (TARGET_SHCOMPACT && TARGET_FPU_ANY)))
+ sh_div_strategy = SH_DIV_CALL_FP;
+ else if (! strcmp (sh_div_str, "call-table") && TARGET_SH2)
+ sh_div_strategy = SH_DIV_CALL_TABLE;
+ else
+ /* Pick one that makes most sense for the target in general.
+ It is not much good to use different functions depending
+ on -Os, since then we'll end up with two different functions
+ when some of the code is compiled for size, and some for
+ speed. */
+
+ /* SH4 tends to emphasize speed. */
+ if (TARGET_HARD_SH4)
+ sh_div_strategy = SH_DIV_CALL_TABLE;
+ /* These have their own way of doing things. */
+ else if (TARGET_SH2A)
+ sh_div_strategy = SH_DIV_INTRINSIC;
+ /* ??? Should we use the integer SHmedia function instead? */
+ else if (TARGET_SHCOMPACT && TARGET_FPU_ANY)
+ sh_div_strategy = SH_DIV_CALL_FP;
+ /* SH1 .. SH3 cores often go into small-footprint systems, so
+ default to the smallest implementation available. */
+ else if (TARGET_SH2) /* ??? EXPERIMENTAL */
+ sh_div_strategy = SH_DIV_CALL_TABLE;
+ else
+ sh_div_strategy = SH_DIV_CALL_DIV1;
+ }
+ if (!TARGET_SH1)
+ TARGET_PRETEND_CMOVE = 0;
+ if (sh_divsi3_libfunc[0])
+ ; /* User supplied - leave it alone. */
+ else if (TARGET_DIVIDE_CALL_FP)
+ sh_divsi3_libfunc = "__sdivsi3_i4";
+ else if (TARGET_DIVIDE_CALL_TABLE)
+ sh_divsi3_libfunc = "__sdivsi3_i4i";
+ else if (TARGET_SH5)
+ sh_divsi3_libfunc = "__sdivsi3_1";
+ else
+ sh_divsi3_libfunc = "__sdivsi3";
+ if (sh_branch_cost == -1)
+ sh_branch_cost
+ = TARGET_SH5 ? 1 : ! TARGET_SH2 || TARGET_HARD_SH4 ? 2 : 1;
+
+ for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
+ if (! VALID_REGISTER_P (regno))
+ sh_register_names[regno][0] = '\0';
+
+ for (regno = 0; regno < ADDREGNAMES_SIZE; regno++)
+ if (! VALID_REGISTER_P (ADDREGNAMES_REGNO (regno)))
+ sh_additional_register_names[regno][0] = '\0';
+
+ if (flag_omit_frame_pointer == 2)
+ {
+ /* The debugging information is sufficient,
+ but gdb doesn't implement this yet */
+ if (0)
+ flag_omit_frame_pointer
+ = (PREFERRED_DEBUGGING_TYPE == DWARF2_DEBUG);
+ else
+ flag_omit_frame_pointer = 0;
+ }
+
+ if ((flag_pic && ! TARGET_PREFERGOT)
+ || (TARGET_SHMEDIA && !TARGET_PT_FIXED))
+ flag_no_function_cse = 1;
+
+ if (SMALL_REGISTER_CLASSES)
+ {
+ /* Never run scheduling before reload, since that can
+ break global alloc, and generates slower code anyway due
+ to the pressure on R0. */
+ /* Enable sched1 for SH4 if the user explicitly requests.
+ When sched1 is enabled, the ready queue will be reordered by
+ the target hooks if pressure is high. We can not do this for
+ PIC, SH3 and lower as they give spill failures for R0. */
+ if (!TARGET_HARD_SH4 || flag_pic)
+ flag_schedule_insns = 0;
+ /* ??? Current exception handling places basic block boundaries
+ after call_insns. It causes the high pressure on R0 and gives
+ spill failures for R0 in reload. See PR 22553 and the thread
+ on gcc-patches
+ <http://gcc.gnu.org/ml/gcc-patches/2005-10/msg00816.html>. */
+ else if (flag_exceptions)
+ {
+ if (flag_schedule_insns == 1)
+ warning (0, "ignoring -fschedule-insns because of exception handling bug");
+ flag_schedule_insns = 0;
+ }
+ else if (flag_schedule_insns == 2)
+ flag_schedule_insns = 0;
+ }
+
+ if (align_loops == 0)
+ align_loops = 1 << (TARGET_SH5 ? 3 : 2);
+ if (align_jumps == 0)
+ align_jumps = 1 << CACHE_LOG;
+ else if (align_jumps < (TARGET_SHMEDIA ? 4 : 2))
+ align_jumps = TARGET_SHMEDIA ? 4 : 2;
+
+ /* Allocation boundary (in *bytes*) for the code of a function.
+ SH1: 32 bit alignment is faster, because instructions are always
+ fetched as a pair from a longword boundary.
+ SH2 .. SH5 : align to cache line start. */
+ if (align_functions == 0)
+ align_functions
+ = TARGET_SMALLCODE ? FUNCTION_BOUNDARY/8 : (1 << CACHE_LOG);
+ /* The linker relaxation code breaks when a function contains
+ alignments that are larger than that at the start of a
+ compilation unit. */
+ if (TARGET_RELAX)
+ {
+ int min_align
+ = align_loops > align_jumps ? align_loops : align_jumps;
+
+ /* Also take possible .long constants / mova tables int account. */
+ if (min_align < 4)
+ min_align = 4;
+ if (align_functions < min_align)
+ align_functions = min_align;
+ }
+
+ if (sh_fixed_range_str)
+ sh_fix_range (sh_fixed_range_str);
+}
+
/* Print the operand address in x to the stream. */
void
@@ -831,7 +1104,7 @@ print_operand (FILE *stream, rtx x, int code)
break;
case 't':
- gcc_assert (GET_CODE (x) == MEM);
+ gcc_assert (MEM_P (x));
x = XEXP (x, 0);
switch (GET_CODE (x))
{
@@ -864,15 +1137,15 @@ print_operand (FILE *stream, rtx x, int code)
case 'M':
if (TARGET_SHMEDIA)
{
- if (GET_CODE (x) == MEM
+ if (MEM_P (x)
&& GET_CODE (XEXP (x, 0)) == PLUS
- && (GET_CODE (XEXP (XEXP (x, 0), 1)) == REG
+ && (REG_P (XEXP (XEXP (x, 0), 1))
|| GET_CODE (XEXP (XEXP (x, 0), 1)) == SUBREG))
fputc ('x', stream);
}
else
{
- if (GET_CODE (x) == MEM)
+ if (MEM_P (x))
{
switch (GET_MODE (x))
{
@@ -888,7 +1161,7 @@ print_operand (FILE *stream, rtx x, int code)
break;
case 'm':
- gcc_assert (GET_CODE (x) == MEM);
+ gcc_assert (MEM_P (x));
x = XEXP (x, 0);
/* Fall through. */
case 'U':
@@ -928,7 +1201,7 @@ print_operand (FILE *stream, rtx x, int code)
break;
case 'd':
- gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == V2SFmode);
+ gcc_assert (REG_P (x) && GET_MODE (x) == V2SFmode);
fprintf ((stream), "d%s", reg_names[REGNO (x)] + 1);
break;
@@ -941,7 +1214,7 @@ print_operand (FILE *stream, rtx x, int code)
}
goto default_output;
case 'u':
- if (GET_CODE (x) == CONST_INT)
+ if (CONST_INT_P (x))
{
fprintf ((stream), "%u", (unsigned) INTVAL (x) & (0x10000 - 1));
break;
@@ -967,7 +1240,7 @@ print_operand (FILE *stream, rtx x, int code)
== GET_MODE_SIZE (GET_MODE (SUBREG_REG (inner))))
&& subreg_lowpart_p (inner))
inner = SUBREG_REG (inner);
- if (GET_CODE (inner) == CONST_INT)
+ if (CONST_INT_P (inner))
{
x = GEN_INT (trunc_int_for_mode (INTVAL (inner), GET_MODE (x)));
goto default_output;
@@ -976,7 +1249,7 @@ print_operand (FILE *stream, rtx x, int code)
if (GET_CODE (inner) == SUBREG
&& (GET_MODE_SIZE (GET_MODE (inner))
< GET_MODE_SIZE (GET_MODE (SUBREG_REG (inner))))
- && GET_CODE (SUBREG_REG (inner)) == REG)
+ && REG_P (SUBREG_REG (inner)))
{
offset = subreg_regno_offset (REGNO (SUBREG_REG (inner)),
GET_MODE (SUBREG_REG (inner)),
@@ -984,7 +1257,7 @@ print_operand (FILE *stream, rtx x, int code)
GET_MODE (inner));
inner = SUBREG_REG (inner);
}
- if (GET_CODE (inner) != REG || GET_MODE_SIZE (inner_mode) > 8)
+ if (!REG_P (inner) || GET_MODE_SIZE (inner_mode) > 8)
abort ();
/* Floating point register pairs are always big endian;
general purpose registers are 64 bit wide. */
@@ -1009,7 +1282,7 @@ print_operand (FILE *stream, rtx x, int code)
goto default_output;
case SUBREG:
gcc_assert (SUBREG_BYTE (x) == 0
- && GET_CODE (SUBREG_REG (x)) == REG);
+ && REG_P (SUBREG_REG (x)));
x = SUBREG_REG (x);
/* Fall through. */
@@ -1023,7 +1296,7 @@ print_operand (FILE *stream, rtx x, int code)
else if (FP_REGISTER_P (REGNO (x))
&& mode == V4SFmode)
fprintf ((stream), "fv%s", reg_names[regno] + 2);
- else if (GET_CODE (x) == REG
+ else if (REG_P (x)
&& mode == V2SFmode)
fprintf ((stream), "fp%s", reg_names[regno] + 2);
else if (FP_REGISTER_P (REGNO (x))
@@ -1080,7 +1353,7 @@ int
expand_block_move (rtx *operands)
{
int align = INTVAL (operands[3]);
- int constp = (GET_CODE (operands[2]) == CONST_INT);
+ int constp = (CONST_INT_P (operands[2]));
int bytes = (constp ? INTVAL (operands[2]) : 0);
if (! constp)
@@ -1226,7 +1499,7 @@ prepare_move_operands (rtx operands[], enum machine_mode mode)
rtx temp;
if (SYMBOLIC_CONST_P (operands[1]))
{
- if (GET_CODE (operands[0]) == MEM)
+ if (MEM_P (operands[0]))
operands[1] = force_reg (Pmode, operands[1]);
else if (TARGET_SHMEDIA
&& GET_CODE (operands[1]) == LABEL_REF
@@ -1263,7 +1536,7 @@ prepare_move_operands (rtx operands[], enum machine_mode mode)
&& ! sh_register_operand (operands[1], mode))
operands[1] = copy_to_mode_reg (mode, operands[1]);
- if (GET_CODE (operands[0]) == MEM && ! memory_operand (operands[0], mode))
+ if (MEM_P (operands[0]) && ! memory_operand (operands[0], mode))
{
/* This is like change_address_1 (operands[0], mode, 0, 1) ,
except that we can't use that function because it is static. */
@@ -1278,9 +1551,9 @@ prepare_move_operands (rtx operands[], enum machine_mode mode)
being used for the source. */
else if (TARGET_SH1
&& refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0)
- && GET_CODE (operands[0]) == MEM
+ && MEM_P (operands[0])
&& GET_CODE (XEXP (operands[0], 0)) == PLUS
- && GET_CODE (XEXP (XEXP (operands[0], 0), 1)) == REG)
+ && REG_P (XEXP (XEXP (operands[0], 0), 1)))
operands[1] = copy_to_mode_reg (mode, operands[1]);
}
@@ -1386,8 +1659,8 @@ prepare_cbranch_operands (rtx *operands, enum machine_mode mode,
comparison = GET_CODE (operands[0]);
else
scratch = operands[4];
- if (GET_CODE (operands[1]) == CONST_INT
- && GET_CODE (operands[2]) != CONST_INT)
+ if (CONST_INT_P (operands[1])
+ && !CONST_INT_P (operands[2]))
{
rtx tmp = operands[1];
@@ -1395,7 +1668,7 @@ prepare_cbranch_operands (rtx *operands, enum machine_mode mode,
operands[2] = tmp;
comparison = swap_condition (comparison);
}
- if (GET_CODE (operands[2]) == CONST_INT)
+ if (CONST_INT_P (operands[2]))
{
HOST_WIDE_INT val = INTVAL (operands[2]);
if ((val == -1 || val == -0x81)
@@ -1446,7 +1719,7 @@ prepare_cbranch_operands (rtx *operands, enum machine_mode mode,
allocated to a different hard register, thus we load the constant into
a register unless it is zero. */
if (!REG_P (operands[2])
- && (GET_CODE (operands[2]) != CONST_INT
+ && (!CONST_INT_P (operands[2])
|| (mode == SImode && operands[2] != CONST0_RTX (SImode)
&& ((comparison != EQ && comparison != NE)
|| (REG_P (op1) && REGNO (op1) != R0_REG)
@@ -1571,7 +1844,7 @@ expand_cbranchdi4 (rtx *operands, enum rtx_code comparison)
break;
case GTU: case GT:
msw_taken = comparison;
- if (GET_CODE (op2l) == CONST_INT && INTVAL (op2l) == -1)
+ if (CONST_INT_P (op2l) && INTVAL (op2l) == -1)
break;
if (comparison != GTU || op2h != CONST0_RTX (SImode))
msw_skip = swap_condition (msw_taken);
@@ -1595,7 +1868,7 @@ expand_cbranchdi4 (rtx *operands, enum rtx_code comparison)
lsw_taken = LTU;
break;
case LEU: case LE:
- if (GET_CODE (op2l) == CONST_INT && INTVAL (op2l) == -1)
+ if (CONST_INT_P (op2l) && INTVAL (op2l) == -1)
msw_taken = comparison;
else
{
@@ -1638,7 +1911,8 @@ expand_cbranchdi4 (rtx *operands, enum rtx_code comparison)
operands[2] = op2h;
operands[4] = NULL_RTX;
if (reload_completed
- && ! arith_reg_or_0_operand (op2h, SImode) && true_regnum (op1h)
+ && ! arith_reg_or_0_operand (op2h, SImode)
+ && (true_regnum (op1h) || (comparison != EQ && comparison != NE))
&& (msw_taken != LAST_AND_UNUSED_RTX_CODE
|| msw_skip != LAST_AND_UNUSED_RTX_CODE))
{
@@ -1668,8 +1942,12 @@ expand_cbranchdi4 (rtx *operands, enum rtx_code comparison)
if (lsw_taken != LAST_AND_UNUSED_RTX_CODE)
{
if (reload_completed
- && ! arith_reg_or_0_operand (op2l, SImode) && true_regnum (op1l))
- operands[4] = scratch;
+ && ! arith_reg_or_0_operand (op2l, SImode)
+ && (true_regnum (op1l) || (lsw_taken != EQ && lsw_taken != NE)))
+ {
+ emit_move_insn (scratch, operands[2]);
+ operands[2] = scratch;
+ }
expand_cbranchsi4 (operands, lsw_taken, lsw_taken_prob);
}
if (msw_skip != LAST_AND_UNUSED_RTX_CODE)
@@ -1677,10 +1955,26 @@ expand_cbranchdi4 (rtx *operands, enum rtx_code comparison)
return true;
}
+/* Emit INSN, possibly in a PARALLEL with an USE of fpscr for SH4. */
+
+static void
+sh_emit_set_t_insn (rtx insn, enum machine_mode mode)
+{
+ if ((TARGET_SH4 || TARGET_SH2A) && GET_MODE_CLASS (mode) == MODE_FLOAT)
+ {
+ insn = gen_rtx_PARALLEL (VOIDmode,
+ gen_rtvec (2, insn,
+ gen_rtx_USE (VOIDmode, get_fpscr_rtx ())));
+ (mode == SFmode ? emit_sf_insn : emit_df_insn) (insn);
+ }
+ else
+ emit_insn (insn);
+}
+
/* Prepare the operands for an scc instruction; make sure that the
- compare has been done. */
-rtx
-prepare_scc_operands (enum rtx_code code)
+ compare has been done and the result is in T_REG. */
+void
+sh_emit_scc_to_t (enum rtx_code code, rtx op0, rtx op1)
{
rtx t_reg = gen_rtx_REG (SImode, T_REG);
enum rtx_code oldcode = code;
@@ -1709,77 +2003,222 @@ prepare_scc_operands (enum rtx_code code)
}
if (code != oldcode)
{
- rtx tmp = sh_compare_op0;
- sh_compare_op0 = sh_compare_op1;
- sh_compare_op1 = tmp;
+ rtx tmp = op0;
+ op0 = op1;
+ op1 = tmp;
}
- mode = GET_MODE (sh_compare_op0);
+ mode = GET_MODE (op0);
if (mode == VOIDmode)
- mode = GET_MODE (sh_compare_op1);
+ mode = GET_MODE (op1);
- sh_compare_op0 = force_reg (mode, sh_compare_op0);
+ op0 = force_reg (mode, op0);
if ((code != EQ && code != NE
- && (sh_compare_op1 != const0_rtx
+ && (op1 != const0_rtx
|| code == GTU || code == GEU || code == LTU || code == LEU))
- || (mode == DImode && sh_compare_op1 != const0_rtx)
+ || (mode == DImode && op1 != const0_rtx)
|| (TARGET_SH2E && GET_MODE_CLASS (mode) == MODE_FLOAT))
- sh_compare_op1 = force_reg (mode, sh_compare_op1);
+ op1 = force_reg (mode, op1);
- if ((TARGET_SH4 || TARGET_SH2A) && GET_MODE_CLASS (mode) == MODE_FLOAT)
- (mode == SFmode ? emit_sf_insn : emit_df_insn)
- (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
- gen_rtx_SET (VOIDmode, t_reg,
- gen_rtx_fmt_ee (code, SImode,
- sh_compare_op0, sh_compare_op1)),
- gen_rtx_USE (VOIDmode, get_fpscr_rtx ()))));
- else
- emit_insn (gen_rtx_SET (VOIDmode, t_reg,
- gen_rtx_fmt_ee (code, SImode,
- sh_compare_op0, sh_compare_op1)));
+ sh_emit_set_t_insn (gen_rtx_SET (VOIDmode, t_reg,
+ gen_rtx_fmt_ee (code, SImode, op0, op1)),
+ mode);
+}
+
+rtx
+sh_emit_cheap_store_flag (enum machine_mode mode, enum rtx_code code,
+ rtx op0, rtx op1)
+{
+ rtx target = gen_reg_rtx (SImode);
+ rtx tmp;
- return t_reg;
+ gcc_assert (TARGET_SHMEDIA);
+ switch (code)
+ {
+ case EQ:
+ case GT:
+ case LT:
+ case UNORDERED:
+ case GTU:
+ case LTU:
+ tmp = gen_rtx_fmt_ee (code, SImode, op0, op1);
+ emit_insn (gen_cstore4_media (target, tmp, op0, op1));
+ code = NE;
+ break;
+
+ case NE:
+ case GE:
+ case LE:
+ case ORDERED:
+ case GEU:
+ case LEU:
+ tmp = gen_rtx_fmt_ee (reverse_condition (code), mode, op0, op1);
+ emit_insn (gen_cstore4_media (target, tmp, op0, op1));
+ code = EQ;
+ break;
+
+ case UNEQ:
+ case UNGE:
+ case UNGT:
+ case UNLE:
+ case UNLT:
+ case LTGT:
+ return NULL_RTX;
+
+ default:
+ gcc_unreachable ();
+ }
+
+ if (mode == DImode)
+ {
+ rtx t2 = gen_reg_rtx (DImode);
+ emit_insn (gen_extendsidi2 (t2, target));
+ target = t2;
+ }
+
+ return gen_rtx_fmt_ee (code, VOIDmode, target, const0_rtx);
}
/* Called from the md file, set up the operands of a compare instruction. */
void
-from_compare (rtx *operands, int code)
+sh_emit_compare_and_branch (rtx *operands, enum machine_mode mode)
{
- enum machine_mode mode = GET_MODE (sh_compare_op0);
- rtx insn;
- if (mode == VOIDmode)
- mode = GET_MODE (sh_compare_op1);
- if (code != EQ
- || mode == DImode
- || (TARGET_SH2E && GET_MODE_CLASS (mode) == MODE_FLOAT))
+ enum rtx_code code = GET_CODE (operands[0]);
+ enum rtx_code branch_code;
+ rtx op0 = operands[1];
+ rtx op1 = operands[2];
+ rtx insn, tem;
+ bool need_ccmpeq = false;
+
+ if (TARGET_SH2E && GET_MODE_CLASS (mode) == MODE_FLOAT)
+ {
+ op0 = force_reg (mode, op0);
+ op1 = force_reg (mode, op1);
+ }
+ else
{
- /* Force args into regs, since we can't use constants here. */
- sh_compare_op0 = force_reg (mode, sh_compare_op0);
- if (sh_compare_op1 != const0_rtx
- || code == GTU || code == GEU
- || (TARGET_SH2E && GET_MODE_CLASS (mode) == MODE_FLOAT))
- sh_compare_op1 = force_reg (mode, sh_compare_op1);
+ if (code != EQ || mode == DImode)
+ {
+ /* Force args into regs, since we can't use constants here. */
+ op0 = force_reg (mode, op0);
+ if (op1 != const0_rtx || code == GTU || code == GEU)
+ op1 = force_reg (mode, op1);
+ }
}
- if (TARGET_SH2E && GET_MODE_CLASS (mode) == MODE_FLOAT && code == GE)
+
+ if (GET_MODE_CLASS (mode) == MODE_FLOAT)
{
- from_compare (operands, GT);
- insn = gen_ieee_ccmpeqsf_t (sh_compare_op0, sh_compare_op1);
+ if (code == LT
+ || (code == LE && TARGET_IEEE && TARGET_SH2E)
+ || (code == GE && !(TARGET_IEEE && TARGET_SH2E)))
+ {
+ tem = op0, op0 = op1, op1 = tem;
+ code = swap_condition (code);
+ }
+
+ /* GE becomes fcmp/gt+fcmp/eq, for SH2E and TARGET_IEEE only. */
+ if (code == GE)
+ {
+ gcc_assert (TARGET_IEEE && TARGET_SH2E);
+ need_ccmpeq = true;
+ code = GT;
+ }
+
+ /* Now we can have EQ, NE, GT, LE. NE and LE are then transformed
+ to EQ/GT respectively. */
+ gcc_assert (code == EQ || code == GT || code == NE || code == LE);
+ }
+
+ switch (code)
+ {
+ case EQ:
+ case GT:
+ case GE:
+ case GTU:
+ case GEU:
+ branch_code = code;
+ break;
+ case NE:
+ case LT:
+ case LE:
+ case LTU:
+ case LEU:
+ branch_code = reverse_condition (code);
+ break;
+ default:
+ gcc_unreachable ();
}
+
+ insn = gen_rtx_SET (VOIDmode,
+ gen_rtx_REG (SImode, T_REG),
+ gen_rtx_fmt_ee (branch_code, SImode, op0, op1));
+
+ sh_emit_set_t_insn (insn, mode);
+ if (need_ccmpeq)
+ sh_emit_set_t_insn (gen_ieee_ccmpeqsf_t (op0, op1), mode);
+
+ if (branch_code == code)
+ emit_jump_insn (gen_branch_true (operands[3]));
else
- insn = gen_rtx_SET (VOIDmode,
- gen_rtx_REG (SImode, T_REG),
- gen_rtx_fmt_ee ((enum rtx_code) code, SImode,
- sh_compare_op0, sh_compare_op1));
- if ((TARGET_SH4 || TARGET_SH2A) && GET_MODE_CLASS (mode) == MODE_FLOAT)
+ emit_jump_insn (gen_branch_false (operands[3]));
+}
+
+void
+sh_emit_compare_and_set (rtx *operands, enum machine_mode mode)
+{
+ enum rtx_code code = GET_CODE (operands[1]);
+ rtx op0 = operands[2];
+ rtx op1 = operands[3];
+ rtx lab = NULL_RTX;
+ bool invert = false;
+ rtx tem;
+
+ op0 = force_reg (mode, op0);
+ if ((code != EQ && code != NE
+ && (op1 != const0_rtx
+ || code == GTU || code == GEU || code == LTU || code == LEU))
+ || (mode == DImode && op1 != const0_rtx)
+ || (TARGET_SH2E && GET_MODE_CLASS (mode) == MODE_FLOAT))
+ op1 = force_reg (mode, op1);
+
+ if (GET_MODE_CLASS (mode) == MODE_FLOAT)
{
- insn = gen_rtx_PARALLEL (VOIDmode,
- gen_rtvec (2, insn,
- gen_rtx_USE (VOIDmode, get_fpscr_rtx ())));
- (mode == SFmode ? emit_sf_insn : emit_df_insn) (insn);
+ if (code == LT || code == LE)
+ {
+ code = swap_condition (code);
+ tem = op0, op0 = op1, op1 = tem;
+ }
+ if (code == GE)
+ {
+ if (TARGET_IEEE)
+ {
+ lab = gen_label_rtx ();
+ sh_emit_scc_to_t (EQ, op0, op1);
+ emit_jump_insn (gen_branch_true (lab));
+ code = GT;
+ }
+ else
+ {
+ code = LT;
+ invert = true;
+ }
+ }
+ }
+
+ if (code == NE)
+ {
+ code = EQ;
+ invert = true;
}
+
+ sh_emit_scc_to_t (code, op0, op1);
+ if (lab)
+ emit_label (lab);
+ if (invert)
+ emit_insn (gen_movnegt (operands[0]));
else
- emit_insn (insn);
+ emit_move_insn (operands[0], gen_rtx_REG (SImode, T_REG));
}
/* Functions to output assembly code. */
@@ -1796,7 +2235,7 @@ output_movedouble (rtx insn ATTRIBUTE_UNUSED, rtx operands[],
rtx dst = operands[0];
rtx src = operands[1];
- if (GET_CODE (dst) == MEM
+ if (MEM_P (dst)
&& GET_CODE (XEXP (dst, 0)) == PRE_DEC)
return "mov.l %T1,%0\n\tmov.l %1,%0";
@@ -1814,7 +2253,7 @@ output_movedouble (rtx insn ATTRIBUTE_UNUSED, rtx operands[],
else
return "mov %1,%0\n\tmov %T1,%T0";
}
- else if (GET_CODE (src) == CONST_INT)
+ else if (CONST_INT_P (src))
{
if (INTVAL (src) < 0)
output_asm_insn ("mov #-1,%S0", operands);
@@ -1823,7 +2262,7 @@ output_movedouble (rtx insn ATTRIBUTE_UNUSED, rtx operands[],
return "mov %1,%R0";
}
- else if (GET_CODE (src) == MEM)
+ else if (MEM_P (src))
{
int ptrreg = -1;
int dreg = REGNO (dst);
@@ -1848,7 +2287,7 @@ output_movedouble (rtx insn ATTRIBUTE_UNUSED, rtx operands[],
supported, so we can't use the 'o' constraint.
Thus we must check for and handle r0+REG addresses here.
We punt for now, since this is likely very rare. */
- gcc_assert (GET_CODE (XEXP (inside, 1)) != REG);
+ gcc_assert (!REG_P (XEXP (inside, 1)));
break;
case LABEL_REF:
@@ -1912,7 +2351,7 @@ output_far_jump (rtx insn, rtx op)
jump = "mov.l %O0,%1; jmp @%1";
}
/* If we have a scratch register available, use it. */
- if (GET_CODE ((prev = prev_nonnote_insn (insn))) == INSN
+ if (NONJUMP_INSN_P ((prev = prev_nonnote_insn (insn)))
&& INSN_CODE (prev) == CODE_FOR_indirect_jump_scratch)
{
this_jmp.reg = SET_DEST (XVECEXP (PATTERN (prev), 0, 0));
@@ -2071,7 +2510,7 @@ output_branchy_insn (enum rtx_code code, const char *templ,
{
rtx next_insn = NEXT_INSN (insn);
- if (next_insn && GET_CODE (next_insn) == JUMP_INSN && condjump_p (next_insn))
+ if (next_insn && JUMP_P (next_insn) && condjump_p (next_insn))
{
rtx src = SET_SRC (PATTERN (next_insn));
if (GET_CODE (src) == IF_THEN_ELSE && GET_CODE (XEXP (src, 0)) != code)
@@ -2184,7 +2623,7 @@ sh_cannot_copy_insn_p (rtx insn)
if (!reload_completed || !flag_pic)
return false;
- if (GET_CODE (insn) != INSN)
+ if (!NONJUMP_INSN_P (insn))
return false;
if (asm_noperands (insn) >= 0)
return false;
@@ -2279,7 +2718,7 @@ shiftcosts (rtx x)
if (GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD)
{
if (GET_MODE (x) == DImode
- && GET_CODE (XEXP (x, 1)) == CONST_INT
+ && CONST_INT_P (XEXP (x, 1))
&& INTVAL (XEXP (x, 1)) == 1)
return 2;
@@ -2287,7 +2726,7 @@ shiftcosts (rtx x)
return MAX_COST;
}
/* If shift by a non constant, then this will be expensive. */
- if (GET_CODE (XEXP (x, 1)) != CONST_INT)
+ if (!CONST_INT_P (XEXP (x, 1)))
return SH_DYNAMIC_SHIFT_COST;
/* Otherwise, return the true cost in instructions. Cope with out of range
@@ -2314,7 +2753,7 @@ andcosts (rtx x)
int i;
/* Anding with a register is a single cycle and instruction. */
- if (GET_CODE (XEXP (x, 1)) != CONST_INT)
+ if (!CONST_INT_P (XEXP (x, 1)))
return 1;
i = INTVAL (XEXP (x, 1));
@@ -2350,12 +2789,12 @@ static inline int
addsubcosts (rtx x)
{
/* Adding a register is a single cycle insn. */
- if (GET_CODE (XEXP (x, 1)) == REG
+ if (REG_P (XEXP (x, 1))
|| GET_CODE (XEXP (x, 1)) == SUBREG)
return 1;
/* Likewise for small constants. */
- if (GET_CODE (XEXP (x, 1)) == CONST_INT
+ if (CONST_INT_P (XEXP (x, 1))
&& CONST_OK_FOR_ADD (INTVAL (XEXP (x, 1))))
return 1;
@@ -2656,7 +3095,7 @@ gen_shifty_op (int code, rtx *operands)
{
/* There is a two instruction sequence for 31 bit left shifts,
but it requires r0. */
- if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 0)
+ if (REG_P (operands[0]) && REGNO (operands[0]) == 0)
{
emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
@@ -2724,7 +3163,7 @@ expand_ashiftrt (rtx *operands)
if (TARGET_SH3)
{
- if (GET_CODE (operands[2]) != CONST_INT)
+ if (!CONST_INT_P (operands[2]))
{
rtx count = copy_to_mode_reg (SImode, operands[2]);
emit_insn (gen_negsi2 (count, count));
@@ -2740,7 +3179,7 @@ expand_ashiftrt (rtx *operands)
return 1;
}
}
- if (GET_CODE (operands[2]) != CONST_INT)
+ if (!CONST_INT_P (operands[2]))
return 0;
value = INTVAL (operands[2]) & 31;
@@ -2831,7 +3270,7 @@ shl_and_kind (rtx left_rtx, rtx mask_rtx, int *attrp)
if (left < 0 || left > 31)
return 0;
- if (GET_CODE (mask_rtx) == CONST_INT)
+ if (CONST_INT_P (mask_rtx))
mask = (unsigned HOST_WIDE_INT) INTVAL (mask_rtx) >> left;
else
mask = (unsigned HOST_WIDE_INT) GET_MODE_MASK (SImode) >> left;
@@ -3568,7 +4007,7 @@ dump_table (rtx start, rtx barrier)
scan = emit_insn_after (gen_align_4 (), scan);
need_align = 0;
for (; start != barrier; start = NEXT_INSN (start))
- if (GET_CODE (start) == INSN
+ if (NONJUMP_INSN_P (start)
&& recog_memoized (start) == CODE_FOR_casesi_worker_2)
{
rtx src = SET_SRC (XVECEXP (PATTERN (start), 0, 0));
@@ -3712,7 +4151,7 @@ dump_table (rtx start, rtx barrier)
static int
hi_const (rtx src)
{
- return (GET_CODE (src) == CONST_INT
+ return (CONST_INT_P (src)
&& INTVAL (src) >= -32768
&& INTVAL (src) <= 32767);
}
@@ -3728,7 +4167,7 @@ hi_const (rtx src)
static int
broken_move (rtx insn)
{
- if (GET_CODE (insn) == INSN)
+ if (NONJUMP_INSN_P (insn))
{
rtx pat = PATTERN (insn);
if (GET_CODE (pat) == PARALLEL)
@@ -3756,7 +4195,7 @@ broken_move (rtx insn)
&& (! TARGET_SH4 || TARGET_FMOVD
|| (GET_CODE (XEXP (XVECEXP (PATTERN (insn), 0, 2), 0))
== SCRATCH))
- && GET_CODE (SET_DEST (pat)) == REG
+ && REG_P (SET_DEST (pat))
&& FP_REGISTER_P (REGNO (SET_DEST (pat))))
&& ! (TARGET_SH2A
&& GET_MODE (SET_DEST (pat)) == SImode
@@ -3772,7 +4211,7 @@ broken_move (rtx insn)
static int
mova_p (rtx insn)
{
- return (GET_CODE (insn) == INSN
+ return (NONJUMP_INSN_P (insn)
&& GET_CODE (PATTERN (insn)) == SET
&& GET_CODE (SET_SRC (PATTERN (insn))) == UNSPEC
&& XINT (SET_SRC (PATTERN (insn)), 1) == UNSPEC_MOVA
@@ -3800,9 +4239,9 @@ fixup_mova (rtx mova)
{
worker = NEXT_INSN (worker);
gcc_assert (worker
- && GET_CODE (worker) != CODE_LABEL
- && GET_CODE (worker) != JUMP_INSN);
- } while (GET_CODE (worker) == NOTE
+ && !LABEL_P (worker)
+ && !JUMP_P (worker));
+ } while (NOTE_P (worker)
|| recog_memoized (worker) != CODE_FOR_casesi_worker_1);
wpat = PATTERN (worker);
wpat0 = XVECEXP (wpat, 0, 0);
@@ -3920,12 +4359,12 @@ find_barrier (int num_mova, rtx mova, rtx from)
call, determine the alignment. N.B. When find_barrier recurses for
an out-of-reach mova, we might see labels at the start of previously
inserted constant tables. */
- if (GET_CODE (from) == CODE_LABEL
+ if (LABEL_P (from)
&& CODE_LABEL_NUMBER (from) <= max_labelno_before_reorg)
{
if (optimize)
new_align = 1 << label_to_alignment (from);
- else if (GET_CODE (prev_nonnote_insn (from)) == BARRIER)
+ else if (BARRIER_P (prev_nonnote_insn (from)))
new_align = 1 << barrier_align (from);
else
new_align = 1;
@@ -3935,7 +4374,7 @@ find_barrier (int num_mova, rtx mova, rtx from)
for explicit alignments. If the table is long, we might be forced
to emit the new table in front of it; the length of the alignment
might be the last straw. */
- else if (GET_CODE (from) == INSN
+ else if (NONJUMP_INSN_P (from)
&& GET_CODE (PATTERN (from)) == UNSPEC_VOLATILE
&& XINT (PATTERN (from), 1) == UNSPECV_ALIGN)
new_align = INTVAL (XVECEXP (PATTERN (from), 0, 0));
@@ -3943,12 +4382,12 @@ find_barrier (int num_mova, rtx mova, rtx from)
at the end. That is better than putting it in front because
this way, we don't need extra alignment for adding a 4-byte-aligned
mov(a) label to a 2/4 or 8/4 byte aligned table. */
- else if (GET_CODE (from) == INSN
+ else if (NONJUMP_INSN_P (from)
&& GET_CODE (PATTERN (from)) == UNSPEC_VOLATILE
&& XINT (PATTERN (from), 1) == UNSPECV_CONST_END)
return from;
- if (GET_CODE (from) == BARRIER)
+ if (BARRIER_P (from))
{
rtx next;
@@ -4034,9 +4473,7 @@ find_barrier (int num_mova, rtx mova, rtx from)
if (found_si > count_si)
count_si = found_si;
}
- else if (GET_CODE (from) == JUMP_INSN
- && (GET_CODE (PATTERN (from)) == ADDR_VEC
- || GET_CODE (PATTERN (from)) == ADDR_DIFF_VEC))
+ else if (JUMP_TABLE_DATA_P (from))
{
if ((num_mova > 1 && GET_MODE (prev_nonnote_insn (from)) == VOIDmode)
|| (num_mova
@@ -4063,7 +4500,7 @@ find_barrier (int num_mova, rtx mova, rtx from)
}
}
/* For the SH1, we generate alignments even after jumps-around-jumps. */
- else if (GET_CODE (from) == JUMP_INSN
+ else if (JUMP_P (from)
&& ! TARGET_SH2
&& ! TARGET_SMALLCODE)
new_align = 4;
@@ -4134,8 +4571,8 @@ find_barrier (int num_mova, rtx mova, rtx from)
around the constant pool table will be hit. Putting it before
a jump makes it more likely that the bra delay slot will be
filled. */
- while (GET_CODE (from) == JUMP_INSN || GET_CODE (from) == NOTE
- || GET_CODE (from) == CODE_LABEL)
+ while (NOTE_P (from) || JUMP_P (from)
+ || LABEL_P (from))
from = PREV_INSN (from);
from = emit_jump_insn_after (gen_jump (label), from);
@@ -4158,7 +4595,7 @@ sfunc_uses_reg (rtx insn)
int i;
rtx pattern, part, reg_part, reg;
- if (GET_CODE (insn) != INSN)
+ if (!NONJUMP_INSN_P (insn))
return 0;
pattern = PATTERN (insn);
if (GET_CODE (pattern) != PARALLEL || get_attr_type (insn) != TYPE_SFUNC)
@@ -4179,7 +4616,7 @@ sfunc_uses_reg (rtx insn)
if (part == reg_part || GET_CODE (part) == CLOBBER)
continue;
if (reg_mentioned_p (reg, ((GET_CODE (part) == SET
- && GET_CODE (SET_DEST (part)) == REG)
+ && REG_P (SET_DEST (part)))
? SET_SRC (part) : part)))
return 0;
}
@@ -4202,18 +4639,18 @@ noncall_uses_reg (rtx reg, rtx insn, rtx *set)
{
pattern = single_set (insn);
if (pattern
- && GET_CODE (SET_DEST (pattern)) == REG
+ && REG_P (SET_DEST (pattern))
&& REGNO (reg) == REGNO (SET_DEST (pattern)))
*set = pattern;
return 0;
}
- if (GET_CODE (insn) != CALL_INSN)
+ if (!CALL_P (insn))
{
/* We don't use rtx_equal_p because we don't care if the mode is
different. */
pattern = single_set (insn);
if (pattern
- && GET_CODE (SET_DEST (pattern)) == REG
+ && REG_P (SET_DEST (pattern))
&& REGNO (reg) == REGNO (SET_DEST (pattern)))
{
rtx par, part;
@@ -4252,7 +4689,7 @@ noncall_uses_reg (rtx reg, rtx insn, rtx *set)
{
/* We don't use rtx_equal_p, because we don't care if the
mode is different. */
- if (GET_CODE (SET_DEST (pattern)) != REG
+ if (!REG_P (SET_DEST (pattern))
|| REGNO (reg) != REGNO (SET_DEST (pattern)))
return 1;
@@ -4263,7 +4700,7 @@ noncall_uses_reg (rtx reg, rtx insn, rtx *set)
}
if (GET_CODE (pattern) != CALL
- || GET_CODE (XEXP (pattern, 0)) != MEM
+ || !MEM_P (XEXP (pattern, 0))
|| ! rtx_equal_p (reg, XEXP (XEXP (pattern, 0), 0)))
return 1;
@@ -4296,7 +4733,7 @@ regs_used (rtx x, int is_dest)
{
rtx y = SUBREG_REG (x);
- if (GET_CODE (y) != REG)
+ if (!REG_P (y))
break;
if (REGNO (y) < 16)
return (((1 << HARD_REGNO_NREGS (0, GET_MODE (x))) - 1)
@@ -4359,7 +4796,7 @@ gen_block_redirect (rtx jump, int addr, int need_block)
rtx dest;
/* First, check if we already have an instruction that satisfies our need. */
- if (prev && GET_CODE (prev) == INSN && ! INSN_DELETED_P (prev))
+ if (prev && NONJUMP_INSN_P (prev) && ! INSN_DELETED_P (prev))
{
if (INSN_CODE (prev) == CODE_FOR_indirect_jump_scratch)
return prev;
@@ -4456,7 +4893,7 @@ gen_block_redirect (rtx jump, int addr, int need_block)
else if (optimize && need_block >= 0)
{
rtx next = next_active_insn (next_active_insn (dest));
- if (next && GET_CODE (next) == JUMP_INSN
+ if (next && JUMP_P (next)
&& GET_CODE (PATTERN (next)) == SET
&& recog_memoized (next) == CODE_FOR_jump_compact)
{
@@ -4573,7 +5010,7 @@ fixup_addr_diff_vecs (rtx first)
{
rtx vec_lab, pat, prev, prevpat, x, braf_label;
- if (GET_CODE (insn) != JUMP_INSN
+ if (!JUMP_P (insn)
|| GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC)
continue;
pat = PATTERN (insn);
@@ -4582,7 +5019,7 @@ fixup_addr_diff_vecs (rtx first)
/* Search the matching casesi_jump_2. */
for (prev = vec_lab; ; prev = PREV_INSN (prev))
{
- if (GET_CODE (prev) != JUMP_INSN)
+ if (!JUMP_P (prev))
continue;
prevpat = PATTERN (prev);
if (GET_CODE (prevpat) != PARALLEL || XVECLEN (prevpat, 0) != 2)
@@ -4671,7 +5108,7 @@ barrier_align (rtx barrier_or_label)
prev = prev_real_insn (prev);
for (slot = 2, credit = (1 << (CACHE_LOG - 2)) + 2;
- credit >= 0 && prev && GET_CODE (prev) == INSN;
+ credit >= 0 && prev && NONJUMP_INSN_P (prev);
prev = prev_real_insn (prev))
{
jump_to_next = 0;
@@ -4695,7 +5132,7 @@ barrier_align (rtx barrier_or_label)
credit -= get_attr_length (prev);
}
if (prev
- && GET_CODE (prev) == JUMP_INSN
+ && JUMP_P (prev)
&& JUMP_LABEL (prev))
{
rtx x;
@@ -4739,7 +5176,7 @@ sh_loop_align (rtx label)
do
next = next_nonnote_insn (next);
- while (next && GET_CODE (next) == CODE_LABEL);
+ while (next && LABEL_P (next));
if (! next
|| ! INSN_P (next)
@@ -4805,7 +5242,7 @@ sh_reorg (void)
rtx pattern, reg, link, set, scan, dies, label;
int rescan = 0, foundinsn = 0;
- if (GET_CODE (insn) == CALL_INSN)
+ if (CALL_P (insn))
{
pattern = PATTERN (insn);
@@ -4815,7 +5252,7 @@ sh_reorg (void)
pattern = SET_SRC (pattern);
if (GET_CODE (pattern) != CALL
- || GET_CODE (XEXP (pattern, 0)) != MEM)
+ || !MEM_P (XEXP (pattern, 0)))
continue;
reg = XEXP (XEXP (pattern, 0), 0);
@@ -4827,13 +5264,13 @@ sh_reorg (void)
continue;
}
- if (GET_CODE (reg) != REG)
+ if (!REG_P (reg))
continue;
/* Try scanning backward to find where the register is set. */
link = NULL;
for (scan = PREV_INSN (insn);
- scan && GET_CODE (scan) != CODE_LABEL;
+ scan && !LABEL_P (scan);
scan = PREV_INSN (scan))
{
if (! INSN_P (scan))
@@ -4885,7 +5322,7 @@ sh_reorg (void)
the call, and can result in situations where a single call
insn may have two targets depending on where we came from. */
- if (GET_CODE (scan) == CODE_LABEL && ! foundinsn)
+ if (LABEL_P (scan) && ! foundinsn)
break;
if (! INSN_P (scan))
@@ -4895,7 +5332,7 @@ sh_reorg (void)
safely, we would have to check that all the
instructions at the jump destination did not use REG. */
- if (GET_CODE (scan) == JUMP_INSN)
+ if (JUMP_P (scan))
break;
if (! reg_mentioned_p (reg, scan))
@@ -4908,7 +5345,7 @@ sh_reorg (void)
foundinsn = 1;
if (scan != insn
- && (GET_CODE (scan) == CALL_INSN || sfunc_uses_reg (scan)))
+ && (CALL_P (scan) || sfunc_uses_reg (scan)))
{
/* There is a function call to this register other
than the one we are checking. If we optimize
@@ -4964,7 +5401,7 @@ sh_reorg (void)
scan = NEXT_INSN (scan);
if (scan != insn
- && ((GET_CODE (scan) == CALL_INSN
+ && ((CALL_P (scan)
&& reg_mentioned_p (reg, scan))
|| ((reg2 = sfunc_uses_reg (scan))
&& REGNO (reg2) == REGNO (reg))))
@@ -5004,7 +5441,7 @@ sh_reorg (void)
num_mova = 0;
}
}
- else if (GET_CODE (insn) == JUMP_INSN
+ else if (JUMP_P (insn)
&& GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
&& num_mova
/* ??? loop invariant motion can also move a mova out of a
@@ -5039,7 +5476,7 @@ sh_reorg (void)
}
}
if (broken_move (insn)
- || (GET_CODE (insn) == INSN
+ || (NONJUMP_INSN_P (insn)
&& recog_memoized (insn) == CODE_FOR_casesi_worker_2))
{
rtx scan;
@@ -5059,9 +5496,9 @@ sh_reorg (void)
/* Now find all the moves between the points and modify them. */
for (scan = insn; scan != barrier; scan = NEXT_INSN (scan))
{
- if (GET_CODE (scan) == CODE_LABEL)
+ if (LABEL_P (scan))
last_float = 0;
- if (GET_CODE (scan) == INSN
+ if (NONJUMP_INSN_P (scan)
&& recog_memoized (scan) == CODE_FOR_casesi_worker_2)
need_aligned_label = 1;
if (broken_move (scan))
@@ -5094,7 +5531,7 @@ sh_reorg (void)
}
dst = gen_rtx_REG (HImode, REGNO (dst) + offset);
}
- if (GET_CODE (dst) == REG && FP_ANY_REGISTER_P (REGNO (dst)))
+ if (REG_P (dst) && FP_ANY_REGISTER_P (REGNO (dst)))
{
/* This must be an insn that clobbers r0. */
rtx *clobberp = &XVECEXP (PATTERN (scan), 0,
@@ -5223,7 +5660,7 @@ get_dest_uid (rtx label, int max_uid)
dest = NEXT_INSN (dest);
dest_uid = INSN_UID (dest);
}
- if (GET_CODE (dest) == JUMP_INSN && GET_CODE (PATTERN (dest)) == RETURN)
+ if (JUMP_P (dest) && GET_CODE (PATTERN (dest)) == RETURN)
return 0;
return dest_uid;
}
@@ -5257,7 +5694,7 @@ split_branches (rtx first)
so transform it into a note. */
SET_INSN_DELETED (insn);
}
- else if (GET_CODE (insn) == JUMP_INSN
+ else if (JUMP_P (insn)
/* Don't mess with ADDR_DIFF_VEC */
&& (GET_CODE (PATTERN (insn)) == SET
|| GET_CODE (PATTERN (insn)) == RETURN))
@@ -5345,9 +5782,9 @@ split_branches (rtx first)
0));
if (beyond
- && (GET_CODE (beyond) == JUMP_INSN
+ && (JUMP_P (beyond)
|| ((beyond = next_active_insn (beyond))
- && GET_CODE (beyond) == JUMP_INSN))
+ && JUMP_P (beyond)))
&& GET_CODE (PATTERN (beyond)) == SET
&& recog_memoized (beyond) == CODE_FOR_jump_compact
&& ((INSN_ADDRESSES
@@ -5360,9 +5797,9 @@ split_branches (rtx first)
next = next_active_insn (insn);
- if ((GET_CODE (next) == JUMP_INSN
+ if ((JUMP_P (next)
|| ((next = next_active_insn (next))
- && GET_CODE (next) == JUMP_INSN))
+ && JUMP_P (next)))
&& GET_CODE (PATTERN (next)) == SET
&& recog_memoized (next) == CODE_FOR_jump_compact
&& ((INSN_ADDRESSES
@@ -5926,7 +6363,7 @@ calc_live_regs (HARD_REG_SET *live_regs_mask)
{
rtx pr_initial = has_hard_reg_initial_val (Pmode, PR_REG);
pr_live = (pr_initial
- ? (GET_CODE (pr_initial) != REG
+ ? (!REG_P (pr_initial)
|| REGNO (pr_initial) != (PR_REG))
: df_regs_ever_live_p (PR_REG));
/* For Shcompact, if not optimizing, we end up with a memory reference
@@ -6582,10 +7019,9 @@ sh_expand_epilogue (bool sibcall_p)
if (frame_pointer_needed)
{
- /* We must avoid scheduling the epilogue with previous basic blocks
- when exception handling is enabled. See PR/18032. */
- if (flag_exceptions)
- emit_insn (gen_blockage ());
+ /* We must avoid scheduling the epilogue with previous basic blocks.
+ See PR/18032 and PR/40313. */
+ emit_insn (gen_blockage ());
output_stack_adjust (frame_size, hard_frame_pointer_rtx, e,
&live_regs_mask);
@@ -6891,6 +7327,8 @@ sh_set_return_address (rtx ra, rtx tmp)
tmp = gen_frame_mem (Pmode, tmp);
emit_insn (GEN_MOV (tmp, ra));
+ /* Tell this store isn't dead. */
+ emit_use (tmp);
}
/* Clear variables at function end. */
@@ -7063,17 +7501,22 @@ sh_build_builtin_va_list (void)
record = (*lang_hooks.types.make_type) (RECORD_TYPE);
- f_next_o = build_decl (FIELD_DECL, get_identifier ("__va_next_o"),
+ f_next_o = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, get_identifier ("__va_next_o"),
ptr_type_node);
- f_next_o_limit = build_decl (FIELD_DECL,
+ f_next_o_limit = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL,
get_identifier ("__va_next_o_limit"),
ptr_type_node);
- f_next_fp = build_decl (FIELD_DECL, get_identifier ("__va_next_fp"),
+ f_next_fp = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, get_identifier ("__va_next_fp"),
ptr_type_node);
- f_next_fp_limit = build_decl (FIELD_DECL,
+ f_next_fp_limit = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL,
get_identifier ("__va_next_fp_limit"),
ptr_type_node);
- f_next_stack = build_decl (FIELD_DECL, get_identifier ("__va_next_stack"),
+ f_next_stack = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, get_identifier ("__va_next_stack"),
ptr_type_node);
DECL_FIELD_CONTEXT (f_next_o) = record;
@@ -7276,8 +7719,8 @@ sh_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
}
addr = create_tmp_var (pptr_type_node, NULL);
- lab_false = create_artificial_label ();
- lab_over = create_artificial_label ();
+ lab_false = create_artificial_label (UNKNOWN_LOCATION);
+ lab_over = create_artificial_label (UNKNOWN_LOCATION);
valist = build1 (INDIRECT_REF, ptr_type_node, addr);
@@ -8492,7 +8935,7 @@ reg_unused_after (rtx reg, rtx insn)
case. Disregard the case where this is a store to memory, since
we are checking a register used in the store address. */
set = single_set (insn);
- if (set && GET_CODE (SET_DEST (set)) != MEM
+ if (set && !MEM_P (SET_DEST (set))
&& reg_overlap_mentioned_p (reg, SET_DEST (set)))
return 1;
@@ -8531,9 +8974,9 @@ reg_unused_after (rtx reg, rtx insn)
rtx this_insn = XVECEXP (PATTERN (insn), 0, i);
rtx set = single_set (this_insn);
- if (GET_CODE (this_insn) == CALL_INSN)
+ if (CALL_P (this_insn))
code = CALL_INSN;
- else if (GET_CODE (this_insn) == JUMP_INSN)
+ else if (JUMP_P (this_insn))
{
if (INSN_ANNULLED_BRANCH_P (this_insn))
return 0;
@@ -8544,7 +8987,7 @@ reg_unused_after (rtx reg, rtx insn)
return 0;
if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
{
- if (GET_CODE (SET_DEST (set)) != MEM)
+ if (!MEM_P (SET_DEST (set)))
retval = 1;
else
return 0;
@@ -8563,7 +9006,7 @@ reg_unused_after (rtx reg, rtx insn)
if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
return 0;
if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
- return GET_CODE (SET_DEST (set)) != MEM;
+ return !MEM_P (SET_DEST (set));
if (set == 0 && reg_overlap_mentioned_p (reg, PATTERN (insn)))
return 0;
@@ -8603,7 +9046,8 @@ emit_fpu_switch (rtx scratch, int index)
t = build_index_type (integer_one_node);
t = build_array_type (integer_type_node, t);
- t = build_decl (VAR_DECL, get_identifier ("__fpscr_values"), t);
+ t = build_decl (BUILTINS_LOCATION,
+ VAR_DECL, get_identifier ("__fpscr_values"), t);
DECL_ARTIFICIAL (t) = 1;
DECL_IGNORED_P (t) = 1;
DECL_EXTERNAL (t) = 1;
@@ -8718,11 +9162,11 @@ sh_insn_length_adjustment (rtx insn)
{
/* Instructions with unfilled delay slots take up an extra two bytes for
the nop in the delay slot. */
- if (((GET_CODE (insn) == INSN
+ if (((NONJUMP_INSN_P (insn)
&& GET_CODE (PATTERN (insn)) != USE
&& GET_CODE (PATTERN (insn)) != CLOBBER)
- || GET_CODE (insn) == CALL_INSN
- || (GET_CODE (insn) == JUMP_INSN
+ || CALL_P (insn)
+ || (JUMP_P (insn)
&& GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC
&& GET_CODE (PATTERN (insn)) != ADDR_VEC))
&& GET_CODE (PATTERN (NEXT_INSN (PREV_INSN (insn)))) != SEQUENCE
@@ -8732,7 +9176,7 @@ sh_insn_length_adjustment (rtx insn)
/* SH2e has a bug that prevents the use of annulled branches, so if
the delay slot is not filled, we'll have to put a NOP in it. */
if (sh_cpu_attr == CPU_SH2E
- && GET_CODE (insn) == JUMP_INSN
+ && JUMP_P (insn)
&& GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC
&& GET_CODE (PATTERN (insn)) != ADDR_VEC
&& get_attr_type (insn) == TYPE_CBRANCH
@@ -8741,7 +9185,7 @@ sh_insn_length_adjustment (rtx insn)
/* sh-dsp parallel processing insn take four bytes instead of two. */
- if (GET_CODE (insn) == INSN)
+ if (NONJUMP_INSN_P (insn))
{
int sum = 0;
rtx body = PATTERN (insn);
@@ -8795,6 +9239,124 @@ sh_insn_length_adjustment (rtx insn)
return 0;
}
+/* Return TRUE for a valid displacement for the REG+disp addressing
+ with MODE. */
+
+/* ??? The SH2e does not have the REG+disp addressing mode when loading values
+ into the FRx registers. We implement this by setting the maximum offset
+ to zero when the value is SFmode. This also restricts loading of SFmode
+ values into the integer registers, but that can't be helped. */
+
+/* The SH allows a displacement in a QI or HI amode, but only when the
+ other operand is R0. GCC doesn't handle this very well, so we forgot
+ all of that.
+
+ A legitimate index for a QI or HI is 0, SI can be any number 0..63,
+ DI can be any number 0..60. */
+
+bool
+sh_legitimate_index_p (enum machine_mode mode, rtx op)
+{
+ if (CONST_INT_P (op))
+ {
+ if (TARGET_SHMEDIA)
+ {
+ int size;
+
+ /* Check if this the address of an unaligned load / store. */
+ if (mode == VOIDmode)
+ return CONST_OK_FOR_I06 (INTVAL (op));
+
+ size = GET_MODE_SIZE (mode);
+ return (!(INTVAL (op) & (size - 1))
+ && INTVAL (op) >= -512 * size
+ && INTVAL (op) < 512 * size);
+ }
+
+ if (TARGET_SH2A)
+ {
+ if (GET_MODE_SIZE (mode) == 1
+ && (unsigned) INTVAL (op) < 4096)
+ return true;
+ }
+
+ if ((GET_MODE_SIZE (mode) == 4
+ && (unsigned) INTVAL (op) < 64
+ && !(INTVAL (op) & 3)
+ && !(TARGET_SH2E && mode == SFmode))
+ || (GET_MODE_SIZE (mode) == 4
+ && (unsigned) INTVAL (op) < 16383
+ && !(INTVAL (op) & 3) && TARGET_SH2A))
+ return true;
+
+ if ((GET_MODE_SIZE (mode) == 8
+ && (unsigned) INTVAL (op) < 60
+ && !(INTVAL (op) & 3)
+ && !((TARGET_SH4 || TARGET_SH2A) && mode == DFmode))
+ || ((GET_MODE_SIZE (mode)==8)
+ && (unsigned) INTVAL (op) < 8192
+ && !(INTVAL (op) & (TARGET_SH2A_DOUBLE ? 7 : 3))
+ && (TARGET_SH2A && mode == DFmode)))
+ return true;
+ }
+
+ return false;
+}
+
+/* Recognize an RTL expression that is a valid memory address for
+ an instruction.
+ The MODE argument is the machine mode for the MEM expression
+ that wants to use this address.
+ Allow REG
+ REG+disp
+ REG+r0
+ REG++
+ --REG */
+
+static bool
+sh_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
+{
+ if (MAYBE_BASE_REGISTER_RTX_P (x, strict))
+ return true;
+ else if ((GET_CODE (x) == POST_INC || GET_CODE (x) == PRE_DEC)
+ && ! TARGET_SHMEDIA
+ && MAYBE_BASE_REGISTER_RTX_P (XEXP (x, 0), strict))
+ return true;
+ else if (GET_CODE (x) == PLUS
+ && (mode != PSImode || reload_completed))
+ {
+ rtx xop0 = XEXP (x, 0);
+ rtx xop1 = XEXP (x, 1);
+
+ if (GET_MODE_SIZE (mode) <= 8
+ && MAYBE_BASE_REGISTER_RTX_P (xop0, strict)
+ && sh_legitimate_index_p (mode, xop1))
+ return true;
+
+ if ((ALLOW_INDEXED_ADDRESS || GET_MODE (x) == DImode
+ || ((xop0 == stack_pointer_rtx
+ || xop0 == hard_frame_pointer_rtx)
+ && REG_P (xop1) && REGNO (xop1) == R0_REG)
+ || ((xop1 == stack_pointer_rtx
+ || xop1 == hard_frame_pointer_rtx)
+ && REG_P (xop0) && REGNO (xop0) == R0_REG))
+ && ((!TARGET_SHMEDIA && GET_MODE_SIZE (mode) <= 4)
+ || (TARGET_SHMEDIA && GET_MODE_SIZE (mode) <= 8)
+ || ((TARGET_SH4 || TARGET_SH2A_DOUBLE)
+ && TARGET_FMOVD && mode == DFmode)))
+ {
+ if (MAYBE_BASE_REGISTER_RTX_P (xop1, strict)
+ && MAYBE_INDEX_REGISTER_RTX_P (xop0, strict))
+ return true;
+ if (MAYBE_INDEX_REGISTER_RTX_P (xop1, strict)
+ && MAYBE_BASE_REGISTER_RTX_P (xop0, strict))
+ return true;
+ }
+ }
+
+ return false;
+}
+
/* Return TRUE if X references a SYMBOL_REF or LABEL_REF whose symbol
isn't protected by a PIC unspec. */
int
@@ -8888,7 +9450,7 @@ sh_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
if (GET_CODE (x) == PLUS
&& (GET_MODE_SIZE (mode) == 4
|| GET_MODE_SIZE (mode) == 8)
- && GET_CODE (XEXP (x, 1)) == CONST_INT
+ && CONST_INT_P (XEXP (x, 1))
&& BASE_REGISTER_RTX_P (XEXP (x, 0))
&& ! TARGET_SHMEDIA
&& ! ((TARGET_SH4 || TARGET_SH2A_DOUBLE) && mode == DFmode)
@@ -8950,7 +9512,7 @@ mark_constant_pool_use (rtx x)
lab = x;
for (insn = PREV_INSN (x); insn; insn = PREV_INSN (insn))
{
- if (GET_CODE (insn) != CODE_LABEL
+ if (!LABEL_P (insn)
|| LABEL_REFS (insn) != NEXT_INSN (insn))
break;
lab = insn;
@@ -8962,7 +9524,7 @@ mark_constant_pool_use (rtx x)
/* Mark constants in a window. */
for (insn = NEXT_INSN (x); insn; insn = NEXT_INSN (insn))
{
- if (GET_CODE (insn) != INSN)
+ if (!NONJUMP_INSN_P (insn))
continue;
pattern = PATTERN (insn);
@@ -9136,7 +9698,7 @@ sh_adjust_cost (rtx insn, rtx link ATTRIBUTE_UNUSED, rtx dep_insn, int cost)
}
/* The only input for a call that is timing-critical is the
function's address. */
- if (GET_CODE (insn) == CALL_INSN)
+ if (CALL_P (insn))
{
rtx call = PATTERN (insn);
@@ -9144,7 +9706,7 @@ sh_adjust_cost (rtx insn, rtx link ATTRIBUTE_UNUSED, rtx dep_insn, int cost)
call = XVECEXP (call, 0 ,0);
if (GET_CODE (call) == SET)
call = SET_SRC (call);
- if (GET_CODE (call) == CALL && GET_CODE (XEXP (call, 0)) == MEM
+ if (GET_CODE (call) == CALL && MEM_P (XEXP (call, 0))
/* sibcalli_thunk uses a symbol_ref in an unspec. */
&& (GET_CODE (XEXP (XEXP (call, 0), 0)) == UNSPEC
|| ! reg_set_p (XEXP (XEXP (call, 0), 0), dep_insn)))
@@ -9322,7 +9884,7 @@ find_set_regmode_weight (rtx x, enum machine_mode mode)
return 1;
if (GET_CODE (x) == SET && register_operand (SET_DEST (x), mode))
{
- if (GET_CODE (SET_DEST (x)) == REG)
+ if (REG_P (SET_DEST (x)))
{
if (!reg_mentioned_p (SET_DEST (x), SET_SRC (x)))
return 1;
@@ -9359,7 +9921,7 @@ find_insn_regmode_weight (rtx insn, enum machine_mode mode)
if (REG_NOTE_KIND (x) == REG_DEAD || REG_NOTE_KIND (x) == REG_UNUSED)
{
rtx note = XEXP (x, 0);
- if (GET_CODE (note) == REG && GET_MODE (note) == mode)
+ if (REG_P (note) && GET_MODE (note) == mode)
reg_weight--;
}
}
@@ -10401,7 +10963,7 @@ sh_mark_label (rtx address, int nuses)
address = XVECEXP (address, 0, 0);
}
if (GET_CODE (address) == LABEL_REF
- && GET_CODE (XEXP (address, 0)) == CODE_LABEL)
+ && LABEL_P (XEXP (address, 0)))
LABEL_NUSES (XEXP (address, 0)) += nuses;
}
@@ -10782,22 +11344,26 @@ sh_get_pr_initial_val (void)
}
int
-sh_expand_t_scc (enum rtx_code code, rtx target)
+sh_expand_t_scc (rtx operands[])
{
+ enum rtx_code code = GET_CODE (operands[1]);
+ rtx target = operands[0];
+ rtx op0 = operands[2];
+ rtx op1 = operands[3];
rtx result = target;
HOST_WIDE_INT val;
- if (GET_CODE (sh_compare_op0) != REG || REGNO (sh_compare_op0) != T_REG
- || GET_CODE (sh_compare_op1) != CONST_INT)
+ if (!REG_P (op0) || REGNO (op0) != T_REG
+ || !CONST_INT_P (op1))
return 0;
- if (GET_CODE (result) != REG)
+ if (!REG_P (result))
result = gen_reg_rtx (SImode);
- val = INTVAL (sh_compare_op1);
+ val = INTVAL (op1);
if ((code == EQ && val == 1) || (code == NE && val == 0))
emit_insn (gen_movt (result));
else if (TARGET_SH2A && ((code == EQ && val == 0)
|| (code == NE && val == 1)))
- emit_insn (gen_movrt (result));
+ emit_insn (gen_xorsi3_movrt (result));
else if ((code == EQ && val == 0) || (code == NE && val == 1))
{
emit_clobber (result);
@@ -10844,7 +11410,7 @@ check_use_sfunc_addr (rtx insn, rtx reg)
/* Search for the sfunc. It should really come right after INSN. */
while ((insn = NEXT_INSN (insn)))
{
- if (GET_CODE (insn) == CODE_LABEL || GET_CODE (insn) == JUMP_INSN)
+ if (LABEL_P (insn) || JUMP_P (insn))
break;
if (! INSN_P (insn))
continue;
@@ -11032,7 +11598,7 @@ replace_n_hard_rtx (rtx x, rtx *replacements, int n_replacements, int modify)
rtx new_rtx = replace_n_hard_rtx (SUBREG_REG (x), replacements,
n_replacements, modify);
- if (GET_CODE (new_rtx) == CONST_INT)
+ if (CONST_INT_P (new_rtx))
{
x = simplify_subreg (GET_MODE (x), new_rtx,
GET_MODE (SUBREG_REG (x)),
@@ -11045,7 +11611,7 @@ replace_n_hard_rtx (rtx x, rtx *replacements, int n_replacements, int modify)
return x;
}
- else if (GET_CODE (x) == REG)
+ else if (REG_P (x))
{
unsigned regno = REGNO (x);
unsigned nregs = (regno < FIRST_PSEUDO_REGISTER
@@ -11058,7 +11624,7 @@ replace_n_hard_rtx (rtx x, rtx *replacements, int n_replacements, int modify)
rtx to = replacements[i*2+1];
unsigned from_regno, from_nregs, to_regno, new_regno;
- if (GET_CODE (from) != REG)
+ if (!REG_P (from))
continue;
from_regno = REGNO (from);
from_nregs = (from_regno < FIRST_PSEUDO_REGISTER
@@ -11067,7 +11633,7 @@ replace_n_hard_rtx (rtx x, rtx *replacements, int n_replacements, int modify)
{
if (regno < from_regno
|| regno + nregs > from_regno + nregs
- || GET_CODE (to) != REG
+ || !REG_P (to)
|| result)
return NULL_RTX;
to_regno = REGNO (to);
@@ -11092,7 +11658,7 @@ replace_n_hard_rtx (rtx x, rtx *replacements, int n_replacements, int modify)
rtx new_rtx = replace_n_hard_rtx (XEXP (x, 0), replacements,
n_replacements, modify);
- if (GET_CODE (new_rtx) == CONST_INT)
+ if (CONST_INT_P (new_rtx))
{
x = simplify_unary_operation (ZERO_EXTEND, GET_MODE (x),
new_rtx, GET_MODE (XEXP (x, 0)));
@@ -11168,7 +11734,7 @@ shmedia_cleanup_truncate (rtx *p, void *n_changes)
if (GET_CODE (x) != TRUNCATE)
return 0;
reg = XEXP (x, 0);
- if (GET_MODE_SIZE (GET_MODE (reg)) > 8 && GET_CODE (reg) == REG)
+ if (GET_MODE_SIZE (GET_MODE (reg)) > 8 && REG_P (reg))
{
enum machine_mode reg_mode = GET_MODE (reg);
XEXP (x, 0) = simplify_subreg (DImode, reg, reg_mode,
@@ -11188,7 +11754,7 @@ shmedia_cleanup_truncate (rtx *p, void *n_changes)
static int
sh_contains_memref_p_1 (rtx *loc, void *data ATTRIBUTE_UNUSED)
{
- return (GET_CODE (*loc) == MEM);
+ return (MEM_P (*loc));
}
/* Return nonzero iff INSN contains a MEM. */
@@ -11287,7 +11853,7 @@ sh_secondary_reload (bool in_p, rtx x, enum reg_class rclass,
abort ();
}
if (rclass == FPUL_REGS
- && ((GET_CODE (x) == REG
+ && ((REG_P (x)
&& (REGNO (x) == MACL_REG || REGNO (x) == MACH_REG
|| REGNO (x) == T_REG))
|| GET_CODE (x) == PLUS))
@@ -11302,8 +11868,8 @@ sh_secondary_reload (bool in_p, rtx x, enum reg_class rclass,
return NO_REGS;
}
if (rclass == FPSCR_REGS
- && ((GET_CODE (x) == REG && REGNO (x) >= FIRST_PSEUDO_REGISTER)
- || (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == PLUS)))
+ && ((REG_P (x) && REGNO (x) >= FIRST_PSEUDO_REGISTER)
+ || (MEM_P (x) && GET_CODE (XEXP (x, 0)) == PLUS)))
return GENERAL_REGS;
if (REGCLASS_HAS_FP_REG (rclass)
&& TARGET_SHMEDIA
@@ -11324,12 +11890,12 @@ sh_secondary_reload (bool in_p, rtx x, enum reg_class rclass,
} /* end of input-only processing. */
if (((REGCLASS_HAS_FP_REG (rclass)
- && (GET_CODE (x) == REG
+ && (REG_P (x)
&& (GENERAL_OR_AP_REGISTER_P (REGNO (x))
|| (FP_REGISTER_P (REGNO (x)) && mode == SImode
&& TARGET_FMOVD))))
|| (REGCLASS_HAS_GENERAL_REG (rclass)
- && GET_CODE (x) == REG
+ && REG_P (x)
&& FP_REGISTER_P (REGNO (x))))
&& ! TARGET_SHMEDIA
&& (mode == SFmode || mode == SImode))
@@ -11337,8 +11903,8 @@ sh_secondary_reload (bool in_p, rtx x, enum reg_class rclass,
if ((rclass == FPUL_REGS
|| (REGCLASS_HAS_FP_REG (rclass)
&& ! TARGET_SHMEDIA && mode == SImode))
- && (GET_CODE (x) == MEM
- || (GET_CODE (x) == REG
+ && (MEM_P (x)
+ || (REG_P (x)
&& (REGNO (x) >= FIRST_PSEUDO_REGISTER
|| REGNO (x) == T_REG
|| system_reg_operand (x, VOIDmode)))))
@@ -11350,13 +11916,13 @@ sh_secondary_reload (bool in_p, rtx x, enum reg_class rclass,
if ((rclass == TARGET_REGS
|| (TARGET_SHMEDIA && rclass == SIBCALL_REGS))
&& !satisfies_constraint_Csy (x)
- && (GET_CODE (x) != REG || ! GENERAL_REGISTER_P (REGNO (x))))
+ && (!REG_P (x) || ! GENERAL_REGISTER_P (REGNO (x))))
return GENERAL_REGS;
if ((rclass == MAC_REGS || rclass == PR_REGS)
- && GET_CODE (x) == REG && ! GENERAL_REGISTER_P (REGNO (x))
+ && REG_P (x) && ! GENERAL_REGISTER_P (REGNO (x))
&& rclass != REGNO_REG_CLASS (REGNO (x)))
return GENERAL_REGS;
- if (rclass != GENERAL_REGS && GET_CODE (x) == REG
+ if (rclass != GENERAL_REGS && REG_P (x)
&& TARGET_REGISTER_P (REGNO (x)))
return GENERAL_REGS;
return NO_REGS;
diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h
index 71e202a87dd..7f90147bccd 100644
--- a/gcc/config/sh/sh.h
+++ b/gcc/config/sh/sh.h
@@ -459,46 +459,8 @@ do { \
#endif
#define DRIVER_SELF_SPECS "%{m2a:%{ml:%eSH2a does not support little-endian}}"
-#define OPTIMIZATION_OPTIONS(LEVEL,SIZE) \
-do { \
- if (LEVEL) \
- { \
- flag_omit_frame_pointer = 2; \
- if (! SIZE) \
- sh_div_str = "inv:minlat"; \
- } \
- if (SIZE) \
- { \
- target_flags |= MASK_SMALLCODE; \
- sh_div_str = SH_DIV_STR_FOR_SIZE ; \
- } \
- else \
- { \
- TARGET_CBRANCHDI4 = 1; \
- TARGET_EXPAND_CBRANCHDI4 = 1; \
- } \
- /* We can't meaningfully test TARGET_SHMEDIA here, because -m options \
- haven't been parsed yet, hence we'd read only the default. \
- sh_target_reg_class will return NO_REGS if this is not SHMEDIA, so \
- it's OK to always set flag_branch_target_load_optimize. */ \
- if (LEVEL > 1) \
- { \
- flag_branch_target_load_optimize = 1; \
- if (! (SIZE)) \
- target_flags |= MASK_SAVE_ALL_TARGET_REGS; \
- } \
- /* Likewise, we can't meaningfully test TARGET_SH2E / TARGET_IEEE \
- here, so leave it to OVERRIDE_OPTIONS to set \
- flag_finite_math_only. We set it to 2 here so we know if the user \
- explicitly requested this to be on or off. */ \
- flag_finite_math_only = 2; \
- /* If flag_schedule_insns is 1, we set it to 2 here so we know if \
- the user explicitly requested this to be on or off. */ \
- if (flag_schedule_insns > 0) \
- flag_schedule_insns = 2; \
- \
- set_param_value ("simultaneous-prefetches", 2); \
-} while (0)
+
+#define OPTIMIZATION_OPTIONS(LEVEL,SIZE) sh_optimization_options (LEVEL, SIZE)
#define ASSEMBLER_DIALECT assembler_dialect
@@ -535,233 +497,8 @@ extern enum sh_divide_strategy_e sh_div_strategy;
extern const char *sh_fixed_range_str;
-#define OVERRIDE_OPTIONS \
-do { \
- int regno; \
- \
- SUBTARGET_OVERRIDE_OPTIONS; \
- if (flag_finite_math_only == 2) \
- flag_finite_math_only \
- = !flag_signaling_nans && TARGET_SH2E && ! TARGET_IEEE; \
- if (TARGET_SH2E && !flag_finite_math_only) \
- target_flags |= MASK_IEEE; \
- sh_cpu = PROCESSOR_SH1; \
- assembler_dialect = 0; \
- if (TARGET_SH2) \
- sh_cpu = PROCESSOR_SH2; \
- if (TARGET_SH2E) \
- sh_cpu = PROCESSOR_SH2E; \
- if (TARGET_SH2A) \
- { \
- sh_cpu = PROCESSOR_SH2A; \
- if (TARGET_SH2A_DOUBLE) \
- target_flags |= MASK_FMOVD; \
- } \
- if (TARGET_SH3) \
- sh_cpu = PROCESSOR_SH3; \
- if (TARGET_SH3E) \
- sh_cpu = PROCESSOR_SH3E; \
- if (TARGET_SH4) \
- { \
- assembler_dialect = 1; \
- sh_cpu = PROCESSOR_SH4; \
- } \
- if (TARGET_SH4A_ARCH) \
- { \
- assembler_dialect = 1; \
- sh_cpu = PROCESSOR_SH4A; \
- } \
- if (TARGET_SH5) \
- { \
- sh_cpu = PROCESSOR_SH5; \
- target_flags |= MASK_ALIGN_DOUBLE; \
- if (TARGET_SHMEDIA_FPU) \
- target_flags |= MASK_FMOVD; \
- if (TARGET_SHMEDIA) \
- { \
- /* There are no delay slots on SHmedia. */ \
- flag_delayed_branch = 0; \
- /* Relaxation isn't yet supported for SHmedia */ \
- target_flags &= ~MASK_RELAX; \
- /* After reload, if conversion does little good but can cause \
- ICEs: \
- - find_if_block doesn't do anything for SH because we don't\
- have conditional execution patterns. (We use conditional\
- move patterns, which are handled differently, and only \
- before reload). \
- - find_cond_trap doesn't do anything for the SH because we \
- don't have conditional traps. \
- - find_if_case_1 uses redirect_edge_and_branch_force in \
- the only path that does an optimization, and this causes \
- an ICE when branch targets are in registers. \
- - find_if_case_2 doesn't do anything for the SHmedia after \
- reload except when it can redirect a tablejump - and \
- that's rather rare. */ \
- flag_if_conversion2 = 0; \
- if (! strcmp (sh_div_str, "call")) \
- sh_div_strategy = SH_DIV_CALL; \
- else if (! strcmp (sh_div_str, "call2")) \
- sh_div_strategy = SH_DIV_CALL2; \
- if (! strcmp (sh_div_str, "fp") && TARGET_FPU_ANY) \
- sh_div_strategy = SH_DIV_FP; \
- else if (! strcmp (sh_div_str, "inv")) \
- sh_div_strategy = SH_DIV_INV; \
- else if (! strcmp (sh_div_str, "inv:minlat")) \
- sh_div_strategy = SH_DIV_INV_MINLAT; \
- else if (! strcmp (sh_div_str, "inv20u")) \
- sh_div_strategy = SH_DIV_INV20U; \
- else if (! strcmp (sh_div_str, "inv20l")) \
- sh_div_strategy = SH_DIV_INV20L; \
- else if (! strcmp (sh_div_str, "inv:call2")) \
- sh_div_strategy = SH_DIV_INV_CALL2; \
- else if (! strcmp (sh_div_str, "inv:call")) \
- sh_div_strategy = SH_DIV_INV_CALL; \
- else if (! strcmp (sh_div_str, "inv:fp")) \
- { \
- if (TARGET_FPU_ANY) \
- sh_div_strategy = SH_DIV_INV_FP; \
- else \
- sh_div_strategy = SH_DIV_INV; \
- } \
- TARGET_CBRANCHDI4 = 0; \
- /* Assembler CFI isn't yet fully supported for SHmedia. */ \
- flag_dwarf2_cfi_asm = 0; \
- } \
- } \
- else \
- { \
- /* Only the sh64-elf assembler fully supports .quad properly. */\
- targetm.asm_out.aligned_op.di = NULL; \
- targetm.asm_out.unaligned_op.di = NULL; \
- } \
- if (TARGET_SH1) \
- { \
- if (! strcmp (sh_div_str, "call-div1")) \
- sh_div_strategy = SH_DIV_CALL_DIV1; \
- else if (! strcmp (sh_div_str, "call-fp") \
- && (TARGET_FPU_DOUBLE \
- || (TARGET_HARD_SH4 && TARGET_SH2E) \
- || (TARGET_SHCOMPACT && TARGET_FPU_ANY))) \
- sh_div_strategy = SH_DIV_CALL_FP; \
- else if (! strcmp (sh_div_str, "call-table") && TARGET_SH2) \
- sh_div_strategy = SH_DIV_CALL_TABLE; \
- else \
- /* Pick one that makes most sense for the target in general. \
- It is not much good to use different functions depending \
- on -Os, since then we'll end up with two different functions \
- when some of the code is compiled for size, and some for \
- speed. */ \
- \
- /* SH4 tends to emphasize speed. */ \
- if (TARGET_HARD_SH4) \
- sh_div_strategy = SH_DIV_CALL_TABLE; \
- /* These have their own way of doing things. */ \
- else if (TARGET_SH2A) \
- sh_div_strategy = SH_DIV_INTRINSIC; \
- /* ??? Should we use the integer SHmedia function instead? */ \
- else if (TARGET_SHCOMPACT && TARGET_FPU_ANY) \
- sh_div_strategy = SH_DIV_CALL_FP; \
- /* SH1 .. SH3 cores often go into small-footprint systems, so \
- default to the smallest implementation available. */ \
- else if (TARGET_SH2) /* ??? EXPERIMENTAL */ \
- sh_div_strategy = SH_DIV_CALL_TABLE; \
- else \
- sh_div_strategy = SH_DIV_CALL_DIV1; \
- } \
- if (!TARGET_SH1) \
- TARGET_PRETEND_CMOVE = 0; \
- if (sh_divsi3_libfunc[0]) \
- ; /* User supplied - leave it alone. */ \
- else if (TARGET_DIVIDE_CALL_FP) \
- sh_divsi3_libfunc = "__sdivsi3_i4"; \
- else if (TARGET_DIVIDE_CALL_TABLE) \
- sh_divsi3_libfunc = "__sdivsi3_i4i"; \
- else if (TARGET_SH5) \
- sh_divsi3_libfunc = "__sdivsi3_1"; \
- else \
- sh_divsi3_libfunc = "__sdivsi3"; \
- if (sh_branch_cost == -1) \
- sh_branch_cost \
- = TARGET_SH5 ? 1 : ! TARGET_SH2 || TARGET_HARD_SH4 ? 2 : 1; \
- \
- for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) \
- if (! VALID_REGISTER_P (regno)) \
- sh_register_names[regno][0] = '\0'; \
- \
- for (regno = 0; regno < ADDREGNAMES_SIZE; regno++) \
- if (! VALID_REGISTER_P (ADDREGNAMES_REGNO (regno))) \
- sh_additional_register_names[regno][0] = '\0'; \
- \
- if (flag_omit_frame_pointer == 2) \
- { \
- /* The debugging information is sufficient, \
- but gdb doesn't implement this yet */ \
- if (0) \
- flag_omit_frame_pointer \
- = (PREFERRED_DEBUGGING_TYPE == DWARF2_DEBUG); \
- else \
- flag_omit_frame_pointer = 0; \
- } \
- \
- if ((flag_pic && ! TARGET_PREFERGOT) \
- || (TARGET_SHMEDIA && !TARGET_PT_FIXED)) \
- flag_no_function_cse = 1; \
- \
- if (SMALL_REGISTER_CLASSES) \
- { \
- /* Never run scheduling before reload, since that can \
- break global alloc, and generates slower code anyway due \
- to the pressure on R0. */ \
- /* Enable sched1 for SH4; ready queue will be reordered by \
- the target hooks when pressure is high. We can not do this for \
- PIC, SH3 and lower as they give spill failures for R0. */ \
- if (!TARGET_HARD_SH4 || flag_pic) \
- flag_schedule_insns = 0; \
- /* ??? Current exception handling places basic block boundaries \
- after call_insns. It causes the high pressure on R0 and gives \
- spill failures for R0 in reload. See PR 22553 and the thread \
- on gcc-patches \
- <http://gcc.gnu.org/ml/gcc-patches/2005-10/msg00816.html>. */ \
- else if (flag_exceptions) \
- { \
- if (flag_schedule_insns == 1) \
- warning (0, "ignoring -fschedule-insns because of exception handling bug"); \
- flag_schedule_insns = 0; \
- } \
- } \
- \
- if (align_loops == 0) \
- align_loops = 1 << (TARGET_SH5 ? 3 : 2); \
- if (align_jumps == 0) \
- align_jumps = 1 << CACHE_LOG; \
- else if (align_jumps < (TARGET_SHMEDIA ? 4 : 2)) \
- align_jumps = TARGET_SHMEDIA ? 4 : 2; \
- \
- /* Allocation boundary (in *bytes*) for the code of a function. \
- SH1: 32 bit alignment is faster, because instructions are always \
- fetched as a pair from a longword boundary. \
- SH2 .. SH5 : align to cache line start. */ \
- if (align_functions == 0) \
- align_functions \
- = TARGET_SMALLCODE ? FUNCTION_BOUNDARY/8 : (1 << CACHE_LOG); \
- /* The linker relaxation code breaks when a function contains \
- alignments that are larger than that at the start of a \
- compilation unit. */ \
- if (TARGET_RELAX) \
- { \
- int min_align \
- = align_loops > align_jumps ? align_loops : align_jumps; \
- \
- /* Also take possible .long constants / mova tables int account. */\
- if (min_align < 4) \
- min_align = 4; \
- if (align_functions < min_align) \
- align_functions = min_align; \
- } \
- \
- if (sh_fixed_range_str) \
- sh_fix_range (sh_fixed_range_str); \
-} while (0)
+#define OVERRIDE_OPTIONS sh_override_options ()
+
/* Target machine storage layout. */
@@ -888,7 +625,7 @@ do { \
#define LABEL_ALIGN(A_LABEL) \
( \
(PREV_INSN (A_LABEL) \
- && GET_CODE (PREV_INSN (A_LABEL)) == INSN \
+ && NONJUMP_INSN_P (PREV_INSN (A_LABEL)) \
&& GET_CODE (PATTERN (PREV_INSN (A_LABEL))) == UNSPEC_VOLATILE \
&& XINT (PATTERN (PREV_INSN (A_LABEL)), 1) == UNSPECV_ALIGN) \
/* explicit alignment insn in constant tables. */ \
@@ -900,9 +637,9 @@ do { \
/* The base two logarithm of the known minimum alignment of an insn length. */
#define INSN_LENGTH_ALIGNMENT(A_INSN) \
- (GET_CODE (A_INSN) == INSN \
+ (NONJUMP_INSN_P (A_INSN) \
? 1 << TARGET_SHMEDIA \
- : GET_CODE (A_INSN) == JUMP_INSN || GET_CODE (A_INSN) == CALL_INSN \
+ : JUMP_P (A_INSN) || CALL_P (A_INSN) \
? 1 << TARGET_SHMEDIA \
: CACHE_LOG)
@@ -1547,12 +1284,12 @@ extern enum reg_class regno_reg_class[FIRST_PSEUDO_REGISTER];
#if 0
#define SECONDARY_INOUT_RELOAD_CLASS(CLASS,MODE,X,ELSE) \
((((REGCLASS_HAS_FP_REG (CLASS) \
- && (GET_CODE (X) == REG \
+ && (REG_P (X) \
&& (GENERAL_OR_AP_REGISTER_P (REGNO (X)) \
|| (FP_REGISTER_P (REGNO (X)) && (MODE) == SImode \
&& TARGET_FMOVD)))) \
|| (REGCLASS_HAS_GENERAL_REG (CLASS) \
- && GET_CODE (X) == REG \
+ && REG_P (X) \
&& FP_REGISTER_P (REGNO (X)))) \
&& ! TARGET_SHMEDIA \
&& ((MODE) == SFmode || (MODE) == SImode)) \
@@ -1560,8 +1297,8 @@ extern enum reg_class regno_reg_class[FIRST_PSEUDO_REGISTER];
: (((CLASS) == FPUL_REGS \
|| (REGCLASS_HAS_FP_REG (CLASS) \
&& ! TARGET_SHMEDIA && MODE == SImode)) \
- && (GET_CODE (X) == MEM \
- || (GET_CODE (X) == REG \
+ && (MEM_P (X) \
+ || (REG_P (X) \
&& (REGNO (X) >= FIRST_PSEUDO_REGISTER \
|| REGNO (X) == T_REG \
|| system_reg_operand (X, VOIDmode))))) \
@@ -1569,13 +1306,13 @@ extern enum reg_class regno_reg_class[FIRST_PSEUDO_REGISTER];
: (((CLASS) == TARGET_REGS \
|| (TARGET_SHMEDIA && (CLASS) == SIBCALL_REGS)) \
&& !satisfies_constraint_Csy (X) \
- && (GET_CODE (X) != REG || ! GENERAL_REGISTER_P (REGNO (X)))) \
+ && (!REG_P (X) || ! GENERAL_REGISTER_P (REGNO (X)))) \
? GENERAL_REGS \
: (((CLASS) == MAC_REGS || (CLASS) == PR_REGS) \
- && GET_CODE (X) == REG && ! GENERAL_REGISTER_P (REGNO (X)) \
+ && REG_P (X) && ! GENERAL_REGISTER_P (REGNO (X)) \
&& (CLASS) != REGNO_REG_CLASS (REGNO (X))) \
? GENERAL_REGS \
- : ((CLASS) != GENERAL_REGS && GET_CODE (X) == REG \
+ : ((CLASS) != GENERAL_REGS && REG_P (X) \
&& TARGET_REGISTER_P (REGNO (X))) \
? GENERAL_REGS : (ELSE))
@@ -1590,7 +1327,7 @@ extern enum reg_class regno_reg_class[FIRST_PSEUDO_REGISTER];
&& (MODE) == SFmode && fldi_ok ())) \
? R0_REGS \
: ((CLASS) == FPUL_REGS \
- && ((GET_CODE (X) == REG \
+ && ((REG_P (X) \
&& (REGNO (X) == MACL_REG || REGNO (X) == MACH_REG \
|| REGNO (X) == T_REG)) \
|| GET_CODE (X) == PLUS)) \
@@ -1600,8 +1337,8 @@ extern enum reg_class regno_reg_class[FIRST_PSEUDO_REGISTER];
? GENERAL_REGS \
: R0_REGS) \
: ((CLASS) == FPSCR_REGS \
- && ((GET_CODE (X) == REG && REGNO (X) >= FIRST_PSEUDO_REGISTER) \
- || (GET_CODE (X) == MEM && GET_CODE (XEXP ((X), 0)) == PLUS)))\
+ && ((REG_P (X) && REGNO (X) >= FIRST_PSEUDO_REGISTER) \
+ || (MEM_P (X) && GET_CODE (XEXP ((X), 0)) == PLUS))) \
? GENERAL_REGS \
: (REGCLASS_HAS_FP_REG (CLASS) \
&& TARGET_SHMEDIA \
@@ -2191,45 +1928,25 @@ struct sh_args {
/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
and check its validity for a certain class.
- We have two alternate definitions for each of them.
- The usual definition accepts all pseudo regs; the other rejects
- them unless they have been allocated suitable hard regs.
- The symbol REG_OK_STRICT causes the latter definition to be used. */
-
-#ifndef REG_OK_STRICT
-
-/* Nonzero if X is a hard reg that can be used as a base reg
- or if it is a pseudo reg. */
-#define REG_OK_FOR_BASE_P(X) \
- (GENERAL_OR_AP_REGISTER_P (REGNO (X)) || REGNO (X) >= FIRST_PSEUDO_REGISTER)
-
-/* Nonzero if X is a hard reg that can be used as an index
- or if it is a pseudo reg. */
-#define REG_OK_FOR_INDEX_P(X) \
- ((TARGET_SHMEDIA ? GENERAL_REGISTER_P (REGNO (X)) \
- : REGNO (X) == R0_REG) || REGNO (X) >= FIRST_PSEUDO_REGISTER)
-
-/* Nonzero if X/OFFSET is a hard reg that can be used as an index
- or if X is a pseudo reg. */
-#define SUBREG_OK_FOR_INDEX_P(X, OFFSET) \
- ((TARGET_SHMEDIA ? GENERAL_REGISTER_P (REGNO (X)) \
- : REGNO (X) == R0_REG && OFFSET == 0) || REGNO (X) >= FIRST_PSEUDO_REGISTER)
-
-#else
-
-/* Nonzero if X is a hard reg that can be used as a base reg. */
-#define REG_OK_FOR_BASE_P(X) \
- REGNO_OK_FOR_BASE_P (REGNO (X))
-
-/* Nonzero if X is a hard reg that can be used as an index. */
-#define REG_OK_FOR_INDEX_P(X) \
- REGNO_OK_FOR_INDEX_P (REGNO (X))
-
-/* Nonzero if X/OFFSET is a hard reg that can be used as an index. */
-#define SUBREG_OK_FOR_INDEX_P(X, OFFSET) \
- (REGNO_OK_FOR_INDEX_P (REGNO (X)) && (OFFSET) == 0)
-
-#endif
+ The suitable hard regs are always accepted and all pseudo regs
+ are also accepted if STRICT is not set. */
+
+/* Nonzero if X is a reg that can be used as a base reg. */
+#define REG_OK_FOR_BASE_P(X, STRICT) \
+ (GENERAL_OR_AP_REGISTER_P (REGNO (X)) \
+ || (!STRICT && REGNO (X) >= FIRST_PSEUDO_REGISTER))
+
+/* Nonzero if X is a reg that can be used as an index. */
+#define REG_OK_FOR_INDEX_P(X, STRICT) \
+ ((TARGET_SHMEDIA ? GENERAL_REGISTER_P (REGNO (X)) \
+ : REGNO (X) == R0_REG) \
+ || (!STRICT && REGNO (X) >= FIRST_PSEUDO_REGISTER))
+
+/* Nonzero if X/OFFSET is a reg that can be used as an index. */
+#define SUBREG_OK_FOR_INDEX_P(X, OFFSET, STRICT) \
+ ((TARGET_SHMEDIA ? GENERAL_REGISTER_P (REGNO (X)) \
+ : REGNO (X) == R0_REG && OFFSET == 0) \
+ || (!STRICT && REGNO (X) >= FIRST_PSEUDO_REGISTER))
/* Macros for extra constraints. */
@@ -2238,11 +1955,11 @@ struct sh_args {
|| (GET_CODE ((OP)) == CONST \
&& GET_CODE (XEXP ((OP), 0)) == PLUS \
&& GET_CODE (XEXP (XEXP ((OP), 0), 0)) == LABEL_REF \
- && GET_CODE (XEXP (XEXP ((OP), 0), 1)) == CONST_INT))
+ && CONST_INT_P (XEXP (XEXP ((OP), 0), 1))))
#define IS_NON_EXPLICIT_CONSTANT_P(OP) \
(CONSTANT_P (OP) \
- && GET_CODE (OP) != CONST_INT \
+ && !CONST_INT_P (OP) \
&& GET_CODE (OP) != CONST_DOUBLE \
&& (!flag_pic \
|| (LEGITIMATE_PIC_OPERAND_P (OP) \
@@ -2272,7 +1989,7 @@ struct sh_args {
&& (UNSPEC_GOTOFF_P (XEXP ((OP), 0)) \
|| (GET_CODE (XEXP ((OP), 0)) == PLUS \
&& UNSPEC_GOTOFF_P (XEXP (XEXP ((OP), 0), 0)) \
- && GET_CODE (XEXP (XEXP ((OP), 0), 1)) == CONST_INT)))
+ && CONST_INT_P (XEXP (XEXP ((OP), 0), 1)))))
#define PIC_ADDR_P(OP) \
(GET_CODE (OP) == CONST && GET_CODE (XEXP ((OP), 0)) == UNSPEC \
@@ -2293,7 +2010,7 @@ struct sh_args {
&& (GET_CODE (XEXP (XEXP ((OP), 0), 0)) == SYMBOL_REF \
|| GET_CODE (XEXP (XEXP ((OP), 0), 0)) == LABEL_REF \
|| DATALABEL_REF_NO_CONST_P (XEXP (XEXP ((OP), 0), 0))) \
- && GET_CODE (XEXP (XEXP ((OP), 0), 1)) == CONST_INT))
+ && CONST_INT_P (XEXP (XEXP ((OP), 0), 1))))
#define PIC_REFERENCE_P(OP) \
(GOT_ENTRY_P (OP) || GOTPLT_ENTRY_P (OP) \
@@ -2305,144 +2022,41 @@ struct sh_args {
|| PCREL_SYMOFF_P (OP)) \
: NON_PIC_REFERENCE_P (OP))
-/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
- that is a valid memory address for an instruction.
- The MODE argument is the machine mode for the MEM expression
- that wants to use this address. */
-
-#define MODE_DISP_OK_4(X,MODE) \
-(GET_MODE_SIZE (MODE) == 4 && (unsigned) INTVAL (X) < 64 \
- && ! (INTVAL (X) & 3) && ! (TARGET_SH2E && (MODE) == SFmode))
-
-#define MODE_DISP_OK_8(X,MODE) \
-((GET_MODE_SIZE(MODE)==8) && ((unsigned)INTVAL(X)<60) \
- && ! (INTVAL(X) & 3) && ! (TARGET_SH4 && (MODE) == DFmode))
-
-#undef MODE_DISP_OK_4
-#define MODE_DISP_OK_4(X,MODE) \
-((GET_MODE_SIZE (MODE) == 4 && (unsigned) INTVAL (X) < 64 \
- && ! (INTVAL (X) & 3) && ! (TARGET_SH2E && (MODE) == SFmode)) \
- || ((GET_MODE_SIZE(MODE)==4) && ((unsigned)INTVAL(X)<16383) \
- && ! (INTVAL(X) & 3) && TARGET_SH2A))
-
-#undef MODE_DISP_OK_8
-#define MODE_DISP_OK_8(X,MODE) \
-(((GET_MODE_SIZE(MODE)==8) && ((unsigned)INTVAL(X)<60) \
- && ! (INTVAL(X) & 3) && ! ((TARGET_SH4 || TARGET_SH2A) && (MODE) == DFmode)) \
- || ((GET_MODE_SIZE(MODE)==8) && ((unsigned)INTVAL(X)<8192) \
- && ! (INTVAL(X) & (TARGET_SH2A_DOUBLE ? 7 : 3)) && (TARGET_SH2A && (MODE) == DFmode)))
-
-#define BASE_REGISTER_RTX_P(X) \
- ((GET_CODE (X) == REG && REG_OK_FOR_BASE_P (X)) \
- || (GET_CODE (X) == SUBREG \
- && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (GET_MODE ((X))), \
+#define MAYBE_BASE_REGISTER_RTX_P(X, STRICT) \
+ ((REG_P (X) && REG_OK_FOR_BASE_P (X, STRICT)) \
+ || (GET_CODE (X) == SUBREG \
+ && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (GET_MODE ((X))), \
GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (X)))) \
- && GET_CODE (SUBREG_REG (X)) == REG \
- && REG_OK_FOR_BASE_P (SUBREG_REG (X))))
+ && REG_P (SUBREG_REG (X)) \
+ && REG_OK_FOR_BASE_P (SUBREG_REG (X), STRICT)))
/* Since this must be r0, which is a single register class, we must check
SUBREGs more carefully, to be sure that we don't accept one that extends
outside the class. */
-#define INDEX_REGISTER_RTX_P(X) \
- ((GET_CODE (X) == REG && REG_OK_FOR_INDEX_P (X)) \
- || (GET_CODE (X) == SUBREG \
+#define MAYBE_INDEX_REGISTER_RTX_P(X, STRICT) \
+ ((REG_P (X) && REG_OK_FOR_INDEX_P (X, STRICT)) \
+ || (GET_CODE (X) == SUBREG \
&& TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (GET_MODE ((X))), \
GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (X)))) \
- && GET_CODE (SUBREG_REG (X)) == REG \
- && SUBREG_OK_FOR_INDEX_P (SUBREG_REG (X), SUBREG_BYTE (X))))
-
-/* Jump to LABEL if X is a valid address RTX. This must also take
- REG_OK_STRICT into account when deciding about valid registers, but it uses
- the above macros so we are in luck.
-
- Allow REG
- REG+disp
- REG+r0
- REG++
- --REG */
-
-/* ??? The SH2e does not have the REG+disp addressing mode when loading values
- into the FRx registers. We implement this by setting the maximum offset
- to zero when the value is SFmode. This also restricts loading of SFmode
- values into the integer registers, but that can't be helped. */
-
-/* The SH allows a displacement in a QI or HI amode, but only when the
- other operand is R0. GCC doesn't handle this very well, so we forgo
- all of that.
-
- A legitimate index for a QI or HI is 0, SI can be any number 0..63,
- DI can be any number 0..60. */
-
-#define GO_IF_LEGITIMATE_INDEX(MODE, OP, LABEL) \
- do { \
- if (GET_CODE (OP) == CONST_INT) \
- { \
- if (TARGET_SHMEDIA) \
- { \
- int MODE_SIZE; \
- /* Check if this the address of an unaligned load / store. */\
- if ((MODE) == VOIDmode) \
- { \
- if (CONST_OK_FOR_I06 (INTVAL (OP))) \
- goto LABEL; \
- break; \
- } \
- MODE_SIZE = GET_MODE_SIZE (MODE); \
- if (! (INTVAL (OP) & (MODE_SIZE - 1)) \
- && INTVAL (OP) >= -512 * MODE_SIZE \
- && INTVAL (OP) < 512 * MODE_SIZE) \
- goto LABEL; \
- else \
- break; \
- } \
- if (TARGET_SH2A) \
- { \
- if (GET_MODE_SIZE (MODE) == 1 \
- && (unsigned) INTVAL (OP) < 4096) \
- goto LABEL; \
- } \
- if (MODE_DISP_OK_4 ((OP), (MODE))) goto LABEL; \
- if (MODE_DISP_OK_8 ((OP), (MODE))) goto LABEL; \
- } \
- } while(0)
+ && REG_P (SUBREG_REG (X)) \
+ && SUBREG_OK_FOR_INDEX_P (SUBREG_REG (X), SUBREG_BYTE (X), STRICT)))
+
+#ifdef REG_OK_STRICT
+#define BASE_REGISTER_RTX_P(X) MAYBE_BASE_REGISTER_RTX_P(X, true)
+#define INDEX_REGISTER_RTX_P(X) MAYBE_INDEX_REGISTER_RTX_P(X, true)
+#else
+#define BASE_REGISTER_RTX_P(X) MAYBE_BASE_REGISTER_RTX_P(X, false)
+#define INDEX_REGISTER_RTX_P(X) MAYBE_INDEX_REGISTER_RTX_P(X, false)
+#endif
#define ALLOW_INDEXED_ADDRESS \
((!TARGET_SHMEDIA32 && !TARGET_SHCOMPACT) || TARGET_ALLOW_INDEXED_ADDRESS)
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, LABEL) \
-{ \
- if (BASE_REGISTER_RTX_P (X)) \
- goto LABEL; \
- else if ((GET_CODE (X) == POST_INC || GET_CODE (X) == PRE_DEC) \
- && ! TARGET_SHMEDIA \
- && BASE_REGISTER_RTX_P (XEXP ((X), 0))) \
- goto LABEL; \
- else if (GET_CODE (X) == PLUS \
- && ((MODE) != PSImode || reload_completed)) \
- { \
- rtx xop0 = XEXP ((X), 0); \
- rtx xop1 = XEXP ((X), 1); \
- if (GET_MODE_SIZE (MODE) <= 8 && BASE_REGISTER_RTX_P (xop0)) \
- GO_IF_LEGITIMATE_INDEX ((MODE), xop1, LABEL); \
- if ((ALLOW_INDEXED_ADDRESS || GET_MODE (X) == DImode \
- || ((xop0 == stack_pointer_rtx \
- || xop0 == hard_frame_pointer_rtx) \
- && REG_P (xop1) && REGNO (xop1) == R0_REG) \
- || ((xop1 == stack_pointer_rtx \
- || xop1 == hard_frame_pointer_rtx) \
- && REG_P (xop0) && REGNO (xop0) == R0_REG)) \
- && ((!TARGET_SHMEDIA && GET_MODE_SIZE (MODE) <= 4) \
- || (TARGET_SHMEDIA && GET_MODE_SIZE (MODE) <= 8) \
- || ((TARGET_SH4 || TARGET_SH2A_DOUBLE) \
- && TARGET_FMOVD && MODE == DFmode))) \
- { \
- if (BASE_REGISTER_RTX_P (xop1) && INDEX_REGISTER_RTX_P (xop0))\
- goto LABEL; \
- if (INDEX_REGISTER_RTX_P (xop1) && BASE_REGISTER_RTX_P (xop0))\
- goto LABEL; \
- } \
- } \
-}
+#define GO_IF_LEGITIMATE_INDEX(MODE, OP, WIN) \
+ do { \
+ if (sh_legitimate_index_p ((MODE), (OP))) \
+ goto WIN; \
+ } while (0)
/* A C compound statement that attempts to replace X, which is an address
that needs reloading, with a valid memory address for an operand of
@@ -2455,7 +2069,7 @@ struct sh_args {
{ \
if (GET_CODE (X) == PLUS \
&& (GET_MODE_SIZE (MODE) == 4 || GET_MODE_SIZE (MODE) == 8) \
- && GET_CODE (XEXP (X, 1)) == CONST_INT \
+ && CONST_INT_P (XEXP (X, 1)) \
&& BASE_REGISTER_RTX_P (XEXP (X, 0)) \
&& ! TARGET_SHMEDIA \
&& ! (TARGET_SH4 && (MODE) == DFmode) \
@@ -2510,9 +2124,9 @@ struct sh_args {
else if (GET_CODE (X) == PLUS \
&& (GET_MODE_SIZE (MODE) == 4 || GET_MODE_SIZE (MODE) == 8) \
&& GET_CODE (XEXP (X, 0)) == PLUS \
- && GET_CODE (XEXP (XEXP (X, 0), 1)) == CONST_INT \
+ && CONST_INT_P (XEXP (XEXP (X, 0), 1)) \
&& BASE_REGISTER_RTX_P (XEXP (XEXP (X, 0), 0)) \
- && GET_CODE (XEXP (X, 1)) == CONST_INT \
+ && CONST_INT_P (XEXP (X, 1)) \
&& ! TARGET_SHMEDIA \
&& ! (TARGET_SH2E && MODE == SFmode)) \
{ \
@@ -2644,14 +2258,14 @@ struct sh_args {
in particular. */
#define INSN_SETS_ARE_DELAYED(X) \
- ((GET_CODE (X) == INSN \
+ ((NONJUMP_INSN_P (X) \
&& GET_CODE (PATTERN (X)) != SEQUENCE \
&& GET_CODE (PATTERN (X)) != USE \
&& GET_CODE (PATTERN (X)) != CLOBBER \
&& get_attr_is_sfunc (X)))
#define INSN_REFERENCES_ARE_DELAYED(X) \
- ((GET_CODE (X) == INSN \
+ ((NONJUMP_INSN_P (X) \
&& GET_CODE (PATTERN (X)) != SEQUENCE \
&& GET_CODE (PATTERN (X)) != USE \
&& GET_CODE (PATTERN (X)) != CLOBBER \
diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md
index dc6a7ab6b82..e446164eaea 100644
--- a/gcc/config/sh/sh.md
+++ b/gcc/config/sh/sh.md
@@ -1,6 +1,6 @@
;;- Machine description for Renesas / SuperH SH.
;; Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-;; 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+;; 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
;; Contributed by Steve Chamberlain (sac@cygnus.com).
;; Improved by Jim Wilson (wilson@cygnus.com).
@@ -646,8 +646,15 @@
(label_ref (match_operand 3 "" ""))
(pc)))
(clobber (reg:SI T_REG))]
- "TARGET_CBRANCHDI4"
- "expand_cbranchsi4 (operands, LAST_AND_UNUSED_RTX_CODE, -1); DONE;")
+ ""
+ "if (TARGET_SHMEDIA)
+ emit_jump_insn (gen_cbranchint4_media (operands[0], operands[1],
+ operands[2], operands[3]));
+ else if (TARGET_CBRANCHDI4)
+ expand_cbranchsi4 (operands, LAST_AND_UNUSED_RTX_CODE, -1);
+ else
+ sh_emit_compare_and_branch (operands, SImode);
+ DONE;")
;; -------------------------------------------------------------------------
;; SImode unsigned integer comparisons
@@ -676,23 +683,6 @@
"cmp/hi %1,%0"
[(set_attr "type" "mt_group")])
-;; We save the compare operands in the cmpxx patterns and use them when
-;; we generate the branch.
-
-(define_expand "cmpsi"
- [(set (reg:SI T_REG)
- (compare (match_operand:SI 0 "cmpsi_operand" "")
- (match_operand:SI 1 "arith_operand" "")))]
- "TARGET_SH1 || TARGET_SHMEDIA"
- "
-{
- if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == T_REG
- && GET_CODE (operands[1]) != CONST_INT)
- operands[0] = copy_to_mode_reg (SImode, operands[0]);
- sh_compare_op0 = operands[0];
- sh_compare_op1 = operands[1];
- DONE;
-}")
;; -------------------------------------------------------------------------
;; DImode compare and branch
@@ -713,29 +703,43 @@
(pc)))
(clobber (match_dup 4))
(clobber (reg:SI T_REG))]
- "TARGET_CBRANCHDI4"
+ "TARGET_CBRANCHDI4 || TARGET_SH2 || TARGET_SHMEDIA"
"
{
enum rtx_code comparison;
- if (TARGET_EXPAND_CBRANCHDI4)
+ if (TARGET_SHMEDIA)
+ {
+ emit_jump_insn (gen_cbranchint4_media (operands[0], operands[1],
+ operands[2], operands[3]));
+ DONE;
+ }
+
+ else if (!TARGET_CBRANCHDI4)
+ {
+ sh_emit_compare_and_branch (operands, DImode);
+ DONE;
+ }
+
+ else
{
if (expand_cbranchdi4 (operands, LAST_AND_UNUSED_RTX_CODE))
DONE;
+
+ comparison = prepare_cbranch_operands (operands, DImode,
+ LAST_AND_UNUSED_RTX_CODE);
+ if (comparison != GET_CODE (operands[0]))
+ operands[0]
+ = gen_rtx_fmt_ee (comparison, VOIDmode, operands[1], operands[2]);
+ operands[4] = gen_rtx_SCRATCH (SImode);
}
- comparison = prepare_cbranch_operands (operands, DImode,
- LAST_AND_UNUSED_RTX_CODE);
- if (comparison != GET_CODE (operands[0]))
- operands[0]
- = gen_rtx_fmt_ee (comparison, VOIDmode, operands[1], operands[2]);
- operands[4] = gen_rtx_SCRATCH (SImode);
}")
(define_insn_and_split "cbranchdi4_i"
[(set (pc)
(if_then_else (match_operator 0 "comparison_operator"
[(match_operand:DI 1 "arith_operand" "r,r")
- (match_operand:DI 2 "arith_operand" "rN,i")])
+ (match_operand:DI 2 "arith_operand" "rN,I08")])
(label_ref (match_operand 3 "" ""))
(pc)))
(clobber (match_scratch:SI 4 "=X,&r"))
@@ -907,20 +911,6 @@
"cmpgtu %1,r63,%0"
[(set_attr "type" "cmp_media")])
-;; We save the compare operands in the cmpxx patterns and use them when
-;; we generate the branch.
-
-(define_expand "cmpdi"
- [(set (reg:SI T_REG)
- (compare (match_operand:DI 0 "arith_operand" "")
- (match_operand:DI 1 "arith_operand" "")))]
- "TARGET_SH2 || TARGET_SHMEDIA"
- "
-{
- sh_compare_op0 = operands[0];
- sh_compare_op1 = operands[1];
- DONE;
-}")
;; -------------------------------------------------------------------------
;; Conditional move instructions
;; -------------------------------------------------------------------------
@@ -988,92 +978,20 @@
"
{
if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
- && GET_MODE (sh_compare_op0) == DImode
- && sh_compare_op1 == const0_rtx)
- operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
- sh_compare_op0, sh_compare_op1);
+ && GET_MODE (XEXP (operands[1], 0)) == DImode
+ && XEXP (operands[1], 1) == const0_rtx)
+ ;
else
{
- rtx tmp;
-
if (!can_create_pseudo_p ())
FAIL;
- tmp = gen_reg_rtx (DImode);
-
- switch (GET_CODE (operands[1]))
- {
- case EQ:
- emit_insn (gen_seq (tmp));
- operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
- break;
-
- case NE:
- emit_insn (gen_seq (tmp));
- operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
- break;
-
- case GT:
- emit_insn (gen_sgt (tmp));
- operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
- break;
-
- case LT:
- emit_insn (gen_slt (tmp));
- operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
- break;
-
- case GE:
- emit_insn (gen_slt (tmp));
- operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
- break;
-
- case LE:
- emit_insn (gen_sgt (tmp));
- operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
- break;
-
- case GTU:
- emit_insn (gen_sgtu (tmp));
- operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
- break;
-
- case LTU:
- emit_insn (gen_sltu (tmp));
- operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
- break;
-
- case GEU:
- emit_insn (gen_sltu (tmp));
- operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
- break;
-
- case LEU:
- emit_insn (gen_sgtu (tmp));
- operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
- break;
-
- case UNORDERED:
- emit_insn (gen_sunordered (tmp));
- operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
- break;
-
- case ORDERED:
- emit_insn (gen_sunordered (tmp));
- operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
- break;
-
- case UNEQ:
- case UNGE:
- case UNGT:
- case UNLE:
- case UNLT:
- case LTGT:
- FAIL;
-
- default:
- gcc_unreachable ();
- }
+ operands[1] = sh_emit_cheap_store_flag (GET_MODE (operands[0]),
+ GET_CODE (operands[1]),
+ XEXP (operands[1], 0),
+ XEXP (operands[1], 1));
+ if (!operands[1])
+ FAIL;
}
}")
@@ -1126,7 +1044,7 @@
(match_dup 0)
(match_dup 2)))]
"TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])
- && (GET_CODE (operands[1]) != REG || GENERAL_REGISTER_P (REGNO (operands[1])))"
+ && (!REG_P (operands[1]) || GENERAL_REGISTER_P (REGNO (operands[1])))"
[(set (match_dup 2)
(if_then_else:SI (match_dup 4) (match_dup 1) (match_dup 2)))]
"
@@ -1268,24 +1186,26 @@
"
{
if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
- && GET_MODE (sh_compare_op0) == SImode
+ && GET_MODE (XEXP (operands[1], 0)) == SImode
&& (TARGET_SHMEDIA
- || (REG_P (sh_compare_op0) && REGNO (sh_compare_op0) == T_REG))
- && sh_compare_op1 == const0_rtx)
- operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
- sh_compare_op0, sh_compare_op1);
+ || (REG_P (XEXP (operands[1], 0))
+ && REGNO (XEXP (operands[1], 0)) == T_REG))
+ && XEXP (operands[1], 1) == const0_rtx)
+ ;
+
else if (TARGET_PRETEND_CMOVE)
{
enum rtx_code code = GET_CODE (operands[1]);
enum rtx_code new_code = code;
- rtx tmp;
+ rtx op0 = XEXP (operands[1], 0);
+ rtx op1 = XEXP (operands[1], 1);
if (! currently_expanding_to_rtl)
FAIL;
switch (code)
{
case LT: case LE: case LEU: case LTU:
- if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) != MODE_INT)
+ if (GET_MODE_CLASS (GET_MODE (op0)) != MODE_INT)
break;
case NE:
new_code = reverse_condition (code);
@@ -1295,92 +1215,21 @@
default:
FAIL;
}
- tmp = prepare_scc_operands (new_code);
+ sh_emit_scc_to_t (new_code, op0, op1);
operands[1] = gen_rtx_fmt_ee (new_code == code ? NE : EQ, VOIDmode,
- tmp, const0_rtx);
+ gen_rtx_REG (SImode, T_REG), const0_rtx);
}
else
{
- rtx tmp;
-
if (!can_create_pseudo_p ())
FAIL;
- tmp = gen_reg_rtx (SImode);
-
- switch (GET_CODE (operands[1]))
- {
- case EQ:
- emit_insn (gen_seq (tmp));
- operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
- break;
-
- case NE:
- emit_insn (gen_seq (tmp));
- operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
- break;
-
- case GT:
- emit_insn (gen_sgt (tmp));
- operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
- break;
-
- case LT:
- emit_insn (gen_slt (tmp));
- operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
- break;
-
- case GE:
- emit_insn (gen_slt (tmp));
- operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
- break;
-
- case LE:
- emit_insn (gen_sgt (tmp));
- operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
- break;
-
- case GTU:
- emit_insn (gen_sgtu (tmp));
- operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
- break;
-
- case LTU:
- emit_insn (gen_sltu (tmp));
- operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
- break;
-
- case GEU:
- emit_insn (gen_sltu (tmp));
- operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
- break;
-
- case LEU:
- emit_insn (gen_sgtu (tmp));
- operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
- break;
-
- case UNORDERED:
- emit_insn (gen_sunordered (tmp));
- operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
- break;
-
- case ORDERED:
- emit_insn (gen_sunordered (tmp));
- operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
- break;
-
- case UNEQ:
- case UNGE:
- case UNGT:
- case UNLE:
- case UNLT:
- case LTGT:
- FAIL;
-
- default:
- abort ();
- }
+ operands[1] = sh_emit_cheap_store_flag (GET_MODE (operands[0]),
+ GET_CODE (operands[1]),
+ XEXP (operands[1], 0),
+ XEXP (operands[1], 1));
+ if (!operands[1])
+ FAIL;
}
}")
@@ -1699,7 +1548,7 @@
""
"
{
- if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
+ if (TARGET_SH1 && CONST_INT_P (operands[1]))
{
emit_insn (gen_negsi2 (operands[0], operands[2]));
emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
@@ -1887,8 +1736,9 @@
implemented by comparing with the divisor. */
if (operands[1] == const1_rtx && currently_expanding_to_rtl)
{
- emit_insn (gen_cmpsi (operands[1], operands[2]));
- emit_insn (gen_sgeu (operands[0]));
+ rtx test = gen_rtx_GEU (VOIDmode, operands[1], operands[2]);
+ emit_insn (gen_cstoresi4 (operands[0], test,
+ operands[1], operands[2]));
DONE;
}
else if (operands[2] == const0_rtx)
@@ -3204,7 +3054,7 @@ label:
"
{
if (TARGET_SH1
- && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
+ && CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 255)
{
emit_insn (gen_zero_extendqisi2 (operands[0],
gen_lowpart (QImode, operands[1])));
@@ -3397,7 +3247,7 @@ label:
offset = SUBREG_BYTE (operands[0]);
operands[0] = SUBREG_REG (operands[0]);
}
- gcc_assert (GET_CODE (operands[0]) == REG);
+ gcc_assert (REG_P (operands[0]));
if (! TARGET_LITTLE_ENDIAN)
offset += 8 - GET_MODE_SIZE (inmode);
operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
@@ -3510,7 +3360,7 @@ label:
int count, choice;
- if (GET_CODE (operands[2]) != CONST_INT)
+ if (!CONST_INT_P (operands[2]))
FAIL;
count = INTVAL (operands[2]);
choice = rot_tab[count];
@@ -3565,7 +3415,7 @@ label:
"TARGET_SH1"
"
{
- if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
+ if (!CONST_INT_P (operands[2]) || INTVAL (operands[2]) != 8)
FAIL;
}")
@@ -3598,7 +3448,7 @@ label:
#"
"TARGET_SH3
&& reload_completed
- && GET_CODE (operands[2]) == CONST_INT
+ && CONST_INT_P (operands[2])
&& ! satisfies_constraint_P27 (operands[2])"
[(set (match_dup 3) (match_dup 2))
(parallel
@@ -3672,7 +3522,7 @@ label:
emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
DONE;
}
- if (GET_CODE (operands[2]) == CONST_INT
+ if (CONST_INT_P (operands[2])
&& sh_dynamicalize_shift_p (operands[2]))
operands[2] = force_reg (SImode, operands[2]);
if (TARGET_SH3)
@@ -3707,7 +3557,7 @@ label:
"TARGET_SH1"
"
{
- if (GET_CODE (operands[2]) != CONST_INT)
+ if (!CONST_INT_P (operands[2]))
FAIL;
/* It may be possible to call gen_ashlhi3 directly with more generic
operands. Make sure operands[1] is a HImode register here. */
@@ -3974,7 +3824,7 @@ label:
emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
DONE;
}
- if (GET_CODE (operands[2]) == CONST_INT
+ if (CONST_INT_P (operands[2])
&& sh_dynamicalize_shift_p (operands[2]))
operands[2] = force_reg (SImode, operands[2]);
if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
@@ -4000,6 +3850,34 @@ label:
[(set_attr "length" "4")
(set_attr "type" "arith")])
+;; Expander for DImode shift left with SImode operations.
+
+(define_expand "ashldi3_std"
+ [(set (match_operand:DI 0 "arith_reg_dest" "=r")
+ (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
+ (match_operand:DI 2 "const_int_operand" "n")))]
+ "TARGET_SH1 && INTVAL (operands[2]) < 32"
+ "
+{
+ int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
+ int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
+ rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
+ rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
+ rtx dst = gen_reg_rtx (DImode);
+ rtx low_dst = operand_subword (dst, low_word, 1, DImode);
+ rtx high_dst = operand_subword (dst, high_word, 1, DImode);
+ rtx tmp0, tmp1;
+
+ tmp0 = gen_reg_rtx (SImode);
+ tmp1 = gen_reg_rtx (SImode);
+ emit_insn (gen_lshrsi3 (tmp0, low_src, GEN_INT (32 - INTVAL (operands[2]))));
+ emit_insn (gen_ashlsi3 (low_dst, low_src, operands[2]));
+ emit_insn (gen_ashlsi3 (tmp1, high_src, operands[2]));
+ emit_insn (gen_iorsi3 (high_dst, tmp0, tmp1));
+ emit_move_insn (operands[0], dst);
+ DONE;
+}")
+
(define_insn "ashldi3_media"
[(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
(ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
@@ -4032,8 +3910,19 @@ label:
emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
DONE;
}
- if (GET_CODE (operands[2]) != CONST_INT
- || INTVAL (operands[2]) != 1)
+ if (CONST_INT_P (operands[2])
+ && INTVAL (operands[2]) == 1)
+ {
+ emit_insn (gen_ashldi3_k (operands[0], operands[1]));
+ DONE;
+ }
+ else if (CONST_INT_P (operands[2])
+ && INTVAL (operands[2]) < 32)
+ {
+ emit_insn (gen_ashldi3_std (operands[0], operands[1], operands[2]));
+ DONE;
+ }
+ else
FAIL;
}")
@@ -4055,7 +3944,7 @@ label:
(match_operand:DI 2 "shift_count_operand" "r,n")))]
"TARGET_SHMEDIA
&& (arith_reg_dest (operands[0], DImode)
- || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 32))"
+ || (CONST_INT_P (operands[2]) && INTVAL (operands[2]) > 32))"
"@
shlrd %1, %2, %0
shlri %1, %2, %0"
@@ -4083,7 +3972,7 @@ label:
emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
DONE;
}
- if (GET_CODE (operands[2]) != CONST_INT
+ if (!CONST_INT_P (operands[2])
|| INTVAL (operands[2]) != 1)
FAIL;
}")
@@ -4106,7 +3995,7 @@ label:
(match_operand:DI 2 "shift_count_operand" "r,n")))]
"TARGET_SHMEDIA
&& (arith_reg_dest (operands[0], DImode)
- || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32))"
+ || (CONST_INT_P (operands[2]) && INTVAL (operands[2]) >= 32))"
"@
shard %1, %2, %0
shari %1, %2, %0"
@@ -4152,7 +4041,7 @@ label:
emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
DONE;
}
- if (GET_CODE (operands[2]) != CONST_INT
+ if (!CONST_INT_P (operands[2])
|| INTVAL (operands[2]) != 1)
FAIL;
}")
@@ -5202,7 +5091,7 @@ label:
[(set (match_operand:SI 0 "register_operand" "")
(match_operand:SI 1 "immediate_operand" ""))]
"TARGET_SHMEDIA && reload_completed
- && ((GET_CODE (operands[1]) == CONST_INT
+ && ((CONST_INT_P (operands[1])
&& ! satisfies_constraint_I16 (operands[1]))
|| GET_CODE (operands[1]) == CONST_DOUBLE)"
[(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
@@ -5390,9 +5279,9 @@ label:
"TARGET_SH1
&& (arith_reg_operand (operands[0], HImode)
|| arith_reg_operand (operands[1], HImode))
- && (GET_CODE (operands[0]) != MEM
+ && (!MEM_P (operands[0])
|| GET_CODE (XEXP (operands[0], 0)) != PLUS
- || GET_CODE (XEXP (XEXP (operands[0], 0), 1)) != REG
+ || !REG_P (XEXP (XEXP (operands[0], 0), 1))
|| ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
"@
mov.w %1,%0
@@ -5477,9 +5366,9 @@ label:
{
int regno;
- if ((GET_CODE (operands[0]) == MEM
+ if ((MEM_P (operands[0])
&& GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
- || (GET_CODE (operands[1]) == MEM
+ || (MEM_P (operands[1])
&& GET_CODE (XEXP (operands[1], 0)) == POST_INC))
FAIL;
@@ -5643,7 +5532,7 @@ label:
[(set (match_operand:DI 0 "ext_dest_operand" "")
(match_operand:DI 1 "immediate_operand" ""))]
"TARGET_SHMEDIA && reload_completed
- && GET_CODE (operands[1]) == CONST_INT
+ && CONST_INT_P (operands[1])
&& ! satisfies_constraint_I16 (operands[1])"
[(set (match_dup 0) (match_dup 2))
(match_dup 1)]
@@ -5875,8 +5764,8 @@ label:
"TARGET_SH1
&& (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
/* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
- || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
- || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
+ || (REG_P (operands[0]) && REGNO (operands[0]) == 3)
+ || (REG_P (operands[1]) && REGNO (operands[1]) == 3))
&& (arith_reg_operand (operands[0], DFmode)
|| arith_reg_operand (operands[1], DFmode))"
"* return output_movedouble (insn, operands, DFmode);"
@@ -6001,12 +5890,12 @@ label:
}
if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
mem = SUBREG_REG (mem);
- if (GET_CODE (mem) == MEM)
+ if (MEM_P (mem))
{
rtx addr = XEXP (mem, 0);
if (GET_CODE (addr) == PLUS
- && GET_CODE (XEXP (addr, 0)) == REG
- && GET_CODE (XEXP (addr, 1)) == REG)
+ && REG_P (XEXP (addr, 0))
+ && REG_P (XEXP (addr, 1)))
{
int offset;
rtx reg0 = gen_rtx_REG (Pmode, 0);
@@ -6226,9 +6115,9 @@ label:
{
int regno;
- if ((GET_CODE (operands[0]) == MEM
+ if ((MEM_P (operands[0])
&& GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
- || (GET_CODE (operands[1]) == MEM
+ || (MEM_P (operands[1])
&& GET_CODE (XEXP (operands[1], 0)) == POST_INC))
FAIL;
@@ -6282,7 +6171,7 @@ label:
{
rtx addr, reg, const_int;
- if (GET_CODE (operands[1]) != MEM)
+ if (!MEM_P (operands[1]))
FAIL;
addr = XEXP (operands[1], 0);
if (GET_CODE (addr) != PLUS)
@@ -6290,7 +6179,7 @@ label:
reg = XEXP (addr, 0);
const_int = XEXP (addr, 1);
if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
- && GET_CODE (const_int) == CONST_INT))
+ && CONST_INT_P (const_int)))
FAIL;
emit_move_insn (operands[2], const_int);
emit_move_insn (operands[0],
@@ -6310,7 +6199,7 @@ label:
{
rtx addr, reg, const_int;
- if (GET_CODE (operands[1]) != MEM)
+ if (!MEM_P (operands[1]))
FAIL;
addr = XEXP (operands[1], 0);
if (GET_CODE (addr) != PLUS)
@@ -6318,7 +6207,7 @@ label:
reg = XEXP (addr, 0);
const_int = XEXP (addr, 1);
if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
- && GET_CODE (const_int) == CONST_INT))
+ && CONST_INT_P (const_int)))
FAIL;
emit_move_insn (operands[2], const_int);
emit_move_insn (change_address (operands[1], VOIDmode,
@@ -6444,13 +6333,13 @@ label:
{
rtx x, y;
- if (GET_CODE (operands[0]) == MEM)
+ if (MEM_P (operands[0]))
x = adjust_address (operands[0], V2SFmode,
i * GET_MODE_SIZE (V2SFmode));
else
x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
- if (GET_CODE (operands[1]) == MEM)
+ if (MEM_P (operands[1]))
y = adjust_address (operands[1], V2SFmode,
i * GET_MODE_SIZE (V2SFmode));
else
@@ -6488,7 +6377,7 @@ label:
{
rtx x,y;
- if (GET_CODE (operands[0]) == MEM)
+ if (MEM_P (operands[0]))
x = adjust_address (operands[0], V2SFmode,
i * GET_MODE_SIZE (V2SFmode));
else
@@ -6497,7 +6386,7 @@ label:
alter_subreg (&x);
}
- if (GET_CODE (operands[1]) == MEM)
+ if (MEM_P (operands[1]))
y = adjust_address (operands[1], V2SFmode,
i * GET_MODE_SIZE (V2SFmode));
else
@@ -6586,8 +6475,8 @@ label:
"TARGET_SH1
&& (! TARGET_SH2E
/* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
- || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
- || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
+ || (REG_P (operands[0]) && REGNO (operands[0]) == 3)
+ || (REG_P (operands[1]) && REGNO (operands[1]) == 3))
&& (arith_reg_operand (operands[0], SFmode)
|| arith_reg_operand (operands[1], SFmode))"
"@
@@ -6877,14 +6766,83 @@ label:
;; Conditional branch insns
-(define_expand "beq_media"
+(define_expand "cbranchint4_media"
[(set (pc)
- (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
- (match_operand:DI 2 "arith_operand" "r,I06"))
- (match_operand 0 "" "")
+ (if_then_else (match_operator 0 "shmedia_cbranch_comparison_operator"
+ [(match_operand 1 "" "")
+ (match_operand 2 "" "")])
+ (match_operand 3 "" "")
(pc)))]
"TARGET_SHMEDIA"
- "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
+ "
+{
+ enum machine_mode mode = GET_MODE (operands[1]);
+ if (mode == VOIDmode)
+ mode = GET_MODE (operands[2]);
+ if (GET_CODE (operands[0]) == EQ || GET_CODE (operands[0]) == NE)
+ {
+ operands[1] = force_reg (mode, operands[1]);
+ if (CONSTANT_P (operands[2])
+ && (! satisfies_constraint_I06 (operands[2])))
+ operands[2] = force_reg (mode, operands[2]);
+ }
+ else
+ {
+ if (operands[1] != const0_rtx)
+ operands[1] = force_reg (mode, operands[1]);
+ if (operands[2] != const0_rtx)
+ operands[2] = force_reg (mode, operands[2]);
+ }
+ switch (GET_CODE (operands[0]))
+ {
+ case LEU:
+ case LE:
+ case LTU:
+ case LT:
+ operands[0] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[0])),
+ VOIDmode, operands[2], operands[1]);
+ operands[1] = XEXP (operands[0], 0);
+ operands[2] = XEXP (operands[0], 1);
+ break;
+ default:
+ operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
+ VOIDmode, operands[1], operands[2]);
+ break;
+ }
+ operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]);
+}")
+
+(define_expand "cbranchfp4_media"
+ [(set (pc)
+ (if_then_else (match_operator 0 "sh_float_comparison_operator"
+ [(match_operand 1 "" "")
+ (match_operand 2 "" "")])
+ (match_operand 3 "" "")
+ (pc)))]
+ "TARGET_SHMEDIA"
+ "
+{
+ /* hack to generate same code. */
+ rtx tmp_di = GET_CODE (operands[0]) == UNORDERED ? NULL : gen_reg_rtx (DImode);
+ rtx tmp = gen_reg_rtx (SImode);
+ rtx cmp;
+ if (GET_CODE (operands[0]) == NE)
+ cmp = gen_rtx_EQ (SImode, operands[1], operands[2]);
+ else
+ cmp = gen_rtx_fmt_ee (GET_CODE (operands[0]), SImode,
+ operands[1], operands[2]);
+
+ emit_insn (gen_cstore4_media (tmp, cmp, operands[1], operands[2]));
+ if (tmp_di) emit_insn (gen_extendsidi2 (tmp_di, tmp)); else tmp_di = tmp;
+
+ if (GET_CODE (cmp) == GET_CODE (operands[0]))
+ operands[0] = gen_rtx_NE (VOIDmode, tmp_di, const0_rtx);
+ else
+ operands[0] = gen_rtx_EQ (VOIDmode, tmp_di, const0_rtx);
+ operands[1] = tmp_di;
+ operands[2] = const0_rtx;
+ operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]);
+}")
(define_insn "*beq_media_i"
[(set (pc)
@@ -6912,51 +6870,6 @@ label:
b%o3i%' %1, %2, %0%>"
[(set_attr "type" "cbranch_media")])
-(define_expand "bne_media"
- [(set (pc)
- (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
- (match_operand:DI 2 "arith_operand" "r,I06"))
- (match_operand 0 "" "")
- (pc)))]
- "TARGET_SHMEDIA"
- "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
-
-(define_expand "bgt_media"
- [(set (pc)
- (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "")
- (match_operand:DI 2 "arith_reg_or_0_operand" ""))
- (match_operand 0 "" "")
- (pc)))]
- "TARGET_SHMEDIA"
- "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
-
-(define_expand "bge_media"
- [(set (pc)
- (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "")
- (match_operand:DI 2 "arith_reg_or_0_operand" ""))
- (match_operand 0 "" "")
- (pc)))]
- "TARGET_SHMEDIA"
- "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
-
-(define_expand "bgtu_media"
- [(set (pc)
- (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "")
- (match_operand:DI 2 "arith_reg_or_0_operand" ""))
- (match_operand 0 "" "")
- (pc)))]
- "TARGET_SHMEDIA"
- "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
-
-(define_expand "bgeu_media"
- [(set (pc)
- (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "")
- (match_operand:DI 2 "arith_reg_or_0_operand" ""))
- (match_operand 0 "" "")
- (pc)))]
- "TARGET_SHMEDIA"
- "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
-
(define_insn "*bgt_media_i"
[(set (pc)
(if_then_else (match_operator 3 "greater_comparison_operator"
@@ -7003,343 +6916,6 @@ label:
"b%o3%' %N2, %N1, %0%>"
[(set_attr "type" "cbranch_media")])
-(define_expand "beq"
- [(set (pc)
- (if_then_else (ne (reg:SI T_REG) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (TARGET_SHMEDIA)
- {
- enum machine_mode mode = GET_MODE (sh_compare_op0);
-
- if (mode != DImode && mode != SImode)
- {
- rtx tmp = gen_reg_rtx (DImode);
-
- emit_insn (gen_seq (tmp));
- emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
- DONE;
- }
-
- sh_compare_op0 = force_reg (mode, sh_compare_op0);
- if (CONSTANT_P (sh_compare_op1)
- && (! satisfies_constraint_I06 (sh_compare_op1)))
- sh_compare_op1 = force_reg (mode, sh_compare_op1);
- emit_jump_insn (gen_beq_media (operands[0],
- sh_compare_op0, sh_compare_op1));
- DONE;
- }
-
- from_compare (operands, EQ);
-}")
-
-(define_expand "bne"
- [(set (pc)
- (if_then_else (eq (reg:SI T_REG) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (TARGET_SHMEDIA)
- {
- enum machine_mode mode = GET_MODE (sh_compare_op0);
-
- if (mode != DImode && mode != SImode)
- {
- rtx tmp = gen_reg_rtx (DImode);
-
- emit_insn (gen_seq (tmp));
- emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
- DONE;
- }
-
- sh_compare_op0 = force_reg (mode, sh_compare_op0);
- if (CONSTANT_P (sh_compare_op1)
- && (! satisfies_constraint_I06 (sh_compare_op1)))
- sh_compare_op1 = force_reg (mode, sh_compare_op1);
- emit_jump_insn (gen_bne_media (operands[0],
- sh_compare_op0, sh_compare_op1));
- DONE;
- }
-
- from_compare (operands, EQ);
-}")
-
-(define_expand "bgt"
- [(set (pc)
- (if_then_else (ne (reg:SI T_REG) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (TARGET_SHMEDIA)
- {
- enum machine_mode mode = GET_MODE (sh_compare_op0);
-
- if (mode != DImode && mode != SImode)
- {
- rtx tmp = gen_reg_rtx (DImode);
-
- emit_insn (gen_sgt (tmp));
- emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
- DONE;
- }
-
- if (sh_compare_op0 != const0_rtx)
- sh_compare_op0 = force_reg (mode, sh_compare_op0);
- if (sh_compare_op1 != const0_rtx)
- sh_compare_op1 = force_reg (mode, sh_compare_op1);
- emit_jump_insn (gen_bgt_media (operands[0],
- sh_compare_op0, sh_compare_op1));
- DONE;
- }
-
- from_compare (operands, GT);
-}")
-
-(define_expand "blt"
- [(set (pc)
- (if_then_else (eq (reg:SI T_REG) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (TARGET_SHMEDIA)
- {
- enum machine_mode mode = GET_MODE (sh_compare_op0);
-
- if (mode != DImode && mode != SImode)
- {
- rtx tmp = gen_reg_rtx (DImode);
-
- emit_insn (gen_slt (tmp));
- emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
- DONE;
- }
-
- if (sh_compare_op0 != const0_rtx)
- sh_compare_op0 = force_reg (mode, sh_compare_op0);
- if (sh_compare_op1 != const0_rtx)
- sh_compare_op1 = force_reg (mode, sh_compare_op1);
- emit_jump_insn (gen_bgt_media (operands[0],
- sh_compare_op1, sh_compare_op0));
- DONE;
- }
-
- if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
- {
- rtx tmp = sh_compare_op0;
- sh_compare_op0 = sh_compare_op1;
- sh_compare_op1 = tmp;
- emit_insn (gen_bgt (operands[0]));
- DONE;
- }
- from_compare (operands, GE);
-}")
-
-(define_expand "ble"
- [(set (pc)
- (if_then_else (eq (reg:SI T_REG) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (TARGET_SHMEDIA)
- {
- enum machine_mode mode = GET_MODE (sh_compare_op0);
-
- if (mode != DImode && mode != SImode)
- {
- rtx tmp = gen_reg_rtx (DImode);
-
- emit_insn (gen_sle (tmp));
- emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
- DONE;
- }
-
- if (sh_compare_op0 != const0_rtx)
- sh_compare_op0 = force_reg (mode, sh_compare_op0);
- if (sh_compare_op1 != const0_rtx)
- sh_compare_op1 = force_reg (mode, sh_compare_op1);
- emit_jump_insn (gen_bge_media (operands[0],
- sh_compare_op1, sh_compare_op0));
- DONE;
- }
-
- if (TARGET_SH2E
- && TARGET_IEEE
- && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
- {
- rtx tmp = sh_compare_op0;
- sh_compare_op0 = sh_compare_op1;
- sh_compare_op1 = tmp;
- emit_insn (gen_bge (operands[0]));
- DONE;
- }
- from_compare (operands, GT);
-}")
-
-(define_expand "bge"
- [(set (pc)
- (if_then_else (ne (reg:SI T_REG) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (TARGET_SHMEDIA)
- {
- enum machine_mode mode = GET_MODE (sh_compare_op0);
-
- if (mode != DImode && mode != SImode)
- {
- rtx tmp = gen_reg_rtx (DImode);
-
- emit_insn (gen_sge (tmp));
- emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
- DONE;
- }
-
- if (sh_compare_op0 != const0_rtx)
- sh_compare_op0 = force_reg (mode, sh_compare_op0);
- if (sh_compare_op1 != const0_rtx)
- sh_compare_op1 = force_reg (mode, sh_compare_op1);
- emit_jump_insn (gen_bge_media (operands[0],
- sh_compare_op0, sh_compare_op1));
- DONE;
- }
-
- if (TARGET_SH2E
- && ! TARGET_IEEE
- && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
- {
- rtx tmp = sh_compare_op0;
- sh_compare_op0 = sh_compare_op1;
- sh_compare_op1 = tmp;
- emit_insn (gen_ble (operands[0]));
- DONE;
- }
- from_compare (operands, GE);
-}")
-
-(define_expand "bgtu"
- [(set (pc)
- (if_then_else (ne (reg:SI T_REG) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (TARGET_SHMEDIA)
- {
- enum machine_mode mode = GET_MODE (sh_compare_op0);
-
- if (sh_compare_op0 != const0_rtx)
- sh_compare_op0 = force_reg (mode, sh_compare_op0);
- if (sh_compare_op1 != const0_rtx)
- sh_compare_op1 = force_reg (mode, sh_compare_op1);
- emit_jump_insn (gen_bgtu_media (operands[0],
- sh_compare_op0, sh_compare_op1));
- DONE;
- }
-
- from_compare (operands, GTU);
-}")
-
-(define_expand "bltu"
- [(set (pc)
- (if_then_else (eq (reg:SI T_REG) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (TARGET_SHMEDIA)
- {
- enum machine_mode mode = GET_MODE (sh_compare_op0);
-
- if (sh_compare_op0 != const0_rtx)
- sh_compare_op0 = force_reg (mode, sh_compare_op0);
- if (sh_compare_op1 != const0_rtx)
- sh_compare_op1 = force_reg (mode, sh_compare_op1);
- emit_jump_insn (gen_bgtu_media (operands[0],
- sh_compare_op1, sh_compare_op0));
- DONE;
- }
-
- from_compare (operands, GEU);
-}")
-
-(define_expand "bgeu"
- [(set (pc)
- (if_then_else (ne (reg:SI T_REG) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (TARGET_SHMEDIA)
- {
- enum machine_mode mode = GET_MODE (sh_compare_op0);
-
- if (sh_compare_op0 != const0_rtx)
- sh_compare_op0 = force_reg (mode, sh_compare_op0);
- if (sh_compare_op1 != const0_rtx)
- sh_compare_op1 = force_reg (mode, sh_compare_op1);
- emit_jump_insn (gen_bgeu_media (operands[0],
- sh_compare_op0, sh_compare_op1));
- DONE;
- }
-
- from_compare (operands, GEU);
-}")
-
-(define_expand "bleu"
- [(set (pc)
- (if_then_else (eq (reg:SI T_REG) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (TARGET_SHMEDIA)
- {
- enum machine_mode mode = GET_MODE (sh_compare_op0);
-
- if (sh_compare_op0 != const0_rtx)
- sh_compare_op0 = force_reg (mode, sh_compare_op0);
- if (sh_compare_op1 != const0_rtx)
- sh_compare_op1 = force_reg (mode, sh_compare_op1);
- emit_jump_insn (gen_bgeu_media (operands[0],
- sh_compare_op1, sh_compare_op0));
- DONE;
- }
-
- from_compare (operands, GTU);
-}")
-
-(define_expand "bunordered"
- [(set (match_dup 1) (unordered:SI (match_dup 2) (match_dup 3)))
- (set (pc)
- (if_then_else (ne (match_dup 1) (const_int 0))
- (match_operand 0 "" "")
- (pc)))]
- "TARGET_SHMEDIA"
- "
-{
- operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);
- operands[1] = gen_reg_rtx (SImode);
- operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
- operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
-}")
-
;; combiner splitter for test-and-branch on single bit in register. This
;; is endian dependent because the non-paradoxical subreg looks different
;; on big endian.
@@ -7824,7 +7400,7 @@ label:
XEXP (operands[0], 0) = reg;
}
if (!flag_pic && TARGET_SH2A
- && GET_CODE (operands[0]) == MEM
+ && MEM_P (operands[0])
&& GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
{
if (sh2a_is_function_vector_call (XEXP (operands[0], 0)))
@@ -7835,7 +7411,7 @@ label:
}
}
if (flag_pic && TARGET_SH2
- && GET_CODE (operands[0]) == MEM
+ && MEM_P (operands[0])
&& GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
{
emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
@@ -8018,7 +7594,7 @@ label:
XEXP (operands[1], 0) = reg;
}
if (!flag_pic && TARGET_SH2A
- && GET_CODE (operands[1]) == MEM
+ && MEM_P (operands[1])
&& GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
{
if (sh2a_is_function_vector_call (XEXP (operands[1], 0)))
@@ -8029,7 +7605,7 @@ label:
}
}
if (flag_pic && TARGET_SH2
- && GET_CODE (operands[1]) == MEM
+ && MEM_P (operands[1])
&& GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
{
emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
@@ -8224,7 +7800,7 @@ label:
XEXP (operands[0], 0) = reg;
}
if (flag_pic && TARGET_SH2
- && GET_CODE (operands[0]) == MEM
+ && MEM_P (operands[0])
&& GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
/* The PLT needs the PIC register, but the epilogue would have
to restore it, so we can only use PC-relative PIC calls for
@@ -8416,7 +7992,7 @@ label:
XEXP (operands[1], 0) = reg;
}
if (flag_pic && TARGET_SH2
- && GET_CODE (operands[1]) == MEM
+ && MEM_P (operands[1])
&& GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
/* The PLT needs the PIC register, but the epilogue would have
to restore it, so we can only use PC-relative PIC calls for
@@ -8547,7 +8123,7 @@ label:
/* If epilogue clobbers r0, preserve it in macl. */
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
if ((set = single_set (insn))
- && GET_CODE (SET_DEST (set)) == REG
+ && REG_P (SET_DEST (set))
&& REGNO (SET_DEST (set)) == R0_REG)
{
rtx r0 = gen_rtx_REG (SImode, R0_REG);
@@ -9120,15 +8696,17 @@ mov.l\\t1f,r0\\n\\
rtx reg3 = gen_reg_rtx (Pmode);
rtx reg4 = gen_reg_rtx (Pmode);
rtx reg5 = gen_reg_rtx (Pmode);
- rtx load;
+ rtx load, test;
operands[0] = convert_modes (DImode, SImode, operands[0], 0);
operands[1] = convert_modes (DImode, SImode, operands[1], 0);
operands[2] = convert_modes (DImode, SImode, operands[2], 1);
- emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
+ test = gen_rtx_GT (VOIDmode, operands[1], operands[0]);
+ emit_jump_insn (gen_cbranchdi4 (test, operands[1], operands[0], operands[4]));
emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
- emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
+ test = gen_rtx_GTU (VOIDmode, reg, operands[2]);
+ emit_jump_insn (gen_cbranchdi4 (test, reg, operands[2], operands[4]));
emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
(Pmode, operands[3])));
@@ -9570,546 +9148,133 @@ mov.l\\t1f,r0\\n\\
"movt %0"
[(set_attr "type" "arith")])
-;; complements the T bit and stores the result in a register
-(define_insn "movrt"
- [(set (match_operand:SI 0 "arith_reg_dest" "=r")
- (if_then_else (eq:SI (reg:SI T_REG) (const_int 0))
- (const_int 1)
- (const_int 0)))]
- "TARGET_SH2A"
- "movrt\\t%0"
- [(set_attr "type" "arith")])
-
-(define_expand "seq"
- [(set (match_operand:SI 0 "arith_reg_dest" "")
- (match_dup 1))]
- ""
+(define_expand "cstore4_media"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (match_operator:SI 1 "sh_float_comparison_operator"
+ [(match_operand 2 "logical_operand" "")
+ (match_operand 3 "cmp_operand" "")]))]
+ "TARGET_SHMEDIA"
"
{
- if (TARGET_SHMEDIA)
+ enum machine_mode mode = GET_MODE (operands[2]);
+ enum rtx_code code = GET_CODE (operands[1]);
+ bool invert, swap;
+ if (mode == VOIDmode)
+ mode = GET_MODE (operands[3]);
+ if (operands[2] == const0_rtx)
{
- rtx reg;
-
- sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
- if (sh_compare_op1 != const0_rtx)
- sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
- ? GET_MODE (sh_compare_op0)
- : GET_MODE (sh_compare_op1),
- sh_compare_op1);
- if (GET_MODE_SIZE (GET_MODE (operands[0])) <= 4)
- {
- if (GET_MODE (operands[0]) != SImode)
- operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
-
- switch (GET_MODE (sh_compare_op0))
- {
- case SImode:
- emit_insn (gen_cmpeqsi_media (operands[0],
- sh_compare_op0, sh_compare_op1));
- break;
-
- case DImode:
- emit_insn (gen_cmpeqdi_media (operands[0],
- sh_compare_op0, sh_compare_op1));
- break;
-
- case SFmode:
- if (! TARGET_SHMEDIA_FPU)
- FAIL;
- emit_insn (gen_cmpeqsf_media (operands[0],
- sh_compare_op0, sh_compare_op1));
- break;
-
- case DFmode:
- if (! TARGET_SHMEDIA_FPU)
- FAIL;
- emit_insn (gen_cmpeqdf_media (operands[0],
- sh_compare_op0, sh_compare_op1));
- break;
-
- default:
- FAIL;
- }
- DONE;
- }
-
- reg = operands[0];
- if (GET_MODE (operands[0]) != SImode)
- reg = (!can_create_pseudo_p ()
- ? gen_rtx_SUBREG (SImode, operands[0], 0)
- : gen_reg_rtx (SImode));
-
- switch (GET_MODE (sh_compare_op0))
- {
- case SImode:
- emit_insn (gen_cmpeqsi_media (reg,
- sh_compare_op0, sh_compare_op1));
- break;
-
- case DImode:
- emit_insn (gen_cmpeqdi_media (reg,
- sh_compare_op0, sh_compare_op1));
- break;
-
- case SFmode:
- if (! TARGET_SHMEDIA_FPU)
- FAIL;
- emit_insn (gen_cmpeqsf_media (reg,
- sh_compare_op0, sh_compare_op1));
- break;
-
- case DFmode:
- if (! TARGET_SHMEDIA_FPU)
- FAIL;
- emit_insn (gen_cmpeqdf_media (reg,
- sh_compare_op0, sh_compare_op1));
- break;
-
- default:
- FAIL;
- }
-
- if (GET_MODE (operands[0]) == DImode)
- emit_insn (gen_extendsidi2 (operands[0], reg));
-
- DONE;
+ if (code == EQ || code == NE)
+ operands[2] = operands[3], operands[3] = const0_rtx;
}
- if (sh_expand_t_scc (EQ, operands[0]))
- DONE;
- if (! currently_expanding_to_rtl)
- FAIL;
- operands[1] = prepare_scc_operands (EQ);
-}")
+ else
+ operands[2] = force_reg (mode, operands[2]);
+ if (operands[3] != const0_rtx)
+ operands[3] = force_reg (mode, operands[3]);
-(define_expand "slt"
- [(set (match_operand:SI 0 "arith_reg_operand" "")
- (match_dup 1))]
- ""
- "
-{
- if (TARGET_SHMEDIA)
+ switch (code)
{
- rtx reg;
-
- sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
- if (sh_compare_op1 != const0_rtx)
- sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
- ? GET_MODE (sh_compare_op0)
- : GET_MODE (sh_compare_op1),
- sh_compare_op1);
-
- reg = operands[0];
- if (GET_MODE (operands[0]) != SImode)
- reg = (!can_create_pseudo_p ()
- ? gen_rtx_SUBREG (SImode, operands[0], 0)
- : gen_reg_rtx (SImode));
-
- switch (GET_MODE (sh_compare_op0))
- {
- case SImode:
- emit_insn (gen_cmpgtsi_media (reg,
- sh_compare_op1, sh_compare_op0));
- break;
-
- case DImode:
- emit_insn (gen_cmpgtdi_media (reg,
- sh_compare_op1, sh_compare_op0));
- break;
-
- case SFmode:
- if (! TARGET_SHMEDIA_FPU)
- FAIL;
- emit_insn (gen_cmpgtsf_media (reg,
- sh_compare_op1, sh_compare_op0));
- break;
+ case GEU:
+ case GE:
+ swap = invert = !FLOAT_MODE_P (mode);
+ break;
- case DFmode:
- if (! TARGET_SHMEDIA_FPU)
- FAIL;
- emit_insn (gen_cmpgtdf_media (reg,
- sh_compare_op1, sh_compare_op0));
- break;
+ case LEU:
+ case LE:
+ swap = FLOAT_MODE_P (mode), invert = !swap;
+ break;
- default:
- FAIL;
- }
+ case LTU:
+ case LT:
+ swap = true, invert = false;
+ break;
- if (GET_MODE (operands[0]) == DImode)
- emit_insn (gen_extendsidi2 (operands[0], reg));
+ case GTU:
+ case GT:
+ case EQ:
+ case UNORDERED:
+ swap = invert = false;
+ break;
- DONE;
- }
- if (! currently_expanding_to_rtl)
- FAIL;
- operands[1] = prepare_scc_operands (LT);
-}")
+ case NE:
+ swap = invert = true;
+ break;
-(define_expand "sle"
- [(match_operand:SI 0 "arith_reg_operand" "")]
- ""
- "
-{
- rtx tmp = sh_compare_op0;
+ default:
+ gcc_unreachable ();
+ }
- if (TARGET_SHMEDIA)
+ if (swap)
{
- rtx reg;
-
- sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
- if (sh_compare_op1 != const0_rtx)
- sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
- ? GET_MODE (sh_compare_op0)
- : GET_MODE (sh_compare_op1),
- sh_compare_op1);
-
- reg = operands[0];
- if (GET_MODE (operands[0]) != SImode)
- reg = (!can_create_pseudo_p ()
- ? gen_rtx_SUBREG (SImode, operands[0], 0)
- : gen_reg_rtx (SImode));
-
- switch (GET_MODE (sh_compare_op0))
- {
- case SImode:
- {
- tmp = !can_create_pseudo_p () ? reg : gen_reg_rtx (SImode);
-
- emit_insn (gen_cmpgtsi_media (tmp,
- sh_compare_op0, sh_compare_op1));
- emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
- break;
- }
-
- case DImode:
- {
- tmp = !can_create_pseudo_p () ? reg : gen_reg_rtx (SImode);
-
- emit_insn (gen_cmpgtdi_media (tmp,
- sh_compare_op0, sh_compare_op1));
- emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
- break;
- }
-
- case SFmode:
- if (! TARGET_SHMEDIA_FPU)
- FAIL;
- emit_insn (gen_cmpgesf_media (reg,
- sh_compare_op1, sh_compare_op0));
- break;
-
- case DFmode:
- if (! TARGET_SHMEDIA_FPU)
- FAIL;
- emit_insn (gen_cmpgedf_media (reg,
- sh_compare_op1, sh_compare_op0));
- break;
-
- default:
- FAIL;
- }
-
- if (GET_MODE (operands[0]) == DImode)
- emit_insn (gen_extendsidi2 (operands[0], reg));
-
- DONE;
+ rtx tem = operands[2];
+ operands[2] = operands[3];
+ operands[3] = tem;
+ code = swap_condition (code);
}
- sh_compare_op0 = sh_compare_op1;
- sh_compare_op1 = tmp;
- emit_insn (gen_sge (operands[0]));
- DONE;
-}")
-
-(define_expand "sgt"
- [(set (match_operand:SI 0 "arith_reg_operand" "")
- (match_dup 1))]
- ""
- "
-{
- if (TARGET_SHMEDIA)
+ if (invert)
{
- rtx reg;
-
- reg = operands[0];
- if (GET_MODE (operands[0]) != SImode)
- reg = (!can_create_pseudo_p () ?
- gen_rtx_SUBREG (SImode, operands[0], 0)
- : gen_reg_rtx (SImode));
- sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
- if (sh_compare_op1 != const0_rtx)
- sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
- ? GET_MODE (sh_compare_op0)
- : GET_MODE (sh_compare_op1),
- sh_compare_op1);
-
- switch (GET_MODE (sh_compare_op0))
- {
- case SImode:
- emit_insn (gen_cmpgtsi_media (reg,
- sh_compare_op0, sh_compare_op1));
- break;
-
- case DImode:
- emit_insn (gen_cmpgtdi_media (reg,
- sh_compare_op0, sh_compare_op1));
- break;
-
- case SFmode:
- if (! TARGET_SHMEDIA_FPU)
- FAIL;
- emit_insn (gen_cmpgtsf_media (reg,
- sh_compare_op0, sh_compare_op1));
- break;
-
- case DFmode:
- if (! TARGET_SHMEDIA_FPU)
- FAIL;
- emit_insn (gen_cmpgtdf_media (reg,
- sh_compare_op0, sh_compare_op1));
- break;
-
- default:
- FAIL;
- }
-
- if (GET_MODE (operands[0]) == DImode)
- emit_insn (gen_extendsidi2 (operands[0], reg));
-
- DONE;
+ rtx tem = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
+ code = reverse_condition (code);
+ operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
+ emit_insn (gen_cstore4_media (tem, operands[1],
+ operands[2], operands[3]));
+ code = EQ;
+ operands[2] = tem;
+ operands[3] = const0_rtx;
}
- if (! currently_expanding_to_rtl)
- FAIL;
- operands[1] = prepare_scc_operands (GT);
-}")
-(define_expand "sge"
- [(set (match_operand:SI 0 "arith_reg_operand" "")
- (match_dup 1))]
- ""
- "
-{
- if (TARGET_SHMEDIA)
- {
- rtx reg;
- enum machine_mode mode = GET_MODE (sh_compare_op0);
-
- if ((mode) == VOIDmode)
- mode = GET_MODE (sh_compare_op1);
- reg = operands[0];
- if (GET_MODE (operands[0]) != SImode)
- reg = (!can_create_pseudo_p ()
- ? gen_rtx_SUBREG (SImode, operands[0], 0)
- : gen_reg_rtx (SImode));
- sh_compare_op0 = force_reg (mode, sh_compare_op0);
- if (sh_compare_op1 != const0_rtx)
- sh_compare_op1 = force_reg (mode, sh_compare_op1);
-
- switch (mode)
- {
- case SImode:
- {
- rtx tmp = !can_create_pseudo_p () ? reg : gen_reg_rtx (SImode);
-
- emit_insn (gen_cmpgtsi_media (tmp,
- sh_compare_op1, sh_compare_op0));
- emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
- break;
- }
-
- case DImode:
- {
- rtx tmp = !can_create_pseudo_p () ? reg : gen_reg_rtx (SImode);
-
- emit_insn (gen_cmpgtdi_media (tmp,
- sh_compare_op1, sh_compare_op0));
- emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
- break;
- }
-
- case SFmode:
- if (! TARGET_SHMEDIA_FPU)
- FAIL;
- emit_insn (gen_cmpgesf_media (reg,
- sh_compare_op0, sh_compare_op1));
- break;
-
- case DFmode:
- if (! TARGET_SHMEDIA_FPU)
- FAIL;
- emit_insn (gen_cmpgedf_media (reg,
- sh_compare_op0, sh_compare_op1));
- break;
-
- default:
- FAIL;
- }
-
- if (GET_MODE (operands[0]) == DImode)
- emit_insn (gen_extendsidi2 (operands[0], reg));
-
- DONE;
- }
-
- if (! currently_expanding_to_rtl)
- FAIL;
- if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
- {
- if (TARGET_IEEE)
- {
- rtx lab = gen_label_rtx ();
- prepare_scc_operands (EQ);
- emit_jump_insn (gen_branch_true (lab));
- prepare_scc_operands (GT);
- emit_label (lab);
- emit_insn (gen_movt (operands[0]));
- }
- else
- emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
- DONE;
- }
- operands[1] = prepare_scc_operands (GE);
+ operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
}")
-(define_expand "sgtu"
- [(set (match_operand:SI 0 "arith_reg_operand" "")
- (match_dup 1))]
- ""
- "
-{
- if (TARGET_SHMEDIA)
+(define_expand "cstoresi4"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (match_operator:SI 1 "comparison_operator"
+ [(match_operand:SI 2 "cmpsi_operand" "")
+ (match_operand:SI 3 "arith_operand" "")]))]
+ "TARGET_SH1 || TARGET_SHMEDIA"
+ "if (TARGET_SHMEDIA)
{
- rtx reg;
-
- reg = operands[0];
- if (GET_MODE (operands[0]) == DImode)
- reg = (!can_create_pseudo_p ()
- ? gen_rtx_SUBREG (SImode, operands[0], 0)
- : gen_reg_rtx (SImode));
- sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
- if (sh_compare_op1 != const0_rtx)
- sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
- ? GET_MODE (sh_compare_op0)
- : GET_MODE (sh_compare_op1),
- sh_compare_op1);
-
- emit_insn (gen_cmpgtudi_media (reg,
- sh_compare_op0, sh_compare_op1));
- if (GET_MODE (operands[0]) == DImode)
- emit_insn (gen_extendsidi2 (operands[0], reg));
-
+ emit_insn (gen_cstore4_media (operands[0], operands[1],
+ operands[2], operands[3]));
DONE;
}
- if (! currently_expanding_to_rtl)
- FAIL;
- operands[1] = prepare_scc_operands (GTU);
-}")
-(define_expand "sltu"
- [(set (match_operand:SI 0 "arith_reg_operand" "")
- (match_dup 1))]
- ""
- "
-{
- if (TARGET_SHMEDIA)
- {
- rtx reg;
-
- reg = operands[0];
- if (GET_MODE (operands[0]) == DImode)
- reg = (!can_create_pseudo_p ()
- ? gen_rtx_SUBREG (SImode, operands[0], 0)
- : gen_reg_rtx (SImode));
- sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
- if (sh_compare_op1 != const0_rtx)
- sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
- ? GET_MODE (sh_compare_op0)
- : GET_MODE (sh_compare_op1),
- sh_compare_op1);
-
- emit_insn (gen_cmpgtudi_media (reg,
- sh_compare_op1, sh_compare_op0));
- if (GET_MODE (operands[0]) == DImode)
- emit_insn (gen_extendsidi2 (operands[0], reg));
+ if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
+ && sh_expand_t_scc (operands))
+ DONE;
- DONE;
- }
- if (! currently_expanding_to_rtl)
- FAIL;
- operands[1] = prepare_scc_operands (LTU);
-}")
+ if (! currently_expanding_to_rtl)
+ FAIL;
+
+ sh_emit_compare_and_set (operands, SImode);
+ DONE;
+")
-(define_expand "sleu"
- [(set (match_operand:SI 0 "arith_reg_operand" "")
- (match_dup 1))]
- ""
- "
-{
- if (TARGET_SHMEDIA)
+(define_expand "cstoredi4"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (match_operator:SI 1 "comparison_operator"
+ [(match_operand:DI 2 "arith_operand" "")
+ (match_operand:DI 3 "arith_operand" "")]))]
+ "TARGET_SH2 || TARGET_SHMEDIA"
+ "if (TARGET_SHMEDIA)
{
- rtx tmp, reg;
-
- reg = operands[0];
- if (GET_MODE (operands[0]) != SImode)
- reg = (!can_create_pseudo_p ()
- ? gen_rtx_SUBREG (SImode, operands[0], 0)
- : gen_reg_rtx (SImode));
- sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
- if (sh_compare_op1 != const0_rtx)
- sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
- ? GET_MODE (sh_compare_op0)
- : GET_MODE (sh_compare_op1),
- sh_compare_op1);
-
- tmp = !can_create_pseudo_p () ? reg : gen_reg_rtx (SImode);
-
- emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
- emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
- if (GET_MODE (operands[0]) == DImode)
- emit_insn (gen_extendsidi2 (operands[0], reg));
-
+ emit_insn (gen_cstore4_media (operands[0], operands[1],
+ operands[2], operands[3]));
DONE;
}
- if (! currently_expanding_to_rtl)
- FAIL;
- operands[1] = prepare_scc_operands (LEU);
-}")
-(define_expand "sgeu"
- [(set (match_operand:SI 0 "arith_reg_operand" "")
- (match_dup 1))]
- ""
- "
-{
- if (TARGET_SHMEDIA)
- {
- rtx tmp, reg;
-
- reg = operands[0];
- if (GET_MODE (operands[0]) != SImode)
- reg = (!can_create_pseudo_p ()
- ? gen_rtx_SUBREG (SImode, operands[0], 0)
- : gen_reg_rtx (SImode));
- sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
- if (sh_compare_op1 != const0_rtx)
- sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
- ? GET_MODE (sh_compare_op0)
- : GET_MODE (sh_compare_op1),
- sh_compare_op1);
-
- tmp = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (SImode);
+ if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
+ && sh_expand_t_scc (operands))
+ DONE;
- emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
- emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
- if (GET_MODE (operands[0]) == DImode)
- emit_insn (gen_extendsidi2 (operands[0], reg));
+ if (! currently_expanding_to_rtl)
+ FAIL;
+
+ sh_emit_compare_and_set (operands, DImode);
+ DONE;
+")
- DONE;
- }
- if (! currently_expanding_to_rtl)
- FAIL;
- operands[1] = prepare_scc_operands (GEU);
-}")
;; sne moves the complement of the T reg to DEST like this:
;; cmp/eq ...
@@ -10119,81 +9284,20 @@ mov.l\\t1f,r0\\n\\
;; not require r0 and further, the -1 may be CSE-ed or lifted out of a
;; loop.
-(define_expand "sne"
- [(set (match_dup 2) (const_int -1))
- (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
- (neg:SI (plus:SI (match_dup 1)
- (match_dup 2))))
+(define_expand "movnegt"
+ [(set (match_dup 1) (const_int -1))
+ (parallel [(set (match_operand:SI 0 "" "")
+ (neg:SI (plus:SI (reg:SI T_REG)
+ (match_dup 1))))
(set (reg:SI T_REG)
- (ne:SI (ior:SI (match_dup 1) (match_dup 2))
+ (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
(const_int 0)))])]
""
"
{
- if (TARGET_SHMEDIA)
- {
- rtx tmp, reg;
-
- reg = operands[0];
- if (GET_MODE (operands[0]) != SImode)
- reg = (!can_create_pseudo_p ()
- ? gen_rtx_SUBREG (SImode, operands[0], 0)
- : gen_reg_rtx (SImode));
- if (! TARGET_SHMEDIA_FPU
- && GET_MODE (sh_compare_op0) != DImode
- && GET_MODE (sh_compare_op0) != SImode)
- FAIL;
-
- sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
- if (sh_compare_op1 != const0_rtx)
- sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
- ? GET_MODE (sh_compare_op0)
- : GET_MODE (sh_compare_op1),
- sh_compare_op1);
-
- tmp = !can_create_pseudo_p () ? reg : gen_reg_rtx (SImode);
-
- emit_insn (gen_seq (tmp));
- emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
- if (GET_MODE (operands[0]) == DImode)
- emit_insn (gen_extendsidi2 (operands[0], reg));
-
- DONE;
- }
-
- if (sh_expand_t_scc (NE, operands[0]))
- DONE;
- if (! currently_expanding_to_rtl)
- FAIL;
- operands[1] = prepare_scc_operands (EQ);
- operands[2] = gen_reg_rtx (SImode);
-}")
-
-(define_expand "sunordered"
- [(set (match_operand:SI 0 "arith_reg_operand" "")
- (unordered:SI (match_dup 1) (match_dup 2)))]
- "TARGET_SHMEDIA_FPU"
- "
-{
- operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
- operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
+ operands[1] = gen_reg_rtx (SImode);
}")
-;; Use the same trick for FP sle / sge
-
-;; Apart from the constant use and the T setting, this is like movt,
-;; except that it uses the logically negated value of T, i.e.
-;; operand[0] := T ? 0 : 1.
-(define_expand "movnegt"
- [(set (match_dup 2) (const_int -1))
- (parallel [(set (match_operand 0 "" "")
- (neg:SI (plus:SI (match_dup 1)
- (match_dup 2))))
- (set (reg:SI T_REG)
- (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
- (const_int 0)))])]
- "TARGET_SH1"
- "operands[2] = gen_reg_rtx (SImode);")
;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
;; This prevents a regression that occurred when we switched from xor to
@@ -10208,6 +9312,47 @@ mov.l\\t1f,r0\\n\\
(set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
"")
+(define_expand "cstoresf4"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (match_operator:SI 1 "sh_float_comparison_operator"
+ [(match_operand:SF 2 "arith_operand" "")
+ (match_operand:SF 3 "arith_operand" "")]))]
+ "TARGET_SH2E || TARGET_SHMEDIA_FPU"
+ "if (TARGET_SHMEDIA)
+ {
+ emit_insn (gen_cstore4_media (operands[0], operands[1],
+ operands[2], operands[3]));
+ DONE;
+ }
+
+ if (! currently_expanding_to_rtl)
+ FAIL;
+
+ sh_emit_compare_and_set (operands, SFmode);
+ DONE;
+")
+
+(define_expand "cstoredf4"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (match_operator:SI 1 "sh_float_comparison_operator"
+ [(match_operand:DF 2 "arith_operand" "")
+ (match_operand:DF 3 "arith_operand" "")]))]
+ "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
+ "if (TARGET_SHMEDIA)
+ {
+ emit_insn (gen_cstore4_media (operands[0], operands[1],
+ operands[2], operands[3]));
+ DONE;
+ }
+
+ if (! currently_expanding_to_rtl)
+ FAIL;
+
+ sh_emit_compare_and_set (operands, DFmode);
+ DONE;
+")
+
+
;; -------------------------------------------------------------------------
;; Instructions to cope with inline literal tables
;; -------------------------------------------------------------------------
@@ -10448,7 +9593,7 @@ mov.l\\t1f,r0\\n\\
;; The c / m alternative is a fake to guide reload to load directly into
;; fpscr, since reload doesn't know how to use post-increment.
-;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
+;; TARGET_LEGITIMATE_ADDRESS_P guards about bogus addresses before reload,
;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
;; predicate after reload.
;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
@@ -10459,7 +9604,7 @@ mov.l\\t1f,r0\\n\\
"TARGET_SH2E
&& (! reload_completed
|| true_regnum (operands[0]) != FPSCR_REG
- || GET_CODE (operands[1]) != MEM
+ || !MEM_P (operands[1])
|| GET_CODE (XEXP (operands[1], 0)) != PLUS)"
"@
! precision stays the same
@@ -10986,15 +10131,21 @@ mov.l\\t1f,r0\\n\\
"fcmpun.s %1, %2, %0"
[(set_attr "type" "fcmp_media")])
-(define_expand "cmpsf"
- [(set (reg:SI T_REG)
- (compare (match_operand:SF 0 "arith_operand" "")
- (match_operand:SF 1 "arith_operand" "")))]
+(define_expand "cbranchsf4"
+ [(set (pc)
+ (if_then_else (match_operator 0 "sh_float_comparison_operator"
+ [(match_operand:SF 1 "arith_operand" "")
+ (match_operand:SF 2 "arith_operand" "")])
+ (match_operand 3 "" "")
+ (pc)))]
"TARGET_SH2E || TARGET_SHMEDIA_FPU"
"
{
- sh_compare_op0 = operands[0];
- sh_compare_op1 = operands[1];
+ if (TARGET_SHMEDIA)
+ emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
+ operands[3]));
+ else
+ sh_emit_compare_and_branch (operands, SFmode);
DONE;
}")
@@ -11484,18 +10635,25 @@ mov.l\\t1f,r0\\n\\
"fcmpun.d %1,%2,%0"
[(set_attr "type" "fcmp_media")])
-(define_expand "cmpdf"
- [(set (reg:SI T_REG)
- (compare (match_operand:DF 0 "arith_operand" "")
- (match_operand:DF 1 "arith_operand" "")))]
+(define_expand "cbranchdf4"
+ [(set (pc)
+ (if_then_else (match_operator 0 "sh_float_comparison_operator"
+ [(match_operand:DF 1 "arith_operand" "")
+ (match_operand:DF 2 "arith_operand" "")])
+ (match_operand 3 "" "")
+ (pc)))]
"(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
"
{
- sh_compare_op0 = operands[0];
- sh_compare_op1 = operands[1];
+ if (TARGET_SHMEDIA)
+ emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
+ operands[3]));
+ else
+ sh_emit_compare_and_branch (operands, DFmode);
DONE;
}")
+
(define_expand "negdf2"
[(set (match_operand:DF 0 "arith_reg_operand" "")
(neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
@@ -11704,7 +10862,7 @@ mov.l\\t1f,r0\\n\\
size = bitsize / 8;
orig_address = XEXP (operands[0], 0);
shift_reg = gen_reg_rtx (SImode);
- if (GET_CODE (x) == CONST_INT)
+ if (CONST_INT_P (x))
{
v = INTVAL (x);
qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
@@ -11721,7 +10879,7 @@ mov.l\\t1f,r0\\n\\
while (size -= 1)
{
- if (GET_CODE (x) == CONST_INT)
+ if (CONST_INT_P (x))
qi_val
= force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
else
@@ -11781,7 +10939,7 @@ mov.l\\t1f,r0\\n\\
if (TARGET_SH4A_ARCH
&& INTVAL (operands[2]) == 32
&& INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
- && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
+ && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
{
rtx src = adjust_address (operands[1], BLKmode, 0);
set_mem_size (src, GEN_INT (4));
@@ -11813,7 +10971,7 @@ mov.l\\t1f,r0\\n\\
if (TARGET_SH4A_ARCH
&& INTVAL (operands[2]) == 32
&& INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
- && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
+ && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
{
rtx src = adjust_address (operands[1], BLKmode, 0);
set_mem_size (src, GEN_INT (4));
@@ -12146,7 +11304,7 @@ mov.l\\t1f,r0\\n\\
(set (mem:SF (match_dup 0))
(match_operand:SF 2 "general_movsrc_operand" ""))]
"TARGET_SH1 && REGNO (operands[0]) == 0
- && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
+ && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
|| (GET_CODE (operands[2]) == SUBREG
&& REGNO (SUBREG_REG (operands[2])) < 16))
&& reg_unused_after (operands[0], insn)"
@@ -12159,7 +11317,7 @@ mov.l\\t1f,r0\\n\\
(mem:SF (match_dup 0)))]
"TARGET_SH1 && REGNO (operands[0]) == 0
- && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
+ && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
|| (GET_CODE (operands[2]) == SUBREG
&& REGNO (SUBREG_REG (operands[2])) < 16))
&& reg_unused_after (operands[0], insn)"
@@ -12171,7 +11329,7 @@ mov.l\\t1f,r0\\n\\
(set (mem:SF (match_dup 0))
(match_operand:SF 2 "general_movsrc_operand" ""))]
"TARGET_SH2E && REGNO (operands[0]) == 0
- && ((GET_CODE (operands[2]) == REG
+ && ((REG_P (operands[2])
&& FP_OR_XD_REGISTER_P (REGNO (operands[2])))
|| (GET_CODE (operands[2]) == SUBREG
&& FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
@@ -12185,7 +11343,7 @@ mov.l\\t1f,r0\\n\\
(mem:SF (match_dup 0)))]
"TARGET_SH2E && REGNO (operands[0]) == 0
- && ((GET_CODE (operands[2]) == REG
+ && ((REG_P (operands[2])
&& FP_OR_XD_REGISTER_P (REGNO (operands[2])))
|| (GET_CODE (operands[2]) == SUBREG
&& FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
@@ -12274,7 +11432,7 @@ mov.l\\t1f,r0\\n\\
operands[1] = XVECEXP (operands[1], 0, 0);
if (unit_size < 2)
{
- if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
+ if (CONST_INT_P (operands[1]) && CONST_INT_P (elt1))
operands[1]
= GEN_INT (TARGET_LITTLE_ENDIAN
? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
@@ -14036,8 +13194,8 @@ mov.l\\t1f,r0\\n\\
"
{
if (GET_MODE (operands[0]) != Pmode
- || GET_CODE (operands[1]) != CONST_INT
- || GET_CODE (operands[2]) != CONST_INT)
+ || !CONST_INT_P (operands[1])
+ || !CONST_INT_P (operands[2]))
FAIL;
if (! TARGET_SHMEDIA)
operands[0] = force_reg (Pmode, operands[0]);
@@ -14144,15 +13302,21 @@ mov.l\\t1f,r0\\n\\
if (TARGET_SHMEDIA)
{
rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
+ rtx test;
+ test = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
if (TARGET_SHMEDIA64)
- emit_insn (gen_stack_protect_test_di_media (tmp, operands[0],
- operands[1]));
+ {
+ emit_insn (gen_stack_protect_test_di_media (tmp, operands[0],
+ operands[1]));
+ emit_jump_insn (gen_cbranchdi4 (test, tmp, const0_rtx, operands[2]));
+ }
else
- emit_insn (gen_stack_protect_test_si_media (tmp, operands[0],
- operands[1]));
-
- emit_jump_insn (gen_bne_media (operands[2], tmp, const0_rtx));
+ {
+ emit_insn (gen_stack_protect_test_si_media (tmp, operands[0],
+ operands[1]));
+ emit_jump_insn (gen_cbranchsi4 (test, tmp, const0_rtx, operands[2]));
+ }
}
else
{
diff --git a/gcc/config/sh/sh.opt b/gcc/config/sh/sh.opt
index 9aaba6c151e..8aa0c9f1b7c 100644
--- a/gcc/config/sh/sh.opt
+++ b/gcc/config/sh/sh.opt
@@ -1,6 +1,6 @@
; Options for the SH port of the compiler.
-; Copyright (C) 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+; Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
;
; This file is part of GCC.
;
@@ -224,13 +224,9 @@ mcbranchdi
Target Var(TARGET_CBRANCHDI4)
Enable cbranchdi4 pattern
-mexpand-cbranchdi
-Target Var(TARGET_EXPAND_CBRANCHDI4)
-Expand cbranchdi4 pattern early into separate comparisons and branches.
-
mcmpeqdi
Target Var(TARGET_CMPEQDI_T)
-Emit cmpeqdi_t pattern even when -mcbranchdi and -mexpand-cbranchdi are in effect.
+Emit cmpeqdi_t pattern even when -mcbranchdi is in effect.
mcut2-workaround
Target RejectNegative Var(TARGET_SH5_CUT2_WORKAROUND)
diff --git a/gcc/config/sh/symbian.c b/gcc/config/sh/symbian.c
index f32adf9717f..b4dbc3fb3c2 100644
--- a/gcc/config/sh/symbian.c
+++ b/gcc/config/sh/symbian.c
@@ -217,7 +217,7 @@ sh_symbian_mark_dllexport (tree decl)
tree idp;
rtlname = XEXP (DECL_RTL (decl), 0);
- if (GET_CODE (rtlname) == MEM)
+ if (MEM_P (rtlname))
rtlname = XEXP (rtlname, 0);
gcc_assert (GET_CODE (rtlname) == SYMBOL_REF);
oldname = XSTR (rtlname, 0);
@@ -262,7 +262,7 @@ sh_symbian_mark_dllimport (tree decl)
rtx newrtl;
rtlname = XEXP (DECL_RTL (decl), 0);
- if (GET_CODE (rtlname) == MEM)
+ if (MEM_P (rtlname))
rtlname = XEXP (rtlname, 0);
gcc_assert (GET_CODE (rtlname) == SYMBOL_REF);
oldname = XSTR (rtlname, 0);
@@ -312,8 +312,8 @@ sh_symbian_encode_section_info (tree decl, rtx rtl, int first)
else if ( (TREE_CODE (decl) == FUNCTION_DECL
|| TREE_CODE (decl) == VAR_DECL)
&& DECL_RTL (decl) != NULL_RTX
- && GET_CODE (DECL_RTL (decl)) == MEM
- && GET_CODE (XEXP (DECL_RTL (decl), 0)) == MEM
+ && MEM_P (DECL_RTL (decl))
+ && MEM_P (XEXP (DECL_RTL (decl), 0))
&& GET_CODE (XEXP (XEXP (DECL_RTL (decl), 0), 0)) == SYMBOL_REF
&& sh_symbian_dllimport_name_p (XSTR (XEXP (XEXP (DECL_RTL (decl), 0), 0), 0)))
{
diff --git a/gcc/config/sh/t-sh b/gcc/config/sh/t-sh
index 07481bcc342..216a86b0090 100644
--- a/gcc/config/sh/t-sh
+++ b/gcc/config/sh/t-sh
@@ -19,7 +19,8 @@
sh-c.o: $(srcdir)/config/sh/sh-c.c \
$(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(TM_H) $(TM_P_H) coretypes.h
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/config/sh/sh-c.c
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $(srcdir)/config/sh/sh-c.c
LIB1ASMSRC = sh/lib1funcs.asm
LIB1ASMFUNCS = _ashiftrt _ashiftrt_n _ashiftlt _lshiftrt _movmem \
diff --git a/gcc/config/sh/t-symbian b/gcc/config/sh/t-symbian
index 03f84edcf82..1698b722edc 100644
--- a/gcc/config/sh/t-symbian
+++ b/gcc/config/sh/t-symbian
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2006, 2008 Free Software Foundation, Inc.
+# Copyright (C) 2004, 2006, 2008, 2009 Free Software Foundation, Inc.
#
# This file is part of GCC.
#
@@ -18,7 +18,8 @@
sh-c.o: $(srcdir)/config/sh/sh-c.c \
$(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(TM_H) $(TM_P_H) coretypes.h
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/config/sh/sh-c.c
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $(srcdir)/config/sh/sh-c.c
LIB1ASMSRC = sh/lib1funcs.asm
LIB1ASMFUNCS = _ashiftrt _ashiftrt_n _ashiftlt _lshiftrt _movstr \
@@ -49,7 +50,8 @@ gt-sh.h : s-gtype ; @true
symbian.o: $(srcdir)/config/sh/symbian.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_H) output.h flags.h $(TREE_H) expr.h toplev.h $(TM_P_H)
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/config/sh/symbian.c
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $(srcdir)/config/sh/symbian.c
# Local Variables:
diff --git a/gcc/config/sparc/sparc-protos.h b/gcc/config/sparc/sparc-protos.h
index 40ac75e130c..8b3547ad907 100644
--- a/gcc/config/sparc/sparc-protos.h
+++ b/gcc/config/sparc/sparc-protos.h
@@ -54,22 +54,19 @@ extern void sparc_output_scratch_registers (FILE *);
#ifdef RTX_CODE
extern enum machine_mode select_cc_mode (enum rtx_code, rtx, rtx);
/* Define the function that build the compare insn for scc and bcc. */
-extern rtx gen_compare_reg (enum rtx_code code);
-extern rtx gen_compare_operator (enum rtx_code code);
-extern enum rtx_code sparc_emit_float_lib_cmp (rtx, rtx, enum rtx_code);
+extern rtx gen_compare_reg (rtx cmp);
+extern rtx sparc_emit_float_lib_cmp (rtx, rtx, enum rtx_code);
extern void sparc_emit_floatunsdi (rtx [2], enum machine_mode);
extern void sparc_emit_fixunsdi (rtx [2], enum machine_mode);
extern void emit_tfmode_binop (enum rtx_code, rtx *);
extern void emit_tfmode_unop (enum rtx_code, rtx *);
extern void emit_tfmode_cvt (enum rtx_code, rtx *);
/* This function handles all v9 scc insns */
-extern int gen_v9_scc (enum rtx_code, rtx *);
extern void sparc_initialize_trampoline (rtx, rtx, rtx);
extern void sparc64_initialize_trampoline (rtx, rtx, rtx);
extern bool legitimate_constant_p (rtx);
extern bool constant_address_p (rtx);
extern bool legitimate_pic_operand_p (rtx);
-extern int legitimate_address_p (enum machine_mode, rtx, int);
extern rtx legitimize_pic_address (rtx, enum machine_mode, rtx);
extern rtx legitimize_tls_address (rtx);
extern void sparc_emit_call_insn (rtx, rtx);
@@ -86,7 +83,8 @@ extern const char *output_return (rtx);
extern const char *output_sibcall (rtx, rtx);
extern const char *output_v8plus_shift (rtx *, rtx, const char *);
extern const char *output_v9branch (rtx, rtx, int, int, int, int, rtx);
-extern void emit_v9_brxx_insn (enum rtx_code, rtx, rtx);
+extern bool emit_scc_insn (rtx []);
+extern void emit_conditional_branch_insn (rtx []);
extern void print_operand (FILE *, rtx, int);
extern int mems_ok_for_ldd_peep (rtx, rtx, rtx);
extern int arith_double_4096_operand (rtx, enum machine_mode);
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index ab2b57bbcd9..2d9431804ab 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -280,10 +280,6 @@ static GTY(()) alias_set_type sparc_sr_alias_set;
/* The alias set for the structure return value. */
static GTY(()) alias_set_type struct_value_alias_set;
-/* Save the operands last given to a compare for use when we
- generate a scc or bcc insn. */
-rtx sparc_compare_op0, sparc_compare_op1;
-
/* Vector to say how input registers are mapped to output registers.
HARD_FRAME_POINTER_REGNUM cannot be remapped by this function to
eliminate it. You must use -fomit-frame-pointer to get that. */
@@ -361,6 +357,7 @@ static int hypersparc_adjust_cost (rtx, rtx, rtx, int);
static void sparc_output_addr_vec (rtx);
static void sparc_output_addr_diff_vec (rtx);
static void sparc_output_deferred_case_vectors (void);
+static bool sparc_legitimate_address_p (enum machine_mode, rtx, bool);
static rtx sparc_builtin_saveregs (void);
static int epilogue_renumber (rtx *, int);
static bool sparc_assemble_integer (rtx, unsigned int, int);
@@ -424,7 +421,7 @@ static void sparc_file_end (void);
static const char *sparc_mangle_type (const_tree);
#endif
#ifdef SUBTARGET_ATTRIBUTE_TABLE
-const struct attribute_spec sparc_attribute_table[];
+EXPORTED_CONST struct attribute_spec sparc_attribute_table[];
#endif
/* Option handling. */
@@ -592,6 +589,9 @@ static bool fpu_option_set = false;
#define TARGET_MANGLE_TYPE sparc_mangle_type
#endif
+#undef TARGET_LEGITIMATE_ADDRESS_P
+#define TARGET_LEGITIMATE_ADDRESS_P sparc_legitimate_address_p
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* Implement TARGET_HANDLE_OPTION. */
@@ -2005,19 +2005,18 @@ select_cc_mode (enum rtx_code op, rtx x, rtx y ATTRIBUTE_UNUSED)
}
}
-/* Emit the compare insn and return the CC reg for a CODE comparison. */
+/* Emit the compare insn and return the CC reg for a CODE comparison
+ with operands X and Y. */
-rtx
-gen_compare_reg (enum rtx_code code)
+static rtx
+gen_compare_reg_1 (enum rtx_code code, rtx x, rtx y)
{
enum machine_mode mode;
- rtx x, y, cc_reg;
+ rtx cc_reg;
- if (GET_MODE_CLASS (GET_MODE (sparc_compare_op0)) == MODE_CC)
- return sparc_compare_op0;
+ if (GET_MODE_CLASS (GET_MODE (x)) == MODE_CC)
+ return x;
- x = sparc_compare_op0;
- y = sparc_compare_op1;
mode = SELECT_CC_MODE (code, x, y);
/* ??? We don't have movcc patterns so we cannot generate pseudo regs for the
@@ -2073,26 +2072,19 @@ gen_compare_reg (enum rtx_code code)
return cc_reg;
}
-/* Same as above but return the whole compare operator. */
+
+/* Emit the compare insn and return the CC reg for the comparison in CMP. */
rtx
-gen_compare_operator (enum rtx_code code)
+gen_compare_reg (rtx cmp)
{
- rtx cc_reg;
-
- if (GET_MODE (sparc_compare_op0) == TFmode && !TARGET_HARD_QUAD)
- code
- = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, code);
-
- cc_reg = gen_compare_reg (code);
- return gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
+ return gen_compare_reg_1 (GET_CODE (cmp), XEXP (cmp, 0), XEXP (cmp, 1));
}
/* This function is used for v9 only.
+ DEST is the target of the Scc insn.
CODE is the code for an Scc's comparison.
- OPERANDS[0] is the target of the Scc insn.
- OPERANDS[1] is the value we compare against const0_rtx (which hasn't
- been generated yet).
+ X and Y are the values we compare.
This function is needed to turn
@@ -2106,53 +2098,50 @@ gen_compare_operator (enum rtx_code code)
IE: The instruction recognizer needs to see the mode of the comparison to
find the right instruction. We could use "gt:DI" right in the
- define_expand, but leaving it out allows us to handle DI, SI, etc.
-
- We refer to the global sparc compare operands sparc_compare_op0 and
- sparc_compare_op1. */
+ define_expand, but leaving it out allows us to handle DI, SI, etc. */
-int
-gen_v9_scc (enum rtx_code compare_code, register rtx *operands)
+static int
+gen_v9_scc (rtx dest, enum rtx_code compare_code, rtx x, rtx y)
{
if (! TARGET_ARCH64
- && (GET_MODE (sparc_compare_op0) == DImode
- || GET_MODE (operands[0]) == DImode))
+ && (GET_MODE (x) == DImode
+ || GET_MODE (dest) == DImode))
return 0;
/* Try to use the movrCC insns. */
if (TARGET_ARCH64
- && GET_MODE_CLASS (GET_MODE (sparc_compare_op0)) == MODE_INT
- && sparc_compare_op1 == const0_rtx
+ && GET_MODE_CLASS (GET_MODE (x)) == MODE_INT
+ && y == const0_rtx
&& v9_regcmp_p (compare_code))
{
- rtx op0 = sparc_compare_op0;
+ rtx op0 = x;
rtx temp;
/* Special case for op0 != 0. This can be done with one instruction if
- operands[0] == sparc_compare_op0. */
+ dest == x. */
if (compare_code == NE
- && GET_MODE (operands[0]) == DImode
- && rtx_equal_p (op0, operands[0]))
+ && GET_MODE (dest) == DImode
+ && rtx_equal_p (op0, dest))
{
- emit_insn (gen_rtx_SET (VOIDmode, operands[0],
+ emit_insn (gen_rtx_SET (VOIDmode, dest,
gen_rtx_IF_THEN_ELSE (DImode,
gen_rtx_fmt_ee (compare_code, DImode,
op0, const0_rtx),
const1_rtx,
- operands[0])));
+ dest)));
return 1;
}
- if (reg_overlap_mentioned_p (operands[0], op0))
+ if (reg_overlap_mentioned_p (dest, op0))
{
- /* Handle the case where operands[0] == sparc_compare_op0.
+ /* Handle the case where dest == x.
We "early clobber" the result. */
- op0 = gen_reg_rtx (GET_MODE (sparc_compare_op0));
- emit_move_insn (op0, sparc_compare_op0);
+ op0 = gen_reg_rtx (GET_MODE (x));
+ emit_move_insn (op0, x);
}
- emit_insn (gen_rtx_SET (VOIDmode, operands[0], const0_rtx));
+ emit_insn (gen_rtx_SET (VOIDmode, dest, const0_rtx));
if (GET_MODE (op0) != DImode)
{
temp = gen_reg_rtx (DImode);
@@ -2160,47 +2149,137 @@ gen_v9_scc (enum rtx_code compare_code, register rtx *operands)
}
else
temp = op0;
- emit_insn (gen_rtx_SET (VOIDmode, operands[0],
- gen_rtx_IF_THEN_ELSE (GET_MODE (operands[0]),
+ emit_insn (gen_rtx_SET (VOIDmode, dest,
+ gen_rtx_IF_THEN_ELSE (GET_MODE (dest),
gen_rtx_fmt_ee (compare_code, DImode,
temp, const0_rtx),
const1_rtx,
- operands[0])));
+ dest)));
return 1;
}
else
{
- operands[1] = gen_compare_reg (compare_code);
+ x = gen_compare_reg_1 (compare_code, x, y);
+ y = const0_rtx;
- switch (GET_MODE (operands[1]))
- {
- case CCmode :
- case CCXmode :
- case CCFPEmode :
- case CCFPmode :
- break;
- default :
- gcc_unreachable ();
- }
- emit_insn (gen_rtx_SET (VOIDmode, operands[0], const0_rtx));
- emit_insn (gen_rtx_SET (VOIDmode, operands[0],
- gen_rtx_IF_THEN_ELSE (GET_MODE (operands[0]),
+ gcc_assert (GET_MODE (x) != CC_NOOVmode
+ && GET_MODE (x) != CCX_NOOVmode);
+
+ emit_insn (gen_rtx_SET (VOIDmode, dest, const0_rtx));
+ emit_insn (gen_rtx_SET (VOIDmode, dest,
+ gen_rtx_IF_THEN_ELSE (GET_MODE (dest),
gen_rtx_fmt_ee (compare_code,
- GET_MODE (operands[1]),
- operands[1], const0_rtx),
- const1_rtx, operands[0])));
+ GET_MODE (x), x, y),
+ const1_rtx, dest)));
return 1;
}
}
+
+/* Emit an scc insn. For seq, sne, sgeu, and sltu, we can do this
+ without jumps using the addx/subx instructions. */
+
+bool
+emit_scc_insn (rtx operands[])
+{
+ rtx tem;
+ rtx x;
+ rtx y;
+ enum rtx_code code;
+
+ /* The quad-word fp compare library routines all return nonzero to indicate
+ true, which is different from the equivalent libgcc routines, so we must
+ handle them specially here. */
+ if (GET_MODE (operands[2]) == TFmode && ! TARGET_HARD_QUAD)
+ {
+ operands[1] = sparc_emit_float_lib_cmp (operands[2], operands[3],
+ GET_CODE (operands[1]));
+ operands[2] = XEXP (operands[1], 0);
+ operands[3] = XEXP (operands[1], 1);
+ }
+
+ code = GET_CODE (operands[1]);
+ x = operands[2];
+ y = operands[3];
+
+ /* For seq/sne on v9 we use the same code as v8 (the addx/subx method has
+ more applications). The exception to this is "reg != 0" which can
+ be done in one instruction on v9 (so we do it). */
+ if (code == EQ)
+ {
+ if (GET_MODE (x) == SImode)
+ {
+ rtx pat = gen_seqsi_special (operands[0], x, y);
+ emit_insn (pat);
+ return true;
+ }
+ else if (GET_MODE (x) == DImode)
+ {
+ rtx pat = gen_seqdi_special (operands[0], x, y);
+ emit_insn (pat);
+ return true;
+ }
+ }
+
+ if (code == NE)
+ {
+ if (GET_MODE (x) == SImode)
+ {
+ rtx pat = gen_snesi_special (operands[0], x, y);
+ emit_insn (pat);
+ return true;
+ }
+ else if (GET_MODE (x) == DImode)
+ {
+ rtx pat = gen_snedi_special (operands[0], x, y);
+ emit_insn (pat);
+ return true;
+ }
+ }
+
+ /* For the rest, on v9 we can use conditional moves. */
+
+ if (TARGET_V9)
+ {
+ if (gen_v9_scc (operands[0], code, x, y))
+ return true;
+ }
+
+ /* We can do LTU and GEU using the addx/subx instructions too. And
+ for GTU/LEU, if both operands are registers swap them and fall
+ back to the easy case. */
+ if (code == GTU || code == LEU)
+ {
+ if ((GET_CODE (x) == REG || GET_CODE (x) == SUBREG)
+ && (GET_CODE (y) == REG || GET_CODE (y) == SUBREG))
+ {
+ tem = x;
+ x = y;
+ y = tem;
+ code = swap_condition (code);
+ }
+ }
+
+ if (code == LTU || code == GEU)
+ {
+ emit_insn (gen_rtx_SET (VOIDmode, operands[0],
+ gen_rtx_fmt_ee (code, SImode,
+ gen_compare_reg_1 (code, x, y),
+ const0_rtx)));
+ return true;
+ }
+
+ /* Nope, do branches. */
+ return false;
+}
+
/* Emit a conditional jump insn for the v9 architecture using comparison code
CODE and jump target LABEL.
This function exists to take advantage of the v9 brxx insns. */
-void
+static void
emit_v9_brxx_insn (enum rtx_code code, rtx op0, rtx label)
{
- gcc_assert (GET_MODE_CLASS (GET_MODE (sparc_compare_op0)) != MODE_CC);
emit_jump_insn (gen_rtx_SET (VOIDmode,
pc_rtx,
gen_rtx_IF_THEN_ELSE (VOIDmode,
@@ -2210,6 +2289,37 @@ emit_v9_brxx_insn (enum rtx_code code, rtx op0, rtx label)
pc_rtx)));
}
+void
+emit_conditional_branch_insn (rtx operands[])
+{
+ /* The quad-word fp compare library routines all return nonzero to indicate
+ true, which is different from the equivalent libgcc routines, so we must
+ handle them specially here. */
+ if (GET_MODE (operands[1]) == TFmode && ! TARGET_HARD_QUAD)
+ {
+ operands[0] = sparc_emit_float_lib_cmp (operands[1], operands[2],
+ GET_CODE (operands[0]));
+ operands[1] = XEXP (operands[0], 0);
+ operands[2] = XEXP (operands[0], 1);
+ }
+
+ if (TARGET_ARCH64 && operands[2] == const0_rtx
+ && GET_CODE (operands[1]) == REG
+ && GET_MODE (operands[1]) == DImode)
+ {
+ emit_v9_brxx_insn (GET_CODE (operands[0]), operands[1], operands[3]);
+ return;
+ }
+
+ operands[1] = gen_compare_reg (operands[0]);
+ operands[2] = const0_rtx;
+ operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]), VOIDmode,
+ operands[1], operands[2]);
+ emit_jump_insn (gen_cbranchcc4 (operands[0], operands[1], operands[2],
+ operands[3]));
+}
+
+
/* Generate a DFmode part of a hard TFmode register.
REG is the TFmode hard register, LOW is 1 for the
low 64bit of the register and 0 otherwise.
@@ -2961,8 +3071,8 @@ legitimate_pic_operand_p (rtx x)
/* Return nonzero if ADDR is a valid memory address.
STRICT specifies whether strict register checking applies. */
-int
-legitimate_address_p (enum machine_mode mode, rtx addr, int strict)
+static bool
+sparc_legitimate_address_p (enum machine_mode mode, rtx addr, bool strict)
{
rtx rs1 = NULL, rs2 = NULL, imm1 = NULL;
@@ -3397,7 +3507,7 @@ sparc_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
x = gen_rtx_PLUS (Pmode, XEXP (x, 0),
force_operand (XEXP (x, 1), NULL_RTX));
- if (x != orig_x && legitimate_address_p (mode, x, FALSE))
+ if (x != orig_x && sparc_legitimate_address_p (mode, x, FALSE))
return x;
if (SPARC_SYMBOL_REF_TLS_P (x))
@@ -6116,7 +6226,7 @@ output_cbranch (rtx op, rtx dest, int label, int reversed, int annul,
values as arguments instead of the TFmode registers themselves,
that's why we cannot call emit_float_lib_cmp. */
-enum rtx_code
+rtx
sparc_emit_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison)
{
const char *qpfunc;
@@ -6207,32 +6317,24 @@ sparc_emit_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison)
switch (comparison)
{
default:
- new_comparison = NE;
- emit_cmp_insn (result, const0_rtx, new_comparison, NULL_RTX, mode, 0);
- break;
+ return gen_rtx_NE (VOIDmode, result, const0_rtx);
case ORDERED:
case UNORDERED:
new_comparison = (comparison == UNORDERED ? EQ : NE);
- emit_cmp_insn (result, GEN_INT(3), new_comparison, NULL_RTX, mode, 0);
- break;
+ return gen_rtx_fmt_ee (new_comparison, VOIDmode, result, GEN_INT(3));
case UNGT:
case UNGE:
new_comparison = (comparison == UNGT ? GT : NE);
- emit_cmp_insn (result, const1_rtx, new_comparison, NULL_RTX, mode, 0);
- break;
+ return gen_rtx_fmt_ee (new_comparison, VOIDmode, result, const1_rtx);
case UNLE:
- new_comparison = NE;
- emit_cmp_insn (result, const2_rtx, new_comparison, NULL_RTX, mode, 0);
- break;
+ return gen_rtx_NE (VOIDmode, result, const2_rtx);
case UNLT:
tem = gen_reg_rtx (mode);
if (TARGET_ARCH32)
emit_insn (gen_andsi3 (tem, result, const1_rtx));
else
emit_insn (gen_anddi3 (tem, result, const1_rtx));
- new_comparison = NE;
- emit_cmp_insn (tem, const0_rtx, new_comparison, NULL_RTX, mode, 0);
- break;
+ return gen_rtx_NE (VOIDmode, tem, const0_rtx);
case UNEQ:
case LTGT:
tem = gen_reg_rtx (mode);
@@ -6246,11 +6348,10 @@ sparc_emit_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison)
else
emit_insn (gen_anddi3 (tem2, tem, const2_rtx));
new_comparison = (comparison == UNEQ ? EQ : NE);
- emit_cmp_insn (tem2, const0_rtx, new_comparison, NULL_RTX, mode, 0);
- break;
+ return gen_rtx_fmt_ee (new_comparison, VOIDmode, tem2, const0_rtx);
}
- return new_comparison;
+ gcc_unreachable ();
}
/* Generate an unsigned DImode to FP conversion. This is the same code
@@ -9021,15 +9122,12 @@ sparc_expand_compare_and_swap_12 (rtx result, rtx mem, rtx oldval, rtx newval)
gen_rtx_AND (SImode, gen_rtx_NOT (SImode, mask),
res)));
- sparc_compare_op0 = resv;
- sparc_compare_op1 = val;
- cc = gen_compare_reg (NE);
-
+ cc = gen_compare_reg_1 (NE, resv, val);
emit_insn (gen_rtx_SET (VOIDmode, val, resv));
- sparc_compare_op0 = cc;
- sparc_compare_op1 = const0_rtx;
- emit_jump_insn (gen_bne (loop_label));
+ /* Use cbranchcc4 to separate the compare and branch! */
+ emit_jump_insn (gen_cbranchcc4 (gen_rtx_NE (VOIDmode, cc, const0_rtx),
+ cc, const0_rtx, loop_label));
emit_label (end_label);
diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h
index d21900135e2..406ee68cf2f 100644
--- a/gcc/config/sparc/sparc.h
+++ b/gcc/config/sparc/sparc.h
@@ -1558,12 +1558,6 @@ function_arg_padding ((MODE), (TYPE))
&& (GET_MODE_ALIGNMENT (MODE) == 128 \
|| ((TYPE) && TYPE_ALIGN (TYPE) == 128))) \
? 128 : PARM_BOUNDARY)
-
-/* Define the information needed to generate branch and scc insns. This is
- stored from the compare operation. */
-
-extern GTY(()) rtx sparc_compare_op0;
-extern GTY(()) rtx sparc_compare_op1;
/* Generate the special assembly code needed to tell the assembler whatever
@@ -1851,15 +1845,9 @@ do { \
#define USE_AS_OFFSETABLE_LO10 0
#endif
-/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
- that is a valid memory address for an instruction.
- The MODE argument is the machine mode for the MEM expression
- that wants to use this address.
-
- On SPARC, the actual legitimate addresses must be REG+REG or REG+SMALLINT
- ordinarily. This changes a bit when generating PIC.
-
- If you change this, execute "rm explow.o recog.o reload.o". */
+/* On SPARC, the actual legitimate addresses must be REG+REG or REG+SMALLINT
+ ordinarily. This changes a bit when generating PIC. The details are
+ in sparc.c's implementation of TARGET_LEGITIMATE_ADDRESS_P. */
#define SYMBOLIC_CONST(X) symbolic_operand (X, VOIDmode)
@@ -1881,20 +1869,6 @@ do { \
#define RTX_OK_FOR_OLO10_P(X) \
(GET_CODE (X) == CONST_INT && INTVAL (X) >= -0x1000 && INTVAL (X) < 0xc00 - 8)
-#ifdef REG_OK_STRICT
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
-{ \
- if (legitimate_address_p (MODE, X, 1)) \
- goto ADDR; \
-}
-#else
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
-{ \
- if (legitimate_address_p (MODE, X, 0)) \
- goto ADDR; \
-}
-#endif
-
/* Go to LABEL if ADDR (a legitimate address expression)
has an effect that depends on the machine mode it is used for.
diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md
index 4fae329cd9a..9e35910f4db 100644
--- a/gcc/config/sparc/sparc.md
+++ b/gcc/config/sparc/sparc.md
@@ -76,6 +76,18 @@
(UNSPECV_LDSTUB 10)
])
+
+(define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
+(define_mode_iterator I [QI HI SI DI])
+(define_mode_iterator F [SF DF TF])
+
+;; We don't define V1SI because SI should work just fine.
+(define_mode_iterator V32 [SF V2HI V4QI])
+(define_mode_iterator V32I [SI V2HI V4QI])
+
+(define_mode_iterator V64 [DF V2SI V4HI V8QI])
+(define_mode_iterator V64I [DI V2SI V4HI V8QI])
+
;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this
;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name
;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding
@@ -340,84 +352,11 @@
;; Compare instructions.
-;; We generate RTL for comparisons and branches by having the cmpxx
-;; patterns store away the operands. Then, the scc and bcc patterns
-;; emit RTL for both the compare and the branch.
-;;
-;; We do this because we want to generate different code for an sne and
-;; seq insn. In those cases, if the second operand of the compare is not
-;; const0_rtx, we want to compute the xor of the two operands and test
-;; it against zero.
-;;
-;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
-;; the patterns. Finally, we have the DEFINE_SPLITs for some of the scc
-;; insns that actually require more than one machine instruction.
-
-(define_expand "cmpsi"
- [(set (reg:CC 100)
- (compare:CC (match_operand:SI 0 "compare_operand" "")
- (match_operand:SI 1 "arith_operand" "")))]
- ""
-{
- if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
- operands[0] = force_reg (SImode, operands[0]);
-
- sparc_compare_op0 = operands[0];
- sparc_compare_op1 = operands[1];
- DONE;
-})
-
-(define_expand "cmpdi"
- [(set (reg:CCX 100)
- (compare:CCX (match_operand:DI 0 "compare_operand" "")
- (match_operand:DI 1 "arith_operand" "")))]
- "TARGET_ARCH64"
-{
- if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
- operands[0] = force_reg (DImode, operands[0]);
-
- sparc_compare_op0 = operands[0];
- sparc_compare_op1 = operands[1];
- DONE;
-})
-
-(define_expand "cmpsf"
- ;; The 96 here isn't ever used by anyone.
- [(set (reg:CCFP 96)
- (compare:CCFP (match_operand:SF 0 "register_operand" "")
- (match_operand:SF 1 "register_operand" "")))]
- "TARGET_FPU"
-{
- sparc_compare_op0 = operands[0];
- sparc_compare_op1 = operands[1];
- DONE;
-})
-
-(define_expand "cmpdf"
- ;; The 96 here isn't ever used by anyone.
- [(set (reg:CCFP 96)
- (compare:CCFP (match_operand:DF 0 "register_operand" "")
- (match_operand:DF 1 "register_operand" "")))]
- "TARGET_FPU"
-{
- sparc_compare_op0 = operands[0];
- sparc_compare_op1 = operands[1];
- DONE;
-})
-
-(define_expand "cmptf"
- ;; The 96 here isn't ever used by anyone.
- [(set (reg:CCFP 96)
- (compare:CCFP (match_operand:TF 0 "register_operand" "")
- (match_operand:TF 1 "register_operand" "")))]
- "TARGET_FPU"
-{
- sparc_compare_op0 = operands[0];
- sparc_compare_op1 = operands[1];
- DONE;
-})
+;; These are just the DEFINE_INSNs to match the patterns and the
+;; DEFINE_SPLITs for some of the scc insns that actually require
+;; more than one machine instruction. DEFINE_EXPANDs are further down.
-;; Now the compare DEFINE_INSNs.
+;; The compare DEFINE_INSNs.
(define_insn "*cmpsi_insn"
[(set (reg:CC 100)
@@ -509,12 +448,41 @@
}
[(set_attr "type" "fpcmp")])
-;; Next come the scc insns. For seq, sne, sgeu, and sltu, we can do this
-;; without jumps using the addx/subx instructions. For seq/sne on v9 we use
-;; the same code as v8 (the addx/subx method has more applications). The
-;; exception to this is "reg != 0" which can be done in one instruction on v9
-;; (so we do it). For the rest, on v9 we use conditional moves; on v8, we do
-;; branches.
+;; Next come the scc insns.
+
+(define_expand "cstoresi4"
+ [(use (match_operator 1 "comparison_operator"
+ [(match_operand:SI 2 "compare_operand" "")
+ (match_operand:SI 3 "arith_operand" "")]))
+ (clobber (match_operand:SI 0 "register_operand"))]
+ ""
+{
+ if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
+ operands[2] = force_reg (SImode, operands[2]);
+ if (emit_scc_insn (operands)) DONE; else FAIL;
+})
+
+(define_expand "cstoredi4"
+ [(use (match_operator 1 "comparison_operator"
+ [(match_operand:DI 2 "compare_operand" "")
+ (match_operand:DI 3 "arith_operand" "")]))
+ (clobber (match_operand:SI 0 "register_operand"))]
+ "TARGET_ARCH64"
+{
+ if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
+ operands[2] = force_reg (DImode, operands[2]);
+ if (emit_scc_insn (operands)) DONE; else FAIL;
+})
+
+(define_expand "cstore<F:mode>4"
+ [(use (match_operator 1 "comparison_operator"
+ [(match_operand:F 2 "register_operand" "")
+ (match_operand:F 3 "register_operand" "")]))
+ (clobber (match_operand:SI 0 "register_operand"))]
+ "TARGET_FPU"
+ { if (emit_scc_insn (operands)) DONE; else FAIL; })
+
+
;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
;; generate addcc/subcc instructions.
@@ -533,8 +501,8 @@
[(set (match_dup 3)
(xor:DI (match_operand:DI 1 "register_operand" "")
(match_operand:DI 2 "register_operand" "")))
- (set (match_operand:DI 0 "register_operand" "")
- (eq:DI (match_dup 3) (const_int 0)))]
+ (set (match_operand:SI 0 "register_operand" "")
+ (eq:SI (match_dup 3) (const_int 0)))]
"TARGET_ARCH64"
{ operands[3] = gen_reg_rtx (DImode); })
@@ -552,338 +520,11 @@
[(set (match_dup 3)
(xor:DI (match_operand:DI 1 "register_operand" "")
(match_operand:DI 2 "register_operand" "")))
- (set (match_operand:DI 0 "register_operand" "")
- (ne:DI (match_dup 3) (const_int 0)))]
- "TARGET_ARCH64"
- { operands[3] = gen_reg_rtx (DImode); })
-
-(define_expand "seqdi_special_trunc"
- [(set (match_dup 3)
- (xor:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "register_operand" "")))
- (set (match_operand:SI 0 "register_operand" "")
- (eq:SI (match_dup 3) (const_int 0)))]
- "TARGET_ARCH64"
- { operands[3] = gen_reg_rtx (DImode); })
-
-(define_expand "snedi_special_trunc"
- [(set (match_dup 3)
- (xor:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "register_operand" "")))
(set (match_operand:SI 0 "register_operand" "")
(ne:SI (match_dup 3) (const_int 0)))]
"TARGET_ARCH64"
{ operands[3] = gen_reg_rtx (DImode); })
-(define_expand "seqsi_special_extend"
- [(set (match_dup 3)
- (xor:SI (match_operand:SI 1 "register_operand" "")
- (match_operand:SI 2 "register_operand" "")))
- (parallel [(set (match_operand:DI 0 "register_operand" "")
- (eq:DI (match_dup 3) (const_int 0)))
- (clobber (reg:CC 100))])]
- "TARGET_ARCH64"
- { operands[3] = gen_reg_rtx (SImode); })
-
-(define_expand "snesi_special_extend"
- [(set (match_dup 3)
- (xor:SI (match_operand:SI 1 "register_operand" "")
- (match_operand:SI 2 "register_operand" "")))
- (parallel [(set (match_operand:DI 0 "register_operand" "")
- (ne:DI (match_dup 3) (const_int 0)))
- (clobber (reg:CC 100))])]
- "TARGET_ARCH64"
- { operands[3] = gen_reg_rtx (SImode); })
-
-;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
-;; However, the code handles both SImode and DImode.
-(define_expand "seq"
- [(set (match_operand:SI 0 "int_register_operand" "")
- (eq:SI (match_dup 1) (const_int 0)))]
- ""
-{
- if (GET_MODE (sparc_compare_op0) == SImode)
- {
- rtx pat;
-
- if (GET_MODE (operands[0]) == SImode)
- pat = gen_seqsi_special (operands[0], sparc_compare_op0,
- sparc_compare_op1);
- else if (! TARGET_ARCH64)
- FAIL;
- else
- pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
- sparc_compare_op1);
- emit_insn (pat);
- DONE;
- }
- else if (GET_MODE (sparc_compare_op0) == DImode)
- {
- rtx pat;
-
- if (! TARGET_ARCH64)
- FAIL;
- else if (GET_MODE (operands[0]) == SImode)
- pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
- sparc_compare_op1);
- else
- pat = gen_seqdi_special (operands[0], sparc_compare_op0,
- sparc_compare_op1);
- emit_insn (pat);
- DONE;
- }
- else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
- {
- enum rtx_code code
- = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
- gcc_assert (code == NE);
- emit_insn (gen_sne (operands[0]));
- DONE;
- }
- else if (TARGET_V9)
- {
- if (gen_v9_scc (EQ, operands))
- DONE;
- /* fall through */
- }
- FAIL;
-})
-
-;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
-;; However, the code handles both SImode and DImode.
-(define_expand "sne"
- [(set (match_operand:SI 0 "int_register_operand" "")
- (ne:SI (match_dup 1) (const_int 0)))]
- ""
-{
- if (GET_MODE (sparc_compare_op0) == SImode)
- {
- rtx pat;
-
- if (GET_MODE (operands[0]) == SImode)
- pat = gen_snesi_special (operands[0], sparc_compare_op0,
- sparc_compare_op1);
- else if (! TARGET_ARCH64)
- FAIL;
- else
- pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
- sparc_compare_op1);
- emit_insn (pat);
- DONE;
- }
- else if (GET_MODE (sparc_compare_op0) == DImode)
- {
- rtx pat;
-
- if (! TARGET_ARCH64)
- FAIL;
- else if (GET_MODE (operands[0]) == SImode)
- pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
- sparc_compare_op1);
- else
- pat = gen_snedi_special (operands[0], sparc_compare_op0,
- sparc_compare_op1);
- emit_insn (pat);
- DONE;
- }
- else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
- {
- enum rtx_code code
- = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
- gcc_assert (code == NE);
- emit_insn (gen_sne (operands[0]));
- DONE;
- }
- else if (TARGET_V9)
- {
- if (gen_v9_scc (NE, operands))
- DONE;
- /* fall through */
- }
- FAIL;
-})
-
-(define_expand "sgt"
- [(set (match_operand:SI 0 "int_register_operand" "")
- (gt:SI (match_dup 1) (const_int 0)))]
- ""
-{
- if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
- {
- enum rtx_code code
- = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
- gcc_assert (code == NE);
- emit_insn (gen_sne (operands[0]));
- DONE;
- }
- else if (TARGET_V9)
- {
- if (gen_v9_scc (GT, operands))
- DONE;
- /* fall through */
- }
- FAIL;
-})
-
-(define_expand "slt"
- [(set (match_operand:SI 0 "int_register_operand" "")
- (lt:SI (match_dup 1) (const_int 0)))]
- ""
-{
- if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
- {
- enum rtx_code code
- = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
- gcc_assert (code == NE);
- emit_insn (gen_sne (operands[0]));
- DONE;
- }
- else if (TARGET_V9)
- {
- if (gen_v9_scc (LT, operands))
- DONE;
- /* fall through */
- }
- FAIL;
-})
-
-(define_expand "sge"
- [(set (match_operand:SI 0 "int_register_operand" "")
- (ge:SI (match_dup 1) (const_int 0)))]
- ""
-{
- if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
- {
- enum rtx_code code
- = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
- gcc_assert (code == NE);
- emit_insn (gen_sne (operands[0]));
- DONE;
- }
- else if (TARGET_V9)
- {
- if (gen_v9_scc (GE, operands))
- DONE;
- /* fall through */
- }
- FAIL;
-})
-
-(define_expand "sle"
- [(set (match_operand:SI 0 "int_register_operand" "")
- (le:SI (match_dup 1) (const_int 0)))]
- ""
-{
- if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
- {
- enum rtx_code code
- = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
- gcc_assert (code == NE);
- emit_insn (gen_sne (operands[0]));
- DONE;
- }
- else if (TARGET_V9)
- {
- if (gen_v9_scc (LE, operands))
- DONE;
- /* fall through */
- }
- FAIL;
-})
-
-(define_expand "sgtu"
- [(set (match_operand:SI 0 "int_register_operand" "")
- (gtu:SI (match_dup 1) (const_int 0)))]
- ""
-{
- if (! TARGET_V9)
- {
- rtx tem, pat;
-
- /* We can do ltu easily, so if both operands are registers, swap them and
- do a LTU. */
- if ((GET_CODE (sparc_compare_op0) == REG
- || GET_CODE (sparc_compare_op0) == SUBREG)
- && (GET_CODE (sparc_compare_op1) == REG
- || GET_CODE (sparc_compare_op1) == SUBREG))
- {
- tem = sparc_compare_op0;
- sparc_compare_op0 = sparc_compare_op1;
- sparc_compare_op1 = tem;
- pat = gen_sltu (operands[0]);
- if (pat == NULL_RTX)
- FAIL;
- emit_insn (pat);
- DONE;
- }
- }
- else
- {
- if (gen_v9_scc (GTU, operands))
- DONE;
- }
- FAIL;
-})
-
-(define_expand "sltu"
- [(set (match_operand:SI 0 "int_register_operand" "")
- (ltu:SI (match_dup 1) (const_int 0)))]
- ""
-{
- if (TARGET_V9)
- {
- if (gen_v9_scc (LTU, operands))
- DONE;
- }
- operands[1] = gen_compare_reg (LTU);
-})
-
-(define_expand "sgeu"
- [(set (match_operand:SI 0 "int_register_operand" "")
- (geu:SI (match_dup 1) (const_int 0)))]
- ""
-{
- if (TARGET_V9)
- {
- if (gen_v9_scc (GEU, operands))
- DONE;
- }
- operands[1] = gen_compare_reg (GEU);
-})
-
-(define_expand "sleu"
- [(set (match_operand:SI 0 "int_register_operand" "")
- (leu:SI (match_dup 1) (const_int 0)))]
- ""
-{
- if (! TARGET_V9)
- {
- rtx tem, pat;
-
- /* We can do geu easily, so if both operands are registers, swap them and
- do a GEU. */
- if ((GET_CODE (sparc_compare_op0) == REG
- || GET_CODE (sparc_compare_op0) == SUBREG)
- && (GET_CODE (sparc_compare_op1) == REG
- || GET_CODE (sparc_compare_op1) == SUBREG))
- {
- tem = sparc_compare_op0;
- sparc_compare_op0 = sparc_compare_op1;
- sparc_compare_op1 = tem;
- pat = gen_sgeu (operands[0]);
- if (pat == NULL_RTX)
- FAIL;
- emit_insn (pat);
- DONE;
- }
- }
- else
- {
- if (gen_v9_scc (LEU, operands))
- DONE;
- }
- FAIL;
-})
;; Now the DEFINE_INSNs for the scc cases.
@@ -1275,344 +916,51 @@
;; These control RTL generation for conditional jump insns
-;; The quad-word fp compare library routines all return nonzero to indicate
-;; true, which is different from the equivalent libgcc routines, so we must
-;; handle them specially here.
-
-(define_expand "beq"
- [(set (pc)
- (if_then_else (eq (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
-{
- if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
- && GET_CODE (sparc_compare_op0) == REG
- && GET_MODE (sparc_compare_op0) == DImode)
- {
- emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
- DONE;
- }
- else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
- {
- enum rtx_code code
- = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
- gcc_assert (code == NE);
- emit_jump_insn (gen_bne (operands[0]));
- DONE;
- }
- operands[1] = gen_compare_reg (EQ);
-})
-
-(define_expand "bne"
- [(set (pc)
- (if_then_else (ne (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
-{
- if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
- && GET_CODE (sparc_compare_op0) == REG
- && GET_MODE (sparc_compare_op0) == DImode)
- {
- emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
- DONE;
- }
- else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
- {
- enum rtx_code code
- = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
- gcc_assert (code == NE);
- emit_jump_insn (gen_bne (operands[0]));
- DONE;
- }
- operands[1] = gen_compare_reg (NE);
-})
-
-(define_expand "bgt"
- [(set (pc)
- (if_then_else (gt (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
-{
- if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
- && GET_CODE (sparc_compare_op0) == REG
- && GET_MODE (sparc_compare_op0) == DImode)
- {
- emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
- DONE;
- }
- else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
- {
- enum rtx_code code
- = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
- gcc_assert (code == NE);
- emit_jump_insn (gen_bne (operands[0]));
- DONE;
- }
- operands[1] = gen_compare_reg (GT);
-})
-
-(define_expand "bgtu"
- [(set (pc)
- (if_then_else (gtu (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
-{
- operands[1] = gen_compare_reg (GTU);
-})
-
-(define_expand "blt"
- [(set (pc)
- (if_then_else (lt (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
-{
- if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
- && GET_CODE (sparc_compare_op0) == REG
- && GET_MODE (sparc_compare_op0) == DImode)
- {
- emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
- DONE;
- }
- else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
- {
- enum rtx_code code
- = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
- gcc_assert (code == NE);
- emit_jump_insn (gen_bne (operands[0]));
- DONE;
- }
- operands[1] = gen_compare_reg (LT);
-})
-
-(define_expand "bltu"
- [(set (pc)
- (if_then_else (ltu (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
-{
- operands[1] = gen_compare_reg (LTU);
-})
-
-(define_expand "bge"
- [(set (pc)
- (if_then_else (ge (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
-{
- if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
- && GET_CODE (sparc_compare_op0) == REG
- && GET_MODE (sparc_compare_op0) == DImode)
- {
- emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
- DONE;
- }
- else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
- {
- enum rtx_code code
- = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
- gcc_assert (code == NE);
- emit_jump_insn (gen_bne (operands[0]));
- DONE;
- }
- operands[1] = gen_compare_reg (GE);
-})
-
-(define_expand "bgeu"
- [(set (pc)
- (if_then_else (geu (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
-{
- operands[1] = gen_compare_reg (GEU);
-})
-
-(define_expand "ble"
+(define_expand "cbranchcc4"
[(set (pc)
- (if_then_else (le (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
+ (if_then_else (match_operator 0 "comparison_operator"
+ [(match_operand 1 "compare_operand" "")
+ (match_operand 2 "const_zero_operand" "")])
+ (label_ref (match_operand 3 "" ""))
(pc)))]
""
-{
- if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
- && GET_CODE (sparc_compare_op0) == REG
- && GET_MODE (sparc_compare_op0) == DImode)
- {
- emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
- DONE;
- }
- else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
- {
- enum rtx_code code
- = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
- gcc_assert (code == NE);
- emit_jump_insn (gen_bne (operands[0]));
- DONE;
- }
- operands[1] = gen_compare_reg (LE);
-})
-
-(define_expand "bleu"
- [(set (pc)
- (if_then_else (leu (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
-{
- operands[1] = gen_compare_reg (LEU);
-})
-
-(define_expand "bunordered"
- [(set (pc)
- (if_then_else (unordered (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
-{
- if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
- {
- enum rtx_code code
- = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNORDERED);
- gcc_assert (code == EQ);
- emit_jump_insn (gen_beq (operands[0]));
- DONE;
- }
- operands[1] = gen_compare_reg (UNORDERED);
-})
-
-(define_expand "bordered"
- [(set (pc)
- (if_then_else (ordered (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
-{
- if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
- {
- enum rtx_code code
- = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
- gcc_assert (code == NE);
- emit_jump_insn (gen_bne (operands[0]));
- DONE;
- }
- operands[1] = gen_compare_reg (ORDERED);
-})
-
-(define_expand "bungt"
- [(set (pc)
- (if_then_else (ungt (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
-{
- if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
- {
- enum rtx_code code
- = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
- gcc_assert (code == GT);
- emit_jump_insn (gen_bgt (operands[0]));
- DONE;
- }
- operands[1] = gen_compare_reg (UNGT);
-})
+ "")
-(define_expand "bunlt"
- [(set (pc)
- (if_then_else (unlt (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
+(define_expand "cbranchsi4"
+ [(use (match_operator 0 "comparison_operator"
+ [(match_operand:SI 1 "compare_operand" "")
+ (match_operand:SI 2 "arith_operand" "")]))
+ (use (match_operand 3 ""))]
""
{
- if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
- {
- enum rtx_code code
- = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
- gcc_assert (code == NE);
- emit_jump_insn (gen_bne (operands[0]));
- DONE;
- }
- operands[1] = gen_compare_reg (UNLT);
+ if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
+ operands[1] = force_reg (SImode, operands[1]);
+ emit_conditional_branch_insn (operands);
+ DONE;
})
-(define_expand "buneq"
- [(set (pc)
- (if_then_else (uneq (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
+(define_expand "cbranchdi4"
+ [(use (match_operator 0 "comparison_operator"
+ [(match_operand:DI 1 "compare_operand" "")
+ (match_operand:DI 2 "arith_operand" "")]))
+ (use (match_operand 3 ""))]
+ "TARGET_ARCH64"
{
- if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
- {
- enum rtx_code code
- = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
- gcc_assert (code == EQ);
- emit_jump_insn (gen_beq (operands[0]));
- DONE;
- }
- operands[1] = gen_compare_reg (UNEQ);
+ if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
+ operands[1] = force_reg (DImode, operands[1]);
+ emit_conditional_branch_insn (operands);
+ DONE;
})
-(define_expand "bunge"
- [(set (pc)
- (if_then_else (unge (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
-{
- if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
- {
- enum rtx_code code
- = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
- gcc_assert (code == NE);
- emit_jump_insn (gen_bne (operands[0]));
- DONE;
- }
- operands[1] = gen_compare_reg (UNGE);
-})
+(define_expand "cbranch<F:mode>4"
+ [(use (match_operator 0 "comparison_operator"
+ [(match_operand:F 1 "register_operand" "")
+ (match_operand:F 2 "register_operand" "")]))
+ (use (match_operand 3 ""))]
+ "TARGET_FPU"
+ { emit_conditional_branch_insn (operands); DONE; })
-(define_expand "bunle"
- [(set (pc)
- (if_then_else (unle (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
-{
- if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
- {
- enum rtx_code code
- = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
- gcc_assert (code == NE);
- emit_jump_insn (gen_bne (operands[0]));
- DONE;
- }
- operands[1] = gen_compare_reg (UNLE);
-})
-(define_expand "bltgt"
- [(set (pc)
- (if_then_else (ltgt (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
-{
- if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
- {
- enum rtx_code code
- = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
- gcc_assert (code == NE);
- emit_jump_insn (gen_bne (operands[0]));
- DONE;
- }
- operands[1] = gen_compare_reg (LTGT);
-})
-
;; Now match both normal and inverted jump.
;; XXX fpcmp nop braindamage
@@ -1755,8 +1103,6 @@
(set_attr "branch_type" "reg")])
-(define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
-
;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
;; value subject to a PC-relative relocation. Operand 2 is a helper function
;; that adds the PC value at the call point to operand 0.
@@ -2393,9 +1739,6 @@
;; Floating point and vector move instructions
-;; We don't define V1SI because SI should work just fine.
-(define_mode_iterator V32 [SF V2HI V4QI])
-
;; Yes, you guessed it right, the former movsf expander.
(define_expand "mov<V32:mode>"
[(set (match_operand:V32 0 "nonimmediate_operand" "")
@@ -2530,8 +1873,6 @@
[(set (match_dup 0) (high:SF (match_dup 1)))
(set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
-(define_mode_iterator V64 [DF V2SI V4HI V8QI])
-
;; Yes, you again guessed it right, the former movdf expander.
(define_expand "mov<V64:mode>"
[(set (match_operand:V64 0 "nonimmediate_operand" "")
@@ -3073,8 +2414,6 @@
;; 3 contains the constant if one is present, but we handle either for
;; generality (sparc.c puts a constant in operand 2).
-(define_mode_iterator I [QI HI SI DI])
-
(define_expand "mov<I:mode>cc"
[(set (match_operand:I 0 "register_operand" "")
(if_then_else:I (match_operand 1 "comparison_operator" "")
@@ -3083,21 +2422,27 @@
"TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
{
enum rtx_code code = GET_CODE (operands[1]);
+ rtx cc_reg;
- if (GET_MODE (sparc_compare_op0) == DImode
+ if (GET_MODE (XEXP (operands[1], 0)) == DImode
&& ! TARGET_ARCH64)
FAIL;
- if (sparc_compare_op1 == const0_rtx
- && GET_CODE (sparc_compare_op0) == REG
- && GET_MODE (sparc_compare_op0) == DImode
+ if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD)
+ operands[1]
+ = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1),
+ GET_CODE (operands[1]));
+
+ if (XEXP (operands[1], 1) == const0_rtx
+ && GET_CODE (XEXP (operands[1], 0)) == REG
+ && GET_MODE (XEXP (operands[1], 0)) == DImode
&& v9_regcmp_p (code))
- operands[1] = gen_rtx_fmt_ee (code, DImode, sparc_compare_op0, const0_rtx);
+ cc_reg = XEXP (operands[1], 0);
else
- operands[1] = gen_compare_operator (code);
-})
+ cc_reg = gen_compare_reg (operands[1]);
-(define_mode_iterator F [SF DF TF])
+ operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
+})
(define_expand "mov<F:mode>cc"
[(set (match_operand:F 0 "register_operand" "")
@@ -3107,18 +2452,26 @@
"TARGET_V9 && TARGET_FPU"
{
enum rtx_code code = GET_CODE (operands[1]);
+ rtx cc_reg;
- if (GET_MODE (sparc_compare_op0) == DImode
+ if (GET_MODE (XEXP (operands[1], 0)) == DImode
&& ! TARGET_ARCH64)
FAIL;
- if (sparc_compare_op1 == const0_rtx
- && GET_CODE (sparc_compare_op0) == REG
- && GET_MODE (sparc_compare_op0) == DImode
+ if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD)
+ operands[1]
+ = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1),
+ GET_CODE (operands[1]));
+
+ if (XEXP (operands[1], 1) == const0_rtx
+ && GET_CODE (XEXP (operands[1], 0)) == REG
+ && GET_MODE (XEXP (operands[1], 0)) == DImode
&& v9_regcmp_p (code))
- operands[1] = gen_rtx_fmt_ee (code, DImode, sparc_compare_op0, const0_rtx);
+ cc_reg = XEXP (operands[1], 0);
else
- operands[1] = gen_compare_operator (code);
+ cc_reg = gen_compare_reg (operands[1]);
+
+ operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
})
;; Conditional move define_insns
@@ -5133,9 +4486,6 @@
;; We define DImode `and' so with DImode `not' we can get
;; DImode `andn'. Other combinations are possible.
-(define_mode_iterator V64I [DI V2SI V4HI V8QI])
-(define_mode_iterator V32I [SI V2HI V4QI])
-
(define_expand "and<V64I:mode>3"
[(set (match_operand:V64I 0 "register_operand" "")
(and:V64I (match_operand:V64I 1 "arith_double_operand" "")
@@ -7434,14 +6784,28 @@
"ta\t5"
[(set_attr "type" "trap")])
-(define_expand "conditional_trap"
- [(trap_if (match_operator 0 "noov_compare_operator" [(match_dup 2) (match_dup 3)])
- (match_operand:SI 1 "arith_operand" ""))]
+(define_expand "ctrapsi4"
+ [(trap_if (match_operator 0 "noov_compare_operator"
+ [(match_operand:SI 1 "compare_operand" "")
+ (match_operand:SI 2 "arith_operand" "")])
+ (match_operand 3 ""))]
""
- "operands[2] = gen_compare_reg (GET_CODE (operands[0]));
- if (GET_MODE (operands[2]) != CCmode && GET_MODE (operands[2]) != CCXmode)
+ "operands[1] = gen_compare_reg (operands[0]);
+ if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
FAIL;
- operands[3] = const0_rtx;")
+ operands[2] = const0_rtx;")
+
+(define_expand "ctrapdi4"
+ [(trap_if (match_operator 0 "noov_compare_operator"
+ [(match_operand:DI 1 "compare_operand" "")
+ (match_operand:DI 2 "arith_operand" "")])
+ (match_operand 3 ""))]
+ "TARGET_ARCH64"
+ "operands[1] = gen_compare_reg (operands[0]);
+ if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
+ FAIL;
+ operands[2] = const0_rtx;")
+
(define_insn ""
[(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC 100) (const_int 0)])
@@ -8071,6 +7435,7 @@
(match_operand 2 "" "")]
""
{
+ rtx result, test;
#ifdef TARGET_THREAD_SSP_OFFSET
rtx tlsreg = gen_rtx_REG (Pmode, 7);
rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
@@ -8078,18 +7443,18 @@
#endif
if (TARGET_ARCH64)
{
- rtx temp = gen_reg_rtx (Pmode);
- emit_insn (gen_stack_protect_testdi (temp, operands[0], operands[1]));
- sparc_compare_op0 = temp;
- sparc_compare_op1 = const0_rtx;
+ result = gen_reg_rtx (Pmode);
+ emit_insn (gen_stack_protect_testdi (result, operands[0], operands[1]));
+ test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
+ emit_jump_insn (gen_cbranchdi4 (test, result, const0_rtx, operands[2]));
}
else
{
emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
- sparc_compare_op0 = gen_rtx_REG (CCmode, SPARC_ICC_REG);
- sparc_compare_op1 = const0_rtx;
+ result = gen_rtx_REG (CCmode, SPARC_ICC_REG);
+ test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
+ emit_jump_insn (gen_cbranchcc4 (test, result, const0_rtx, operands[2]));
}
- emit_jump_insn (gen_beq (operands[2]));
DONE;
})
diff --git a/gcc/config/spu/predicates.md b/gcc/config/spu/predicates.md
index ce91ba230bb..8c6798d8063 100644
--- a/gcc/config/spu/predicates.md
+++ b/gcc/config/spu/predicates.md
@@ -39,14 +39,14 @@
(ior (not (match_code "subreg"))
(match_test "valid_subreg (op)"))))
-(define_predicate "spu_mem_operand"
- (and (match_operand 0 "memory_operand")
- (match_test "reload_in_progress || reload_completed || aligned_mem_p (op)")))
-
(define_predicate "spu_mov_operand"
- (ior (match_operand 0 "spu_mem_operand")
+ (ior (match_operand 0 "memory_operand")
(match_operand 0 "spu_nonmem_operand")))
+(define_predicate "spu_dest_operand"
+ (ior (match_operand 0 "memory_operand")
+ (match_operand 0 "spu_reg_operand")))
+
(define_predicate "call_operand"
(and (match_code "mem")
(match_test "(!TARGET_LARGE_MEM && satisfies_constraint_S (op))
@@ -114,3 +114,9 @@
(and (match_operand 0 "immediate_operand")
(match_test "exp2_immediate_p (op, mode, 0, 127)"))))
+(define_predicate "shiftrt_operator"
+ (match_code "lshiftrt,ashiftrt"))
+
+(define_predicate "extend_operator"
+ (match_code "sign_extend,zero_extend"))
+
diff --git a/gcc/config/spu/spu-c.c b/gcc/config/spu/spu-c.c
index a946b037cb7..fbbbf32e157 100644
--- a/gcc/config/spu/spu-c.c
+++ b/gcc/config/spu/spu-c.c
@@ -94,7 +94,7 @@ spu_macro_to_expand (cpp_reader *pfile, const cpp_token *tok)
/* target hook for resolve_overloaded_builtin(). Returns a function call
RTX if we can resolve the overloaded builtin */
tree
-spu_resolve_overloaded_builtin (tree fndecl, void *passed_args)
+spu_resolve_overloaded_builtin (location_t loc, tree fndecl, void *passed_args)
{
#define SCALAR_TYPE_P(t) (INTEGRAL_TYPE_P (t) \
|| SCALAR_FLOAT_TYPE_P (t) \
@@ -187,7 +187,7 @@ spu_resolve_overloaded_builtin (tree fndecl, void *passed_args)
return error_mark_node;
}
- return build_function_call_vec (match, fnargs, NULL);
+ return build_function_call_vec (loc, match, fnargs, NULL);
#undef SCALAR_TYPE_P
}
diff --git a/gcc/config/spu/spu-protos.h b/gcc/config/spu/spu-protos.h
index 06e02ba0b48..65cdd07264e 100644
--- a/gcc/config/spu/spu-protos.h
+++ b/gcc/config/spu/spu-protos.h
@@ -28,8 +28,7 @@ extern int valid_subreg (rtx op);
extern void spu_expand_extv (rtx * ops, int unsignedp);
extern void spu_expand_insv (rtx * ops);
extern int spu_expand_block_move (rtx * ops);
-extern void spu_emit_branch_or_set (int is_set, enum rtx_code code,
- rtx * operands);
+extern void spu_emit_branch_or_set (int is_set, rtx cmp, rtx * operands);
extern int spu_emit_vector_cond_expr (rtx, rtx, rtx, rtx, rtx, rtx);
extern HOST_WIDE_INT const_double_to_hwint (rtx x);
extern rtx hwint_to_const_double (enum machine_mode mode, HOST_WIDE_INT v);
@@ -55,8 +54,6 @@ extern bool exp2_immediate_p (rtx op, enum machine_mode mode, int low,
int high);
extern int spu_constant_address_p (rtx x);
extern int spu_legitimate_constant_p (rtx x);
-extern int spu_legitimate_address (enum machine_mode mode, rtx x,
- int reg_ok_strict);
extern int spu_initial_elimination_offset (int from, int to);
extern rtx spu_function_value (const_tree type, const_tree func);
extern rtx spu_function_arg (int cum, enum machine_mode mode, tree type,
@@ -65,11 +62,9 @@ extern void spu_setup_incoming_varargs (int *cum, enum machine_mode mode,
tree type, int *pretend_size,
int no_rtl);
extern void spu_conditional_register_usage (void);
-extern int aligned_mem_p (rtx mem);
extern int spu_expand_mov (rtx * ops, enum machine_mode mode);
-extern void spu_split_load (rtx * ops);
-extern void spu_split_store (rtx * ops);
-extern int spu_valid_move (rtx * ops);
+extern int spu_split_load (rtx * ops);
+extern int spu_split_store (rtx * ops);
extern int fsmbi_const_p (rtx x);
extern int cpat_const_p (rtx x, enum machine_mode mode);
extern rtx gen_cpat_const (rtx * ops);
@@ -90,9 +85,11 @@ extern void spu_initialize_trampoline (rtx tramp, rtx fnaddr, rtx cxt);
extern void spu_expand_sign_extend (rtx ops[]);
extern void spu_expand_vector_init (rtx target, rtx vals);
extern void spu_init_expanders (void);
+extern void spu_split_convert (rtx *);
/* spu-c.c */
-extern tree spu_resolve_overloaded_builtin (tree fndecl, void *fnargs);
+extern tree spu_resolve_overloaded_builtin (location_t, tree fndecl,
+ void *fnargs);
extern rtx spu_expand_builtin (tree exp, rtx target, rtx subtarget,
enum machine_mode mode, int ignore);
extern rtx spu_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
diff --git a/gcc/config/spu/spu.c b/gcc/config/spu/spu.c
index bb73622f9d5..8a40550f807 100644
--- a/gcc/config/spu/spu.c
+++ b/gcc/config/spu/spu.c
@@ -152,6 +152,7 @@ char regs_ever_allocated[FIRST_PSEUDO_REGISTER];
static void spu_init_builtins (void);
static unsigned char spu_scalar_mode_supported_p (enum machine_mode mode);
static unsigned char spu_vector_mode_supported_p (enum machine_mode mode);
+static bool spu_legitimate_address_p (enum machine_mode, rtx, bool);
static rtx adjust_operand (rtx op, HOST_WIDE_INT * start);
static rtx get_pic_reg (void);
static int need_to_save_reg (int regno, int saving);
@@ -188,9 +189,9 @@ static tree spu_build_builtin_va_list (void);
static void spu_va_start (tree, rtx);
static tree spu_gimplify_va_arg_expr (tree valist, tree type,
gimple_seq * pre_p, gimple_seq * post_p);
-static int regno_aligned_for_load (int regno);
static int store_with_one_insn_p (rtx mem);
static int mem_is_padded_component_ref (rtx x);
+static int reg_aligned_for_addr (rtx x);
static bool spu_assemble_integer (rtx x, unsigned int size, int aligned_p);
static void spu_asm_globalize_label (FILE * file, const char *name);
static unsigned char spu_rtx_costs (rtx x, int code, int outer_code,
@@ -210,9 +211,9 @@ static tree spu_builtin_vec_perm (tree, tree *);
static int spu_sms_res_mii (struct ddg *g);
static void asm_file_start (void);
static unsigned int spu_section_type_flags (tree, const char *, int);
+static rtx spu_expand_load (rtx, rtx, rtx, int);
extern const char *reg_names[];
-rtx spu_compare_op0, spu_compare_op1;
/* Which instruction set architecture to use. */
int spu_arch;
@@ -315,7 +316,7 @@ spu_libgcc_shift_count_mode (void);
#undef TARGET_SCHED_ADJUST_COST
#define TARGET_SCHED_ADJUST_COST spu_sched_adjust_cost
-const struct attribute_spec spu_attribute_table[];
+EXPORTED_CONST struct attribute_spec spu_attribute_table[];
#undef TARGET_ATTRIBUTE_TABLE
#define TARGET_ATTRIBUTE_TABLE spu_attribute_table
@@ -400,6 +401,9 @@ const struct attribute_spec spu_attribute_table[];
#undef TARGET_SECTION_TYPE_FLAGS
#define TARGET_SECTION_TYPE_FLAGS spu_section_type_flags
+#undef TARGET_LEGITIMATE_ADDRESS_P
+#define TARGET_LEGITIMATE_ADDRESS_P spu_legitimate_address_p
+
struct gcc_target targetm = TARGET_INITIALIZER;
void
@@ -579,66 +583,85 @@ adjust_operand (rtx op, HOST_WIDE_INT * start)
void
spu_expand_extv (rtx ops[], int unsignedp)
{
+ rtx dst = ops[0], src = ops[1];
HOST_WIDE_INT width = INTVAL (ops[2]);
HOST_WIDE_INT start = INTVAL (ops[3]);
- HOST_WIDE_INT src_size, dst_size;
- enum machine_mode src_mode, dst_mode;
- rtx dst = ops[0], src = ops[1];
- rtx s;
+ HOST_WIDE_INT align_mask;
+ rtx s0, s1, mask, r0;
- dst = adjust_operand (ops[0], 0);
- dst_mode = GET_MODE (dst);
- dst_size = GET_MODE_BITSIZE (GET_MODE (dst));
-
- src = adjust_operand (src, &start);
- src_mode = GET_MODE (src);
- src_size = GET_MODE_BITSIZE (GET_MODE (src));
+ gcc_assert (REG_P (dst) && GET_MODE (dst) == TImode);
- if (start > 0)
+ if (MEM_P (src))
{
- s = gen_reg_rtx (src_mode);
- switch (src_mode)
+ /* First, determine if we need 1 TImode load or 2. We need only 1
+ if the bits being extracted do not cross the alignment boundary
+ as determined by the MEM and its address. */
+
+ align_mask = -MEM_ALIGN (src);
+ if ((start & align_mask) == ((start + width - 1) & align_mask))
{
- case SImode:
- emit_insn (gen_ashlsi3 (s, src, GEN_INT (start)));
- break;
- case DImode:
- emit_insn (gen_ashldi3 (s, src, GEN_INT (start)));
- break;
- case TImode:
- emit_insn (gen_ashlti3 (s, src, GEN_INT (start)));
- break;
- default:
- abort ();
+ /* Alignment is sufficient for 1 load. */
+ s0 = gen_reg_rtx (TImode);
+ r0 = spu_expand_load (s0, 0, src, start / 8);
+ start &= 7;
+ if (r0)
+ emit_insn (gen_rotqby_ti (s0, s0, r0));
+ }
+ else
+ {
+ /* Need 2 loads. */
+ s0 = gen_reg_rtx (TImode);
+ s1 = gen_reg_rtx (TImode);
+ r0 = spu_expand_load (s0, s1, src, start / 8);
+ start &= 7;
+
+ gcc_assert (start + width <= 128);
+ if (r0)
+ {
+ rtx r1 = gen_reg_rtx (SImode);
+ mask = gen_reg_rtx (TImode);
+ emit_move_insn (mask, GEN_INT (-1));
+ emit_insn (gen_rotqby_ti (s0, s0, r0));
+ emit_insn (gen_rotqby_ti (s1, s1, r0));
+ if (GET_CODE (r0) == CONST_INT)
+ r1 = GEN_INT (INTVAL (r0) & 15);
+ else
+ emit_insn (gen_andsi3 (r1, r0, GEN_INT (15)));
+ emit_insn (gen_shlqby_ti (mask, mask, r1));
+ emit_insn (gen_selb (s0, s1, s0, mask));
+ }
}
- src = s;
+
}
+ else if (GET_CODE (src) == SUBREG)
+ {
+ rtx r = SUBREG_REG (src);
+ gcc_assert (REG_P (r) && SCALAR_INT_MODE_P (GET_MODE (r)));
+ s0 = gen_reg_rtx (TImode);
+ if (GET_MODE_SIZE (GET_MODE (r)) < GET_MODE_SIZE (TImode))
+ emit_insn (gen_rtx_SET (VOIDmode, s0, gen_rtx_ZERO_EXTEND (TImode, r)));
+ else
+ emit_move_insn (s0, src);
+ }
+ else
+ {
+ gcc_assert (REG_P (src) && GET_MODE (src) == TImode);
+ s0 = gen_reg_rtx (TImode);
+ emit_move_insn (s0, src);
+ }
+
+ /* Now s0 is TImode and contains the bits to extract at start. */
+
+ if (start)
+ emit_insn (gen_rotlti3 (s0, s0, GEN_INT (start)));
- if (width < src_size)
+ if (128 - width)
{
- rtx pat;
- int icode;
- switch (src_mode)
- {
- case SImode:
- icode = unsignedp ? CODE_FOR_lshrsi3 : CODE_FOR_ashrsi3;
- break;
- case DImode:
- icode = unsignedp ? CODE_FOR_lshrdi3 : CODE_FOR_ashrdi3;
- break;
- case TImode:
- icode = unsignedp ? CODE_FOR_lshrti3 : CODE_FOR_ashrti3;
- break;
- default:
- abort ();
- }
- s = gen_reg_rtx (src_mode);
- pat = GEN_FCN (icode) (s, src, GEN_INT (src_size - width));
- emit_insn (pat);
- src = s;
+ tree c = build_int_cst (NULL_TREE, 128 - width);
+ s0 = expand_shift (RSHIFT_EXPR, TImode, s0, c, s0, unsignedp);
}
- convert_move (dst, src, unsignedp);
+ emit_move_insn (dst, s0);
}
void
@@ -731,38 +754,41 @@ spu_expand_insv (rtx ops[])
}
if (GET_CODE (ops[0]) == MEM)
{
- rtx aligned = gen_reg_rtx (SImode);
rtx low = gen_reg_rtx (SImode);
- rtx addr = gen_reg_rtx (SImode);
rtx rotl = gen_reg_rtx (SImode);
rtx mask0 = gen_reg_rtx (TImode);
+ rtx addr;
+ rtx addr0;
+ rtx addr1;
rtx mem;
- emit_move_insn (addr, XEXP (ops[0], 0));
- emit_insn (gen_andsi3 (aligned, addr, GEN_INT (-16)));
+ addr = force_reg (Pmode, XEXP (ops[0], 0));
+ addr0 = gen_rtx_AND (Pmode, addr, GEN_INT (-16));
emit_insn (gen_andsi3 (low, addr, GEN_INT (15)));
emit_insn (gen_negsi2 (rotl, low));
emit_insn (gen_rotqby_ti (shift_reg, shift_reg, rotl));
emit_insn (gen_rotqmby_ti (mask0, mask, rotl));
- mem = change_address (ops[0], TImode, aligned);
+ mem = change_address (ops[0], TImode, addr0);
set_mem_alias_set (mem, 0);
emit_move_insn (dst, mem);
emit_insn (gen_selb (dst, dst, shift_reg, mask0));
- emit_move_insn (mem, dst);
if (start + width > MEM_ALIGN (ops[0]))
{
rtx shl = gen_reg_rtx (SImode);
rtx mask1 = gen_reg_rtx (TImode);
rtx dst1 = gen_reg_rtx (TImode);
rtx mem1;
+ addr1 = plus_constant (addr, 16);
+ addr1 = gen_rtx_AND (Pmode, addr1, GEN_INT (-16));
emit_insn (gen_subsi3 (shl, GEN_INT (16), low));
emit_insn (gen_shlqby_ti (mask1, mask, shl));
- mem1 = adjust_address (mem, TImode, 16);
+ mem1 = change_address (ops[0], TImode, addr1);
set_mem_alias_set (mem1, 0);
emit_move_insn (dst1, mem1);
emit_insn (gen_selb (dst1, dst1, shift_reg, mask1));
emit_move_insn (mem1, dst1);
}
+ emit_move_insn (mem, dst);
}
else
emit_insn (gen_selb (dst, copy_rtx (dst), shift_reg, mask));
@@ -844,42 +870,44 @@ int spu_comp_icode[12][3] = {
WORD_MODE, we can generate better code in most cases if we do it
ourselves. */
void
-spu_emit_branch_or_set (int is_set, enum rtx_code code, rtx operands[])
+spu_emit_branch_or_set (int is_set, rtx cmp, rtx operands[])
{
int reverse_compare = 0;
int reverse_test = 0;
rtx compare_result, eq_result;
rtx comp_rtx, eq_rtx;
- rtx target = operands[0];
enum machine_mode comp_mode;
enum machine_mode op_mode;
enum spu_comp_code scode, eq_code;
enum insn_code ior_code;
+ enum rtx_code code = GET_CODE (cmp);
+ rtx op0 = XEXP (cmp, 0);
+ rtx op1 = XEXP (cmp, 1);
int index;
int eq_test = 0;
- /* When spu_compare_op1 is a CONST_INT change (X >= C) to (X > C-1),
+ /* When op1 is a CONST_INT change (X >= C) to (X > C-1),
and so on, to keep the constant in operand 1. */
- if (GET_CODE (spu_compare_op1) == CONST_INT)
+ if (GET_CODE (op1) == CONST_INT)
{
- HOST_WIDE_INT val = INTVAL (spu_compare_op1) - 1;
- if (trunc_int_for_mode (val, GET_MODE (spu_compare_op0)) == val)
+ HOST_WIDE_INT val = INTVAL (op1) - 1;
+ if (trunc_int_for_mode (val, GET_MODE (op0)) == val)
switch (code)
{
case GE:
- spu_compare_op1 = GEN_INT (val);
+ op1 = GEN_INT (val);
code = GT;
break;
case LT:
- spu_compare_op1 = GEN_INT (val);
+ op1 = GEN_INT (val);
code = LE;
break;
case GEU:
- spu_compare_op1 = GEN_INT (val);
+ op1 = GEN_INT (val);
code = GTU;
break;
case LTU:
- spu_compare_op1 = GEN_INT (val);
+ op1 = GEN_INT (val);
code = LEU;
break;
default:
@@ -888,7 +916,7 @@ spu_emit_branch_or_set (int is_set, enum rtx_code code, rtx operands[])
}
comp_mode = SImode;
- op_mode = GET_MODE (spu_compare_op0);
+ op_mode = GET_MODE (op0);
switch (code)
{
@@ -1012,18 +1040,18 @@ spu_emit_branch_or_set (int is_set, enum rtx_code code, rtx operands[])
abort ();
}
- if (GET_MODE (spu_compare_op1) == DFmode
+ if (GET_MODE (op1) == DFmode
&& (scode != SPU_GT && scode != SPU_EQ))
abort ();
- if (is_set == 0 && spu_compare_op1 == const0_rtx
- && (GET_MODE (spu_compare_op0) == SImode
- || GET_MODE (spu_compare_op0) == HImode) && scode == SPU_EQ)
+ if (is_set == 0 && op1 == const0_rtx
+ && (GET_MODE (op0) == SImode
+ || GET_MODE (op0) == HImode) && scode == SPU_EQ)
{
/* Don't need to set a register with the result when we are
comparing against zero and branching. */
reverse_test = !reverse_test;
- compare_result = spu_compare_op0;
+ compare_result = op0;
}
else
{
@@ -1031,23 +1059,22 @@ spu_emit_branch_or_set (int is_set, enum rtx_code code, rtx operands[])
if (reverse_compare)
{
- rtx t = spu_compare_op1;
- spu_compare_op1 = spu_compare_op0;
- spu_compare_op0 = t;
+ rtx t = op1;
+ op1 = op0;
+ op0 = t;
}
if (spu_comp_icode[index][scode] == 0)
abort ();
if (!(*insn_data[spu_comp_icode[index][scode]].operand[1].predicate)
- (spu_compare_op0, op_mode))
- spu_compare_op0 = force_reg (op_mode, spu_compare_op0);
+ (op0, op_mode))
+ op0 = force_reg (op_mode, op0);
if (!(*insn_data[spu_comp_icode[index][scode]].operand[2].predicate)
- (spu_compare_op1, op_mode))
- spu_compare_op1 = force_reg (op_mode, spu_compare_op1);
+ (op1, op_mode))
+ op1 = force_reg (op_mode, op1);
comp_rtx = GEN_FCN (spu_comp_icode[index][scode]) (compare_result,
- spu_compare_op0,
- spu_compare_op1);
+ op0, op1);
if (comp_rtx == 0)
abort ();
emit_insn (comp_rtx);
@@ -1056,8 +1083,7 @@ spu_emit_branch_or_set (int is_set, enum rtx_code code, rtx operands[])
{
eq_result = gen_reg_rtx (comp_mode);
eq_rtx = GEN_FCN (spu_comp_icode[index][eq_code]) (eq_result,
- spu_compare_op0,
- spu_compare_op1);
+ op0, op1);
if (eq_rtx == 0)
abort ();
emit_insn (eq_rtx);
@@ -1088,13 +1114,14 @@ spu_emit_branch_or_set (int is_set, enum rtx_code code, rtx operands[])
else
bcomp = gen_rtx_NE (comp_mode, compare_result, const0_rtx);
- loc_ref = gen_rtx_LABEL_REF (VOIDmode, target);
+ loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
loc_ref, pc_rtx)));
}
else if (is_set == 2)
{
+ rtx target = operands[0];
int compare_size = GET_MODE_BITSIZE (comp_mode);
int target_size = GET_MODE_BITSIZE (GET_MODE (target));
enum machine_mode mode = mode_for_size (target_size, MODE_INT, 0);
@@ -1129,6 +1156,7 @@ spu_emit_branch_or_set (int is_set, enum rtx_code code, rtx operands[])
}
else
{
+ rtx target = operands[0];
if (reverse_test)
emit_insn (gen_rtx_SET (VOIDmode, compare_result,
gen_rtx_NOT (comp_mode, compare_result)));
@@ -2993,7 +3021,7 @@ spu_sched_reorder (FILE *file ATTRIBUTE_UNUSED, int verbose ATTRIBUTE_UNUSED,
insn = ready[i];
if (INSN_CODE (insn) == -1
|| INSN_CODE (insn) == CODE_FOR_blockage
- || INSN_CODE (insn) == CODE_FOR__spu_convert)
+ || (INSN_P (insn) && get_attr_length (insn) == 0))
{
ready[i] = ready[nready - 1];
ready[nready - 1] = insn;
@@ -3124,8 +3152,8 @@ spu_sched_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
|| INSN_CODE (dep_insn) == CODE_FOR_blockage)
return 0;
- if (INSN_CODE (insn) == CODE_FOR__spu_convert
- || INSN_CODE (dep_insn) == CODE_FOR__spu_convert)
+ if ((INSN_P (insn) && get_attr_length (insn) == 0)
+ || (INSN_P (dep_insn) && get_attr_length (dep_insn) == 0))
return 0;
/* Make sure hbrps are spread out. */
@@ -3606,44 +3634,36 @@ spu_legitimate_constant_p (rtx x)
/* Valid address are:
- symbol_ref, label_ref, const
- reg
- - reg + const, where either reg or const is 16 byte aligned
+ - reg + const_int, where const_int is 16 byte aligned
- reg + reg, alignment doesn't matter
The alignment matters in the reg+const case because lqd and stqd
- ignore the 4 least significant bits of the const. (TODO: It might be
- preferable to allow any alignment and fix it up when splitting.) */
-int
-spu_legitimate_address (enum machine_mode mode ATTRIBUTE_UNUSED,
- rtx x, int reg_ok_strict)
+ ignore the 4 least significant bits of the const. We only care about
+ 16 byte modes because the expand phase will change all smaller MEM
+ references to TImode. */
+static bool
+spu_legitimate_address_p (enum machine_mode mode,
+ rtx x, bool reg_ok_strict)
{
- if (mode == TImode && GET_CODE (x) == AND
+ int aligned = GET_MODE_SIZE (mode) >= 16;
+ if (aligned
+ && GET_CODE (x) == AND
&& GET_CODE (XEXP (x, 1)) == CONST_INT
- && INTVAL (XEXP (x, 1)) == (HOST_WIDE_INT) -16)
+ && INTVAL (XEXP (x, 1)) == (HOST_WIDE_INT) - 16)
x = XEXP (x, 0);
switch (GET_CODE (x))
{
- case SYMBOL_REF:
case LABEL_REF:
- return !TARGET_LARGE_MEM;
-
+ case SYMBOL_REF:
case CONST:
- if (!TARGET_LARGE_MEM && GET_CODE (XEXP (x, 0)) == PLUS)
- {
- rtx sym = XEXP (XEXP (x, 0), 0);
- rtx cst = XEXP (XEXP (x, 0), 1);
-
- /* Accept any symbol_ref + constant, assuming it does not
- wrap around the local store addressability limit. */
- if (GET_CODE (sym) == SYMBOL_REF && GET_CODE (cst) == CONST_INT)
- return 1;
- }
- return 0;
+ return !TARGET_LARGE_MEM;
case CONST_INT:
return INTVAL (x) >= 0 && INTVAL (x) <= 0x3ffff;
case SUBREG:
x = XEXP (x, 0);
- gcc_assert (GET_CODE (x) == REG);
+ if (REG_P (x))
+ return 0;
case REG:
return INT_REG_OK_FOR_BASE_P (x, reg_ok_strict);
@@ -3657,29 +3677,25 @@ spu_legitimate_address (enum machine_mode mode ATTRIBUTE_UNUSED,
op0 = XEXP (op0, 0);
if (GET_CODE (op1) == SUBREG)
op1 = XEXP (op1, 0);
- /* We can't just accept any aligned register because CSE can
- change it to a register that is not marked aligned and then
- recog will fail. So we only accept frame registers because
- they will only be changed to other frame registers. */
if (GET_CODE (op0) == REG
&& INT_REG_OK_FOR_BASE_P (op0, reg_ok_strict)
&& GET_CODE (op1) == CONST_INT
&& INTVAL (op1) >= -0x2000
&& INTVAL (op1) <= 0x1fff
- && (regno_aligned_for_load (REGNO (op0)) || (INTVAL (op1) & 15) == 0))
- return 1;
+ && (!aligned || (INTVAL (op1) & 15) == 0))
+ return TRUE;
if (GET_CODE (op0) == REG
&& INT_REG_OK_FOR_BASE_P (op0, reg_ok_strict)
&& GET_CODE (op1) == REG
&& INT_REG_OK_FOR_INDEX_P (op1, reg_ok_strict))
- return 1;
+ return TRUE;
}
break;
default:
break;
}
- return 0;
+ return FALSE;
}
/* When the address is reg + const_int, force the const_int into a
@@ -3936,10 +3952,13 @@ spu_build_builtin_va_list (void)
record = (*lang_hooks.types.make_type) (RECORD_TYPE);
type_decl =
- build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
+ build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier ("__va_list_tag"), record);
- f_args = build_decl (FIELD_DECL, get_identifier ("__args"), ptr_type_node);
- f_skip = build_decl (FIELD_DECL, get_identifier ("__skip"), ptr_type_node);
+ f_args = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, get_identifier ("__args"), ptr_type_node);
+ f_skip = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, get_identifier ("__skip"), ptr_type_node);
DECL_FIELD_CONTEXT (f_args) = record;
DECL_ALIGN (f_args) = 128;
@@ -4132,60 +4151,14 @@ spu_conditional_register_usage (void)
}
}
-/* This is called to decide when we can simplify a load instruction. We
- must only return true for registers which we know will always be
- aligned. Taking into account that CSE might replace this reg with
- another one that has not been marked aligned.
- So this is really only true for frame, stack and virtual registers,
- which we know are always aligned and should not be adversely effected
- by CSE. */
+/* This is called any time we inspect the alignment of a register for
+ addresses. */
static int
-regno_aligned_for_load (int regno)
+reg_aligned_for_addr (rtx x)
{
- return regno == FRAME_POINTER_REGNUM
- || (frame_pointer_needed && regno == HARD_FRAME_POINTER_REGNUM)
- || regno == ARG_POINTER_REGNUM
- || regno == STACK_POINTER_REGNUM
- || (regno >= FIRST_VIRTUAL_REGISTER
- && regno <= LAST_VIRTUAL_REGISTER);
-}
-
-/* Return TRUE when mem is known to be 16-byte aligned. */
-int
-aligned_mem_p (rtx mem)
-{
- if (MEM_ALIGN (mem) >= 128)
- return 1;
- if (GET_MODE_SIZE (GET_MODE (mem)) >= 16)
- return 1;
- if (GET_CODE (XEXP (mem, 0)) == PLUS)
- {
- rtx p0 = XEXP (XEXP (mem, 0), 0);
- rtx p1 = XEXP (XEXP (mem, 0), 1);
- if (regno_aligned_for_load (REGNO (p0)))
- {
- if (GET_CODE (p1) == REG && regno_aligned_for_load (REGNO (p1)))
- return 1;
- if (GET_CODE (p1) == CONST_INT && (INTVAL (p1) & 15) == 0)
- return 1;
- }
- }
- else if (GET_CODE (XEXP (mem, 0)) == REG)
- {
- if (regno_aligned_for_load (REGNO (XEXP (mem, 0))))
- return 1;
- }
- else if (ALIGNED_SYMBOL_REF_P (XEXP (mem, 0)))
- return 1;
- else if (GET_CODE (XEXP (mem, 0)) == CONST)
- {
- rtx p0 = XEXP (XEXP (XEXP (mem, 0), 0), 0);
- rtx p1 = XEXP (XEXP (XEXP (mem, 0), 0), 1);
- if (GET_CODE (p0) == SYMBOL_REF
- && GET_CODE (p1) == CONST_INT && (INTVAL (p1) & 15) == 0)
- return 1;
- }
- return 0;
+ int regno =
+ REGNO (x) < FIRST_PSEUDO_REGISTER ? ORIGINAL_REGNO (x) : REGNO (x);
+ return REGNO_POINTER_ALIGN (regno) >= 128;
}
/* Encode symbol attributes (local vs. global, tls model) of a SYMBOL_REF
@@ -4214,9 +4187,12 @@ spu_encode_section_info (tree decl, rtx rtl, int first)
static int
store_with_one_insn_p (rtx mem)
{
+ enum machine_mode mode = GET_MODE (mem);
rtx addr = XEXP (mem, 0);
- if (GET_MODE (mem) == BLKmode)
+ if (mode == BLKmode)
return 0;
+ if (GET_MODE_SIZE (mode) >= 16)
+ return 1;
/* Only static objects. */
if (GET_CODE (addr) == SYMBOL_REF)
{
@@ -4240,6 +4216,22 @@ store_with_one_insn_p (rtx mem)
return 0;
}
+/* Return 1 when the address is not valid for a simple load and store as
+ required by the '_mov*' patterns. We could make this less strict
+ for loads, but we prefer mem's to look the same so they are more
+ likely to be merged. */
+static int
+address_needs_split (rtx mem)
+{
+ if (GET_MODE_SIZE (GET_MODE (mem)) < 16
+ && (GET_MODE_SIZE (GET_MODE (mem)) < 4
+ || !(store_with_one_insn_p (mem)
+ || mem_is_padded_component_ref (mem))))
+ return 1;
+
+ return 0;
+}
+
int
spu_expand_mov (rtx * ops, enum machine_mode mode)
{
@@ -4284,54 +4276,63 @@ spu_expand_mov (rtx * ops, enum machine_mode mode)
return spu_split_immediate (ops);
return 0;
}
- else
+
+ /* Catch the SImode immediates greater than 0x7fffffff, and sign
+ extend them. */
+ if (GET_CODE (ops[1]) == CONST_INT)
{
- if (GET_CODE (ops[0]) == MEM)
- {
- if (!spu_valid_move (ops))
- {
- emit_insn (gen_store (ops[0], ops[1], gen_reg_rtx (TImode),
- gen_reg_rtx (TImode)));
- return 1;
- }
- }
- else if (GET_CODE (ops[1]) == MEM)
+ HOST_WIDE_INT val = trunc_int_for_mode (INTVAL (ops[1]), mode);
+ if (val != INTVAL (ops[1]))
{
- if (!spu_valid_move (ops))
- {
- emit_insn (gen_load
- (ops[0], ops[1], gen_reg_rtx (TImode),
- gen_reg_rtx (SImode)));
- return 1;
- }
- }
- /* Catch the SImode immediates greater than 0x7fffffff, and sign
- extend them. */
- if (GET_CODE (ops[1]) == CONST_INT)
- {
- HOST_WIDE_INT val = trunc_int_for_mode (INTVAL (ops[1]), mode);
- if (val != INTVAL (ops[1]))
- {
- emit_move_insn (ops[0], GEN_INT (val));
- return 1;
- }
+ emit_move_insn (ops[0], GEN_INT (val));
+ return 1;
}
}
+ if (MEM_P (ops[0]))
+ return spu_split_store (ops);
+ if (MEM_P (ops[1]))
+ return spu_split_load (ops);
+
return 0;
}
-void
-spu_split_load (rtx * ops)
+static void
+spu_convert_move (rtx dst, rtx src)
{
- enum machine_mode mode = GET_MODE (ops[0]);
- rtx addr, load, rot, mem, p0, p1;
- int rot_amt;
+ enum machine_mode mode = GET_MODE (dst);
+ enum machine_mode int_mode = mode_for_size (GET_MODE_BITSIZE (mode), MODE_INT, 0);
+ rtx reg;
+ gcc_assert (GET_MODE (src) == TImode);
+ reg = int_mode != mode ? gen_reg_rtx (int_mode) : dst;
+ emit_insn (gen_rtx_SET (VOIDmode, reg,
+ gen_rtx_TRUNCATE (int_mode,
+ gen_rtx_LSHIFTRT (TImode, src,
+ GEN_INT (int_mode == DImode ? 64 : 96)))));
+ if (int_mode != mode)
+ {
+ reg = simplify_gen_subreg (mode, reg, int_mode, 0);
+ emit_move_insn (dst, reg);
+ }
+}
- addr = XEXP (ops[1], 0);
+/* Load TImode values into DST0 and DST1 (when it is non-NULL) using
+ the address from SRC and SRC+16. Return a REG or CONST_INT that
+ specifies how many bytes to rotate the loaded registers, plus any
+ extra from EXTRA_ROTQBY. The address and rotate amounts are
+ normalized to improve merging of loads and rotate computations. */
+static rtx
+spu_expand_load (rtx dst0, rtx dst1, rtx src, int extra_rotby)
+{
+ rtx addr = XEXP (src, 0);
+ rtx p0, p1, rot, addr0, addr1;
+ int rot_amt;
rot = 0;
rot_amt = 0;
- if (GET_CODE (addr) == PLUS)
+
+ if (MEM_ALIGN (src) >= 128)
+ /* Address is already aligned; simply perform a TImode load. */ ;
+ else if (GET_CODE (addr) == PLUS)
{
/* 8 cases:
aligned reg + aligned reg => lqx
@@ -4345,12 +4346,34 @@ spu_split_load (rtx * ops)
*/
p0 = XEXP (addr, 0);
p1 = XEXP (addr, 1);
- if (REG_P (p0) && !regno_aligned_for_load (REGNO (p0)))
+ if (!reg_aligned_for_addr (p0))
{
- if (REG_P (p1) && !regno_aligned_for_load (REGNO (p1)))
+ if (REG_P (p1) && !reg_aligned_for_addr (p1))
{
- emit_insn (gen_addsi3 (ops[3], p0, p1));
- rot = ops[3];
+ rot = gen_reg_rtx (SImode);
+ emit_insn (gen_addsi3 (rot, p0, p1));
+ }
+ else if (GET_CODE (p1) == CONST_INT && (INTVAL (p1) & 15))
+ {
+ if (INTVAL (p1) > 0
+ && REG_POINTER (p0)
+ && INTVAL (p1) * BITS_PER_UNIT
+ < REGNO_POINTER_ALIGN (REGNO (p0)))
+ {
+ rot = gen_reg_rtx (SImode);
+ emit_insn (gen_addsi3 (rot, p0, p1));
+ addr = p0;
+ }
+ else
+ {
+ rtx x = gen_reg_rtx (SImode);
+ emit_move_insn (x, p1);
+ if (!spu_arith_operand (p1, SImode))
+ p1 = x;
+ rot = gen_reg_rtx (SImode);
+ emit_insn (gen_addsi3 (rot, p0, p1));
+ addr = gen_rtx_PLUS (Pmode, p0, x);
+ }
}
else
rot = p0;
@@ -4360,16 +4383,21 @@ spu_split_load (rtx * ops)
if (GET_CODE (p1) == CONST_INT && (INTVAL (p1) & 15))
{
rot_amt = INTVAL (p1) & 15;
- p1 = GEN_INT (INTVAL (p1) & -16);
- addr = gen_rtx_PLUS (SImode, p0, p1);
+ if (INTVAL (p1) & -16)
+ {
+ p1 = GEN_INT (INTVAL (p1) & -16);
+ addr = gen_rtx_PLUS (SImode, p0, p1);
+ }
+ else
+ addr = p0;
}
- else if (REG_P (p1) && !regno_aligned_for_load (REGNO (p1)))
+ else if (REG_P (p1) && !reg_aligned_for_addr (p1))
rot = p1;
}
}
- else if (GET_CODE (addr) == REG)
+ else if (REG_P (addr))
{
- if (!regno_aligned_for_load (REGNO (addr)))
+ if (!reg_aligned_for_addr (addr))
rot = addr;
}
else if (GET_CODE (addr) == CONST)
@@ -4388,7 +4416,10 @@ spu_split_load (rtx * ops)
addr = XEXP (XEXP (addr, 0), 0);
}
else
- rot = addr;
+ {
+ rot = gen_reg_rtx (Pmode);
+ emit_move_insn (rot, addr);
+ }
}
else if (GET_CODE (addr) == CONST_INT)
{
@@ -4396,49 +4427,96 @@ spu_split_load (rtx * ops)
addr = GEN_INT (rot_amt & -16);
}
else if (!ALIGNED_SYMBOL_REF_P (addr))
- rot = addr;
+ {
+ rot = gen_reg_rtx (Pmode);
+ emit_move_insn (rot, addr);
+ }
- if (GET_MODE_SIZE (mode) < 4)
- rot_amt += GET_MODE_SIZE (mode) - 4;
+ rot_amt += extra_rotby;
rot_amt &= 15;
if (rot && rot_amt)
{
- emit_insn (gen_addsi3 (ops[3], rot, GEN_INT (rot_amt)));
- rot = ops[3];
+ rtx x = gen_reg_rtx (SImode);
+ emit_insn (gen_addsi3 (x, rot, GEN_INT (rot_amt)));
+ rot = x;
rot_amt = 0;
}
+ if (!rot && rot_amt)
+ rot = GEN_INT (rot_amt);
+
+ addr0 = copy_rtx (addr);
+ addr0 = gen_rtx_AND (SImode, copy_rtx (addr), GEN_INT (-16));
+ emit_insn (gen__movti (dst0, change_address (src, TImode, addr0)));
+
+ if (dst1)
+ {
+ addr1 = plus_constant (copy_rtx (addr), 16);
+ addr1 = gen_rtx_AND (SImode, addr1, GEN_INT (-16));
+ emit_insn (gen__movti (dst1, change_address (src, TImode, addr1)));
+ }
- load = ops[2];
+ return rot;
+}
+
+int
+spu_split_load (rtx * ops)
+{
+ enum machine_mode mode = GET_MODE (ops[0]);
+ rtx addr, load, rot;
+ int rot_amt;
- addr = gen_rtx_AND (SImode, copy_rtx (addr), GEN_INT (-16));
- mem = change_address (ops[1], TImode, addr);
+ if (GET_MODE_SIZE (mode) >= 16)
+ return 0;
- emit_insn (gen_movti (load, mem));
+ addr = XEXP (ops[1], 0);
+ gcc_assert (GET_CODE (addr) != AND);
+
+ if (!address_needs_split (ops[1]))
+ {
+ ops[1] = change_address (ops[1], TImode, addr);
+ load = gen_reg_rtx (TImode);
+ emit_insn (gen__movti (load, ops[1]));
+ spu_convert_move (ops[0], load);
+ return 1;
+ }
+
+ rot_amt = GET_MODE_SIZE (mode) < 4 ? GET_MODE_SIZE (mode) - 4 : 0;
+
+ load = gen_reg_rtx (TImode);
+ rot = spu_expand_load (load, 0, ops[1], rot_amt);
if (rot)
emit_insn (gen_rotqby_ti (load, load, rot));
- else if (rot_amt)
- emit_insn (gen_rotlti3 (load, load, GEN_INT (rot_amt * 8)));
- if (reload_completed)
- emit_move_insn (ops[0], gen_rtx_REG (GET_MODE (ops[0]), REGNO (load)));
- else
- emit_insn (gen_spu_convert (ops[0], load));
+ spu_convert_move (ops[0], load);
+ return 1;
}
-void
+int
spu_split_store (rtx * ops)
{
enum machine_mode mode = GET_MODE (ops[0]);
- rtx pat = ops[2];
- rtx reg = ops[3];
+ rtx reg;
rtx addr, p0, p1, p1_lo, smem;
int aform;
int scalar;
+ if (GET_MODE_SIZE (mode) >= 16)
+ return 0;
+
addr = XEXP (ops[0], 0);
+ gcc_assert (GET_CODE (addr) != AND);
+
+ if (!address_needs_split (ops[0]))
+ {
+ reg = gen_reg_rtx (TImode);
+ emit_insn (gen_spu_convert (reg, ops[1]));
+ ops[0] = change_address (ops[0], TImode, addr);
+ emit_move_insn (ops[0], reg);
+ return 1;
+ }
if (GET_CODE (addr) == PLUS)
{
@@ -4450,19 +4528,31 @@ spu_split_store (rtx * ops)
unaligned reg + aligned reg => lqx, c?x, shuf, stqx
unaligned reg + unaligned reg => lqx, c?x, shuf, stqx
unaligned reg + aligned const => lqd, c?d, shuf, stqx
- unaligned reg + unaligned const -> not allowed by legitimate address
+ unaligned reg + unaligned const -> lqx, c?d, shuf, stqx
*/
aform = 0;
p0 = XEXP (addr, 0);
p1 = p1_lo = XEXP (addr, 1);
- if (GET_CODE (p0) == REG && GET_CODE (p1) == CONST_INT)
+ if (REG_P (p0) && GET_CODE (p1) == CONST_INT)
{
p1_lo = GEN_INT (INTVAL (p1) & 15);
- p1 = GEN_INT (INTVAL (p1) & -16);
- addr = gen_rtx_PLUS (SImode, p0, p1);
+ if (reg_aligned_for_addr (p0))
+ {
+ p1 = GEN_INT (INTVAL (p1) & -16);
+ if (p1 == const0_rtx)
+ addr = p0;
+ else
+ addr = gen_rtx_PLUS (SImode, p0, p1);
+ }
+ else
+ {
+ rtx x = gen_reg_rtx (SImode);
+ emit_move_insn (x, p1);
+ addr = gen_rtx_PLUS (SImode, p0, x);
+ }
}
}
- else if (GET_CODE (addr) == REG)
+ else if (REG_P (addr))
{
aform = 0;
p0 = addr;
@@ -4476,31 +4566,34 @@ spu_split_store (rtx * ops)
p1_lo = addr;
if (ALIGNED_SYMBOL_REF_P (addr))
p1_lo = const0_rtx;
- else if (GET_CODE (addr) == CONST)
+ else if (GET_CODE (addr) == CONST
+ && GET_CODE (XEXP (addr, 0)) == PLUS
+ && ALIGNED_SYMBOL_REF_P (XEXP (XEXP (addr, 0), 0))
+ && GET_CODE (XEXP (XEXP (addr, 0), 1)) == CONST_INT)
{
- if (GET_CODE (XEXP (addr, 0)) == PLUS
- && ALIGNED_SYMBOL_REF_P (XEXP (XEXP (addr, 0), 0))
- && GET_CODE (XEXP (XEXP (addr, 0), 1)) == CONST_INT)
- {
- HOST_WIDE_INT v = INTVAL (XEXP (XEXP (addr, 0), 1));
- if ((v & -16) != 0)
- addr = gen_rtx_CONST (Pmode,
- gen_rtx_PLUS (Pmode,
- XEXP (XEXP (addr, 0), 0),
- GEN_INT (v & -16)));
- else
- addr = XEXP (XEXP (addr, 0), 0);
- p1_lo = GEN_INT (v & 15);
- }
+ HOST_WIDE_INT v = INTVAL (XEXP (XEXP (addr, 0), 1));
+ if ((v & -16) != 0)
+ addr = gen_rtx_CONST (Pmode,
+ gen_rtx_PLUS (Pmode,
+ XEXP (XEXP (addr, 0), 0),
+ GEN_INT (v & -16)));
+ else
+ addr = XEXP (XEXP (addr, 0), 0);
+ p1_lo = GEN_INT (v & 15);
}
else if (GET_CODE (addr) == CONST_INT)
{
p1_lo = GEN_INT (INTVAL (addr) & 15);
addr = GEN_INT (INTVAL (addr) & -16);
}
+ else
+ {
+ p1_lo = gen_reg_rtx (SImode);
+ emit_move_insn (p1_lo, addr);
+ }
}
- addr = gen_rtx_AND (SImode, copy_rtx (addr), GEN_INT (-16));
+ reg = gen_reg_rtx (TImode);
scalar = store_with_one_insn_p (ops[0]);
if (!scalar)
@@ -4510,11 +4603,12 @@ spu_split_store (rtx * ops)
possible, and copying the flags will prevent that in certain
cases, e.g. consider the volatile flag. */
+ rtx pat = gen_reg_rtx (TImode);
rtx lmem = change_address (ops[0], TImode, copy_rtx (addr));
set_mem_alias_set (lmem, 0);
emit_insn (gen_movti (reg, lmem));
- if (!p0 || regno_aligned_for_load (REGNO (p0)))
+ if (!p0 || reg_aligned_for_addr (p0))
p0 = stack_pointer_rtx;
if (!p1_lo)
p1_lo = const0_rtx;
@@ -4522,17 +4616,6 @@ spu_split_store (rtx * ops)
emit_insn (gen_cpat (pat, p0, p1_lo, GEN_INT (GET_MODE_SIZE (mode))));
emit_insn (gen_shufb (reg, ops[1], reg, pat));
}
- else if (reload_completed)
- {
- if (GET_CODE (ops[1]) == REG)
- emit_move_insn (reg, gen_rtx_REG (GET_MODE (reg), REGNO (ops[1])));
- else if (GET_CODE (ops[1]) == SUBREG)
- emit_move_insn (reg,
- gen_rtx_REG (GET_MODE (reg),
- REGNO (SUBREG_REG (ops[1]))));
- else
- abort ();
- }
else
{
if (GET_CODE (ops[1]) == REG)
@@ -4544,15 +4627,16 @@ spu_split_store (rtx * ops)
}
if (GET_MODE_SIZE (mode) < 4 && scalar)
- emit_insn (gen_shlqby_ti
- (reg, reg, GEN_INT (4 - GET_MODE_SIZE (mode))));
+ emit_insn (gen_ashlti3
+ (reg, reg, GEN_INT (32 - GET_MODE_BITSIZE (mode))));
- smem = change_address (ops[0], TImode, addr);
+ smem = change_address (ops[0], TImode, copy_rtx (addr));
/* We can't use the previous alias set because the memory has changed
size and can potentially overlap objects of other types. */
set_mem_alias_set (smem, 0);
emit_insn (gen_movti (smem, reg));
+ return 1;
}
/* Return TRUE if X is MEM which is a struct member reference
@@ -4651,37 +4735,6 @@ fix_range (const char *const_str)
}
}
-int
-spu_valid_move (rtx * ops)
-{
- enum machine_mode mode = GET_MODE (ops[0]);
- if (!register_operand (ops[0], mode) && !register_operand (ops[1], mode))
- return 0;
-
- /* init_expr_once tries to recog against load and store insns to set
- the direct_load[] and direct_store[] arrays. We always want to
- consider those loads and stores valid. init_expr_once is called in
- the context of a dummy function which does not have a decl. */
- if (cfun->decl == 0)
- return 1;
-
- /* Don't allows loads/stores which would require more than 1 insn.
- During and after reload we assume loads and stores only take 1
- insn. */
- if (GET_MODE_SIZE (mode) < 16 && !reload_in_progress && !reload_completed)
- {
- if (GET_CODE (ops[0]) == MEM
- && (GET_MODE_SIZE (mode) < 4
- || !(store_with_one_insn_p (ops[0])
- || mem_is_padded_component_ref (ops[0]))))
- return 0;
- if (GET_CODE (ops[1]) == MEM
- && (GET_MODE_SIZE (mode) < 4 || !aligned_mem_p (ops[1])))
- return 0;
- }
- return 1;
-}
-
/* Return TRUE if x is a CONST_INT, CONST_DOUBLE or CONST_VECTOR that
can be generated using the fsmbi instruction. */
int
@@ -6395,12 +6448,25 @@ spu_sms_res_mii (struct ddg *g)
void
spu_init_expanders (void)
-{
- /* HARD_FRAME_REGISTER is only 128 bit aligned when
- * frame_pointer_needed is true. We don't know that until we're
- * expanding the prologue. */
+{
if (cfun)
- REGNO_POINTER_ALIGN (HARD_FRAME_POINTER_REGNUM) = 8;
+ {
+ rtx r0, r1;
+ /* HARD_FRAME_REGISTER is only 128 bit aligned when
+ frame_pointer_needed is true. We don't know that until we're
+ expanding the prologue. */
+ REGNO_POINTER_ALIGN (HARD_FRAME_POINTER_REGNUM) = 8;
+
+ /* A number of passes use LAST_VIRTUAL_REGISTER+1 and
+ LAST_VIRTUAL_REGISTER+2 to test the back-end. We want them
+ to be treated as aligned, so generate them here. */
+ r0 = gen_reg_rtx (SImode);
+ r1 = gen_reg_rtx (SImode);
+ mark_reg_pointer (r0, 128);
+ mark_reg_pointer (r1, 128);
+ gcc_assert (REGNO (r0) == LAST_VIRTUAL_REGISTER + 1
+ && REGNO (r1) == LAST_VIRTUAL_REGISTER + 2);
+ }
}
static enum machine_mode
@@ -6475,4 +6541,20 @@ spu_gen_exp2 (enum machine_mode mode, rtx scale)
}
}
+/* After reload, just change the convert into a move instruction
+ or a dead instruction. */
+void
+spu_split_convert (rtx ops[])
+{
+ if (REGNO (ops[0]) == REGNO (ops[1]))
+ emit_note (NOTE_INSN_DELETED);
+ else
+ {
+ /* Use TImode always as this might help hard reg copyprop. */
+ rtx op0 = gen_rtx_REG (TImode, REGNO (ops[0]));
+ rtx op1 = gen_rtx_REG (TImode, REGNO (ops[1]));
+ emit_insn (gen_move_insn (op0, op1));
+ }
+}
+
#include "gt-spu.h"
diff --git a/gcc/config/spu/spu.h b/gcc/config/spu/spu.h
index ed92715cd01..f994f3709c1 100644
--- a/gcc/config/spu/spu.h
+++ b/gcc/config/spu/spu.h
@@ -416,17 +416,6 @@ targetm.resolve_overloaded_builtin = spu_resolve_overloaded_builtin; \
#define MAX_REGS_PER_ADDRESS 2
-#ifdef REG_OK_STRICT
-# define REG_OK_STRICT_FLAG 1
-#else
-# define REG_OK_STRICT_FLAG 0
-#endif
-
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
- { if (spu_legitimate_address (MODE, X, REG_OK_STRICT_FLAG)) \
- goto ADDR; \
- }
-
#define LEGITIMATE_CONSTANT_P(X) spu_legitimate_constant_p(X)
@@ -606,11 +595,6 @@ targetm.resolve_overloaded_builtin = spu_resolve_overloaded_builtin; \
} \
} while (0)
-/* These are set by the cmp patterns and used while expanding
- conditional branches. */
-extern GTY(()) rtx spu_compare_op0;
-extern GTY(()) rtx spu_compare_op1;
-
/* Builtins. */
diff --git a/gcc/config/spu/spu.md b/gcc/config/spu/spu.md
index bd6936fd9e3..181d0db991c 100644
--- a/gcc/config/spu/spu.md
+++ b/gcc/config/spu/spu.md
@@ -178,6 +178,8 @@
SF V4SF
DF V2DF])
+(define_mode_iterator QHSI [QI HI SI])
+(define_mode_iterator QHSDI [QI HI SI DI])
(define_mode_iterator DTI [DI TI])
(define_mode_iterator VINT [QI V16QI
@@ -316,9 +318,10 @@
;; move internal
(define_insn "_mov<mode>"
- [(set (match_operand:MOV 0 "spu_nonimm_operand" "=r,r,r,r,r,m")
+ [(set (match_operand:MOV 0 "spu_dest_operand" "=r,r,r,r,r,m")
(match_operand:MOV 1 "spu_mov_operand" "r,A,f,j,m,r"))]
- "spu_valid_move (operands)"
+ "register_operand(operands[0], <MODE>mode)
+ || register_operand(operands[1], <MODE>mode)"
"@
ori\t%0,%1,0
il%s1\t%0,%S1
@@ -336,9 +339,10 @@
"iohl\t%0,%2@l")
(define_insn "_movdi"
- [(set (match_operand:DI 0 "spu_nonimm_operand" "=r,r,r,r,r,m")
+ [(set (match_operand:DI 0 "spu_dest_operand" "=r,r,r,r,r,m")
(match_operand:DI 1 "spu_mov_operand" "r,a,f,k,m,r"))]
- "spu_valid_move (operands)"
+ "register_operand(operands[0], DImode)
+ || register_operand(operands[1], DImode)"
"@
ori\t%0,%1,0
il%d1\t%0,%D1
@@ -349,9 +353,10 @@
[(set_attr "type" "fx2,fx2,shuf,shuf,load,store")])
(define_insn "_movti"
- [(set (match_operand:TI 0 "spu_nonimm_operand" "=r,r,r,r,r,m")
+ [(set (match_operand:TI 0 "spu_dest_operand" "=r,r,r,r,r,m")
(match_operand:TI 1 "spu_mov_operand" "r,U,f,l,m,r"))]
- "spu_valid_move (operands)"
+ "register_operand(operands[0], TImode)
+ || register_operand(operands[1], TImode)"
"@
ori\t%0,%1,0
il%t1\t%0,%T1
@@ -361,30 +366,29 @@
stq%p0\t%1,%0"
[(set_attr "type" "fx2,fx2,shuf,shuf,load,store")])
-(define_insn_and_split "load"
- [(set (match_operand 0 "spu_reg_operand" "=r")
- (match_operand 1 "memory_operand" "m"))
- (clobber (match_operand:TI 2 "spu_reg_operand" "=&r"))
- (clobber (match_operand:SI 3 "spu_reg_operand" "=&r"))]
- "GET_MODE(operands[0]) == GET_MODE(operands[1])"
- "#"
- ""
+(define_split
+ [(set (match_operand 0 "spu_reg_operand")
+ (match_operand 1 "memory_operand"))]
+ "GET_MODE_SIZE (GET_MODE (operands[0])) < 16
+ && GET_MODE(operands[0]) == GET_MODE(operands[1])
+ && !reload_in_progress && !reload_completed"
[(set (match_dup 0)
(match_dup 1))]
- { spu_split_load(operands); DONE; })
+ { if (spu_split_load(operands))
+ DONE;
+ })
-(define_insn_and_split "store"
- [(set (match_operand 0 "memory_operand" "=m")
- (match_operand 1 "spu_reg_operand" "r"))
- (clobber (match_operand:TI 2 "spu_reg_operand" "=&r"))
- (clobber (match_operand:TI 3 "spu_reg_operand" "=&r"))]
- "GET_MODE(operands[0]) == GET_MODE(operands[1])"
- "#"
- ""
+(define_split
+ [(set (match_operand 0 "memory_operand")
+ (match_operand 1 "spu_reg_operand"))]
+ "GET_MODE_SIZE (GET_MODE (operands[0])) < 16
+ && GET_MODE(operands[0]) == GET_MODE(operands[1])
+ && !reload_in_progress && !reload_completed"
[(set (match_dup 0)
(match_dup 1))]
- { spu_split_store(operands); DONE; })
-
+ { if (spu_split_store(operands))
+ DONE;
+ })
;; Operand 3 is the number of bytes. 1:b 2:h 4:w 8:d
(define_expand "cpat"
@@ -462,33 +466,20 @@
""
"xswd\t%0,%1");
-(define_expand "extendqiti2"
+;; By splitting this late we don't allow much opportunity for sharing of
+;; constants. That's ok because this should really be optimized away.
+(define_insn_and_split "extend<mode>ti2"
[(set (match_operand:TI 0 "register_operand" "")
- (sign_extend:TI (match_operand:QI 1 "register_operand" "")))]
+ (sign_extend:TI (match_operand:QHSDI 1 "register_operand" "")))]
""
- "spu_expand_sign_extend(operands);
- DONE;")
-
-(define_expand "extendhiti2"
- [(set (match_operand:TI 0 "register_operand" "")
- (sign_extend:TI (match_operand:HI 1 "register_operand" "")))]
- ""
- "spu_expand_sign_extend(operands);
- DONE;")
-
-(define_expand "extendsiti2"
- [(set (match_operand:TI 0 "register_operand" "")
- (sign_extend:TI (match_operand:SI 1 "register_operand" "")))]
- ""
- "spu_expand_sign_extend(operands);
- DONE;")
-
-(define_expand "extendditi2"
- [(set (match_operand:TI 0 "register_operand" "")
- (sign_extend:TI (match_operand:DI 1 "register_operand" "")))]
+ "#"
""
- "spu_expand_sign_extend(operands);
- DONE;")
+ [(set (match_dup:TI 0)
+ (sign_extend:TI (match_dup:QHSDI 1)))]
+ {
+ spu_expand_sign_extend(operands);
+ DONE;
+ })
;; zero_extend
@@ -525,6 +516,22 @@
"rotqmbyi\t%0,%1,-4"
[(set_attr "type" "shuf")])
+(define_insn "zero_extendqiti2"
+ [(set (match_operand:TI 0 "spu_reg_operand" "=r")
+ (zero_extend:TI (match_operand:QI 1 "spu_reg_operand" "r")))]
+ ""
+ "andi\t%0,%1,0x00ff\;rotqmbyi\t%0,%0,-12"
+ [(set_attr "type" "multi0")
+ (set_attr "length" "8")])
+
+(define_insn "zero_extendhiti2"
+ [(set (match_operand:TI 0 "spu_reg_operand" "=r")
+ (zero_extend:TI (match_operand:HI 1 "spu_reg_operand" "r")))]
+ ""
+ "shli\t%0,%1,16\;rotqmbyi\t%0,%0,-14"
+ [(set_attr "type" "multi1")
+ (set_attr "length" "8")])
+
(define_insn "zero_extendsiti2"
[(set (match_operand:TI 0 "spu_reg_operand" "=r")
(zero_extend:TI (match_operand:SI 1 "spu_reg_operand" "r")))]
@@ -2348,6 +2355,13 @@
""
[(set_attr "type" "*,fx3")])
+(define_insn "<v>lshr<mode>3_imm"
+ [(set (match_operand:VHSI 0 "spu_reg_operand" "=r")
+ (lshiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r")
+ (match_operand:VHSI 2 "immediate_operand" "W")))]
+ ""
+ "rot<bh>mi\t%0,%1,-%<umask>2"
+ [(set_attr "type" "fx3")])
(define_insn "rotm_<mode>"
[(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
@@ -2359,89 +2373,59 @@
rot<bh>mi\t%0,%1,-%<nmask>2"
[(set_attr "type" "fx3")])
-(define_expand "lshr<mode>3"
- [(parallel [(set (match_operand:DTI 0 "spu_reg_operand" "")
- (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "")
- (match_operand:SI 2 "spu_nonmem_operand" "")))
- (clobber (match_dup:DTI 3))
- (clobber (match_dup:SI 4))
- (clobber (match_dup:SI 5))])]
- ""
- "if (GET_CODE (operands[2]) == CONST_INT)
- {
- emit_insn (gen_lshr<mode>3_imm(operands[0], operands[1], operands[2]));
- DONE;
- }
- operands[3] = gen_reg_rtx (<MODE>mode);
- operands[4] = gen_reg_rtx (SImode);
- operands[5] = gen_reg_rtx (SImode);")
-
-(define_insn_and_split "lshr<mode>3_imm"
- [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
- (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
- (match_operand:SI 2 "immediate_operand" "O,P")))]
+(define_insn_and_split "lshr<mode>3"
+ [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r,r")
+ (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r,r")
+ (match_operand:SI 2 "spu_nonmem_operand" "r,O,P")))]
""
"@
+ #
rotqmbyi\t%0,%1,-%h2
rotqmbii\t%0,%1,-%e2"
- "!satisfies_constraint_O (operands[2]) && !satisfies_constraint_P (operands[2])"
- [(set (match_dup:DTI 0)
+ "REG_P (operands[2]) || (!satisfies_constraint_O (operands[2]) && !satisfies_constraint_P (operands[2]))"
+ [(set (match_dup:DTI 3)
(lshiftrt:DTI (match_dup:DTI 1)
(match_dup:SI 4)))
(set (match_dup:DTI 0)
- (lshiftrt:DTI (match_dup:DTI 0)
+ (lshiftrt:DTI (match_dup:DTI 3)
(match_dup:SI 5)))]
{
- HOST_WIDE_INT val = INTVAL(operands[2]);
- operands[4] = GEN_INT (val&7);
- operands[5] = GEN_INT (val&-8);
+ operands[3] = gen_reg_rtx (<MODE>mode);
+ if (GET_CODE (operands[2]) == CONST_INT)
+ {
+ HOST_WIDE_INT val = INTVAL(operands[2]);
+ operands[4] = GEN_INT (val & 7);
+ operands[5] = GEN_INT (val & -8);
+ }
+ else
+ {
+ rtx t0 = gen_reg_rtx (SImode);
+ rtx t1 = gen_reg_rtx (SImode);
+ emit_insn (gen_subsi3(t0, GEN_INT(0), operands[2]));
+ emit_insn (gen_subsi3(t1, GEN_INT(7), operands[2]));
+ operands[4] = gen_rtx_AND (SImode, gen_rtx_NEG (SImode, t0), GEN_INT (7));
+ operands[5] = gen_rtx_AND (SImode, gen_rtx_NEG (SImode, gen_rtx_AND (SImode, t1, GEN_INT (-8))), GEN_INT (-8));
+ }
}
- [(set_attr "type" "shuf,shuf")])
+ [(set_attr "type" "*,shuf,shuf")])
-(define_insn_and_split "lshr<mode>3_reg"
- [(set (match_operand:DTI 0 "spu_reg_operand" "=r")
- (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r")
- (match_operand:SI 2 "spu_reg_operand" "r")))
- (clobber (match_operand:DTI 3 "spu_reg_operand" "=&r"))
- (clobber (match_operand:SI 4 "spu_reg_operand" "=&r"))
- (clobber (match_operand:SI 5 "spu_reg_operand" "=&r"))]
- ""
- "#"
- ""
- [(set (match_dup:DTI 3)
- (lshiftrt:DTI (match_dup:DTI 1)
- (and:SI (neg:SI (match_dup:SI 4))
- (const_int 7))))
- (set (match_dup:DTI 0)
- (lshiftrt:DTI (match_dup:DTI 3)
- (and:SI (neg:SI (and:SI (match_dup:SI 5)
- (const_int -8)))
- (const_int -8))))]
- {
- emit_insn (gen_subsi3(operands[4], GEN_INT(0), operands[2]));
- emit_insn (gen_subsi3(operands[5], GEN_INT(7), operands[2]));
- })
-
-(define_insn_and_split "shrqbybi_<mode>"
+(define_expand "shrqbybi_<mode>"
[(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
(lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
- (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
- (const_int -8))))
- (clobber (match_scratch:SI 3 "=&r,X"))]
- ""
- "#"
- "reload_completed"
- [(set (match_dup:DTI 0)
- (lshiftrt:DTI (match_dup:DTI 1)
- (and:SI (neg:SI (and:SI (match_dup:SI 3) (const_int -8)))
+ (and:SI (neg:SI (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
+ (const_int -8)))
(const_int -8))))]
+ ""
{
if (GET_CODE (operands[2]) == CONST_INT)
- operands[3] = GEN_INT (7 - INTVAL (operands[2]));
+ operands[2] = GEN_INT (7 - INTVAL (operands[2]));
else
- emit_insn (gen_subsi3 (operands[3], GEN_INT (7), operands[2]));
- }
- [(set_attr "type" "shuf")])
+ {
+ rtx t0 = gen_reg_rtx (SImode);
+ emit_insn (gen_subsi3 (t0, GEN_INT (7), operands[2]));
+ operands[2] = t0;
+ }
+ })
(define_insn "rotqmbybi_<mode>"
[(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
@@ -2486,25 +2470,22 @@
rotqmbii\t%0,%1,-%E2"
[(set_attr "type" "shuf")])
-(define_insn_and_split "shrqby_<mode>"
+(define_expand "shrqby_<mode>"
[(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
(lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
- (mult:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
- (const_int 8))))
- (clobber (match_scratch:SI 3 "=&r,X"))]
+ (mult:SI (neg:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I"))
+ (const_int 8))))]
""
- "#"
- "reload_completed"
- [(set (match_dup:DTI 0)
- (lshiftrt:DTI (match_dup:DTI 1)
- (mult:SI (neg:SI (match_dup:SI 3)) (const_int 8))))]
{
if (GET_CODE (operands[2]) == CONST_INT)
- operands[3] = GEN_INT (-INTVAL (operands[2]));
+ operands[2] = GEN_INT (-INTVAL (operands[2]));
else
- emit_insn (gen_subsi3 (operands[3], GEN_INT (0), operands[2]));
- }
- [(set_attr "type" "shuf")])
+ {
+ rtx t0 = gen_reg_rtx (SImode);
+ emit_insn (gen_subsi3 (t0, GEN_INT (0), operands[2]));
+ operands[2] = t0;
+ }
+ })
(define_insn "rotqmby_<mode>"
[(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
@@ -2538,6 +2519,14 @@
""
[(set_attr "type" "*,fx3")])
+(define_insn "<v>ashr<mode>3_imm"
+ [(set (match_operand:VHSI 0 "spu_reg_operand" "=r")
+ (ashiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r")
+ (match_operand:VHSI 2 "immediate_operand" "W")))]
+ ""
+ "rotma<bh>i\t%0,%1,-%<umask>2"
+ [(set_attr "type" "fx3")])
+
(define_insn "rotma_<mode>"
[(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
@@ -2622,11 +2611,16 @@
})
-(define_expand "ashrti3"
- [(set (match_operand:TI 0 "spu_reg_operand" "")
- (ashiftrt:TI (match_operand:TI 1 "spu_reg_operand" "")
- (match_operand:SI 2 "spu_nonmem_operand" "")))]
+(define_insn_and_split "ashrti3"
+ [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
+ (ashiftrt:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
+ (match_operand:SI 2 "spu_nonmem_operand" "r,i")))]
""
+ "#"
+ ""
+ [(set (match_dup:TI 0)
+ (ashiftrt:TI (match_dup:TI 1)
+ (match_dup:SI 2)))]
{
rtx sign_shift = gen_reg_rtx (SImode);
rtx sign_mask = gen_reg_rtx (TImode);
@@ -2711,33 +2705,133 @@
;; struct extract/insert
-;; We have to handle mem's because GCC will generate invalid SUBREG's
-;; if it handles them. We generate better code anyway.
+;; We handle mem's because GCC will generate invalid SUBREG's
+;; and inefficient code.
(define_expand "extv"
- [(set (match_operand 0 "register_operand" "")
- (sign_extract (match_operand 1 "register_operand" "")
- (match_operand:SI 2 "const_int_operand" "")
- (match_operand:SI 3 "const_int_operand" "")))]
+ [(set (match_operand:TI 0 "register_operand" "")
+ (sign_extract:TI (match_operand 1 "nonimmediate_operand" "")
+ (match_operand:SI 2 "const_int_operand" "")
+ (match_operand:SI 3 "const_int_operand" "")))]
""
- { spu_expand_extv(operands, 0); DONE; })
+ {
+ spu_expand_extv (operands, 0);
+ DONE;
+ })
(define_expand "extzv"
- [(set (match_operand 0 "register_operand" "")
- (zero_extract (match_operand 1 "register_operand" "")
+ [(set (match_operand:TI 0 "register_operand" "")
+ (zero_extract:TI (match_operand 1 "nonimmediate_operand" "")
(match_operand:SI 2 "const_int_operand" "")
(match_operand:SI 3 "const_int_operand" "")))]
""
- { spu_expand_extv(operands, 1); DONE; })
+ {
+ spu_expand_extv (operands, 1);
+ DONE;
+ })
(define_expand "insv"
- [(set (zero_extract (match_operand 0 "register_operand" "")
+ [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
(match_operand:SI 1 "const_int_operand" "")
(match_operand:SI 2 "const_int_operand" ""))
(match_operand 3 "nonmemory_operand" ""))]
""
{ spu_expand_insv(operands); DONE; })
+;; Simplify a number of patterns that get generated by extv, extzv,
+;; insv, and loads.
+(define_insn_and_split "trunc_shr_ti<mode>"
+ [(set (match_operand:QHSI 0 "spu_reg_operand" "=r")
+ (truncate:QHSI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "0")
+ (const_int 96)])))]
+ ""
+ "#"
+ "reload_completed"
+ [(const_int 0)]
+ {
+ spu_split_convert (operands);
+ DONE;
+ }
+ [(set_attr "type" "convert")
+ (set_attr "length" "0")])
+
+(define_insn_and_split "trunc_shr_tidi"
+ [(set (match_operand:DI 0 "spu_reg_operand" "=r")
+ (truncate:DI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "0")
+ (const_int 64)])))]
+ ""
+ "#"
+ "reload_completed"
+ [(const_int 0)]
+ {
+ spu_split_convert (operands);
+ DONE;
+ }
+ [(set_attr "type" "convert")
+ (set_attr "length" "0")])
+
+(define_insn_and_split "shl_ext_<mode>ti"
+ [(set (match_operand:TI 0 "spu_reg_operand" "=r")
+ (ashift:TI (match_operator:TI 2 "extend_operator" [(match_operand:QHSI 1 "spu_reg_operand" "0")])
+ (const_int 96)))]
+ ""
+ "#"
+ "reload_completed"
+ [(const_int 0)]
+ {
+ spu_split_convert (operands);
+ DONE;
+ }
+ [(set_attr "type" "convert")
+ (set_attr "length" "0")])
+
+(define_insn_and_split "shl_ext_diti"
+ [(set (match_operand:TI 0 "spu_reg_operand" "=r")
+ (ashift:TI (match_operator:TI 2 "extend_operator" [(match_operand:DI 1 "spu_reg_operand" "0")])
+ (const_int 64)))]
+ ""
+ "#"
+ "reload_completed"
+ [(const_int 0)]
+ {
+ spu_split_convert (operands);
+ DONE;
+ }
+ [(set_attr "type" "convert")
+ (set_attr "length" "0")])
+
+(define_insn "sext_trunc_lshr_tiqisi"
+ [(set (match_operand:SI 0 "spu_reg_operand" "=r")
+ (sign_extend:SI (truncate:QI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "r")
+ (const_int 120)]))))]
+ ""
+ "rotmai\t%0,%1,-24"
+ [(set_attr "type" "fx3")])
+
+(define_insn "zext_trunc_lshr_tiqisi"
+ [(set (match_operand:SI 0 "spu_reg_operand" "=r")
+ (zero_extend:SI (truncate:QI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "r")
+ (const_int 120)]))))]
+ ""
+ "rotmi\t%0,%1,-24"
+ [(set_attr "type" "fx3")])
+
+(define_insn "sext_trunc_lshr_tihisi"
+ [(set (match_operand:SI 0 "spu_reg_operand" "=r")
+ (sign_extend:SI (truncate:HI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "r")
+ (const_int 112)]))))]
+ ""
+ "rotmai\t%0,%1,-16"
+ [(set_attr "type" "fx3")])
+
+(define_insn "zext_trunc_lshr_tihisi"
+ [(set (match_operand:SI 0 "spu_reg_operand" "=r")
+ (zero_extend:SI (truncate:HI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "r")
+ (const_int 112)]))))]
+ ""
+ "rotmi\t%0,%1,-16"
+ [(set_attr "type" "fx3")])
+
;; String/block move insn.
;; Argument 0 is the destination
@@ -3657,57 +3751,6 @@ selb\t%0,%4,%0,%3"
[(set_attr "type" "br")])
-;; Compare insns are next. Note that the spu has two types of compares,
-;; signed & unsigned, and one type of branch.
-;;
-;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
-;; insns, and branches. We store the operands of compares until we see
-;; how it is used.
-
-(define_expand "cmp<mode>"
- [(set (cc0)
- (compare (match_operand:VQHSI 0 "spu_reg_operand" "")
- (match_operand:VQHSI 1 "spu_nonmem_operand" "")))]
- ""
- {
- spu_compare_op0 = operands[0];
- spu_compare_op1 = operands[1];
- DONE;
- })
-
-(define_expand "cmp<mode>"
- [(set (cc0)
- (compare (match_operand:DTI 0 "spu_reg_operand" "")
- (match_operand:DTI 1 "spu_reg_operand" "")))]
- ""
- {
- spu_compare_op0 = operands[0];
- spu_compare_op1 = operands[1];
- DONE;
- })
-
-(define_expand "cmp<mode>"
- [(set (cc0)
- (compare (match_operand:VSF 0 "spu_reg_operand" "")
- (match_operand:VSF 1 "spu_reg_operand" "")))]
- ""
- {
- spu_compare_op0 = operands[0];
- spu_compare_op1 = operands[1];
- DONE;
- })
-
-(define_expand "cmpdf"
- [(set (cc0)
- (compare (match_operand:DF 0 "register_operand" "")
- (match_operand:DF 1 "register_operand" "")))]
- ""
- "{
- spu_compare_op0 = operands[0];
- spu_compare_op1 = operands[1];
- DONE;
-}")
-
;; vector conditional compare patterns
(define_expand "vcond<mode>"
[(set (match_operand:VCMP 0 "spu_reg_operand" "=r")
@@ -3746,108 +3789,72 @@ selb\t%0,%4,%0,%3"
;; branch on condition
-(define_expand "beq"
- [(use (match_operand 0 "" ""))]
+(define_expand "cbranch<mode>4"
+ [(use (match_operator 0 "ordered_comparison_operator"
+ [(match_operand:VQHSI 1 "spu_reg_operand" "")
+ (match_operand:VQHSI 2 "spu_nonmem_operand" "")]))
+ (use (match_operand 3 ""))]
""
- { spu_emit_branch_or_set (0, EQ, operands); DONE; })
+ { spu_emit_branch_or_set (0, operands[0], operands); DONE; })
-(define_expand "bne"
- [(use (match_operand 0 "" ""))]
+(define_expand "cbranch<mode>4"
+ [(use (match_operator 0 "ordered_comparison_operator"
+ [(match_operand:DTI 1 "spu_reg_operand" "")
+ (match_operand:DTI 2 "spu_reg_operand" "")]))
+ (use (match_operand 3 ""))]
""
- { spu_emit_branch_or_set (0, NE, operands); DONE; })
+ { spu_emit_branch_or_set (0, operands[0], operands); DONE; })
-(define_expand "bge"
- [(use (match_operand 0 "" ""))]
+(define_expand "cbranch<mode>4"
+ [(use (match_operator 0 "ordered_comparison_operator"
+ [(match_operand:VSF 1 "spu_reg_operand" "")
+ (match_operand:VSF 2 "spu_reg_operand" "")]))
+ (use (match_operand 3 ""))]
""
- { spu_emit_branch_or_set (0, GE, operands); DONE; })
+ { spu_emit_branch_or_set (0, operands[0], operands); DONE; })
-(define_expand "bgt"
- [(use (match_operand 0 "" ""))]
+(define_expand "cbranchdf4"
+ [(use (match_operator 0 "ordered_comparison_operator"
+ [(match_operand:DF 1 "spu_reg_operand" "")
+ (match_operand:DF 2 "spu_reg_operand" "")]))
+ (use (match_operand 3 ""))]
""
- { spu_emit_branch_or_set (0, GT, operands); DONE; })
-
-(define_expand "ble"
- [(use (match_operand 0 "" ""))]
- ""
- { spu_emit_branch_or_set (0, LE, operands); DONE; })
-
-(define_expand "blt"
- [(use (match_operand 0 "" ""))]
- ""
- { spu_emit_branch_or_set (0, LT, operands); DONE; })
-
-(define_expand "bgeu"
- [(use (match_operand 0 "" ""))]
- ""
- { spu_emit_branch_or_set (0, GEU, operands); DONE; })
-
-(define_expand "bgtu"
- [(use (match_operand 0 "" ""))]
- ""
- { spu_emit_branch_or_set (0, GTU, operands); DONE; })
-
-(define_expand "bleu"
- [(use (match_operand 0 "" ""))]
- ""
- { spu_emit_branch_or_set (0, LEU, operands); DONE; })
-
-(define_expand "bltu"
- [(use (match_operand 0 "" ""))]
- ""
- { spu_emit_branch_or_set (0, LTU, operands); DONE; })
+ { spu_emit_branch_or_set (0, operands[0], operands); DONE; })
;; set on condition
-(define_expand "seq"
- [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
- ""
- { spu_emit_branch_or_set (1, EQ, operands); DONE; })
-
-(define_expand "sne"
- [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
- ""
- { spu_emit_branch_or_set (1, NE, operands); DONE; })
-
-(define_expand "sgt"
- [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
- ""
- { spu_emit_branch_or_set (1, GT, operands); DONE; })
-
-(define_expand "slt"
- [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
- ""
- { spu_emit_branch_or_set (1, LT, operands); DONE; })
-
-(define_expand "sge"
- [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
- ""
- { spu_emit_branch_or_set (1, GE, operands); DONE; })
-
-(define_expand "sle"
- [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
- ""
- { spu_emit_branch_or_set (1, LE, operands); DONE; })
-
-(define_expand "sgtu"
- [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
+(define_expand "cstore<mode>4"
+ [(use (match_operator 1 "ordered_comparison_operator"
+ [(match_operand:VQHSI 2 "spu_reg_operand" "")
+ (match_operand:VQHSI 3 "spu_nonmem_operand" "")]))
+ (clobber (match_operand:SI 0 "spu_reg_operand"))]
""
- { spu_emit_branch_or_set (1, GTU, operands); DONE; })
+ { spu_emit_branch_or_set (1, operands[1], operands); DONE; })
-(define_expand "sltu"
- [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
+(define_expand "cstore<mode>4"
+ [(use (match_operator 1 "ordered_comparison_operator"
+ [(match_operand:DTI 2 "spu_reg_operand" "")
+ (match_operand:DTI 3 "spu_reg_operand" "")]))
+ (clobber (match_operand:SI 0 "spu_reg_operand"))]
""
- { spu_emit_branch_or_set (1, LTU, operands); DONE; })
+ { spu_emit_branch_or_set (1, operands[1], operands); DONE; })
-(define_expand "sgeu"
- [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
+(define_expand "cstore<mode>4"
+ [(use (match_operator 1 "ordered_comparison_operator"
+ [(match_operand:VSF 2 "spu_reg_operand" "")
+ (match_operand:VSF 3 "spu_reg_operand" "")]))
+ (clobber (match_operand:SI 0 "spu_reg_operand"))]
""
- { spu_emit_branch_or_set (1, GEU, operands); DONE; })
+ { spu_emit_branch_or_set (1, operands[1], operands); DONE; })
-(define_expand "sleu"
- [(clobber (match_operand:SI 0 "spu_reg_operand" ""))]
+(define_expand "cstoredf4"
+ [(use (match_operator 1 "ordered_comparison_operator"
+ [(match_operand:DF 2 "spu_reg_operand" "")
+ (match_operand:DF 3 "spu_reg_operand" "")]))
+ (clobber (match_operand:SI 0 "spu_reg_operand"))]
""
- { spu_emit_branch_or_set (1, LEU, operands); DONE; })
+ { spu_emit_branch_or_set (1, operands[1], operands); DONE; })
;; conditional move
@@ -3863,12 +3870,12 @@ selb\t%0,%4,%0,%3"
(define_expand "mov<mode>cc"
[(set (match_operand:ALL 0 "spu_reg_operand" "")
- (if_then_else:ALL (match_operand 1 "comparison_operator" "")
+ (if_then_else:ALL (match_operand 1 "ordered_comparison_operator" "")
(match_operand:ALL 2 "spu_reg_operand" "")
(match_operand:ALL 3 "spu_reg_operand" "")))]
""
{
- spu_emit_branch_or_set(2, GET_CODE(operands[1]), operands);
+ spu_emit_branch_or_set(2, operands[1], operands);
DONE;
})
@@ -4390,21 +4397,20 @@ selb\t%0,%4,%0,%3"
DONE;
})
-(define_insn "_spu_convert"
+(define_insn_and_split "_spu_convert"
[(set (match_operand 0 "spu_reg_operand" "=r")
(unspec [(match_operand 1 "spu_reg_operand" "0")] UNSPEC_CONVERT))]
- "operands"
""
+ "#"
+ "reload_completed"
+ [(const_int 0)]
+ {
+ spu_split_convert (operands);
+ DONE;
+ }
[(set_attr "type" "convert")
(set_attr "length" "0")])
-(define_peephole2
- [(set (match_operand 0 "spu_reg_operand")
- (unspec [(match_operand 1 "spu_reg_operand")] UNSPEC_CONVERT))]
- ""
- [(use (const_int 0))]
- "")
-
;;
(include "spu-builtins.md")
@@ -5273,8 +5279,8 @@ DONE;
}")
(define_insn "stack_protect_set"
- [(set (match_operand:SI 0 "spu_mem_operand" "=m")
- (unspec:SI [(match_operand:SI 1 "spu_mem_operand" "m")] UNSPEC_SP_SET))
+ [(set (match_operand:SI 0 "memory_operand" "=m")
+ (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
(set (match_scratch:SI 2 "=&r") (const_int 0))]
""
"lq%p1\t%2,%1\;stq%p0\t%2,%0\;xor\t%2,%2,%2"
@@ -5283,8 +5289,8 @@ DONE;
)
(define_expand "stack_protect_test"
- [(match_operand 0 "spu_mem_operand" "")
- (match_operand 1 "spu_mem_operand" "")
+ [(match_operand 0 "memory_operand" "")
+ (match_operand 1 "memory_operand" "")
(match_operand 2 "" "")]
""
{
@@ -5310,8 +5316,8 @@ DONE;
(define_insn "stack_protect_test_si"
[(set (match_operand:SI 0 "spu_reg_operand" "=&r")
- (unspec:SI [(match_operand:SI 1 "spu_mem_operand" "m")
- (match_operand:SI 2 "spu_mem_operand" "m")]
+ (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
+ (match_operand:SI 2 "memory_operand" "m")]
UNSPEC_SP_TEST))
(set (match_scratch:SI 3 "=&r") (const_int 0))]
""
diff --git a/gcc/config/spu/t-spu-elf b/gcc/config/spu/t-spu-elf
index 0a36e959c5b..0c9236fa89f 100644
--- a/gcc/config/spu/t-spu-elf
+++ b/gcc/config/spu/t-spu-elf
@@ -1,4 +1,4 @@
-# Copyright (C) 2006, 2007, 2008 Free Software Foundation, Inc.
+# Copyright (C) 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
#
# This file is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
@@ -91,5 +91,5 @@ spu-c.o: $(srcdir)/config/spu/spu-c.c \
$(srcdir)/config/spu/spu-protos.h \
$(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(CPPLIB_H) \
$(TM_P_H) c-pragma.h coretypes.h $(TM_H) insn-codes.h
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/config/spu/spu-c.c
-
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $(srcdir)/config/spu/spu-c.c
diff --git a/gcc/config/stormy16/stormy16-protos.h b/gcc/config/stormy16/stormy16-protos.h
index 58cff8a26e9..e6fe4c0c969 100644
--- a/gcc/config/stormy16/stormy16-protos.h
+++ b/gcc/config/stormy16/stormy16-protos.h
@@ -48,7 +48,7 @@ extern rtx xstormy16_function_value (const_tree, const_tree);
#endif
#ifdef RTX_CODE
-extern void xstormy16_emit_cbranch (enum rtx_code, rtx);
+extern void xstormy16_emit_cbranch (enum rtx_code, rtx, rtx, rtx);
extern char *xstormy16_output_cbranch_hi (rtx, const char *, int, rtx);
extern char *xstormy16_output_cbranch_si (rtx, const char *, int, rtx);
extern int xstormy16_mode_dependent_address_p (rtx);
@@ -71,7 +71,6 @@ extern int nonimmediate_nonstack_operand (rtx, enum machine_mode);
extern enum reg_class xstormy16_secondary_reload_class
(enum reg_class, enum machine_mode, rtx);
extern enum reg_class xstormy16_preferred_reload_class (rtx, enum reg_class);
-extern int xstormy16_legitimate_address_p (enum machine_mode, rtx, int);
extern void xstormy16_split_move (enum machine_mode, rtx, rtx);
extern void xstormy16_expand_move (enum machine_mode, rtx, rtx);
extern void xstormy16_expand_arith (enum machine_mode, enum rtx_code,
diff --git a/gcc/config/stormy16/stormy16.c b/gcc/config/stormy16/stormy16.c
index eefc58f0847..2e646f98d4c 100644
--- a/gcc/config/stormy16/stormy16.c
+++ b/gcc/config/stormy16/stormy16.c
@@ -61,11 +61,6 @@ static bool xstormy16_rtx_costs (rtx, int, int, int *, bool);
static int xstormy16_address_cost (rtx, bool);
static bool xstormy16_return_in_memory (const_tree, const_tree);
-/* Define the information needed to generate branch and scc insns. This is
- stored from the compare operation. */
-struct rtx_def * xstormy16_compare_op0;
-struct rtx_def * xstormy16_compare_op1;
-
static GTY(()) section *bss100_section;
/* Compute a (partial) cost for rtx X. Return true if the complete
@@ -139,10 +134,8 @@ xstormy16_address_cost (rtx x, bool speed ATTRIBUTE_UNUSED)
/* Emit a branch of kind CODE to location LOC. */
void
-xstormy16_emit_cbranch (enum rtx_code code, rtx loc)
+xstormy16_emit_cbranch (enum rtx_code code, rtx op0, rtx op1, rtx loc)
{
- rtx op0 = xstormy16_compare_op0;
- rtx op1 = xstormy16_compare_op1;
rtx condition_rtx, loc_ref, branch, cy_clobber;
rtvec vec;
enum machine_mode mode;
@@ -159,10 +152,10 @@ xstormy16_emit_cbranch (enum rtx_code code, rtx loc)
if (gt_p)
lab = gen_label_rtx ();
- xstormy16_emit_cbranch (unsigned_p ? LTU : LT, gt_p ? lab : loc);
+ xstormy16_emit_cbranch (unsigned_p ? LTU : LT, op0, op1, gt_p ? lab : loc);
/* This should be generated as a comparison against the temporary
created by the previous insn, but reload can't handle that. */
- xstormy16_emit_cbranch (gt_p ? NE : EQ, loc);
+ xstormy16_emit_cbranch (gt_p ? NE : EQ, op0, op1, loc);
if (gt_p)
emit_label (lab);
return;
@@ -171,6 +164,7 @@ xstormy16_emit_cbranch (enum rtx_code code, rtx loc)
&& (code == NE || code == EQ)
&& op1 != const0_rtx)
{
+ rtx op0_word, op1_word;
rtx lab = NULL_RTX;
int num_words = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
int i;
@@ -180,17 +174,17 @@ xstormy16_emit_cbranch (enum rtx_code code, rtx loc)
for (i = 0; i < num_words - 1; i++)
{
- xstormy16_compare_op0 = simplify_gen_subreg (word_mode, op0, mode,
- i * UNITS_PER_WORD);
- xstormy16_compare_op1 = simplify_gen_subreg (word_mode, op1, mode,
- i * UNITS_PER_WORD);
- xstormy16_emit_cbranch (NE, code == EQ ? lab : loc);
+ op0_word = simplify_gen_subreg (word_mode, op0, mode,
+ i * UNITS_PER_WORD);
+ op1_word = simplify_gen_subreg (word_mode, op1, mode,
+ i * UNITS_PER_WORD);
+ xstormy16_emit_cbranch (NE, op0_word, op1_word, code == EQ ? lab : loc);
}
- xstormy16_compare_op0 = simplify_gen_subreg (word_mode, op0, mode,
- i * UNITS_PER_WORD);
- xstormy16_compare_op1 = simplify_gen_subreg (word_mode, op1, mode,
- i * UNITS_PER_WORD);
- xstormy16_emit_cbranch (code, loc);
+ op0_word = simplify_gen_subreg (word_mode, op0, mode,
+ i * UNITS_PER_WORD);
+ op1_word = simplify_gen_subreg (word_mode, op1, mode,
+ i * UNITS_PER_WORD);
+ xstormy16_emit_cbranch (code, op0_word, op1_word, loc);
if (code == EQ)
emit_label (lab);
@@ -619,9 +613,9 @@ xstormy16_expand_andqi3 (rtx *operands)
&& INTVAL (X) + (OFFSET) < 0x8000 \
&& (INTVAL (X) + (OFFSET) < 0x100 || INTVAL (X) + (OFFSET) >= 0x7F00))
-int
+static bool
xstormy16_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED,
- rtx x, int strict)
+ rtx x, bool strict)
{
if (LEGITIMATE_ADDRESS_CONST_INT_P (x, 0))
return 1;
@@ -1297,11 +1291,14 @@ xstormy16_build_builtin_va_list (void)
tree f_1, f_2, record, type_decl;
record = (*lang_hooks.types.make_type) (RECORD_TYPE);
- type_decl = build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
+ type_decl = build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier ("__va_list_tag"), record);
- f_1 = build_decl (FIELD_DECL, get_identifier ("base"),
+ f_1 = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, get_identifier ("base"),
ptr_type_node);
- f_2 = build_decl (FIELD_DECL, get_identifier ("count"),
+ f_2 = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, get_identifier ("count"),
unsigned_type_node);
DECL_FIELD_CONTEXT (f_1) = record;
@@ -1383,8 +1380,8 @@ xstormy16_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
size_of_reg_args = NUM_ARGUMENT_REGISTERS * UNITS_PER_WORD;
count_tmp = get_initialized_tmp_var (count, pre_p, NULL);
- lab_gotaddr = create_artificial_label ();
- lab_fromstack = create_artificial_label ();
+ lab_gotaddr = create_artificial_label (UNKNOWN_LOCATION);
+ lab_fromstack = create_artificial_label (UNKNOWN_LOCATION);
addr = create_tmp_var (ptr_type_node, NULL);
if (!must_stack)
@@ -2656,6 +2653,9 @@ xstormy16_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
#undef TARGET_MACHINE_DEPENDENT_REORG
#define TARGET_MACHINE_DEPENDENT_REORG xstormy16_reorg
+#undef TARGET_LEGITIMATE_ADDRESS_P
+#define TARGET_LEGITIMATE_ADDRESS_P xstormy16_legitimate_address_p
+
struct gcc_target targetm = TARGET_INITIALIZER;
#include "gt-stormy16.h"
diff --git a/gcc/config/stormy16/stormy16.h b/gcc/config/stormy16/stormy16.h
index 675b94d9949..cb35a13ab6a 100644
--- a/gcc/config/stormy16/stormy16.h
+++ b/gcc/config/stormy16/stormy16.h
@@ -537,20 +537,6 @@ enum reg_class
#define MAX_REGS_PER_ADDRESS 1
#ifdef REG_OK_STRICT
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, LABEL) \
-do { \
- if (xstormy16_legitimate_address_p (MODE, X, 1)) \
- goto LABEL; \
-} while (0)
-#else
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, LABEL) \
-do { \
- if (xstormy16_legitimate_address_p (MODE, X, 0)) \
- goto LABEL; \
-} while (0)
-#endif
-
-#ifdef REG_OK_STRICT
#define REG_OK_FOR_BASE_P(X) \
(REGNO_OK_FOR_BASE_P (REGNO (X)) && (REGNO (X) < FIRST_PSEUDO_REGISTER))
#else
@@ -801,11 +787,4 @@ do { \
is responsible for updating the value of MORE (typically by (MORE)--). */
/* #define MD_SCHED_VARIABLE_ISSUE (FILE, VERBOSE, INSN, MORE) */
-
-/* Define the information needed to generate branch and scc insns. This is
- stored from the compare operation. Note that we can't use "rtx" here
- since it hasn't been defined! */
-
-extern struct rtx_def *xstormy16_compare_op0, *xstormy16_compare_op1;
-
/* End of xstormy16.h */
diff --git a/gcc/config/stormy16/stormy16.md b/gcc/config/stormy16/stormy16.md
index 43e454804a1..9c86d43e627 100644
--- a/gcc/config/stormy16/stormy16.md
+++ b/gcc/config/stormy16/stormy16.md
@@ -736,40 +736,7 @@
operands[0], operands[2], operands[3]);"
[(set_attr "length" "6,10")
(set_attr "psw_operand" "clobber,clobber")])
-
-;; ::::::::::::::::::::
-;; ::
-;; :: Comparisons
-;; ::
-;; ::::::::::::::::::::
-
-;; Note, we store the operands in the comparison insns, and use them later
-;; when generating the branch or scc operation.
-
-;; First the routines called by the machine independent part of the compiler
-(define_expand "cmphi"
- [(set (cc0)
- (compare (match_operand:HI 0 "register_operand" "")
- (match_operand:HI 1 "nonmemory_operand" "")))]
- ""
- {
- xstormy16_compare_op0 = operands[0];
- xstormy16_compare_op1 = operands[1];
- DONE;
- })
-; There are no real SImode comparisons, but some can be emulated
-; by performing a SImode subtract and looking at the condition flags.
-(define_expand "cmpsi"
- [(set (cc0)
- (compare (match_operand:SI 0 "register_operand" "")
- (match_operand:SI 1 "nonmemory_operand" "")))]
- ""
- {
- xstormy16_compare_op0 = operands[0];
- xstormy16_compare_op1 = operands[1];
- DONE;
- })
;; ::::::::::::::::::::
;; ::
@@ -777,55 +744,35 @@
;; ::
;; ::::::::::::::::::::
-(define_expand "beq"
- [(use (match_operand 0 "" ""))]
- ""
- { xstormy16_emit_cbranch (EQ, operands[0]); DONE; })
-
-(define_expand "bne"
- [(use (match_operand 0 "" ""))]
- ""
- { xstormy16_emit_cbranch (NE, operands[0]); DONE; })
-
-(define_expand "bge"
- [(use (match_operand 0 "" ""))]
- ""
- { xstormy16_emit_cbranch (GE, operands[0]); DONE; })
-
-(define_expand "bgt"
- [(use (match_operand 0 "" ""))]
- ""
- { xstormy16_emit_cbranch (GT, operands[0]); DONE; })
-
-(define_expand "ble"
- [(use (match_operand 0 "" ""))]
- ""
- { xstormy16_emit_cbranch (LE, operands[0]); DONE; })
-
-(define_expand "blt"
- [(use (match_operand 0 "" ""))]
- ""
- { xstormy16_emit_cbranch (LT, operands[0]); DONE; })
-
-(define_expand "bgeu"
- [(use (match_operand 0 "" ""))]
- ""
- { xstormy16_emit_cbranch (GEU, operands[0]); DONE; })
-
-(define_expand "bgtu"
- [(use (match_operand 0 "" ""))]
- ""
- { xstormy16_emit_cbranch (GTU, operands[0]); DONE; })
-
-(define_expand "bleu"
- [(use (match_operand 0 "" ""))]
+(define_expand "cbranchhi4"
+ [(set (pc)
+ (if_then_else (match_operator 0 "comparison_operator"
+ [(match_operand:HI 1 "register_operand" "")
+ (match_operand:HI 2 "nonmemory_operand" "")])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))
+ (clobber (reg:BI CARRY_REG))]
""
- { xstormy16_emit_cbranch (LEU, operands[0]); DONE; })
+ {
+ xstormy16_emit_cbranch (GET_CODE (operands[0]), operands[1], operands[2],
+ operands[3]);
+ DONE;
+})
-(define_expand "bltu"
- [(use (match_operand 0 "" ""))]
+(define_expand "cbranchsi4"
+ [(set (pc)
+ (if_then_else (match_operator 0 "comparison_operator"
+ [(match_operand:SI 1 "register_operand" "")
+ (match_operand:SI 2 "nonmemory_operand" "")])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))
+ (clobber (reg:BI CARRY_REG))]
""
- { xstormy16_emit_cbranch (LTU, operands[0]); DONE; })
+ {
+ xstormy16_emit_cbranch (GET_CODE (operands[0]), operands[1], operands[2],
+ operands[3]);
+ DONE;
+})
(define_insn "cbranchhi"
[(set (pc)
diff --git a/gcc/config/t-darwin b/gcc/config/t-darwin
index 09e63dded26..49dfa2ecce8 100644
--- a/gcc/config/t-darwin
+++ b/gcc/config/t-darwin
@@ -1,5 +1,5 @@
-# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007,
-# 2008 Free Software Foundation, Inc.
+# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+# Free Software Foundation, Inc.
#
# This file is part of GCC.
#
@@ -22,22 +22,24 @@ darwin.o: $(srcdir)/config/darwin.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
conditions.h insn-flags.h output.h insn-attr.h flags.h $(TREE_H) expr.h \
reload.h function.h $(GGC_H) langhooks.h $(TARGET_H) $(TM_P_H) gt-darwin.h \
config/darwin-sections.def
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/config/darwin.c
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $(srcdir)/config/darwin.c
darwin-c.o: $(srcdir)/config/darwin-c.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(CPPLIB_H) $(TREE_H) c-pragma.h $(C_TREE_H) toplev.h $(TM_P_H) \
incpath.h flags.h $(C_COMMON_H)
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/config/darwin-c.c $(PREPROCESSOR_DEFINES)
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $(srcdir)/config/darwin-c.c $(PREPROCESSOR_DEFINES)
darwin-f.o: $(srcdir)/config/darwin-f.c $(CONFIG_H) $(SYSTEM_H) coretypes.h
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
$(srcdir)/config/darwin-f.c $(PREPROCESSOR_DEFINES)
gt-darwin.h : s-gtype ; @true
darwin-driver.o: $(srcdir)/config/darwin-driver.c \
$(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(GCC_H)
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
$(srcdir)/config/darwin-driver.c
# How to build crt3.o
diff --git a/gcc/config/t-sol2 b/gcc/config/t-sol2
index a8c44a68ed3..28aa8651f25 100644
--- a/gcc/config/t-sol2
+++ b/gcc/config/t-sol2
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2008 Free Software Foundation, Inc.
+# Copyright (C) 2004, 2008, 2009 Free Software Foundation, Inc.
#
# This file is part of GCC.
#
@@ -20,11 +20,11 @@
sol2-c.o: $(srcdir)/config/sol2-c.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
tree.h c-format.h intl.h $(CPPLIB_H) c-pragma.h $(TM_H) $(TM_P_H) \
toplev.h $(C_COMMON_H)
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
$(srcdir)/config/sol2-c.c
# Solaris-specific attributes
sol2.o: $(srcdir)/config/sol2.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
tree.h $(TM_H) $(TM_P_H) toplev.h $(GGC_H)
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
$(srcdir)/config/sol2.c
diff --git a/gcc/config/t-vxworks b/gcc/config/t-vxworks
index 62cfb5b31a7..42eab72771f 100644
--- a/gcc/config/t-vxworks
+++ b/gcc/config/t-vxworks
@@ -50,4 +50,4 @@ EXTRA_MULTILIB_PARTS =
vxworks.o: $(srcdir)/config/vxworks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TARGET_H) toplev.h output.h $(TM_H)
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
diff --git a/gcc/config/v850/t-v850 b/gcc/config/v850/t-v850
index eca4c5cd59e..5c893d802e3 100644
--- a/gcc/config/v850/t-v850
+++ b/gcc/config/v850/t-v850
@@ -1,5 +1,5 @@
-# Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003,
-# 2008 Free Software Foundation, Inc.
+# Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2008, 2009
+# Free Software Foundation, Inc.
#
# This file is part of GCC.
#
@@ -109,7 +109,8 @@ TCFLAGS = -mno-app-regs -msmall-sld -Wa,-mwarn-signed-overflow -Wa,-mwarn-unsign
v850-c.o: $(srcdir)/config/v850/v850-c.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(CPPLIB_H) $(TREE_H) c-pragma.h toplev.h $(GGC_H) $(TM_P_H)
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/config/v850/v850-c.c
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $(srcdir)/config/v850/v850-c.c
# Local Variables:
# mode: Makefile
diff --git a/gcc/config/v850/t-v850e b/gcc/config/v850/t-v850e
index 1cfef87807b..9fcd897bb17 100644
--- a/gcc/config/v850/t-v850e
+++ b/gcc/config/v850/t-v850e
@@ -107,7 +107,8 @@ TCFLAGS = -mno-app-regs -msmall-sld -Wa,-mwarn-signed-overflow -Wa,-mwarn-unsign
v850-c.o: $(srcdir)/config/v850/v850-c.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(CPPLIB_H) $(TREE_H) c-pragma.h toplev.h $(GGC_H) $(TM_P_H)
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/config/v850/v850-c.c
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $(srcdir)/config/v850/v850-c.c
# Local Variables:
# mode: Makefile
diff --git a/gcc/config/v850/v850.c b/gcc/config/v850/v850.c
index a562202538b..0af2451341a 100644
--- a/gcc/config/v850/v850.c
+++ b/gcc/config/v850/v850.c
@@ -58,7 +58,7 @@ static void substitute_ep_register (rtx, rtx, int, int, rtx *, rtx *);
static void v850_reorg (void);
static int ep_memory_offset (enum machine_mode, int);
static void v850_set_data_area (tree, v850_data_area);
-const struct attribute_spec v850_attribute_table[];
+EXPORTED_CONST struct attribute_spec v850_attribute_table[];
static tree v850_handle_interrupt_attribute (tree *, tree, tree, int, bool *);
static tree v850_handle_data_area_attribute (tree *, tree, tree, int, bool *);
static void v850_insert_attributes (tree, tree *);
@@ -464,6 +464,11 @@ v850_rtx_costs (rtx x,
*total = 20;
return true;
+ case ZERO_EXTRACT:
+ if (outer_code == COMPARE)
+ *total = 0;
+ return false;
+
default:
return false;
}
diff --git a/gcc/config/v850/v850.md b/gcc/config/v850/v850.md
index dad3cdd885b..69c8d881f89 100644
--- a/gcc/config/v850/v850.md
+++ b/gcc/config/v850/v850.md
@@ -227,9 +227,11 @@
;; ----------------------------------------------------------------------
(define_insn "*v850_tst1"
- [(set (cc0) (zero_extract:SI (match_operand:QI 0 "memory_operand" "m")
- (const_int 1)
- (match_operand:QI 1 "const_int_operand" "n")))]
+ [(set (cc0)
+ (compare (zero_extract:SI (match_operand:QI 0 "memory_operand" "m")
+ (const_int 1)
+ (match_operand:QI 1 "const_int_operand" "n"))
+ (const_int 0)))]
""
"tst1 %1,%0"
[(set_attr "length" "4")
@@ -237,37 +239,52 @@
;; This replaces ld.b;sar;andi with tst1;setf nz.
-;; ??? The zero_extract sets the Z bit to the opposite of what one would
-;; expect. This perhaps should be wrapped in a (eq: X (const_int 0)).
-
(define_split
[(set (match_operand:SI 0 "register_operand" "")
- (zero_extract:SI (match_operand:QI 1 "memory_operand" "")
- (const_int 1)
- (match_operand 2 "const_int_operand" "")))]
- ""
- [(set (cc0) (zero_extract:SI (match_dup 1)
- (const_int 1)
- (match_dup 2)))
+ (compare (zero_extract:SI (match_operand:QI 1 "memory_operand" "")
+ (const_int 1)
+ (match_operand 2 "const_int_operand" ""))
+ (const_int 0)))]
+ ""
+ [(set (cc0) (compare (zero_extract:SI (match_dup 1)
+ (const_int 1)
+ (match_dup 2))
+ (const_int 0)))
(set (match_dup 0) (ne:SI (cc0) (const_int 0)))])
-(define_insn "tstsi"
- [(set (cc0) (match_operand:SI 0 "register_operand" "r"))]
- ""
- "cmp %.,%0"
- [(set_attr "length" "2")
- (set_attr "cc" "set_znv")])
+(define_expand "cbranchsi4"
+ [(set (cc0)
+ (compare (match_operand:SI 1 "register_operand" "")
+ (match_operand:SI 2 "reg_or_int5_operand" "")))
+ (set (pc)
+ (if_then_else
+ (match_operator 0 "ordered_comparison_operator" [(cc0)
+ (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
+ "")
+
+(define_expand "cstoresi4"
+ [(set (cc0)
+ (compare (match_operand:SI 2 "register_operand" "")
+ (match_operand:SI 3 "reg_or_int5_operand" "")))
+ (set (match_operand:SI 0 "register_operand")
+ (match_operator:SI 1 "ordered_comparison_operator" [(cc0)
+ (const_int 0)]))]
+ "")
-(define_insn "cmpsi"
+(define_insn "*cmpsi"
[(set (cc0)
- (compare (match_operand:SI 0 "register_operand" "r,r")
- (match_operand:SI 1 "reg_or_int5_operand" "r,J")))]
+ (compare (match_operand:SI 0 "register_operand" "r,r,r")
+ (match_operand:SI 1 "reg_or_int5_operand" "r,I,J")))]
""
"@
cmp %1,%0
+ cmp %.,%0
cmp %1,%0"
- [(set_attr "length" "2,2")
- (set_attr "cc" "compare")])
+ [(set_attr "length" "2,2,2")
+ (set_attr "cc" "compare,set_znv,compare")])
+
;; ----------------------------------------------------------------------
;; ADD INSTRUCTIONS
@@ -688,110 +705,25 @@
;; Scc INSTRUCTIONS
;; -----------------------------------------------------------------
-(define_insn "sle"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (le:SI (cc0) (const_int 0)))]
- ""
- "*
-{
- if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
- return 0;
-
- return \"setf le,%0\";
-}"
- [(set_attr "length" "4")
- (set_attr "cc" "none_0hit")])
-
-(define_insn "sleu"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (leu:SI (cc0) (const_int 0)))]
- ""
- "setf nh,%0"
- [(set_attr "length" "4")
- (set_attr "cc" "none_0hit")])
-
-(define_insn "sge"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (ge:SI (cc0) (const_int 0)))]
- ""
- "*
-{
- if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
- return 0;
-
- return \"setf ge,%0\";
-}"
- [(set_attr "length" "4")
- (set_attr "cc" "none_0hit")])
-
-(define_insn "sgeu"
+(define_insn "*setcc"
[(set (match_operand:SI 0 "register_operand" "=r")
- (geu:SI (cc0) (const_int 0)))]
- ""
- "setf nl,%0"
- [(set_attr "length" "4")
- (set_attr "cc" "none_0hit")])
-
-(define_insn "slt"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (lt:SI (cc0) (const_int 0)))]
- ""
- "*
-{
- if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
- return 0;
-
- return \"setf lt,%0\";
-}"
- [(set_attr "length" "4")
- (set_attr "cc" "none_0hit")])
-
-(define_insn "sltu"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (ltu:SI (cc0) (const_int 0)))]
- ""
- "setf l,%0"
- [(set_attr "length" "4")
- (set_attr "cc" "none_0hit")])
-
-(define_insn "sgt"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (gt:SI (cc0) (const_int 0)))]
+ (match_operator:SI 1 "comparison_operator"
+ [(cc0) (const_int 0)]))]
""
"*
{
- if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0)
+ if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
+ && (GET_CODE (operands[1]) == GT
+ || GET_CODE (operands[1]) == GE
+ || GET_CODE (operands[1]) == LE
+ || GET_CODE (operands[1]) == LT))
return 0;
- return \"setf gt,%0\";
+ return \"setf %c1,%0\";
}"
[(set_attr "length" "4")
(set_attr "cc" "none_0hit")])
-(define_insn "sgtu"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (gtu:SI (cc0) (const_int 0)))]
- ""
- "setf h,%0"
- [(set_attr "length" "4")
- (set_attr "cc" "none_0hit")])
-
-(define_insn "seq"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (eq:SI (cc0) (const_int 0)))]
- ""
- "setf z,%0"
- [(set_attr "length" "4")
- (set_attr "cc" "none_0hit")])
-
-(define_insn "sne"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (ne:SI (cc0) (const_int 0)))]
- ""
- "setf nz,%0"
- [(set_attr "length" "4")
- (set_attr "cc" "none_0hit")])
-
;; ----------------------------------------------------------------------
;; CONDITIONAL MOVE INSTRUCTIONS
;; ----------------------------------------------------------------------
@@ -800,25 +732,15 @@
;; hide the fact that this instruction uses cc0. We do so by including the
;; compare instruction inside it.
-;; ??? This is very ugly. The right way to do this is to modify cmpsi so
-;; that it doesn't emit RTL, and then modify the bcc/scc patterns so that
-;; they emit RTL for the compare instruction. Unfortunately, this requires
-;; lots of changes that will be hard to sanitize. So for now, cmpsi still
-;; emits RTL, and I get the compare operands here from the previous insn.
-
(define_expand "movsicc"
[(set (match_operand:SI 0 "register_operand" "=r")
(if_then_else:SI
- (match_operator 1 "comparison_operator"
- [(match_dup 4) (match_dup 5)])
+ (match_operand 1 "comparison_operator")
(match_operand:SI 2 "reg_or_const_operand" "rJ")
(match_operand:SI 3 "reg_or_const_operand" "rI")))]
"TARGET_V850E"
"
{
- rtx insn = get_last_insn_anywhere ();
- rtx src;
-
if ( (GET_CODE (operands[2]) == CONST_INT
&& GET_CODE (operands[3]) == CONST_INT))
{
@@ -845,28 +767,6 @@
if (GET_CODE (operands[3]) != REG)
operands[3] = copy_to_mode_reg (SImode, operands[3]);
}
- gcc_assert (GET_CODE (insn) == INSN
- && GET_CODE (PATTERN (insn)) == SET
- && SET_DEST (PATTERN (insn)) == cc0_rtx);
-
- src = SET_SRC (PATTERN (insn));
-
- switch (GET_CODE (src))
- {
- case COMPARE:
- operands[4] = XEXP (src, 0);
- operands[5] = XEXP (src, 1);
- break;
-
- case REG:
- case SUBREG:
- operands[4] = src;
- operands[5] = const0_rtx;
- break;
-
- default:
- gcc_unreachable ();
- }
}")
;; ??? Clobbering the condition codes is overkill.
@@ -1037,96 +937,6 @@
;; Conditional jump instructions
-(define_expand "ble"
- [(set (pc)
- (if_then_else (le (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "")
-
-(define_expand "bleu"
- [(set (pc)
- (if_then_else (leu (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "")
-
-(define_expand "bge"
- [(set (pc)
- (if_then_else (ge (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "")
-
-(define_expand "bgeu"
- [(set (pc)
- (if_then_else (geu (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "")
-
-(define_expand "blt"
- [(set (pc)
- (if_then_else (lt (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "")
-
-(define_expand "bltu"
- [(set (pc)
- (if_then_else (ltu (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "")
-
-(define_expand "bgt"
- [(set (pc)
- (if_then_else (gt (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "")
-
-(define_expand "bgtu"
- [(set (pc)
- (if_then_else (gtu (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "")
-
-(define_expand "beq"
- [(set (pc)
- (if_then_else (eq (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "")
-
-(define_expand "bne"
- [(set (pc)
- (if_then_else (ne (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "")
-
(define_insn "*branch_normal"
[(set (pc)
(if_then_else (match_operator 1 "comparison_operator"
@@ -1241,14 +1051,16 @@
{
rtx reg = gen_reg_rtx (SImode);
rtx tableaddress = gen_reg_rtx (SImode);
+ rtx test;
rtx mem;
/* Subtract the lower bound from the index. */
emit_insn (gen_subsi3 (reg, operands[0], operands[1]));
- /* Compare the result against the number of table entries. */
- emit_insn (gen_cmpsi (reg, operands[2]));
- /* Branch to the default label if out of range of the table. */
- emit_jump_insn (gen_bgtu (operands[4]));
+
+ /* Compare the result against the number of table entries;
+ branch to the default label if out of range of the table. */
+ test = gen_rtx_fmt_ee (GTU, VOIDmode, reg, operands[2]);
+ emit_jump_insn (gen_cbranchsi4 (test, reg, operands[2], operands[4]));
/* Shift index for the table array access. */
emit_insn (gen_ashlsi3 (reg, reg, GEN_INT (TARGET_BIG_SWITCH ? 2 : 1)));
diff --git a/gcc/config/vax/vax-protos.h b/gcc/config/vax/vax-protos.h
index 9b43d4f86e9..e9cc61687ca 100644
--- a/gcc/config/vax/vax-protos.h
+++ b/gcc/config/vax/vax-protos.h
@@ -21,11 +21,10 @@ extern void override_options (void);
extern bool legitimate_constant_address_p (rtx);
extern bool legitimate_constant_p (rtx);
-extern bool legitimate_pic_operand_p (rtx);
-extern bool legitimate_address_p (enum machine_mode, rtx, bool);
extern bool vax_mode_dependent_address_p (rtx);
#ifdef RTX_CODE
+extern const char *cond_name (rtx);
extern bool adjacent_operands_p (rtx, rtx, enum machine_mode);
extern const char *rev_cond_name (rtx);
extern void print_operand_address (FILE *, rtx);
@@ -35,7 +34,6 @@ extern void vax_expand_addsub_di_operands (rtx *, enum rtx_code);
extern const char * vax_output_int_move (rtx, rtx *, enum machine_mode);
extern const char * vax_output_int_add (rtx, rtx *, enum machine_mode);
extern const char * vax_output_int_subtract (rtx, rtx *, enum machine_mode);
-extern const char * vax_output_conditional_branch (enum rtx_code);
extern const char * vax_output_movmemsi (rtx, rtx *);
#endif /* RTX_CODE */
diff --git a/gcc/config/vax/vax.c b/gcc/config/vax/vax.c
index e91696947e6..a783b6f7131 100644
--- a/gcc/config/vax/vax.c
+++ b/gcc/config/vax/vax.c
@@ -46,6 +46,7 @@ along with GCC; see the file COPYING3. If not see
#include "target.h"
#include "target-def.h"
+static bool vax_legitimate_address_p (enum machine_mode, rtx, bool);
static void vax_output_function_prologue (FILE *, HOST_WIDE_INT);
static void vax_file_start (void);
static void vax_init_libfuncs (void);
@@ -94,6 +95,9 @@ static rtx vax_builtin_setjmp_frame_value (void);
#undef TARGET_BUILTIN_SETJMP_FRAME_VALUE
#define TARGET_BUILTIN_SETJMP_FRAME_VALUE vax_builtin_setjmp_frame_value
+#undef TARGET_LEGITIMATE_ADDRESS_P
+#define TARGET_LEGITIMATE_ADDRESS_P vax_legitimate_address_p
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* Set global variables as needed for the options enabled. */
@@ -129,7 +133,7 @@ vax_output_function_prologue (FILE * file, HOST_WIDE_INT size)
if (dwarf2out_do_frame ())
{
- const char *label = dwarf2out_cfi_label ();
+ const char *label = dwarf2out_cfi_label (false);
int offset = 0;
for (regno = FIRST_PSEUDO_REGISTER-1; regno >= 0; --regno)
@@ -428,6 +432,8 @@ print_operand (FILE *file, rtx x, int code)
fputc (ASM_DOUBLE_CHAR, file);
else if (code == '|')
fputs (REGISTER_PREFIX, file);
+ else if (code == 'c')
+ fputs (cond_name (x), file);
else if (code == 'C')
fputs (rev_cond_name (x), file);
else if (code == 'D' && CONST_INT_P (x) && INTVAL (x) < 0)
@@ -480,6 +486,37 @@ print_operand (FILE *file, rtx x, int code)
}
const char *
+cond_name (rtx op)
+{
+ switch (GET_CODE (op))
+ {
+ case NE:
+ return "neq";
+ case EQ:
+ return "eql";
+ case GE:
+ return "geq";
+ case GT:
+ return "gtr";
+ case LE:
+ return "leq";
+ case LT:
+ return "lss";
+ case GEU:
+ return "gequ";
+ case GTU:
+ return "gtru";
+ case LEU:
+ return "lequ";
+ case LTU:
+ return "lssu";
+
+ default:
+ gcc_unreachable ();
+ }
+}
+
+const char *
rev_cond_name (rtx op)
{
switch (GET_CODE (op))
@@ -1516,27 +1553,6 @@ vax_output_int_subtract (rtx insn, rtx *operands, enum machine_mode mode)
}
}
-/* Output a conditional branch. */
-const char *
-vax_output_conditional_branch (enum rtx_code code)
-{
- switch (code)
- {
- case EQ: return "jeql %l0";
- case NE: return "jneq %l0";
- case GT: return "jgtr %l0";
- case LT: return "jlss %l0";
- case GTU: return "jgtru %l0";
- case LTU: return "jlssu %l0";
- case GE: return "jgeq %l0";
- case LE: return "jleq %l0";
- case GEU: return "jgequ %l0";
- case LEU: return "jlequ %l0";
- default:
- gcc_unreachable ();
- }
-}
-
/* True if X is an rtx for a constant that is a valid address. */
bool
@@ -1719,7 +1735,7 @@ indexable_address_p (rtx xfoo0, rtx xfoo1, enum machine_mode mode, bool strict)
The MODE argument is the machine mode for the MEM expression
that wants to use this address. */
bool
-legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
+vax_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
{
rtx xfoo0, xfoo1;
diff --git a/gcc/config/vax/vax.h b/gcc/config/vax/vax.h
index 997029e0f62..e22fbd74386 100644
--- a/gcc/config/vax/vax.h
+++ b/gcc/config/vax/vax.h
@@ -540,11 +540,6 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES };
or if it is a pseudo reg. */
#define REG_OK_FOR_BASE_P(X) 1
-/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
- that is a valid memory address for an instruction. */
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
- { if (legitimate_address_p ((MODE), (X), 0)) goto ADDR; }
-
#else
/* Nonzero if X is a hard reg that can be used as an index. */
@@ -553,11 +548,6 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES };
/* Nonzero if X is a hard reg that can be used as a base reg. */
#define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X))
-/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
- that is a valid memory address for an instruction. */
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
- { if (legitimate_address_p ((MODE), (X), 1)) goto ADDR; }
-
#endif
/* Go to LABEL if ADDR (a legitimate address expression)
@@ -802,6 +792,7 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES };
VAX operand formatting codes:
letter print
+ c direct branch condition
C reverse branch condition
D 64-bit immediate operand
B the low 8 bits of the complement of a constant operand
diff --git a/gcc/config/vax/vax.md b/gcc/config/vax/vax.md
index da3ca48e90b..649f17e36ba 100644
--- a/gcc/config/vax/vax.md
+++ b/gcc/config/vax/vax.md
@@ -58,30 +58,16 @@
(include "constraints.md")
(include "predicates.md")
-;; We don't want to allow a constant operand for test insns because
-;; (set (cc0) (const_int foo)) has no mode information. Such insns will
-;; be folded while optimizing anyway.
-
-(define_insn "tst<mode>"
- [(set (cc0)
- (match_operand:VAXint 0 "nonimmediate_operand" "nrmT"))]
- ""
- "tst<VAXint:isfx> %0")
-
-(define_insn "tst<mode>"
+(define_insn "*cmp<mode>"
[(set (cc0)
- (match_operand:VAXfp 0 "general_operand" "gF"))]
+ (compare (match_operand:VAXint 0 "nonimmediate_operand" "nrmT,nrmT")
+ (match_operand:VAXint 1 "general_operand" "I,nrmT")))]
""
- "tst<VAXfp:fsfx> %0")
-
-(define_insn "cmp<mode>"
- [(set (cc0)
- (compare (match_operand:VAXint 0 "nonimmediate_operand" "nrmT")
- (match_operand:VAXint 1 "general_operand" "nrmT")))]
- ""
- "cmp<VAXint:isfx> %0,%1")
+ "@
+ tst<VAXint:isfx> %0
+ cmp<VAXint:isfx> %0,%1")
-(define_insn "cmp<mode>"
+(define_insn "*cmp<mode>"
[(set (cc0)
(compare (match_operand:VAXfp 0 "general_operand" "gF,gF")
(match_operand:VAXfp 1 "general_operand" "G,gF")))]
@@ -92,8 +78,9 @@
(define_insn "*bit<mode>"
[(set (cc0)
- (and:VAXint (match_operand:VAXint 0 "general_operand" "nrmT")
- (match_operand:VAXint 1 "general_operand" "nrmT")))]
+ (compare (and:VAXint (match_operand:VAXint 0 "general_operand" "nrmT")
+ (match_operand:VAXint 1 "general_operand" "nrmT"))
+ (const_int 0)))]
""
"bit<VAXint:isfx> %0,%1")
@@ -1078,21 +1065,45 @@
"jbr %l0")
;; Conditional jumps
-(define_code_iterator any_cond [eq ne gt lt gtu ltu ge le geu leu])
-(define_insn "b<code>"
+(define_expand "cbranch<mode>4"
+ [(set (cc0)
+ (compare (match_operand:VAXint 1 "nonimmediate_operand" "")
+ (match_operand:VAXint 2 "general_operand" "")))
+ (set (pc)
+ (if_then_else
+ (match_operator 0 "ordered_comparison_operator" [(cc0)
+ (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
+ "")
+
+(define_expand "cbranch<mode>4"
+ [(set (cc0)
+ (compare (match_operand:VAXfp 1 "general_operand" "")
+ (match_operand:VAXfp 2 "general_operand" "")))
+ (set (pc)
+ (if_then_else
+ (match_operator 0 "ordered_comparison_operator" [(cc0)
+ (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
+ "")
+
+(define_insn "*branch"
[(set (pc)
- (if_then_else (any_cond (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
+ (if_then_else (match_operator 0 "ordered_comparison_operator"
+ [(cc0)
+ (const_int 0)])
+ (label_ref (match_operand 1 "" ""))
(pc)))]
""
- "* return vax_output_conditional_branch (<CODE>);")
+ "j%c0 %l1")
;; Recognize reversed jumps.
-(define_insn ""
+(define_insn "*branch_reversed"
[(set (pc)
- (if_then_else (match_operator 0 "comparison_operator"
+ (if_then_else (match_operator 0 "ordered_comparison_operator"
[(cc0)
(const_int 0)])
(pc)
@@ -1452,6 +1463,8 @@
(match_operand 4 "" "")]
""
{
+ rtx test;
+
/* i = index - minimum_bound;
But only if the lower bound is not already zero. */
if (operands[1] != const0_rtx)
@@ -1463,9 +1476,9 @@
operands[0] = index;
}
- /* if (i > (maximum_bound - minimum_bound + 1) goto default; */
- emit_insn (gen_cmpsi (operands[0], operands[2]));
- emit_jump_insn (gen_bgtu (operands[4]));
+ /* if (i > (maximum_bound - minimum_bound + 1)) goto default; */
+ test = gen_rtx_fmt_ee (GTU, VOIDmode, operands[0], operands[2]);
+ emit_jump_insn (gen_cbranchsi4 (test, operands[0], operands[2], operands[4]));
/* casesi (i, 0, table); */
emit_jump_insn (gen_casesi1 (operands[0], operands[2], operands[3]));
diff --git a/gcc/config/x-darwin b/gcc/config/x-darwin
index c2ffd7d5c89..f671d911f0d 100644
--- a/gcc/config/x-darwin
+++ b/gcc/config/x-darwin
@@ -1,3 +1,3 @@
host-darwin.o : $(srcdir)/config/host-darwin.c $(CONFIG_H) $(SYSTEM_H) \
coretypes.h toplev.h config/host-darwin.h
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
diff --git a/gcc/config/x-hpux b/gcc/config/x-hpux
index fa0c5553c3d..e9f2f18f1b8 100644
--- a/gcc/config/x-hpux
+++ b/gcc/config/x-hpux
@@ -1,4 +1,4 @@
host-hpux.o : $(srcdir)/config/host-hpux.c $(CONFIG_H) $(SYSTEM_H) \
coretypes.h hosthooks.h hosthooks-def.h $(HOOKS_H)
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
$(srcdir)/config/host-hpux.c
diff --git a/gcc/config/x-linux b/gcc/config/x-linux
index e4aa040bceb..f87a45b24d9 100644
--- a/gcc/config/x-linux
+++ b/gcc/config/x-linux
@@ -1,4 +1,4 @@
host-linux.o : $(srcdir)/config/host-linux.c $(CONFIG_H) $(SYSTEM_H) \
coretypes.h hosthooks.h hosthooks-def.h $(HOOKS_H)
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
$(srcdir)/config/host-linux.c
diff --git a/gcc/config/x-solaris b/gcc/config/x-solaris
index 59c7bf61f5c..3e99df65748 100644
--- a/gcc/config/x-solaris
+++ b/gcc/config/x-solaris
@@ -1,4 +1,4 @@
host-solaris.o : $(srcdir)/config/host-solaris.c $(CONFIG_H) $(SYSTEM_H) \
coretypes.h hosthooks.h hosthooks-def.h $(HOOKS_H)
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
$(srcdir)/config/host-solaris.c
diff --git a/gcc/config/xtensa/predicates.md b/gcc/config/xtensa/predicates.md
index 2cb2a7d1757..27f058de796 100644
--- a/gcc/config/xtensa/predicates.md
+++ b/gcc/config/xtensa/predicates.md
@@ -167,6 +167,9 @@
(define_predicate "boolean_operator"
(match_code "eq,ne"))
+(define_predicate "xtensa_cstoresi_operator"
+ (match_code "eq,ne,gt,ge,lt,le"))
+
(define_predicate "tls_symbol_operand"
(and (match_code "symbol_ref")
(match_test "SYMBOL_REF_TLS_MODEL (op) != 0")))
diff --git a/gcc/config/xtensa/xtensa-protos.h b/gcc/config/xtensa/xtensa-protos.h
index 5f8cd74fe36..c60917f07ed 100644
--- a/gcc/config/xtensa/xtensa-protos.h
+++ b/gcc/config/xtensa/xtensa-protos.h
@@ -39,9 +39,9 @@ extern int smalloffset_mem_p (rtx);
extern int constantpool_address_p (rtx);
extern int constantpool_mem_p (rtx);
extern void xtensa_extend_reg (rtx, rtx);
-extern void xtensa_expand_conditional_branch (rtx *, enum rtx_code);
+extern void xtensa_expand_conditional_branch (rtx *, enum machine_mode);
extern int xtensa_expand_conditional_move (rtx *, int);
-extern int xtensa_expand_scc (rtx *);
+extern int xtensa_expand_scc (rtx *, enum machine_mode);
extern int xtensa_expand_block_move (rtx *);
extern void xtensa_split_operand_pair (rtx *, enum machine_mode);
extern int xtensa_emit_move_sequence (rtx *, enum machine_mode);
@@ -54,7 +54,6 @@ extern char *xtensa_emit_branch (bool, bool, rtx *);
extern char *xtensa_emit_bit_branch (bool, bool, rtx *);
extern char *xtensa_emit_movcc (bool, bool, bool, rtx *);
extern char *xtensa_emit_call (int, rtx *);
-extern bool xtensa_legitimate_address_p (enum machine_mode, rtx, bool);
extern bool xtensa_tls_referenced_p (rtx);
#ifdef TREE_CODE
diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c
index 50467b4602c..773223b2f35 100644
--- a/gcc/config/xtensa/xtensa.c
+++ b/gcc/config/xtensa/xtensa.c
@@ -71,13 +71,6 @@ enum internal_test
ITEST_MAX
};
-/* Cached operands, and operator to compare for use in set/branch on
- condition codes. */
-rtx branch_cmp[2];
-
-/* what type of branch to use */
-enum cmp_type branch_type;
-
/* Array giving truth value on whether or not a given hard register
can support a given mode. */
char xtensa_hard_regno_mode_ok[(int) MAX_MACHINE_MODE][FIRST_PSEUDO_REGISTER];
@@ -128,7 +121,7 @@ const enum reg_class xtensa_regno_to_class[FIRST_PSEUDO_REGISTER] =
static enum internal_test map_test_to_internal_test (enum rtx_code);
static rtx gen_int_relational (enum rtx_code, rtx, rtx, int *);
static rtx gen_float_relational (enum rtx_code, rtx, rtx);
-static rtx gen_conditional_move (rtx);
+static rtx gen_conditional_move (enum rtx_code, enum machine_mode, rtx, rtx);
static rtx fixup_subreg_mem (rtx);
static struct machine_function * xtensa_init_machine_status (void);
static rtx xtensa_legitimize_tls_address (rtx);
@@ -137,6 +130,7 @@ static bool xtensa_return_in_msb (const_tree);
static void printx (FILE *, signed int);
static void xtensa_function_epilogue (FILE *, HOST_WIDE_INT);
static rtx xtensa_builtin_saveregs (void);
+static bool xtensa_legitimate_address_p (enum machine_mode, rtx, bool);
static unsigned int xtensa_multibss_section_type_flags (tree, const char *,
int) ATTRIBUTE_UNUSED;
static section *xtensa_select_rtx_section (enum machine_mode, rtx,
@@ -230,6 +224,9 @@ static const int reg_nonleaf_alloc_order[FIRST_PSEUDO_REGISTER] =
#undef TARGET_CANNOT_FORCE_CONST_MEM
#define TARGET_CANNOT_FORCE_CONST_MEM xtensa_tls_referenced_p
+#undef TARGET_LEGITIMATE_ADDRESS_P
+#define TARGET_LEGITIMATE_ADDRESS_P xtensa_legitimate_address_p
+
struct gcc_target targetm = TARGET_INITIALIZER;
@@ -712,27 +709,27 @@ gen_float_relational (enum rtx_code test_code, /* relational test (EQ, etc) */
void
-xtensa_expand_conditional_branch (rtx *operands, enum rtx_code test_code)
+xtensa_expand_conditional_branch (rtx *operands, enum machine_mode mode)
{
- enum cmp_type type = branch_type;
- rtx cmp0 = branch_cmp[0];
- rtx cmp1 = branch_cmp[1];
+ enum rtx_code test_code = GET_CODE (operands[0]);
+ rtx cmp0 = operands[1];
+ rtx cmp1 = operands[2];
rtx cmp;
int invert;
rtx label1, label2;
- switch (type)
+ switch (mode)
{
- case CMP_DF:
+ case DFmode:
default:
fatal_insn ("bad test", gen_rtx_fmt_ee (test_code, VOIDmode, cmp0, cmp1));
- case CMP_SI:
+ case SImode:
invert = FALSE;
cmp = gen_int_relational (test_code, cmp0, cmp1, &invert);
break;
- case CMP_SF:
+ case SFmode:
if (!TARGET_HARD_FLOAT)
fatal_insn ("bad test", gen_rtx_fmt_ee (test_code, VOIDmode,
cmp0, cmp1));
@@ -743,7 +740,7 @@ xtensa_expand_conditional_branch (rtx *operands, enum rtx_code test_code)
/* Generate the branch. */
- label1 = gen_rtx_LABEL_REF (VOIDmode, operands[0]);
+ label1 = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
label2 = pc_rtx;
if (invert)
@@ -760,14 +757,13 @@ xtensa_expand_conditional_branch (rtx *operands, enum rtx_code test_code)
static rtx
-gen_conditional_move (rtx cmp)
+gen_conditional_move (enum rtx_code code, enum machine_mode mode,
+ rtx op0, rtx op1)
{
- enum rtx_code code = GET_CODE (cmp);
- rtx op0 = branch_cmp[0];
- rtx op1 = branch_cmp[1];
-
- if (branch_type == CMP_SI)
+ if (mode == SImode)
{
+ rtx cmp;
+
/* Jump optimization calls get_condition() which canonicalizes
comparisons like (GE x <const>) to (GT x <const-1>).
Transform those comparisons back to GE, since that is the
@@ -825,7 +821,7 @@ gen_conditional_move (rtx cmp)
return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
}
- if (TARGET_HARD_FLOAT && (branch_type == CMP_SF))
+ if (TARGET_HARD_FLOAT && mode == SFmode)
return gen_float_relational (code, op0, op1);
return 0;
@@ -835,36 +831,39 @@ gen_conditional_move (rtx cmp)
int
xtensa_expand_conditional_move (rtx *operands, int isflt)
{
- rtx cmp;
+ rtx dest = operands[0];
+ rtx cmp = operands[1];
+ enum machine_mode cmp_mode = GET_MODE (XEXP (cmp, 0));
rtx (*gen_fn) (rtx, rtx, rtx, rtx, rtx);
- if (!(cmp = gen_conditional_move (operands[1])))
+ if (!(cmp = gen_conditional_move (GET_CODE (cmp), cmp_mode,
+ XEXP (cmp, 0), XEXP (cmp, 1))))
return 0;
if (isflt)
- gen_fn = (branch_type == CMP_SI
+ gen_fn = (cmp_mode == SImode
? gen_movsfcc_internal0
: gen_movsfcc_internal1);
else
- gen_fn = (branch_type == CMP_SI
+ gen_fn = (cmp_mode == SImode
? gen_movsicc_internal0
: gen_movsicc_internal1);
- emit_insn (gen_fn (operands[0], XEXP (cmp, 0),
- operands[2], operands[3], cmp));
+ emit_insn (gen_fn (dest, XEXP (cmp, 0), operands[2], operands[3], cmp));
return 1;
}
int
-xtensa_expand_scc (rtx *operands)
+xtensa_expand_scc (rtx operands[4], enum machine_mode cmp_mode)
{
rtx dest = operands[0];
- rtx cmp = operands[1];
+ rtx cmp;
rtx one_tmp, zero_tmp;
rtx (*gen_fn) (rtx, rtx, rtx, rtx, rtx);
- if (!(cmp = gen_conditional_move (cmp)))
+ if (!(cmp = gen_conditional_move (GET_CODE (operands[1]), cmp_mode,
+ operands[2], operands[3])))
return 0;
one_tmp = gen_reg_rtx (SImode);
@@ -872,7 +871,7 @@ xtensa_expand_scc (rtx *operands)
emit_insn (gen_movsi (one_tmp, const_true_rtx));
emit_insn (gen_movsi (zero_tmp, const0_rtx));
- gen_fn = (branch_type == CMP_SI
+ gen_fn = (cmp_mode == SImode
? gen_movsicc_internal0
: gen_movsicc_internal1);
emit_insn (gen_fn (dest, XEXP (cmp, 0), one_tmp, zero_tmp, cmp));
@@ -2652,13 +2651,17 @@ xtensa_build_builtin_va_list (void)
tree f_stk, f_reg, f_ndx, record, type_decl;
record = (*lang_hooks.types.make_type) (RECORD_TYPE);
- type_decl = build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
+ type_decl = build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier ("__va_list_tag"), record);
- f_stk = build_decl (FIELD_DECL, get_identifier ("__va_stk"),
+ f_stk = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, get_identifier ("__va_stk"),
ptr_type_node);
- f_reg = build_decl (FIELD_DECL, get_identifier ("__va_reg"),
+ f_reg = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, get_identifier ("__va_reg"),
ptr_type_node);
- f_ndx = build_decl (FIELD_DECL, get_identifier ("__va_ndx"),
+ f_ndx = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, get_identifier ("__va_ndx"),
integer_type_node);
DECL_FIELD_CONTEXT (f_stk) = record;
@@ -2849,8 +2852,8 @@ xtensa_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
lab_over = NULL;
if (!targetm.calls.must_pass_in_stack (TYPE_MODE (type), type))
{
- lab_false = create_artificial_label ();
- lab_over = create_artificial_label ();
+ lab_false = create_artificial_label (UNKNOWN_LOCATION);
+ lab_over = create_artificial_label (UNKNOWN_LOCATION);
t = build2 (GT_EXPR, boolean_type_node, unshare_expr (ndx),
build_int_cst (integer_type_node,
@@ -2880,7 +2883,7 @@ xtensa_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
__array = (AP).__va_stk;
} */
- lab_false2 = create_artificial_label ();
+ lab_false2 = create_artificial_label (UNKNOWN_LOCATION);
t = build2 (GT_EXPR, boolean_type_node, unshare_expr (orig_ndx),
build_int_cst (integer_type_node,
diff --git a/gcc/config/xtensa/xtensa.h b/gcc/config/xtensa/xtensa.h
index 73f68ef315f..ec5dde1726c 100644
--- a/gcc/config/xtensa/xtensa.h
+++ b/gcc/config/xtensa/xtensa.h
@@ -27,17 +27,6 @@ extern int optimize;
/* External variables defined in xtensa.c. */
-/* comparison type */
-enum cmp_type {
- CMP_SI, /* four byte integers */
- CMP_DI, /* eight byte integers */
- CMP_SF, /* single precision floats */
- CMP_DF, /* double precision floats */
- CMP_MAX /* max comparison type */
-};
-
-extern struct rtx_def * branch_cmp[2]; /* operands for compare */
-extern enum cmp_type branch_type; /* what type of branch to use */
extern unsigned xtensa_current_frame_size;
/* Macros used in the machine description to select various Xtensa
@@ -782,13 +771,6 @@ typedef struct xtensa_args
/* Maximum number of registers that can appear in a valid memory address. */
#define MAX_REGS_PER_ADDRESS 1
-/* Identify valid Xtensa addresses. */
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, ADDR, LABEL) \
- do { \
- if (xtensa_legitimate_address_p (MODE, ADDR, REG_OK_STRICT_FLAG)) \
- goto LABEL; \
- } while (0)
-
/* A C expression that is 1 if the RTX X is a constant which is a
valid address. This is defined to be the same as 'CONSTANT_P (X)',
but rejecting CONST_DOUBLE. */
diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md
index 63c5db5b476..13883f1d5ca 100644
--- a/gcc/config/xtensa/xtensa.md
+++ b/gcc/config/xtensa/xtensa.md
@@ -64,15 +64,6 @@
(define_code_attr minmax [(smin "min") (umin "minu")
(smax "max") (umax "maxu")])
-;; This code iterator allows all branch instructions to be generated from
-;; a single define_expand template.
-(define_code_iterator any_cond [eq ne gt ge lt le gtu geu ltu leu
- uneq ltgt ungt unge unlt unle
- unordered ordered])
-
-;; This code iterator is for setting a register from a comparison.
-(define_code_iterator any_scc [eq ne gt ge lt le])
-
;; This code iterator is for floating-point comparisons.
(define_code_iterator any_scc_sf [eq lt le uneq unlt unle unordered])
(define_code_attr scc_sf [(eq "oeq") (lt "olt") (le "ole")
@@ -1131,44 +1122,27 @@
;; Comparisons.
-;; Handle comparisons by stashing away the operands and then using that
-;; information in the subsequent conditional branch.
+;; Conditional branches.
-(define_expand "cmpsi"
- [(set (cc0)
- (compare:CC (match_operand:SI 0 "register_operand" "")
- (match_operand:SI 1 "nonmemory_operand" "")))]
+(define_expand "cbranchsi4"
+ [(match_operator 0 "comparison_operator"
+ [(match_operand:SI 1 "register_operand")
+ (match_operand:SI 2 "nonmemory_operand")])
+ (match_operand 3 "")]
""
{
- branch_cmp[0] = operands[0];
- branch_cmp[1] = operands[1];
- branch_type = CMP_SI;
+ xtensa_expand_conditional_branch (operands, SImode);
DONE;
})
-(define_expand "cmpsf"
- [(set (cc0)
- (compare:CC (match_operand:SF 0 "register_operand" "")
- (match_operand:SF 1 "register_operand" "")))]
+(define_expand "cbranchsf4"
+ [(match_operator 0 "comparison_operator"
+ [(match_operand:SF 1 "register_operand")
+ (match_operand:SF 2 "register_operand")])
+ (match_operand 3 "")]
"TARGET_HARD_FLOAT"
{
- branch_cmp[0] = operands[0];
- branch_cmp[1] = operands[1];
- branch_type = CMP_SF;
- DONE;
-})
-
-
-;; Conditional branches.
-
-(define_expand "b<code>"
- [(set (pc)
- (if_then_else (any_cond (cc0) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
-{
- xtensa_expand_conditional_branch (operands, <CODE>);
+ xtensa_expand_conditional_branch (operands, SFmode);
DONE;
})
@@ -1353,18 +1327,31 @@
;; Setting a register from a comparison.
-(define_expand "s<code>"
- [(set (match_operand:SI 0 "register_operand" "")
- (any_scc:SI (match_dup 1)
- (match_dup 2)))]
+(define_expand "cstoresi4"
+ [(match_operand:SI 0 "register_operand")
+ (match_operator 1 "xtensa_cstoresi_operator"
+ [(match_operand:SI 2 "register_operand")
+ (match_operand:SI 3 "nonmemory_operand")])]
""
{
- operands[1] = gen_rtx_<CODE> (SImode, branch_cmp[0], branch_cmp[1]);
- if (!xtensa_expand_scc (operands))
+ if (!xtensa_expand_scc (operands, SImode))
FAIL;
DONE;
})
+(define_expand "cstoresf4"
+ [(match_operand:SI 0 "register_operand")
+ (match_operator:SI 1 "comparison_operator"
+ [(match_operand:SF 2 "register_operand")
+ (match_operand:SF 3 "register_operand")])]
+ "TARGET_HARD_FLOAT"
+{
+ if (!xtensa_expand_scc (operands, SFmode))
+ FAIL;
+ DONE;
+})
+
+
;; Conditional moves.
diff --git a/gcc/configure b/gcc/configure
index 6033f33b6c7..8713f15ebd5 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -21823,6 +21823,45 @@ cat >>confdefs.h <<_ACEOF
_ACEOF
+echo "$as_me:$LINENO: checking assembler for line table discriminator support" >&5
+echo $ECHO_N "checking assembler for line table discriminator support... $ECHO_C" >&6
+if test "${gcc_cv_as_discriminator+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ gcc_cv_as_discriminator=no
+ if test $in_tree_gas = yes; then
+ if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 19 \) \* 1000 + 51`
+ then gcc_cv_as_discriminator=yes
+fi
+ elif test x$gcc_cv_as != x; then
+ echo ' .text
+ .file 1 "conf.c"
+ .loc 1 1 0 discriminator 1' > conftest.s
+ if { ac_try='$gcc_cv_as -o conftest.o conftest.s >&5'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }
+ then
+ gcc_cv_as_discriminator=yes
+ else
+ echo "configure: failed program was" >&5
+ cat conftest.s >&5
+ fi
+ rm -f conftest.o conftest.s
+ fi
+fi
+echo "$as_me:$LINENO: result: $gcc_cv_as_discriminator" >&5
+echo "${ECHO_T}$gcc_cv_as_discriminator" >&6
+if test $gcc_cv_as_discriminator = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_GAS_DISCRIMINATOR 1
+_ACEOF
+
+fi
+
# Thread-local storage - the check is heavily parameterized.
conftest_s=
tls_first_major=
@@ -21984,6 +22023,22 @@ x:
tls_first_minor=16
tls_as_opt='-32 --fatal-warnings'
;;
+ m68k-*-*)
+ conftest_s='
+ .section .tdata,"awT",@progbits
+x:
+ .word 2
+ .text
+foo:
+ move.l x@TLSGD(%a5),%a0
+ move.l x@TLSLDM(%a5),%a0
+ move.l x@TLSLDO(%a5),%a0
+ move.l x@TLSIE(%a5),%a0
+ move.l x@TLSLE(%a5),%a0'
+ tls_first_major=2
+ tls_first_minor=19
+ tls_as_opt='--fatal-warnings'
+ ;;
powerpc-*-*)
conftest_s='
.section ".tdata","awT",@progbits
@@ -22615,6 +22670,44 @@ fi
i[34567]86-*-* | x86_64-*-*)
case $target_os in
cygwin* | pe | mingw32*)
+ # Recent binutils allows the three-operand form of ".comm" on PE. This
+ # definition is used unconditionally to initialise the default state of
+ # the target option variable that governs usage of the feature.
+ echo "$as_me:$LINENO: checking assembler for .comm with alignment" >&5
+echo $ECHO_N "checking assembler for .comm with alignment... $ECHO_C" >&6
+if test "${gcc_cv_as_comm_has_align+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ gcc_cv_as_comm_has_align=no
+ if test $in_tree_gas = yes; then
+ if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 19 \) \* 1000 + 52`
+ then gcc_cv_as_comm_has_align=yes
+fi
+ elif test x$gcc_cv_as != x; then
+ echo '.comm foo,1,32' > conftest.s
+ if { ac_try='$gcc_cv_as -o conftest.o conftest.s >&5'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }
+ then
+ gcc_cv_as_comm_has_align=yes
+ else
+ echo "configure: failed program was" >&5
+ cat conftest.s >&5
+ fi
+ rm -f conftest.o conftest.s
+ fi
+fi
+echo "$as_me:$LINENO: result: $gcc_cv_as_comm_has_align" >&5
+echo "${ECHO_T}$gcc_cv_as_comm_has_align" >&6
+
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_GAS_ALIGNED_COMM `if test $gcc_cv_as_comm_has_align = yes; then echo 1; else echo 0; fi`
+_ACEOF
+
# Used for DWARF 2 in PE
echo "$as_me:$LINENO: checking assembler for .secrel32 relocs" >&5
echo $ECHO_N "checking assembler for .secrel32 relocs... $ECHO_C" >&6
@@ -24786,6 +24879,14 @@ fi
+case "${GMPLIBS}" in
+ *-lmpc*)
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_mpc 1
+_ACEOF
+ ;;
+esac
+
diff --git a/gcc/configure.ac b/gcc/configure.ac
index 5f9276cbc74..f637a11a50a 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -2408,6 +2408,15 @@ AC_DEFINE_UNQUOTED(HAVE_COMDAT_GROUP,
[`if test $gcc_cv_as_comdat_group = yes || test $gcc_cv_as_comdat_group_percent = yes; then echo 1; else echo 0; fi`],
[Define 0/1 if your assembler and linker support COMDAT groups.])
+gcc_GAS_CHECK_FEATURE([line table discriminator support],
+ gcc_cv_as_discriminator,
+ [2,19,51],,
+[ .text
+ .file 1 "conf.c"
+ .loc 1 1 0 discriminator 1],,
+[AC_DEFINE(HAVE_GAS_DISCRIMINATOR, 1,
+ [Define if your assembler supports the .loc discriminator sub-directive.])])
+
# Thread-local storage - the check is heavily parameterized.
conftest_s=
tls_first_major=
@@ -2570,6 +2579,22 @@ x:
tls_first_minor=16
tls_as_opt='-32 --fatal-warnings'
;;
+ m68k-*-*)
+ conftest_s='
+ .section .tdata,"awT",@progbits
+x:
+ .word 2
+ .text
+foo:
+ move.l x@TLSGD(%a5),%a0
+ move.l x@TLSLDM(%a5),%a0
+ move.l x@TLSLDO(%a5),%a0
+ move.l x@TLSIE(%a5),%a0
+ move.l x@TLSLE(%a5),%a0'
+ tls_first_major=2
+ tls_first_minor=19
+ tls_as_opt='--fatal-warnings'
+ ;;
powerpc-*-*)
conftest_s='
.section ".tdata","awT",@progbits
@@ -2938,6 +2963,15 @@ changequote(,)dnl
changequote([,])dnl
case $target_os in
cygwin* | pe | mingw32*)
+ # Recent binutils allows the three-operand form of ".comm" on PE. This
+ # definition is used unconditionally to initialise the default state of
+ # the target option variable that governs usage of the feature.
+ gcc_GAS_CHECK_FEATURE([.comm with alignment], gcc_cv_as_comm_has_align,
+ [2,19,52],,[.comm foo,1,32])
+ AC_DEFINE_UNQUOTED(HAVE_GAS_ALIGNED_COMM,
+ [`if test $gcc_cv_as_comm_has_align = yes; then echo 1; else echo 0; fi`],
+ [Define if your assembler supports specifying the alignment
+ of objects allocated using the GAS .comm command.])
# Used for DWARF 2 in PE
gcc_GAS_CHECK_FEATURE([.secrel32 relocs],
gcc_cv_as_ix86_pe_secrel32,
@@ -4015,6 +4049,10 @@ fi
AC_ARG_VAR(GMPLIBS,[How to link GMP])
AC_ARG_VAR(GMPINC,[How to find GMP include files])
+case "${GMPLIBS}" in
+ *-lmpc*) AC_DEFINE(HAVE_mpc, 1, [Define if mpc is in use.]) ;;
+esac
+
AC_ARG_VAR(PPLLIBS,[How to link PPL])
AC_ARG_VAR(PPLINC,[How to find PPL include files])
diff --git a/gcc/coverage.c b/gcc/coverage.c
index 47bc71e4df1..ebdc696218b 100644
--- a/gcc/coverage.c
+++ b/gcc/coverage.c
@@ -418,7 +418,8 @@ coverage_counter_alloc (unsigned counter, unsigned num)
tree gcov_type_array_type
= build_array_type (gcov_type_node, NULL_TREE);
tree_ctr_tables[counter]
- = build_decl (VAR_DECL, NULL_TREE, gcov_type_array_type);
+ = build_decl (BUILTINS_LOCATION,
+ VAR_DECL, NULL_TREE, gcov_type_array_type);
TREE_STATIC (tree_ctr_tables[counter]) = 1;
ASM_GENERATE_INTERNAL_LABEL (buf, "LPBX", counter + 1);
DECL_NAME (tree_ctr_tables[counter]) = get_identifier (buf);
@@ -639,10 +640,12 @@ build_fn_info_type (unsigned int counters)
tree array_type;
/* ident */
- fields = build_decl (FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ());
+ fields = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ());
/* checksum */
- field = build_decl (FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ());
+ field = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ());
TREE_CHAIN (field) = fields;
fields = field;
@@ -651,7 +654,8 @@ build_fn_info_type (unsigned int counters)
array_type = build_array_type (get_gcov_unsigned_t (), array_type);
/* counters */
- field = build_decl (FIELD_DECL, NULL_TREE, array_type);
+ field = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, NULL_TREE, array_type);
TREE_CHAIN (field) = fields;
fields = field;
@@ -714,12 +718,14 @@ build_ctr_info_type (void)
tree gcov_merge_fn_type;
/* counters */
- field = build_decl (FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ());
+ field = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ());
TREE_CHAIN (field) = fields;
fields = field;
/* values */
- field = build_decl (FIELD_DECL, NULL_TREE, gcov_ptr_type);
+ field = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, NULL_TREE, gcov_ptr_type);
TREE_CHAIN (field) = fields;
fields = field;
@@ -728,7 +734,8 @@ build_ctr_info_type (void)
build_function_type_list (void_type_node,
gcov_ptr_type, get_gcov_unsigned_t (),
NULL_TREE);
- field = build_decl (FIELD_DECL, NULL_TREE,
+ field = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, NULL_TREE,
build_pointer_type (gcov_merge_fn_type));
TREE_CHAIN (field) = fields;
fields = field;
@@ -780,7 +787,8 @@ build_ctr_info_value (unsigned int counter, tree type)
value = tree_cons (fields, null_pointer_node, value);
fields = TREE_CHAIN (fields);
- fn = build_decl (FUNCTION_DECL,
+ fn = build_decl (BUILTINS_LOCATION,
+ FUNCTION_DECL,
get_identifier (ctr_merge_functions[counter]),
TREE_TYPE (TREE_TYPE (fields)));
DECL_EXTERNAL (fn) = 1;
@@ -825,20 +833,23 @@ build_gcov_info (void)
const_type = build_qualified_type (type, TYPE_QUAL_CONST);
/* Version ident */
- field = build_decl (FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ());
+ field = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ());
TREE_CHAIN (field) = fields;
fields = field;
value = tree_cons (field, build_int_cstu (TREE_TYPE (field), GCOV_VERSION),
value);
/* next -- NULL */
- field = build_decl (FIELD_DECL, NULL_TREE, build_pointer_type (const_type));
+ field = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, NULL_TREE, build_pointer_type (const_type));
TREE_CHAIN (field) = fields;
fields = field;
value = tree_cons (field, null_pointer_node, value);
/* stamp */
- field = build_decl (FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ());
+ field = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ());
TREE_CHAIN (field) = fields;
fields = field;
value = tree_cons (field, build_int_cstu (TREE_TYPE (field), local_tick),
@@ -847,7 +858,8 @@ build_gcov_info (void)
/* Filename */
string_type = build_pointer_type (build_qualified_type (char_type_node,
TYPE_QUAL_CONST));
- field = build_decl (FIELD_DECL, NULL_TREE, string_type);
+ field = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, NULL_TREE, string_type);
TREE_CHAIN (field) = fields;
fields = field;
da_file_name_len = strlen (da_file_name);
@@ -882,7 +894,8 @@ build_gcov_info (void)
fn_info_value = null_pointer_node;
/* number of functions */
- field = build_decl (FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ());
+ field = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ());
TREE_CHAIN (field) = fields;
fields = field;
value = tree_cons (field,
@@ -890,13 +903,15 @@ build_gcov_info (void)
value);
/* fn_info table */
- field = build_decl (FIELD_DECL, NULL_TREE, fn_info_ptr_type);
+ field = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, NULL_TREE, fn_info_ptr_type);
TREE_CHAIN (field) = fields;
fields = field;
value = tree_cons (field, fn_info_value, value);
/* counter_mask */
- field = build_decl (FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ());
+ field = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ());
TREE_CHAIN (field) = fields;
fields = field;
value = tree_cons (field,
@@ -917,7 +932,8 @@ build_gcov_info (void)
ctr_info_value = build_constructor_from_list (ctr_info_ary_type,
nreverse (ctr_info_value));
- field = build_decl (FIELD_DECL, NULL_TREE, ctr_info_ary_type);
+ field = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, NULL_TREE, ctr_info_ary_type);
TREE_CHAIN (field) = fields;
fields = field;
value = tree_cons (field, ctr_info_value, value);
@@ -947,7 +963,8 @@ create_coverage (void)
t = build_gcov_info ();
- gcov_info = build_decl (VAR_DECL, NULL_TREE, TREE_TYPE (t));
+ gcov_info = build_decl (BUILTINS_LOCATION,
+ VAR_DECL, NULL_TREE, TREE_TYPE (t));
TREE_STATIC (gcov_info) = 1;
ASM_GENERATE_INTERNAL_LABEL (name_buf, "LPBX", 0);
DECL_NAME (gcov_info) = get_identifier (name_buf);
@@ -959,7 +976,8 @@ create_coverage (void)
/* Build a decl for __gcov_init. */
t = build_pointer_type (TREE_TYPE (gcov_info));
t = build_function_type_list (void_type_node, t, NULL);
- t = build_decl (FUNCTION_DECL, get_identifier ("__gcov_init"), t);
+ t = build_decl (BUILTINS_LOCATION,
+ FUNCTION_DECL, get_identifier ("__gcov_init"), t);
TREE_PUBLIC (t) = 1;
DECL_EXTERNAL (t) = 1;
gcov_init = t;
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 602b152f3c6..62f93a98526 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,513 @@
+2009-06-16 David Edelsohn <edelsohn@gnu.org>
+
+ * g++-spec.c (LIBSTDCXX_STATIC): Default to NULL.
+ (lang_specific_driver): Always allocate extra argument.
+ Add LIBSTDCXX_STATIC to arglist if defined and linking
+ statically.
+
+2009-06-16 Ian Lance Taylor <iant@google.com>
+
+ * Make-lang.in (cp/class.o): Depend upon gt-cp-class.h.
+ (cp/semantics.o): Depend upon gt-cp-semantics.h.
+
+2009-06-16 Ian Lance Taylor <iant@google.com>
+
+ * parser.c (cp_unevaluated_operand): Define global variable.
+ (cp_parser_question_colon_clause): Increment
+ c_inhibit_evaluation_warnings when evaluating an expression which
+ will never be executed.
+ (cp_parser_decltype): Increment cp_unevaluated_operand and
+ c_inhibit_evaluation_warnings, not skip_evaluation.
+ (cp_parser_sizeof_operand): Likewise.
+ (cp_parser_enclosed_template_argument_list): Save
+ cp_unevaluated_operand and c_inhibit_evaluation_warnings, not
+ skip_evaluation.
+ * cp-tree.h (struct saved_scope): Remove skip_evaluation field.
+ Add unevaluated_operand and inhibit_evaluation_warnings fields.
+ (cp_unevaluated_operand): Declare.
+ * name-lookup.c (push_to_top_level): Save cp_unevaluated_operand
+ and c_inhibit_evaluation_warnings rather than skip_evaluation.
+ (pop_from_top_level): Restore cp_unevaluated_operand and
+ c_inhibit_evaluation_warnings rather than skip_evaluation.
+ * class.c (build_base_path): Check cp_unevaluated_operand rather
+ than skip_evaluation.
+ * typeck.c (build_class_member_access_expr): Likewise.
+ (cp_build_binary_op): Don't warn about bad shift counts if
+ c_inhibit_evaluation_warnings is non-zero.
+ * pt.c (coerce_template_parms): Save state of
+ cp_unevaluated_operand and c_inhibit_evaluation_warnings, not
+ skip_evaluation.
+ (tsubst_aggr_type): Likewise.
+ (tsubst_pack_expansion): Check cp_unevaluated_operand rather than
+ skip_evaluation.
+ (tsubst_copy): Likewise.
+ (tsubst): Set cp_unevaluated_operand and
+ c_inhibit_evaluation_warnings, not skip_evaluation.
+ (tsubst_copy_and_build): Likewise.
+ * call.c (convert_arg_to_ellipsis): Check cp_unevaluated_operand
+ rather than skip_evaluation.
+ * decl2.c (mark_used): Likewise.
+ * semantics.c (finish_non_static_data_member): Likewise.
+ * cvt.c (cp_convert_and_check): Check
+ c_inhibit_evaluation_warnings rather than skip_evaluation.
+ * mangle.c (write_type): Set cp_unevaluated_operand rather than
+ skip_evaluation.
+
+2009-06-15 Ian Lance Taylor <iant@google.com>
+
+ * parser.c (cp_parser_direct_declarator): Add braces around
+ variables declared before label.
+
+2009-06-15 Rafael Avila de Espindola <espindola@google.com>
+
+ * cp-objcp-common.h (LANG_HOOKS_COMDAT_GROUP): Remove.
+ * cp-tree.h (cxx_comdat_group): Change signature.
+ * decl.c (duplicate_decls): Use DECL_COMDAT_GROUP.
+ (cxx_comdat_group): Change signature.
+ * decl2.c (comdat_linkage, maybe_make_one_only): Update call to
+ make_decl_one_only.
+ (constrain_visibility, get_guard): Use DECL_COMDAT_GROUP.
+ * method.c (use_thunk): Update call to make_decl_one_only.
+ * optimize.c (maybe_clone_body): Use DECL_COMDAT_GROUP
+
+2009-06-12 Aldy Hernandez <aldyh@redhat.com>
+
+ * typeck.c (cp_build_binary_op): Pass location to overflow_warning.
+ (build_modify_expr): New arg.
+ * semantics.c (finish_unary_op_expr): Pass location to
+ overflow_warning.
+ (handle_omp_for_class_iterator): Pass location to build_modify_expr.
+ * typeck.c (cxx_sizeof_or_alignof_type): Pass location to
+ c_sizeof_or_alignof_type.
+ (build_array_ref): New argument.
+ (build_compound_expr): Same.
+ (build_const_cast): Same.
+ (build_ptrmemfunc): Pass location to build_c_cast.
+ * init.c (avoid_placement_new_aliasing): Pass location to
+ build_stmt.
+ (build_vec_delete_1): Pass location to cp_build_modify_expr,
+ build_compound_expr.
+ * class.c (build_vtbl_ref_1): Pass location to build_array_ref.
+ * decl.c (poplevel): Pass location to c_build_bind_expr.
+ (finish_case_label): Pass location to build_case_label.
+ (finish_constructor_body): Same.
+ (finish_destructor_body): Pass location to build_stmt.
+ (cxx_maybe_build_cleanup): Same, but to build_compound_expr.
+ * call.c (build_new_op): Pass location to build_array_ref.
+ (build_x_va_arg): Pass location to build_va_arg.
+ * except.c (expand_end_catch_block): Pass location to
+ build_stmt.
+ * cp-tree.h (build_array_ref): New argument.
+ (build_compound_expr): Same.
+ (build_c_cast): Same.
+ * cp-gimplify.c (gimplify_if_stmt): Pass location on down.
+ (gimplify_switch_stmt): Same.
+ * typeck2.c (split_nonconstant_init_1): Same.
+ * pt.c (tsubst_copy): Same.
+ * semantics.c (add_decl_expr): Same.
+ (do_poplevel): Same.
+ (push_cleanup): Same.
+ (finish_goto_stmt): Same.
+ (finish_expr_stmt): Same.
+ (begin_if_stmt): Same.
+ (begin_while_stmt): Same.
+ (begin_do_stmt): Same.
+ (finish_return_stmt): Same.
+ (begin_for_stmt): Same.
+ (finish_break_stmt): Same.
+ (finish_continue_stmt): Same.
+ (begin_switch_stmt): Same.
+ (begin_try_block): Same.
+ (begin_handler): Same.
+ (finish_asm_stmt): Same.
+ (finish_label_stmt): Same.
+ (finish_stmt_expr_expr): Same.
+ (finalize_nrv_r): Same.
+ (finish_omp_atomic): Same.
+ * name-lookup.c (do_using_directive): Same.
+ * decl2.c (grok_array_decl): Same.
+ * parser.c (cp_parser_cast_expression): Same.
+ (cp_parser_selection_statement): Same.
+ (cp_parser_implicitly_scoped_statement): Same.
+ (cp_parser_objc_selector_expression): Same.
+ (cp_parser_objc_synchronized_statement): Same.
+ (cp_parser_objc_throw_statement): Same.
+ (cp_parser_omp_critical): Same.
+ (cp_parser_omp_master): Same.
+ * typeck.c (build_function_call): Add location argument.
+ * init.c: Add location argument to all build_decl calls.
+ * class.c: Same.
+ * method.c: Same.
+ * rtti.c: Same.
+ * tree.c: Same.
+ * pt.c: Same.
+ * semantics.c: Same.
+ * lex.c: Same.
+ * decl2.c: Same.
+ * cp-gimplify.c: Same.
+ * decl.c: Same.
+ (cp_make_fname_decl): Add location argument. Pass location ot
+ build_decl.
+ (finish_case_label): Same.
+ * cp-tree.h (finish_case_label): Add location argument.
+ * parser.c (cp_parser_label_for_labeled_statement): Pass location to
+ finish_case_label.
+
+2009-06-09 Jason Merrill <jason@redhat.com>
+
+ PR c++/40381
+ * decl2.c (mark_used): Return after complaining about deleted fn.
+
+2009-06-08 Jason Merrill <jason@redhat.com>
+
+ * parser.c (cp_parser_type_id_1): 'auto' type is ok with a
+ late-specified return type.
+
+2009-06-08 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/40373
+ * call.c (check_dtor_name): Return false even if
+ get_type_value (name) is error_mark_node.
+
+ PR c++/40370
+ PR c++/40372
+ * parser.c (cp_parser_direct_declarator): Don't set TREE_SIDE_EFFECTS
+ on error_mark_node. Check for VLAs outside of function context
+ before check whether to wrap bounds into a NOP_EXPR with
+ TREE_SIDE_EFFECTS.
+
+2009-06-08 Alexandre Oliva <aoliva@redhat.com>
+
+ * repo.c (get_base_filename): Use aux_base_name rather than
+ alternate temporary file during second compare debug compilation.
+ (finish_repo): Skip during -fcompare-debug-second.
+
+2009-06-06 Ian Lance Taylor <iant@google.com>
+
+ * parser.c (cp_parser_label_for_labeled_statement): Support
+ attribute on labels if immediately followed by semicolon.
+ * semantics.c (finish_label_stmt): Return new label.
+ * pt.c (tsubst_expr): Handle attributes for LABEL_EXPR.
+
+2009-06-03 Ian Lance Taylor <iant@google.com>
+
+ * Make-lang.in (cc1plus-checksum.o): Depend upon $(CONFIG_H) and
+ $(SYSTEM_H).
+
+2009-06-02 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (maybe_deduce_size_from_array_init): Use relayout_decl.
+
+2009-06-02 Jason Merrill <jason@redhat.com>
+
+ PR c++/40308
+ PR c++/40311
+ * typeck.c (cp_build_modify_expr): Always pass init-lists to the
+ conversion code.
+ * call.c (implicit_conversion): Allow init-list conversion to scalar
+ during direct-initialization, too. Mark the conversion bad if it
+ has too many levels of braces.
+ (convert_like_real): And give a helpful error.
+
+ PR c++/40306
+ PR c++/40307
+ * decl.c (cp_finish_decl): Handle auto deduction from ().
+ * typeck.c (build_x_indirect_ref): Handle dereferencing an operand
+ with dependent type that is known to be a pointer.
+
+2009-06-02 Simon Martin <simartin@users.sourceforge.net>
+
+ PR c++/38089
+ * pt.c (register_specialization): Properly setup DECL_CONTEXT for
+ specializations in an invalid namespace.
+
+2009-06-01 Aldy Hernandez <aldyh@redhat.com>
+
+ * error.c (print_instantiation_partial_context): Print column
+ numbers.
+
+2009-05-29 Ian Lance Taylor <iant@google.com>
+
+ * error.c (cp_printer): Don't use va_arg with enum type.
+
+2009-05-28 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/39754
+ * cp-tree.h (canonical_type_variant): Remove this function declaration.
+ (strip_typedefs): New function declaration.
+ * tree.c (strip_typedefs): New function definition.
+ (canonical_type_variant): Remove function definition.
+ * cvt.c (convert_from_reference): No need to use
+ canonical_type_variant.
+ * typeck.c (cp_build_indirect_ref): Likewise.
+ * error.c (dump_template_bindings): Use strip_typedefs instead of
+ canonical_type_variant.
+ * pt.c (convert_template_argument, unify): Likewise.
+ * mangle.c (canonicalize_for_substitution): Don't use
+ canonical_type_variant.
+
+2009-05-27 Jason Merrill <jason@redhat.com>
+
+ * call.c (implicit_conversion): Handle conversion from
+ initializer-list to scalar.
+ (convert_like_real): Likewise. Avoid crashing on list
+ initialization with bad conversions.
+ (can_convert): Use LOOKUP_EXPLICIT.
+ (can_convert_arg_bad): Add flags parm.
+ * cp-tree.h: Adjust.
+ * typeck.c (convert_for_assignment): Pass flags.
+
+2009-05-27 Ian Lance Taylor <iant@google.com>
+
+ * Make-lang.in (g++$(exeext)): Change $(COMPILER) to $(LINKER).
+ (cc1plus-dummy$(exeext), cc1plus$(exeext)): Likewise.
+
+2009-05-26 Ian Lance Taylor <iant@google.com>
+
+ * Make-lang.in (g++spec.o): Use $(COMPILER).
+ (g++$(exeext), cc1plus-dummy$(exeext)): Likewise.
+ (cc1plus$(exeext)): Likewise.
+
+2009-05-26 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/40007
+ * cp-tree.h (MEMBER_TYPES_NEEDING_ACCESS_CHECK): Remove this accessor.
+ (TI_TYPEDEFS_NEEDING_ACCESS_CHECKING): New accessor.
+ (get_types_needing_access_check): Declare new entry point.
+ * pt.c (append_type_to_template_for_access_check_1,
+ get_types_needing_access_check): New functions.
+ (perform_typedefs_access_check): Accept FUNCTION_DECLs and
+ RECORD_TYPEs rather than TEMPLATE_DECLs. Use the new
+ get_types_needing_access_check, no more
+ MEMBER_TYPES_NEEDING_ACCESS_CHECK.
+ (instantiate_class_template): Set input_location to the source
+ location of the most specialized template definition.
+ Perform access check using the RECORD_TYPE of the template, not its
+ associated most generic TEMPLATE_DECL.
+ (append_type_to_template_for_access_check): Augment function
+ comments. Use the new get_types_needing_access_check, not
+ MEMBER_TYPE_NEEDING_ACCESS_CHECK. Use the new
+ append_type_to_template_for_access_check_1 subroutine.
+
+2009-05-22 Jason Merrill <jason@redhat.com>
+
+ PR c++/38064
+ * typeck.c (cp_build_binary_op): Allow ENUMERAL_TYPE in
+ arithmetic comparisons.
+ (cp_common_type): Handle scoped enums.
+
+ * call.c (promoted_arithmetic_type_p): Don't use INTEGRAL_TYPE_P.
+ (add_builtin_candidate, add_builtin_candidates): Likewise.
+ (convert_like_real): Likewise.
+ * class.c (check_bitfield_decl): Likewise.
+ * decl.c (check_static_variable_definition): Likewise.
+ (compute_array_index_type): Likewise.
+ * decl2.c (grokbitfield): Likewise.
+ * init.c (build_new_1): Likewise.
+ * pt.c (convert_nontype_argument): Likewise.
+ (current_instantiation): Likewise.
+ * tree.c (pod_type_p): Likewise.
+ * typeck.c (build_static_cast_1): Likewise.
+ (build_reinterpret_cast_1): Likewise.
+
+2009-05-22 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/38964
+ * init.c (avoid_placement_new_aliasing): Remove.
+ (build_new_1): Do not call it.
+
+2009-05-22 Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (decl_needed_p): Consider dllexport'd functions needed.
+ * semantics.c (expand_or_defer_fn): Similarly.
+
+2009-05-20 Ian Lance Taylor <iant@google.com>
+
+ * parser.c (cp_parser_postfix_expression): Change args to a vec.
+ Release it when done.
+ (tree_vector): Define typedef. Define VEC functions.
+ (cp_parser_parenthesized_expression_list): Change return type to
+ vec. Change all callers.
+ (cp_parser_new_expression): Change placement and initializer to
+ vecs. Release them when done.
+ (cp_parser_new_placement): Change return type to vec. Change all
+ callers.
+ (cp_parser_new_initializer): Likewise.
+ * typeck.c (build_function_call_vec): Just call
+ cp_build_function_call_vec.
+ (cp_build_function_call): Just build a vec and call
+ cp_build_function_call_vec.
+ (cp_build_function_call_vec): New function based on old
+ cp_build_function_call.
+ (convert_arguments): Remove nargs and argarray parameters. Change
+ values to a vec. Change caller.
+ (build_x_compound_expr_from_vec): New function.
+ (cp_build_modify_expr): Build vec to pass to
+ build_special_member_call.
+ * call.c (struct z_candidate): Add first_arg field. Change args
+ field to vec.
+ (convert_class_to_reference): Handle first argument separately.
+ (add_candidate): Add first_arg parameter. Change args parameter
+ to vec. Change all callers.
+ (add_function_candidate, add_conv_candidate): Likewise.
+ (add_template_candidate_real, add_template_candidate): Likewise.
+ (add_template_conv_candidate): Likewise.
+ (build_user_type_conversion_1): Handle first argument separately.
+ (resolve_args): Change return type and parameter type to vecs.
+ Change all callers.
+ (perform_overload_resolution): Change args parameter to vec.
+ Change all callers.
+ (build_new_function_call, build_operator_new_call): Likewise.
+ (add_candidates): Likewise.
+ (build_op_call): New globally visible function, built from and
+ replacing static function build_object_call.
+ (build_new_op): Don't handle CALL_EXPR. Build vec, not tree_list,
+ of arguments.
+ (build_op_delete_call): Build vec to pass to
+ cp_build_function_call_vec.
+ (build_temp): Build vec to pass to build_special_member_call.
+ (convert_like_real): Likewise.
+ (perform_direct_initialization_if_possible): Likewise.
+ (build_over_call): Handle first_arg field. Use build_call_array
+ rather than build_call_list.
+ (build_special_member_call): Change args parameter to vec. Change
+ all callers.
+ (build_new_method_call): Likewise.
+ * init.c (expand_default_init): Change parms to vec.
+ (build_raw_new_expr): Change placement and init to vecs. Change
+ all callers.
+ (build_new_1, build_new): Likewise.
+ * class.c (resolve_address_of_overloaded_function): Build array to
+ pass to fn_type_unification.
+ * pt.c (tsubst_copy_and_build): For NEW_EXPR build vecs to pass to
+ build_new. For CALL_EXPR create a vec rather than a tree_list;
+ expand a pack if necessary.
+ (fn_type_unification): Change args parameter to const tree *. Add
+ nargs parameter. Change all callers.
+ (type_unification_real): Likewise.
+ (unify): Build array to pass to type_unification_real.
+ (get_bindings): Build array to pass to fn_type_unification.
+ (any_type_dependent_arguments_p): Change args parameter to a vec.
+ Change all callers.
+ (make_args_non_dependent): Renamed from build_non_dependent_args.
+ Change return type to void. Change parameter type to vec. Change
+ all callers.
+ (do_auto_deduction): Pass an array to type_unification_real.
+ * semantics.c (perform_koenig_lookup): Change args to vec. Change
+ all callers.
+ (finish_call_expr): Change args to vec. Change all callers. Call
+ build_op_call instead of passing CALL_EXPR to build_new_op.
+ (cxx_omp_create_clause_info): Allocate vec to pass to
+ build_special_member_call.
+ * decl2.c (build_offset_ref_call_from_tree): Change args parameter
+ to vec. Change all callers.
+ * name-lookup.c (lookup_function_nonclass): Likewise.
+ (struct arg_lookup): Change args to vec.
+ (arg_assoc_namespace): Handle args as a vec.
+ (arg_assoc_args_vec): New static function.
+ (lookup_arg_dependent): Change args parameter to vec. Change all
+ callers.
+ * method.c (do_build_assign_ref): Allocate vec to pass to
+ build_special_member_call.
+ * except.c (build_throw): Likewise.
+ * typeck2.c (build_functional_cast): Likewise.
+ * cvt.c (ocp_convert): Likewise.
+ * tree.c (build_min_non_dep_call_vec): Change last parameter to
+ vec. Change all callers.
+ * cp-tree.h: Update declarations.
+ * name-lookup.h: Update declarations.
+
+2009-05-20 Sandra Loosemore <sandra@codesourcery.com>
+
+ * typeck.c (default_conversion): Check targetm.promoted_type.
+ * decl.c (grokdeclarator): Check targetm.invalid_return_type.
+ (grokparms): Check targetm.invalid_parameter_type.
+ * cvt.c (ocp_convert): Check targetm.convert_to_type.
+ (build_expr_type_conversion): Check targetm.promoted_type.
+
+2009-05-19 Andrew Pinski <andrew_pinski@playstation.sony.com>
+
+ * typeck.c (build_binary_op): Allow % on integal vectors.
+
+2009-05-18 Jason Merrill <jason@redhat.com>
+
+ Implement explicit conversions ops as specified in N2437.
+ * decl.c (grokdeclarator): Handle explicit conversion ops.
+ (check_initializer): Pass flags to store_init_value.
+ * decl2.c (maybe_emit_vtables): Likewise.
+ * init.c (expand_aggr_init_1): Likewise.
+ * call.c (convert_class_to_reference): Take flags parm,
+ check DECL_NONCONVERTING_P.
+ (build_user_type_conversion_1): Check DECL_NONCONVERTING_P.
+ (add_builtin_candidates): Simplify getting type of conversion.
+ (build_object_call): Likewise. Check DECL_NONCONVERTING_P.
+ (implicit_conversion): Pass through LOOKUP_ONLYCONVERTING.
+ (reference_binding): Take flags parm. Direct-initialize copy parm.
+ (add_function_candidate): Direct-initialize the copy parm.
+ (add_conv_candidate): Use LOOKUP_IMPLICIT, not LOOKUP_NORMAL.
+ (build_builtin_candidate): Add LOOKUP_ONLYCONVERTING.
+ (conditional_conversion): Likewise.
+ (convert_like_real): Only complain about DECL_NONCONVERTING_P
+ constructors.
+ (perform_implicit_conversion_flags): Add flags parm to
+ perform_implicit_conversion. Improve diagnostics.
+ * cp-tree.h (LOOKUP_IMPLICIT): New macro.
+ (LOOKUP_COPY_PARM): New bit macro.
+ * cvt.c (build_expr_type_conversion): Check DECL_NONCONVERTING_P.
+ * typeck.c (convert_for_assignment): Take flags parm, pass it to
+ perform_implicit_conversion_flags.
+ (cp_build_modify_expr): Pass flags to convert_for_assignment.
+ (convert_for_initialization): Likewise.
+ * typeck2.c (store_init_value): Take flags parm, pass to
+ digest_init_flags.
+ (digest_init_flags): Add flags parm to digest_init.
+ (digest_init_r): Take flags parm, pass to convert_for_initialization.
+ (process_init_constructor_array): Pass it.
+ (process_init_constructor_record): Likewise.
+ (process_init_constructor_union): Likewise.
+
+2009-05-16 Jason Merrill <jason@redhat.com>
+
+ PR c++/40139
+ * pt.c (tsubst_qualified_id): Retain the type if we aren't dealing
+ with a dependent type. Actually look up the destructor.
+ * semantics.c (finish_id_expression): Fix logic.
+ (finish_qualified_id_expr): Don't try to use 'this' if we aren't in
+ a function.
+ * typeck.c (build_x_unary_op): Diagnose taking the address of a
+ constructor or destructor.
+ * tree.c (get_first_fn): Handle OFFSET_REF.
+
+2009-05-17 Joseph Myers <joseph@codesourcery.com>
+
+ * tree.c (cxx_printable_name_internal): Allow consecutive
+ translated and untranslated cached copies of the name of the
+ current function.
+
+2009-05-15 Ian Lance Taylor <iant@google.com>
+
+ * cp-tree.h (enum cp_lvalue_kind_flags): Rename from
+ cp_lvalue_kind. Change all uses.
+ (enum base_access_flags): Rename from enum base_access. Change
+ all uses.
+ * parser.c (enum cp_parser_flags): Remove enum tag.
+
+2009-05-15 Manuel López-Ibáñez <manu@gcc.gnu.org>
+
+ PR 16302
+ * call.c (build_new_op): Update calls to warn_logical_operator.
+
+2009-05-14 Ian Lance Taylor <iant@google.com>
+
+ * class.c (layout_class_type): Change itk to unsigned int.
+ * decl.c (finish_enum): Change itk to unsigned int.
+ * parser.c (cp_parser_check_decl_spec): Change ds to int. Remove
+ casts.
+
+2009-05-13 David Mandelin <dmandelin@mozilla.com>:
+
+ * decl.c (duplicate_decls): Preserve parameter attributes.
+
2009-05-10 Jan Hubicka <jh@suse.cz>
* decl2.c (cxx_callgraph_analyze_expr): Use
diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in
index aadaae6e044..2c562f873f6 100644
--- a/gcc/cp/Make-lang.in
+++ b/gcc/cp/Make-lang.in
@@ -1,6 +1,6 @@
# Top level -*- makefile -*- fragment for GNU C++.
# Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-# 2005, 2007, 2008
+# 2005, 2007, 2008, 2009
# Free Software Foundation, Inc.
#This file is part of GCC.
@@ -54,13 +54,13 @@ c++: cc1plus$(exeext)
g++spec.o: $(srcdir)/cp/g++spec.c $(SYSTEM_H) coretypes.h $(TM_H) $(GCC_H) $(CONFIG_H)
(SHLIB_LINK='$(SHLIB_LINK)'; \
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(DRIVER_DEFINES) \
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(DRIVER_DEFINES) \
$(INCLUDES) $(srcdir)/cp/g++spec.c)
# Create the compiler driver for g++.
GXX_OBJS = $(GCC_OBJS) g++spec.o intl.o prefix.o version.o
g++$(exeext): $(GXX_OBJS) $(EXTRA_GCC_OBJS) $(LIBDEPS)
- $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ \
+ $(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
$(GXX_OBJS) $(EXTRA_GCC_OBJS) $(LIBS)
# Create a version of the g++ driver which calls the cross-compiler.
@@ -92,16 +92,16 @@ c++_OBJS = $(CXX_OBJS) dummy-checksum.o cc1plus-checksum.o cp/g++spec.o
cp-warn = $(STRICT_WARN)
cc1plus-dummy$(exeext): $(CXX_OBJS) dummy-checksum.o $(BACKEND) $(LIBDEPS)
- $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ \
+ $(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
$(CXX_OBJS) dummy-checksum.o $(BACKEND) $(LIBS) $(BACKENDLIBS)
cc1plus-checksum.c : cc1plus-dummy$(exeext) build/genchecksum$(build_exeext)
build/genchecksum$(build_exeext) cc1plus-dummy$(exeext) > $@
-cc1plus-checksum.o : cc1plus-checksum.c
+cc1plus-checksum.o : cc1plus-checksum.c $(CONFIG_H) $(SYSTEM_H)
cc1plus$(exeext): $(CXX_OBJS) cc1plus-checksum.o $(BACKEND) $(LIBDEPS)
- $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ \
+ $(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
$(CXX_OBJS) cc1plus-checksum.o $(BACKEND) $(LIBS) $(BACKENDLIBS)
# Special build rules.
@@ -253,7 +253,7 @@ cp/typeck2.o: cp/typeck2.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) toplev.h output.h \
cp/typeck.o: cp/typeck.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) $(RTL_H) $(EXPR_H) \
toplev.h $(DIAGNOSTIC_H) convert.h $(C_COMMON_H) $(TARGET_H)
cp/class.o: cp/class.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) toplev.h $(RTL_H) \
- $(TARGET_H) convert.h $(CGRAPH_H) $(TREE_DUMP_H)
+ $(TARGET_H) convert.h $(CGRAPH_H) $(TREE_DUMP_H) gt-cp-class.h
cp/call.o: cp/call.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) toplev.h $(RTL_H) \
$(EXPR_H) $(DIAGNOSTIC_H) intl.h gt-cp-call.h convert.h $(TARGET_H) langhooks.h
cp/friend.o: cp/friend.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) $(RTL_H) toplev.h \
@@ -284,7 +284,8 @@ cp/repo.o: cp/repo.c $(CXX_TREE_H) $(TM_H) toplev.h $(DIAGNOSTIC_H) \
gt-cp-repo.h
cp/semantics.o: cp/semantics.c $(CXX_TREE_H) $(TM_H) except.h toplev.h \
$(FLAGS_H) debug.h output.h $(RTL_H) $(TIMEVAR_H) $(EXPR_H) \
- $(TREE_INLINE_H) $(CGRAPH_H) $(TARGET_H) $(C_COMMON_H) $(GIMPLE_H)
+ $(TREE_INLINE_H) $(CGRAPH_H) $(TARGET_H) $(C_COMMON_H) $(GIMPLE_H) \
+ gt-cp-semantics.h
cp/dump.o: cp/dump.c $(CXX_TREE_H) $(TM_H) $(TREE_DUMP_H)
cp/optimize.o: cp/optimize.c $(CXX_TREE_H) $(TM_H) rtl.h $(INTEGRATE_H) \
insn-config.h input.h $(PARAMS_H) debug.h $(TREE_INLINE_H) $(GIMPLE_H) \
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index ee13ba2a414..e89d5857edc 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -145,8 +145,7 @@ static tree convert_like_real (conversion *, tree, tree, int, int, bool,
bool, tsubst_flags_t);
static void op_error (enum tree_code, enum tree_code, tree, tree,
tree, const char *);
-static tree build_object_call (tree, tree, tsubst_flags_t);
-static tree resolve_args (tree);
+static VEC(tree,gc) *resolve_args (VEC(tree,gc) *);
static struct z_candidate *build_user_type_conversion_1 (tree, tree, int);
static void print_z_candidate (const char *, struct z_candidate *);
static void print_z_candidates (struct z_candidate *);
@@ -154,13 +153,14 @@ static tree build_this (tree);
static struct z_candidate *splice_viable (struct z_candidate *, bool, bool *);
static bool any_strictly_viable (struct z_candidate *);
static struct z_candidate *add_template_candidate
- (struct z_candidate **, tree, tree, tree, tree, tree,
- tree, tree, int, unification_kind_t);
+ (struct z_candidate **, tree, tree, tree, tree, const VEC(tree,gc) *,
+ tree, tree, tree, int, unification_kind_t);
static struct z_candidate *add_template_candidate_real
- (struct z_candidate **, tree, tree, tree, tree, tree,
- tree, tree, int, tree, unification_kind_t);
+ (struct z_candidate **, tree, tree, tree, tree, const VEC(tree,gc) *,
+ tree, tree, tree, int, tree, unification_kind_t);
static struct z_candidate *add_template_conv_candidate
- (struct z_candidate **, tree, tree, tree, tree, tree, tree);
+ (struct z_candidate **, tree, tree, tree, const VEC(tree,gc) *, tree,
+ tree, tree);
static void add_builtin_candidates
(struct z_candidate **, enum tree_code, enum tree_code,
tree, tree *, int);
@@ -172,9 +172,11 @@ static void build_builtin_candidate
(struct z_candidate **, tree, tree, tree, tree *, tree *,
int);
static struct z_candidate *add_conv_candidate
- (struct z_candidate **, tree, tree, tree, tree, tree);
+ (struct z_candidate **, tree, tree, tree, const VEC(tree,gc) *, tree,
+ tree);
static struct z_candidate *add_function_candidate
- (struct z_candidate **, tree, tree, tree, tree, tree, int);
+ (struct z_candidate **, tree, tree, tree, const VEC(tree,gc) *, tree,
+ tree, int);
static conversion *implicit_conversion (tree, tree, tree, bool, int);
static conversion *standard_conversion (tree, tree, tree, bool, int);
static conversion *reference_binding (tree, tree, tree, bool, int);
@@ -184,20 +186,20 @@ static bool is_subseq (conversion *, conversion *);
static conversion *maybe_handle_ref_bind (conversion **);
static void maybe_handle_implicit_object (conversion **);
static struct z_candidate *add_candidate
- (struct z_candidate **, tree, tree, size_t,
+ (struct z_candidate **, tree, tree, const VEC(tree,gc) *, size_t,
conversion **, tree, tree, int);
static tree source_type (conversion *);
static void add_warning (struct z_candidate *, struct z_candidate *);
static bool reference_related_p (tree, tree);
static bool reference_compatible_p (tree, tree);
-static conversion *convert_class_to_reference (tree, tree, tree);
+static conversion *convert_class_to_reference (tree, tree, tree, int);
static conversion *direct_reference_binding (tree, conversion *);
static bool promoted_arithmetic_type_p (tree);
static conversion *conditional_conversion (tree, tree);
static char *name_as_c_string (tree, tree, bool *);
static tree call_builtin_trap (void);
static tree prep_operand (tree);
-static void add_candidates (tree, tree, tree, bool, tree, tree,
+static void add_candidates (tree, const VEC(tree,gc) *, tree, bool, tree, tree,
int, struct z_candidate **);
static conversion *merge_conversion_sequences (conversion *, conversion *);
static bool magic_varargs_p (tree);
@@ -240,7 +242,7 @@ check_dtor_name (tree basetype, tree name)
return false;
}
- if (!name)
+ if (!name || name == error_mark_node)
return false;
return same_type_p (TYPE_MAIN_VARIANT (basetype), TYPE_MAIN_VARIANT (name));
}
@@ -413,8 +415,13 @@ struct z_candidate {
/* The FUNCTION_DECL that will be called if this candidate is
selected by overload resolution. */
tree fn;
- /* The arguments to use when calling this function. */
- tree args;
+ /* If not NULL_TREE, the first argument to use when calling this
+ function. */
+ tree first_arg;
+ /* The rest of the arguments to use when calling this function. If
+ there are no further arguments this may be NULL or it may be an
+ empty vector. */
+ const VEC(tree,gc) *args;
/* The implicit conversion sequences for each of the arguments to
FN. */
conversion **convs;
@@ -993,10 +1000,10 @@ reference_compatible_p (tree t1, tree t2)
converted to T as in [over.match.ref]. */
static conversion *
-convert_class_to_reference (tree reference_type, tree s, tree expr)
+convert_class_to_reference (tree reference_type, tree s, tree expr, int flags)
{
tree conversions;
- tree arglist;
+ tree first_arg;
conversion *conv;
tree t;
struct z_candidate *candidates;
@@ -1029,12 +1036,11 @@ convert_class_to_reference (tree reference_type, tree s, tree expr)
error messages, which we should not issue now because we are just
trying to find a conversion operator. Therefore, we use NULL,
cast to the appropriate type. */
- arglist = build_int_cst (build_pointer_type (s), 0);
- arglist = build_tree_list (NULL_TREE, arglist);
+ first_arg = build_int_cst (build_pointer_type (s), 0);
t = TREE_TYPE (reference_type);
- while (conversions)
+ for (; conversions; conversions = TREE_CHAIN (conversions))
{
tree fns = TREE_VALUE (conversions);
@@ -1043,6 +1049,10 @@ convert_class_to_reference (tree reference_type, tree s, tree expr)
tree f = OVL_CURRENT (fns);
tree t2 = TREE_TYPE (TREE_TYPE (f));
+ if (DECL_NONCONVERTING_P (f)
+ && (flags & LOOKUP_ONLYCONVERTING))
+ continue;
+
cand = NULL;
/* If this is a template function, try to get an exact
@@ -1052,7 +1062,8 @@ convert_class_to_reference (tree reference_type, tree s, tree expr)
cand = add_template_candidate (&candidates,
f, s,
NULL_TREE,
- arglist,
+ first_arg,
+ NULL,
reference_type,
TYPE_BINFO (s),
TREE_PURPOSE (conversions),
@@ -1077,8 +1088,8 @@ convert_class_to_reference (tree reference_type, tree s, tree expr)
}
else if (TREE_CODE (t2) == REFERENCE_TYPE
&& reference_compatible_p (t, TREE_TYPE (t2)))
- cand = add_function_candidate (&candidates, f, s, arglist,
- TYPE_BINFO (s),
+ cand = add_function_candidate (&candidates, f, s, first_arg,
+ NULL, TYPE_BINFO (s),
TREE_PURPOSE (conversions),
LOOKUP_NORMAL);
@@ -1101,7 +1112,6 @@ convert_class_to_reference (tree reference_type, tree s, tree expr)
cand->second_conv->bad_p |= cand->convs[0]->bad_p;
}
}
- conversions = TREE_CHAIN (conversions);
}
candidates = splice_viable (candidates, pedantic, &any_viable_p);
@@ -1116,9 +1126,9 @@ convert_class_to_reference (tree reference_type, tree s, tree expr)
/* Now that we know that this is the function we're going to use fix
the dummy first argument. */
- cand->args = tree_cons (NULL_TREE,
- build_this (expr),
- TREE_CHAIN (cand->args));
+ gcc_assert (cand->first_arg == NULL_TREE
+ || integer_zerop (cand->first_arg));
+ cand->first_arg = build_this (expr);
/* Build a user-defined conversion sequence representing the
conversion. */
@@ -1303,7 +1313,7 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags)
the reference is bound to the lvalue result of the conversion
in the second case. */
- conv = convert_class_to_reference (rto, from, expr);
+ conv = convert_class_to_reference (rto, from, expr, flags);
if (conv)
return conv;
}
@@ -1347,6 +1357,12 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags)
conversion operator). */
flags |= LOOKUP_NO_TEMP_BIND;
+ /* Temporaries are copy-initialized, except for this hack to allow
+ explicit conversion ops to the copy ctor. See also
+ add_function_candidate. */
+ if (!(flags & LOOKUP_COPY_PARM))
+ flags |= LOOKUP_ONLYCONVERTING;
+
conv = implicit_conversion (to, from, expr, c_cast_p,
flags);
if (!conv)
@@ -1384,9 +1400,37 @@ implicit_conversion (tree to, tree from, tree expr, bool c_cast_p,
if (conv)
return conv;
- if (is_std_init_list (to) && expr
- && BRACE_ENCLOSED_INITIALIZER_P (expr))
- return build_list_conv (to, expr, flags);
+ if (expr && BRACE_ENCLOSED_INITIALIZER_P (expr))
+ {
+ if (is_std_init_list (to))
+ return build_list_conv (to, expr, flags);
+
+ /* Allow conversion from an initializer-list with one element to a
+ scalar type. */
+ if (SCALAR_TYPE_P (to))
+ {
+ int nelts = CONSTRUCTOR_NELTS (expr);
+ tree elt;
+
+ if (nelts == 0)
+ elt = integer_zero_node;
+ else if (nelts == 1)
+ elt = CONSTRUCTOR_ELT (expr, 0)->value;
+ else
+ elt = error_mark_node;
+
+ conv = implicit_conversion (to, TREE_TYPE (elt), elt,
+ c_cast_p, flags);
+ if (conv)
+ {
+ conv->check_narrowing = true;
+ if (BRACE_ENCLOSED_INITIALIZER_P (elt))
+ /* Too many levels of braces, i.e. '{{1}}'. */
+ conv->bad_p = true;
+ return conv;
+ }
+ }
+ }
if (expr != NULL_TREE
&& (MAYBE_CLASS_TYPE_P (from)
@@ -1394,8 +1438,7 @@ implicit_conversion (tree to, tree from, tree expr, bool c_cast_p,
&& (flags & LOOKUP_NO_CONVERSION) == 0)
{
struct z_candidate *cand;
- int convflags = ((flags & LOOKUP_NO_TEMP_BIND)
- |LOOKUP_ONLYCONVERTING);
+ int convflags = (flags & (LOOKUP_NO_TEMP_BIND|LOOKUP_ONLYCONVERTING));
if (CLASS_TYPE_P (to)
&& !CLASSTYPE_NON_AGGREGATE (complete_type (to))
@@ -1416,11 +1459,12 @@ implicit_conversion (tree to, tree from, tree expr, bool c_cast_p,
}
/* Add a new entry to the list of candidates. Used by the add_*_candidate
- functions. */
+ functions. ARGS will not be changed until a single candidate is
+ selected. */
static struct z_candidate *
add_candidate (struct z_candidate **candidates,
- tree fn, tree args,
+ tree fn, tree first_arg, const VEC(tree,gc) *args,
size_t num_convs, conversion **convs,
tree access_path, tree conversion_path,
int viable)
@@ -1429,6 +1473,7 @@ add_candidate (struct z_candidate **candidates,
conversion_obstack_alloc (sizeof (struct z_candidate));
cand->fn = fn;
+ cand->first_arg = first_arg;
cand->args = args;
cand->convs = convs;
cand->num_convs = num_convs;
@@ -1441,24 +1486,27 @@ add_candidate (struct z_candidate **candidates,
return cand;
}
-/* Create an overload candidate for the function or method FN called with
- the argument list ARGLIST and add it to CANDIDATES. FLAGS is passed on
- to implicit_conversion.
+/* Create an overload candidate for the function or method FN called
+ with the argument list FIRST_ARG/ARGS and add it to CANDIDATES.
+ FLAGS is passed on to implicit_conversion.
+
+ This does not change ARGS.
CTYPE, if non-NULL, is the type we want to pretend this function
comes from for purposes of overload resolution. */
static struct z_candidate *
add_function_candidate (struct z_candidate **candidates,
- tree fn, tree ctype, tree arglist,
- tree access_path, tree conversion_path,
- int flags)
+ tree fn, tree ctype, tree first_arg,
+ const VEC(tree,gc) *args, tree access_path,
+ tree conversion_path, int flags)
{
tree parmlist = TYPE_ARG_TYPES (TREE_TYPE (fn));
int i, len;
conversion **convs;
- tree parmnode, argnode;
- tree orig_arglist;
+ tree parmnode;
+ tree orig_first_arg = first_arg;
+ int skip;
int viable = 1;
/* At this point we should not see any functions which haven't been
@@ -1471,13 +1519,17 @@ add_function_candidate (struct z_candidate **candidates,
if (DECL_CONSTRUCTOR_P (fn))
{
parmlist = skip_artificial_parms_for (fn, parmlist);
- orig_arglist = arglist;
- arglist = skip_artificial_parms_for (fn, arglist);
+ skip = num_artificial_parms_for (fn);
+ if (skip > 0 && first_arg != NULL_TREE)
+ {
+ --skip;
+ first_arg = NULL_TREE;
+ }
}
else
- orig_arglist = arglist;
+ skip = 0;
- len = list_length (arglist);
+ len = VEC_length (tree, args) - skip + (first_arg != NULL_TREE ? 1 : 0);
convs = alloc_conversions (len);
/* 13.3.2 - Viable functions [over.match.viable]
@@ -1510,18 +1562,23 @@ add_function_candidate (struct z_candidate **candidates,
to the corresponding parameter of F. */
parmnode = parmlist;
- argnode = arglist;
for (i = 0; i < len; ++i)
{
- tree arg = TREE_VALUE (argnode);
- tree argtype = lvalue_type (arg);
+ tree arg, argtype;
conversion *t;
int is_this;
if (parmnode == void_list_node)
break;
+ if (i == 0 && first_arg != NULL_TREE)
+ arg = first_arg;
+ else
+ arg = VEC_index (tree, args,
+ i + skip - (first_arg != NULL_TREE ? 1 : 0));
+ argtype = lvalue_type (arg);
+
is_this = (i == 0 && DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)
&& ! DECL_CONSTRUCTOR_P (fn));
@@ -1547,9 +1604,17 @@ add_function_candidate (struct z_candidate **candidates,
parmtype = build_pointer_type (parmtype);
}
- if ((flags & LOOKUP_NO_COPY_CTOR_CONVERSION)
- && ctype && i == 0 && DECL_COPY_CONSTRUCTOR_P (fn))
- lflags |= LOOKUP_NO_CONVERSION;
+ if (ctype && i == 0 && DECL_COPY_CONSTRUCTOR_P (fn))
+ {
+ /* Hack: Direct-initialize copy parm (i.e. suppress
+ LOOKUP_ONLYCONVERTING) to make explicit conversion ops
+ work. See also reference_binding. */
+ lflags |= LOOKUP_COPY_PARM;
+ if (flags & LOOKUP_NO_COPY_CTOR_CONVERSION)
+ lflags |= LOOKUP_NO_CONVERSION;
+ }
+ else
+ lflags |= LOOKUP_ONLYCONVERTING;
t = implicit_conversion (parmtype, argtype, arg,
/*c_cast_p=*/false, lflags);
@@ -1575,18 +1640,18 @@ add_function_candidate (struct z_candidate **candidates,
if (parmnode)
parmnode = TREE_CHAIN (parmnode);
- argnode = TREE_CHAIN (argnode);
}
out:
- return add_candidate (candidates, fn, orig_arglist, len, convs,
+ return add_candidate (candidates, fn, orig_first_arg, args, len, convs,
access_path, conversion_path, viable);
}
/* Create an overload candidate for the conversion function FN which will
be invoked for expression OBJ, producing a pointer-to-function which
- will in turn be called with the argument list ARGLIST, and add it to
- CANDIDATES. FLAGS is passed on to implicit_conversion.
+ will in turn be called with the argument list FIRST_ARG/ARGLIST,
+ and add it to CANDIDATES. This does not change ARGLIST. FLAGS is
+ passed on to implicit_conversion.
Actually, we don't really care about FN; we care about the type it
converts to. There may be multiple conversion functions that will
@@ -1596,23 +1661,23 @@ add_function_candidate (struct z_candidate **candidates,
static struct z_candidate *
add_conv_candidate (struct z_candidate **candidates, tree fn, tree obj,
- tree arglist, tree access_path, tree conversion_path)
+ tree first_arg, const VEC(tree,gc) *arglist,
+ tree access_path, tree conversion_path)
{
tree totype = TREE_TYPE (TREE_TYPE (fn));
int i, len, viable, flags;
- tree parmlist, parmnode, argnode;
+ tree parmlist, parmnode;
conversion **convs;
for (parmlist = totype; TREE_CODE (parmlist) != FUNCTION_TYPE; )
parmlist = TREE_TYPE (parmlist);
parmlist = TYPE_ARG_TYPES (parmlist);
- len = list_length (arglist) + 1;
+ len = VEC_length (tree, arglist) + (first_arg != NULL_TREE ? 1 : 0) + 1;
convs = alloc_conversions (len);
parmnode = parmlist;
- argnode = arglist;
viable = 1;
- flags = LOOKUP_NORMAL;
+ flags = LOOKUP_IMPLICIT;
/* Don't bother looking up the same type twice. */
if (*candidates && (*candidates)->fn == totype)
@@ -1620,11 +1685,19 @@ add_conv_candidate (struct z_candidate **candidates, tree fn, tree obj,
for (i = 0; i < len; ++i)
{
- tree arg = i == 0 ? obj : TREE_VALUE (argnode);
- tree argtype = lvalue_type (arg);
+ tree arg, argtype;
conversion *t;
if (i == 0)
+ arg = obj;
+ else if (i == 1 && first_arg != NULL_TREE)
+ arg = first_arg;
+ else
+ arg = VEC_index (tree, arglist,
+ i - (first_arg != NULL_TREE ? 1 : 0) - 1);
+ argtype = lvalue_type (arg);
+
+ if (i == 0)
t = implicit_conversion (totype, argtype, arg, /*c_cast_p=*/false,
flags);
else if (parmnode == void_list_node)
@@ -1650,7 +1723,6 @@ add_conv_candidate (struct z_candidate **candidates, tree fn, tree obj,
if (parmnode)
parmnode = TREE_CHAIN (parmnode);
- argnode = TREE_CHAIN (argnode);
}
if (i < len)
@@ -1659,7 +1731,7 @@ add_conv_candidate (struct z_candidate **candidates, tree fn, tree obj,
if (!sufficient_parms_p (parmnode))
viable = 0;
- return add_candidate (candidates, totype, arglist, len, convs,
+ return add_candidate (candidates, totype, first_arg, arglist, len, convs,
access_path, conversion_path, viable);
}
@@ -1679,6 +1751,7 @@ build_builtin_candidate (struct z_candidate **candidates, tree fnname,
num_convs = args[2] ? 3 : (args[1] ? 2 : 1);
convs = alloc_conversions (num_convs);
+ flags |= LOOKUP_ONLYCONVERTING;
for (i = 0; i < 2; ++i)
{
@@ -1711,7 +1784,7 @@ build_builtin_candidate (struct z_candidate **candidates, tree fnname,
viable = 0;
}
- add_candidate (candidates, fnname, /*args=*/NULL_TREE,
+ add_candidate (candidates, fnname, /*first_arg=*/NULL_TREE, /*args=*/NULL,
num_convs, convs,
/*access_path=*/NULL_TREE,
/*conversion_path=*/NULL_TREE,
@@ -1736,7 +1809,7 @@ promoted_arithmetic_type_p (tree type)
(including e.g. int and long but excluding e.g. char).
Similarly, the term promoted arithmetic type refers to promoted
integral types plus floating types. */
- return ((INTEGRAL_TYPE_P (type)
+ return ((CP_INTEGRAL_TYPE_P (type)
&& same_type_p (type_promotes_to (type), type))
|| TREE_CODE (type) == REAL_TYPE);
}
@@ -1838,7 +1911,7 @@ add_builtin_candidate (struct z_candidate **candidates, enum tree_code code,
T operator~(T); */
case BIT_NOT_EXPR:
- if (INTEGRAL_TYPE_P (type1))
+ if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type1))
break;
return;
@@ -1908,7 +1981,8 @@ add_builtin_candidate (struct z_candidate **candidates, enum tree_code code,
case MINUS_EXPR:
if (TYPE_PTROB_P (type1) && TYPE_PTROB_P (type2))
break;
- if (TYPE_PTROB_P (type1) && INTEGRAL_TYPE_P (type2))
+ if (TYPE_PTROB_P (type1)
+ && INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type2))
{
type2 = ptrdiff_type_node;
break;
@@ -1968,12 +2042,12 @@ add_builtin_candidate (struct z_candidate **candidates, enum tree_code code,
if (ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2))
break;
case ARRAY_REF:
- if (INTEGRAL_TYPE_P (type1) && TYPE_PTROB_P (type2))
+ if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type1) && TYPE_PTROB_P (type2))
{
type1 = ptrdiff_type_node;
break;
}
- if (TYPE_PTROB_P (type1) && INTEGRAL_TYPE_P (type2))
+ if (TYPE_PTROB_P (type1) && INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type2))
{
type2 = ptrdiff_type_node;
break;
@@ -1997,7 +2071,7 @@ add_builtin_candidate (struct z_candidate **candidates, enum tree_code code,
case BIT_XOR_EXPR:
case LSHIFT_EXPR:
case RSHIFT_EXPR:
- if (INTEGRAL_TYPE_P (type1) && INTEGRAL_TYPE_P (type2))
+ if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type1) && INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type2))
break;
return;
@@ -2042,7 +2116,7 @@ add_builtin_candidate (struct z_candidate **candidates, enum tree_code code,
{
case PLUS_EXPR:
case MINUS_EXPR:
- if (TYPE_PTROB_P (type1) && INTEGRAL_TYPE_P (type2))
+ if (TYPE_PTROB_P (type1) && INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type2))
{
type2 = ptrdiff_type_node;
break;
@@ -2059,7 +2133,7 @@ add_builtin_candidate (struct z_candidate **candidates, enum tree_code code,
case BIT_XOR_EXPR:
case LSHIFT_EXPR:
case RSHIFT_EXPR:
- if (INTEGRAL_TYPE_P (type1) && INTEGRAL_TYPE_P (type2))
+ if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type1) && INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type2))
break;
return;
@@ -2268,7 +2342,7 @@ add_builtin_candidates (struct z_candidate **candidates, enum tree_code code,
for (; convs; convs = TREE_CHAIN (convs))
{
- type = TREE_TYPE (TREE_TYPE (OVL_CURRENT (TREE_VALUE (convs))));
+ type = TREE_TYPE (convs);
if (i == 0 && ref1
&& (TREE_CODE (type) != REFERENCE_TYPE
@@ -2284,7 +2358,7 @@ add_builtin_candidates (struct z_candidate **candidates, enum tree_code code,
type = TYPE_MAIN_VARIANT (type_decays_to (type));
if (enum_p && TREE_CODE (type) == ENUMERAL_TYPE)
types[i] = tree_cons (NULL_TREE, type, types[i]);
- if (INTEGRAL_TYPE_P (type))
+ if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type))
type = type_promotes_to (type);
}
@@ -2301,9 +2375,9 @@ add_builtin_candidates (struct z_candidate **candidates, enum tree_code code,
if (i != 0 || ! ref1)
{
type = TYPE_MAIN_VARIANT (type_decays_to (type));
- if (enum_p && TREE_CODE (type) == ENUMERAL_TYPE)
+ if (enum_p && UNSCOPED_ENUM_P (type))
types[i] = tree_cons (NULL_TREE, type, types[i]);
- if (INTEGRAL_TYPE_P (type))
+ if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type))
type = type_promotes_to (type);
}
types[i] = tree_cons (NULL_TREE, type, types[i]);
@@ -2332,37 +2406,79 @@ add_builtin_candidates (struct z_candidate **candidates, enum tree_code code,
TMPL is the template. EXPLICIT_TARGS are any explicit template
arguments. ARGLIST is the arguments provided at the call-site.
- The RETURN_TYPE is the desired type for conversion operators. If
- OBJ is NULL_TREE, FLAGS and CTYPE are as for add_function_candidate.
- If an OBJ is supplied, FLAGS and CTYPE are ignored, and OBJ is as for
- add_conv_candidate. */
+ This does not change ARGLIST. The RETURN_TYPE is the desired type
+ for conversion operators. If OBJ is NULL_TREE, FLAGS and CTYPE are
+ as for add_function_candidate. If an OBJ is supplied, FLAGS and
+ CTYPE are ignored, and OBJ is as for add_conv_candidate. */
static struct z_candidate*
add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
- tree ctype, tree explicit_targs, tree arglist,
- tree return_type, tree access_path,
- tree conversion_path, int flags, tree obj,
- unification_kind_t strict)
+ tree ctype, tree explicit_targs, tree first_arg,
+ const VEC(tree,gc) *arglist, tree return_type,
+ tree access_path, tree conversion_path,
+ int flags, tree obj, unification_kind_t strict)
{
int ntparms = DECL_NTPARMS (tmpl);
tree targs = make_tree_vec (ntparms);
- tree args_without_in_chrg = arglist;
+ unsigned int nargs;
+ int skip_without_in_chrg;
+ tree first_arg_without_in_chrg;
+ tree *args_without_in_chrg;
+ unsigned int nargs_without_in_chrg;
+ unsigned int ia, ix;
+ tree arg;
struct z_candidate *cand;
int i;
tree fn;
+ nargs = (first_arg == NULL_TREE ? 0 : 1) + VEC_length (tree, arglist);
+
+ skip_without_in_chrg = 0;
+
+ first_arg_without_in_chrg = first_arg;
+
/* We don't do deduction on the in-charge parameter, the VTT
parameter or 'this'. */
if (DECL_NONSTATIC_MEMBER_FUNCTION_P (tmpl))
- args_without_in_chrg = TREE_CHAIN (args_without_in_chrg);
+ {
+ if (first_arg_without_in_chrg != NULL_TREE)
+ first_arg_without_in_chrg = NULL_TREE;
+ else
+ ++skip_without_in_chrg;
+ }
if ((DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (tmpl)
|| DECL_BASE_CONSTRUCTOR_P (tmpl))
&& CLASSTYPE_VBASECLASSES (DECL_CONTEXT (tmpl)))
- args_without_in_chrg = TREE_CHAIN (args_without_in_chrg);
+ {
+ if (first_arg_without_in_chrg != NULL_TREE)
+ first_arg_without_in_chrg = NULL_TREE;
+ else
+ ++skip_without_in_chrg;
+ }
+
+ nargs_without_in_chrg = ((first_arg_without_in_chrg != NULL_TREE ? 1 : 0)
+ + (VEC_length (tree, arglist)
+ - skip_without_in_chrg));
+ args_without_in_chrg = XALLOCAVEC (tree, nargs_without_in_chrg);
+ ia = 0;
+ if (first_arg_without_in_chrg != NULL_TREE)
+ {
+ args_without_in_chrg[ia] = first_arg_without_in_chrg;
+ ++ia;
+ }
+ for (ix = skip_without_in_chrg;
+ VEC_iterate (tree, arglist, ix, arg);
+ ++ix)
+ {
+ args_without_in_chrg[ia] = arg;
+ ++ia;
+ }
+ gcc_assert (ia == nargs_without_in_chrg);
i = fn_type_unification (tmpl, explicit_targs, targs,
args_without_in_chrg,
+ nargs_without_in_chrg,
return_type, strict, flags);
if (i != 0)
@@ -2394,7 +2510,7 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
class type, and a logical interpretation is that the intent was
to forbid the instantiation of member templates which would then
have that form. */
- if (DECL_CONSTRUCTOR_P (fn) && list_length (arglist) == 2)
+ if (DECL_CONSTRUCTOR_P (fn) && nargs == 2)
{
tree arg_types = FUNCTION_FIRST_USER_PARMTYPE (fn);
if (arg_types && same_type_p (TYPE_MAIN_VARIANT (TREE_VALUE (arg_types)),
@@ -2404,11 +2520,11 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
if (obj != NULL_TREE)
/* Aha, this is a conversion function. */
- cand = add_conv_candidate (candidates, fn, obj, access_path,
- conversion_path, arglist);
+ cand = add_conv_candidate (candidates, fn, obj, first_arg, arglist,
+ access_path, conversion_path);
else
cand = add_function_candidate (candidates, fn, ctype,
- arglist, access_path,
+ first_arg, arglist, access_path,
conversion_path, flags);
if (DECL_TI_TEMPLATE (fn) != tmpl)
/* This situation can occur if a member template of a template
@@ -2438,26 +2554,29 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
static struct z_candidate *
add_template_candidate (struct z_candidate **candidates, tree tmpl, tree ctype,
- tree explicit_targs, tree arglist, tree return_type,
+ tree explicit_targs, tree first_arg,
+ const VEC(tree,gc) *arglist, tree return_type,
tree access_path, tree conversion_path, int flags,
unification_kind_t strict)
{
return
add_template_candidate_real (candidates, tmpl, ctype,
- explicit_targs, arglist, return_type,
- access_path, conversion_path,
+ explicit_targs, first_arg, arglist,
+ return_type, access_path, conversion_path,
flags, NULL_TREE, strict);
}
static struct z_candidate *
add_template_conv_candidate (struct z_candidate **candidates, tree tmpl,
- tree obj, tree arglist, tree return_type,
- tree access_path, tree conversion_path)
+ tree obj, tree first_arg,
+ const VEC(tree,gc) *arglist,
+ tree return_type, tree access_path,
+ tree conversion_path)
{
return
add_template_candidate_real (candidates, tmpl, NULL_TREE, NULL_TREE,
- arglist, return_type, access_path,
+ first_arg, arglist, return_type, access_path,
conversion_path, 0, obj, DEDUCE_CONV);
}
@@ -2664,7 +2783,8 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
tree ctors = NULL_TREE;
tree conv_fns = NULL_TREE;
conversion *conv = NULL;
- tree args = NULL_TREE;
+ tree first_arg = NULL_TREE;
+ VEC(tree,gc) *args = NULL;
bool any_viable_p;
int convflags;
@@ -2704,15 +2824,13 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
if (ctors)
{
- tree t;
-
ctors = BASELINK_FUNCTIONS (ctors);
- t = build_int_cst (build_pointer_type (totype), 0);
+ first_arg = build_int_cst (build_pointer_type (totype), 0);
if (BRACE_ENCLOSED_INITIALIZER_P (expr)
&& !TYPE_HAS_LIST_CTOR (totype))
{
- args = ctor_to_list (expr);
+ args = ctor_to_vec (expr);
/* We still allow more conversions within an init-list. */
flags = ((flags & ~LOOKUP_NO_CONVERSION)
/* But not for the copy ctor. */
@@ -2720,12 +2838,12 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
|LOOKUP_NO_NARROWING);
}
else
- args = build_tree_list (NULL_TREE, expr);
+ args = make_tree_vector_single (expr);
+
/* We should never try to call the abstract or base constructor
from here. */
gcc_assert (!DECL_HAS_IN_CHARGE_PARM_P (OVL_CURRENT (ctors))
&& !DECL_HAS_VTT_PARM_P (OVL_CURRENT (ctors)));
- args = tree_cons (NULL_TREE, t, args);
}
for (; ctors; ctors = OVL_NEXT (ctors))
{
@@ -2736,14 +2854,14 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
if (TREE_CODE (ctor) == TEMPLATE_DECL)
cand = add_template_candidate (&candidates, ctor, totype,
- NULL_TREE, args, NULL_TREE,
+ NULL_TREE, first_arg, args, NULL_TREE,
TYPE_BINFO (totype),
TYPE_BINFO (totype),
flags,
DEDUCE_CALL);
else
cand = add_function_candidate (&candidates, ctor, totype,
- args, TYPE_BINFO (totype),
+ first_arg, args, TYPE_BINFO (totype),
TYPE_BINFO (totype),
flags);
@@ -2767,7 +2885,7 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
}
if (conv_fns)
- args = build_tree_list (NULL_TREE, build_this (expr));
+ first_arg = build_this (expr);
for (; conv_fns; conv_fns = TREE_CHAIN (conv_fns))
{
@@ -2785,6 +2903,10 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
{
tree fn = OVL_CURRENT (fns);
+ if (DECL_NONCONVERTING_P (fn)
+ && (flags & LOOKUP_ONLYCONVERTING))
+ continue;
+
/* [over.match.funcs] For conversion functions, the function
is considered to be a member of the class of the implicit
object argument for the purpose of defining the type of
@@ -2795,14 +2917,14 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
if (TREE_CODE (fn) == TEMPLATE_DECL)
cand = add_template_candidate (&candidates, fn, fromtype,
NULL_TREE,
- args, totype,
+ first_arg, NULL, totype,
TYPE_BINFO (fromtype),
conversion_path,
flags,
DEDUCE_CONV);
else
cand = add_function_candidate (&candidates, fn, fromtype,
- args,
+ first_arg, NULL,
TYPE_BINFO (fromtype),
conversion_path,
flags);
@@ -2905,23 +3027,23 @@ build_user_type_conversion (tree totype, tree expr, int flags)
/* Do any initial processing on the arguments to a function call. */
-static tree
-resolve_args (tree args)
+static VEC(tree,gc) *
+resolve_args (VEC(tree,gc) *args)
{
- tree t;
- for (t = args; t; t = TREE_CHAIN (t))
- {
- tree arg = TREE_VALUE (t);
+ unsigned int ix;
+ tree arg;
+ for (ix = 0; VEC_iterate (tree, args, ix, arg); ++ix)
+ {
if (error_operand_p (arg))
- return error_mark_node;
+ return NULL;
else if (VOID_TYPE_P (TREE_TYPE (arg)))
{
error ("invalid use of void expression");
- return error_mark_node;
+ return NULL;
}
else if (invalid_nonstatic_memfn_p (arg, tf_warning_or_error))
- return error_mark_node;
+ return NULL;
}
return args;
}
@@ -2940,7 +3062,7 @@ resolve_args (tree args)
static struct z_candidate *
perform_overload_resolution (tree fn,
- tree args,
+ const VEC(tree,gc) *args,
struct z_candidate **candidates,
bool *any_viable_p)
{
@@ -2951,12 +3073,11 @@ perform_overload_resolution (tree fn,
*candidates = NULL;
*any_viable_p = true;
- /* Check FN and ARGS. */
+ /* Check FN. */
gcc_assert (TREE_CODE (fn) == FUNCTION_DECL
|| TREE_CODE (fn) == TEMPLATE_DECL
|| TREE_CODE (fn) == OVERLOAD
|| TREE_CODE (fn) == TEMPLATE_ID_EXPR);
- gcc_assert (!args || TREE_CODE (args) == TREE_LIST);
if (TREE_CODE (fn) == TEMPLATE_ID_EXPR)
{
@@ -2981,10 +3102,11 @@ perform_overload_resolution (tree fn,
}
/* Return an expression for a call to FN (a namespace-scope function,
- or a static member function) with the ARGS. */
+ or a static member function) with the ARGS. This may change
+ ARGS. */
tree
-build_new_function_call (tree fn, tree args, bool koenig_p,
+build_new_function_call (tree fn, VEC(tree,gc) **args, bool koenig_p,
tsubst_flags_t complain)
{
struct z_candidate *candidates, *cand;
@@ -2992,9 +3114,12 @@ build_new_function_call (tree fn, tree args, bool koenig_p,
void *p;
tree result;
- args = resolve_args (args);
- if (args == error_mark_node)
- return error_mark_node;
+ if (args != NULL && *args != NULL)
+ {
+ *args = resolve_args (*args);
+ if (*args == NULL)
+ return error_mark_node;
+ }
/* If this function was found without using argument dependent
lookup, then we want to ignore any undeclared friend
@@ -3008,7 +3133,8 @@ build_new_function_call (tree fn, tree args, bool koenig_p,
{
if (complain & tf_error)
error ("no matching function for call to %<%D(%A)%>",
- DECL_NAME (OVL_CURRENT (orig_fn)), args);
+ DECL_NAME (OVL_CURRENT (orig_fn)),
+ build_tree_list_vec (*args));
return error_mark_node;
}
}
@@ -3016,22 +3142,22 @@ build_new_function_call (tree fn, tree args, bool koenig_p,
/* Get the high-water mark for the CONVERSION_OBSTACK. */
p = conversion_obstack_alloc (0);
- cand = perform_overload_resolution (fn, args, &candidates, &any_viable_p);
+ cand = perform_overload_resolution (fn, *args, &candidates, &any_viable_p);
if (!cand)
{
if (complain & tf_error)
{
if (!any_viable_p && candidates && ! candidates->next)
- return cp_build_function_call (candidates->fn, args, complain);
+ return cp_build_function_call_vec (candidates->fn, args, complain);
if (TREE_CODE (fn) == TEMPLATE_ID_EXPR)
fn = TREE_OPERAND (fn, 0);
if (!any_viable_p)
error ("no matching function for call to %<%D(%A)%>",
- DECL_NAME (OVL_CURRENT (fn)), args);
+ DECL_NAME (OVL_CURRENT (fn)), build_tree_list_vec (*args));
else
error ("call of overloaded %<%D(%A)%> is ambiguous",
- DECL_NAME (OVL_CURRENT (fn)), args);
+ DECL_NAME (OVL_CURRENT (fn)), build_tree_list_vec (*args));
if (candidates)
print_z_candidates (candidates);
}
@@ -3048,15 +3174,16 @@ build_new_function_call (tree fn, tree args, bool koenig_p,
/* Build a call to a global operator new. FNNAME is the name of the
operator (either "operator new" or "operator new[]") and ARGS are
- the arguments provided. *SIZE points to the total number of bytes
- required by the allocation, and is updated if that is changed here.
- *COOKIE_SIZE is non-NULL if a cookie should be used. If this
- function determines that no cookie should be used, after all,
- *COOKIE_SIZE is set to NULL_TREE. If FN is non-NULL, it will be
- set, upon return, to the allocation function called. */
+ the arguments provided. This may change ARGS. *SIZE points to the
+ total number of bytes required by the allocation, and is updated if
+ that is changed here. *COOKIE_SIZE is non-NULL if a cookie should
+ be used. If this function determines that no cookie should be
+ used, after all, *COOKIE_SIZE is set to NULL_TREE. If FN is
+ non-NULL, it will be set, upon return, to the allocation function
+ called. */
tree
-build_operator_new_call (tree fnname, tree args,
+build_operator_new_call (tree fnname, VEC(tree,gc) **args,
tree *size, tree *cookie_size,
tree *fn)
{
@@ -3067,10 +3194,10 @@ build_operator_new_call (tree fnname, tree args,
if (fn)
*fn = NULL_TREE;
- args = tree_cons (NULL_TREE, *size, args);
- args = resolve_args (args);
- if (args == error_mark_node)
- return args;
+ VEC_safe_insert (tree, gc, *args, 0, *size);
+ *args = resolve_args (*args);
+ if (*args == NULL)
+ return error_mark_node;
/* Based on:
@@ -3081,10 +3208,10 @@ build_operator_new_call (tree fnname, tree args,
up in the global scope.
we disregard block-scope declarations of "operator new". */
- fns = lookup_function_nonclass (fnname, args, /*block_p=*/false);
+ fns = lookup_function_nonclass (fnname, *args, /*block_p=*/false);
/* Figure out what function is being called. */
- cand = perform_overload_resolution (fns, args, &candidates, &any_viable_p);
+ cand = perform_overload_resolution (fns, *args, &candidates, &any_viable_p);
/* If no suitable function could be found, issue an error message
and give up. */
@@ -3092,10 +3219,10 @@ build_operator_new_call (tree fnname, tree args,
{
if (!any_viable_p)
error ("no matching function for call to %<%D(%A)%>",
- DECL_NAME (OVL_CURRENT (fns)), args);
+ DECL_NAME (OVL_CURRENT (fns)), build_tree_list_vec (*args));
else
error ("call of overloaded %<%D(%A)%> is ambiguous",
- DECL_NAME (OVL_CURRENT (fns)), args);
+ DECL_NAME (OVL_CURRENT (fns)), build_tree_list_vec (*args));
if (candidates)
print_z_candidates (candidates);
return error_mark_node;
@@ -3109,12 +3236,11 @@ build_operator_new_call (tree fnname, tree args,
bool use_cookie = true;
if (!abi_version_at_least (2))
{
- tree placement = TREE_CHAIN (args);
/* In G++ 3.2, the check was implemented incorrectly; it
looked at the placement expression, rather than the
type of the function. */
- if (placement && !TREE_CHAIN (placement)
- && same_type_p (TREE_TYPE (TREE_VALUE (placement)),
+ if (VEC_length (tree, *args) == 2
+ && same_type_p (TREE_TYPE (VEC_index (tree, *args, 1)),
ptr_type_node))
use_cookie = false;
}
@@ -3138,7 +3264,7 @@ build_operator_new_call (tree fnname, tree args,
/* Update the total size. */
*size = size_binop (PLUS_EXPR, *size, *cookie_size);
/* Update the argument list to reflect the adjusted size. */
- TREE_VALUE (args) = *size;
+ VEC_replace (tree, *args, 0, *size);
}
else
*cookie_size = NULL_TREE;
@@ -3152,16 +3278,23 @@ build_operator_new_call (tree fnname, tree args,
return build_over_call (cand, LOOKUP_NORMAL, tf_warning_or_error);
}
-static tree
-build_object_call (tree obj, tree args, tsubst_flags_t complain)
+/* Build a new call to operator(). This may change ARGS. */
+
+tree
+build_op_call (tree obj, VEC(tree,gc) **args, tsubst_flags_t complain)
{
struct z_candidate *candidates = 0, *cand;
- tree fns, convs, mem_args = NULL_TREE;
+ tree fns, convs, first_mem_arg = NULL_TREE;
tree type = TREE_TYPE (obj);
bool any_viable_p;
tree result = NULL_TREE;
void *p;
+ if (error_operand_p (obj))
+ return error_mark_node;
+
+ obj = prep_operand (obj);
+
if (TYPE_PTRMEMFUNC_P (type))
{
if (complain & tf_error)
@@ -3180,10 +3313,12 @@ build_object_call (tree obj, tree args, tsubst_flags_t complain)
else
fns = NULL_TREE;
- args = resolve_args (args);
-
- if (args == error_mark_node)
- return error_mark_node;
+ if (args != NULL && *args != NULL)
+ {
+ *args = resolve_args (*args);
+ if (*args == NULL)
+ return error_mark_node;
+ }
/* Get the high-water mark for the CONVERSION_OBSTACK. */
p = conversion_obstack_alloc (0);
@@ -3191,20 +3326,20 @@ build_object_call (tree obj, tree args, tsubst_flags_t complain)
if (fns)
{
tree base = BINFO_TYPE (BASELINK_BINFO (fns));
- mem_args = tree_cons (NULL_TREE, build_this (obj), args);
+ first_mem_arg = build_this (obj);
for (fns = BASELINK_FUNCTIONS (fns); fns; fns = OVL_NEXT (fns))
{
tree fn = OVL_CURRENT (fns);
if (TREE_CODE (fn) == TEMPLATE_DECL)
add_template_candidate (&candidates, fn, base, NULL_TREE,
- mem_args, NULL_TREE,
+ first_mem_arg, *args, NULL_TREE,
TYPE_BINFO (type),
TYPE_BINFO (type),
LOOKUP_NORMAL, DEDUCE_CALL);
else
add_function_candidate
- (&candidates, fn, base, mem_args, TYPE_BINFO (type),
+ (&candidates, fn, base, first_mem_arg, *args, TYPE_BINFO (type),
TYPE_BINFO (type), LOOKUP_NORMAL);
}
}
@@ -3214,7 +3349,7 @@ build_object_call (tree obj, tree args, tsubst_flags_t complain)
for (; convs; convs = TREE_CHAIN (convs))
{
tree fns = TREE_VALUE (convs);
- tree totype = TREE_TYPE (TREE_TYPE (OVL_CURRENT (fns)));
+ tree totype = TREE_TYPE (convs);
if ((TREE_CODE (totype) == POINTER_TYPE
&& TREE_CODE (TREE_TYPE (totype)) == FUNCTION_TYPE)
@@ -3226,14 +3361,18 @@ build_object_call (tree obj, tree args, tsubst_flags_t complain)
for (; fns; fns = OVL_NEXT (fns))
{
tree fn = OVL_CURRENT (fns);
+
+ if (DECL_NONCONVERTING_P (fn))
+ continue;
+
if (TREE_CODE (fn) == TEMPLATE_DECL)
add_template_conv_candidate
- (&candidates, fn, obj, args, totype,
+ (&candidates, fn, obj, NULL_TREE, *args, totype,
/*access_path=*/NULL_TREE,
/*conversion_path=*/NULL_TREE);
else
- add_conv_candidate (&candidates, fn, obj, args,
- /*conversion_path=*/NULL_TREE,
+ add_conv_candidate (&candidates, fn, obj, NULL_TREE,
+ *args, /*conversion_path=*/NULL_TREE,
/*access_path=*/NULL_TREE);
}
}
@@ -3243,7 +3382,8 @@ build_object_call (tree obj, tree args, tsubst_flags_t complain)
{
if (complain & tf_error)
{
- error ("no match for call to %<(%T) (%A)%>", TREE_TYPE (obj), args);
+ error ("no match for call to %<(%T) (%A)%>", TREE_TYPE (obj),
+ build_tree_list_vec (*args));
print_z_candidates (candidates);
}
result = error_mark_node;
@@ -3256,7 +3396,7 @@ build_object_call (tree obj, tree args, tsubst_flags_t complain)
if (complain & tf_error)
{
error ("call of %<(%T) (%A)%> is ambiguous",
- TREE_TYPE (obj), args);
+ TREE_TYPE (obj), build_tree_list_vec (*args));
print_z_candidates (candidates);
}
result = error_mark_node;
@@ -3272,7 +3412,7 @@ build_object_call (tree obj, tree args, tsubst_flags_t complain)
obj = convert_like_with_context (cand->convs[0], obj, cand->fn, -1,
complain);
obj = convert_from_reference (obj);
- result = cp_build_function_call (obj, args, complain);
+ result = cp_build_function_call_vec (obj, args, complain);
}
}
@@ -3348,7 +3488,7 @@ conditional_conversion (tree e1, tree e2)
t1,
e1,
/*c_cast_p=*/false,
- LOOKUP_NO_TEMP_BIND);
+ LOOKUP_NO_TEMP_BIND|LOOKUP_ONLYCONVERTING);
if (conv)
return conv;
}
@@ -3386,7 +3526,7 @@ conditional_conversion (tree e1, tree e2)
converted to the type that expression E2 would have if E2 were
converted to an rvalue (or the type it has, if E2 is an rvalue). */
return implicit_conversion (t2, t1, e1, /*c_cast_p=*/false,
- LOOKUP_NORMAL);
+ LOOKUP_IMPLICIT);
}
/* Implement [expr.cond]. ARG1, ARG2, and ARG3 are the three
@@ -3824,29 +3964,33 @@ prep_operand (tree operand)
/* Add each of the viable functions in FNS (a FUNCTION_DECL or
OVERLOAD) to the CANDIDATES, returning an updated list of
CANDIDATES. The ARGS are the arguments provided to the call,
- without any implicit object parameter. The EXPLICIT_TARGS are
- explicit template arguments provided. TEMPLATE_ONLY is true if
- only template functions should be considered. CONVERSION_PATH,
- ACCESS_PATH, and FLAGS are as for add_function_candidate. */
+ without any implicit object parameter. This may change ARGS. The
+ EXPLICIT_TARGS are explicit template arguments provided.
+ TEMPLATE_ONLY is true if only template functions should be
+ considered. CONVERSION_PATH, ACCESS_PATH, and FLAGS are as for
+ add_function_candidate. */
static void
-add_candidates (tree fns, tree args,
+add_candidates (tree fns, const VEC(tree,gc) *args,
tree explicit_targs, bool template_only,
tree conversion_path, tree access_path,
int flags,
struct z_candidate **candidates)
{
tree ctype;
- tree non_static_args;
+ VEC(tree,gc) *non_static_args;
+ tree first_arg;
ctype = conversion_path ? BINFO_TYPE (conversion_path) : NULL_TREE;
/* Delay creating the implicit this parameter until it is needed. */
- non_static_args = NULL_TREE;
+ non_static_args = NULL;
+ first_arg = NULL_TREE;
while (fns)
{
tree fn;
- tree fn_args;
+ tree fn_first_arg;
+ const VEC(tree,gc) *fn_args;
fn = OVL_CURRENT (fns);
/* Figure out which set of arguments to use. */
@@ -3854,21 +3998,34 @@ add_candidates (tree fns, tree args,
{
/* If this function is a non-static member, prepend the implicit
object parameter. */
- if (!non_static_args)
- non_static_args = tree_cons (NULL_TREE,
- build_this (TREE_VALUE (args)),
- TREE_CHAIN (args));
+ if (non_static_args == NULL)
+ {
+ unsigned int ix;
+ tree arg;
+
+ non_static_args = VEC_alloc (tree, gc,
+ VEC_length (tree, args) - 1);
+ for (ix = 1; VEC_iterate (tree, args, ix, arg); ++ix)
+ VEC_quick_push (tree, non_static_args, arg);
+ }
+ if (first_arg == NULL_TREE)
+ first_arg = build_this (VEC_index (tree, args, 0));
+ fn_first_arg = first_arg;
fn_args = non_static_args;
}
else
- /* Otherwise, just use the list of arguments provided. */
- fn_args = args;
+ {
+ /* Otherwise, just use the list of arguments provided. */
+ fn_first_arg = NULL_TREE;
+ fn_args = args;
+ }
if (TREE_CODE (fn) == TEMPLATE_DECL)
add_template_candidate (candidates,
fn,
ctype,
explicit_targs,
+ fn_first_arg,
fn_args,
NULL_TREE,
access_path,
@@ -3879,6 +4036,7 @@ add_candidates (tree fns, tree args,
add_function_candidate (candidates,
fn,
ctype,
+ fn_first_arg,
fn_args,
access_path,
conversion_path,
@@ -3892,7 +4050,8 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
bool *overloaded_p, tsubst_flags_t complain)
{
struct z_candidate *candidates = 0, *cand;
- tree arglist, fnname;
+ VEC(tree,gc) *arglist;
+ tree fnname;
tree args[3];
tree result = NULL_TREE;
bool result_valid_p = false;
@@ -3930,7 +4089,8 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
gcc_unreachable ();
case CALL_EXPR:
- return build_object_call (arg1, arg2, complain);
+ /* Use build_op_call instead. */
+ gcc_unreachable ();
case TRUTH_ORIF_EXPR:
case TRUTH_ANDIF_EXPR:
@@ -3963,12 +4123,12 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
arg2 = integer_zero_node;
- arglist = NULL_TREE;
- if (arg3)
- arglist = tree_cons (NULL_TREE, arg3, arglist);
- if (arg2)
- arglist = tree_cons (NULL_TREE, arg2, arglist);
- arglist = tree_cons (NULL_TREE, arg1, arglist);
+ arglist = VEC_alloc (tree, gc, 3);
+ VEC_quick_push (tree, arglist, arg1);
+ if (arg2 != NULL_TREE)
+ VEC_quick_push (tree, arglist, arg2);
+ if (arg3 != NULL_TREE)
+ VEC_quick_push (tree, arglist, arg3);
/* Get the high-water mark for the CONVERSION_OBSTACK. */
p = conversion_obstack_alloc (0);
@@ -4108,7 +4268,7 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
if (overloaded_p)
*overloaded_p = true;
- if (resolve_args (arglist) == error_mark_node)
+ if (resolve_args (arglist) == NULL)
result = error_mark_node;
else
result = build_over_call (cand, LOOKUP_NORMAL, complain);
@@ -4161,7 +4321,7 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
/* We need to call warn_logical_operator before
converting arg2 to a boolean_type. */
if (complain & tf_warning)
- warn_logical_operator (input_location, code,
+ warn_logical_operator (input_location, code, boolean_type_node,
code_orig_arg1, arg1,
code_orig_arg2, arg2);
@@ -4202,7 +4362,7 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
case TRUTH_ORIF_EXPR:
case TRUTH_AND_EXPR:
case TRUTH_OR_EXPR:
- warn_logical_operator (input_location, code,
+ warn_logical_operator (input_location, code, boolean_type_node,
code_orig_arg1, arg1, code_orig_arg2, arg2);
/* Fall through. */
case PLUS_EXPR:
@@ -4238,7 +4398,7 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
return cp_build_unary_op (code, arg1, candidates != 0, complain);
case ARRAY_REF:
- return build_array_ref (arg1, arg2, input_location);
+ return build_array_ref (input_location, arg1, arg2);
case COND_EXPR:
return build_conditional_expr (arg1, arg2, arg3, complain);
@@ -4409,13 +4569,14 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
}
else
{
- tree args;
- if (pass == 0)
- args = tree_cons (NULL_TREE, addr, NULL_TREE);
- else
- args = tree_cons (NULL_TREE, addr,
- build_tree_list (NULL_TREE, size));
- return cp_build_function_call (fn, args, tf_warning_or_error);
+ tree ret;
+ VEC(tree,gc) *args = VEC_alloc (tree, gc, 2);
+ VEC_quick_push (tree, args, addr);
+ if (pass != 0)
+ VEC_quick_push (tree, args, size);
+ ret = cp_build_function_call_vec (fn, &args, tf_warning_or_error);
+ VEC_free (tree, gc, args);
+ return ret;
}
}
@@ -4473,12 +4634,13 @@ build_temp (tree expr, tree type, int flags,
diagnostic_t *diagnostic_kind)
{
int savew, savee;
+ VEC(tree,gc) *args;
savew = warningcount, savee = errorcount;
- expr = build_special_member_call (NULL_TREE,
- complete_ctor_identifier,
- build_tree_list (NULL_TREE, expr),
- type, flags, tf_warning_or_error);
+ args = make_tree_vector_single (expr);
+ expr = build_special_member_call (NULL_TREE, complete_ctor_identifier,
+ &args, type, flags, tf_warning_or_error);
+ release_tree_vector (args);
if (warningcount > savew)
*diagnostic_kind = DK_WARNING;
else if (errorcount > savee)
@@ -4535,12 +4697,21 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
if (convs->bad_p
&& convs->kind != ck_user
+ && convs->kind != ck_list
&& convs->kind != ck_ambig
&& convs->kind != ck_ref_bind
&& convs->kind != ck_rvalue
&& convs->kind != ck_base)
{
conversion *t = convs;
+
+ /* Give a helpful error if this is bad because of excess braces. */
+ if (BRACE_ENCLOSED_INITIALIZER_P (expr)
+ && SCALAR_TYPE_P (totype)
+ && CONSTRUCTOR_NELTS (expr) > 0
+ && BRACE_ENCLOSED_INITIALIZER_P (CONSTRUCTOR_ELT (expr, 0)->value))
+ permerror (input_location, "too many braces around initializer for %qT", totype);
+
for (; t; t = convs->u.next)
{
if (t->kind == ck_user || !t->bad_p)
@@ -4584,7 +4755,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
/* When converting from an init list we consider explicit
constructors, but actually trying to call one is an error. */
- if (DECL_NONCONVERTING_P (convfn))
+ if (DECL_NONCONVERTING_P (convfn) && DECL_CONSTRUCTOR_P (convfn))
{
if (complain & tf_error)
error ("converting to %qT from initializer list would use "
@@ -4614,6 +4785,17 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
return expr;
}
case ck_identity:
+ if (BRACE_ENCLOSED_INITIALIZER_P (expr))
+ {
+ int nelts = CONSTRUCTOR_NELTS (expr);
+ if (nelts == 0)
+ expr = integer_zero_node;
+ else if (nelts == 1)
+ expr = CONSTRUCTOR_ELT (expr, 0)->value;
+ else
+ gcc_unreachable ();
+ }
+
if (type_unknown_p (expr))
expr = instantiate_type (totype, expr, complain);
/* Convert a constant to its underlying value, unless we are
@@ -4622,7 +4804,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
if (inner >= 0)
{
expr = decl_constant_value (expr);
- if (expr == null_node && INTEGRAL_TYPE_P (totype))
+ if (expr == null_node && INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (totype))
/* If __null has been converted to an integer type, we do not
want to warn about uses of EXPR as an integer, rather than
as a pointer. */
@@ -4640,7 +4822,8 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
tree elttype = TREE_VEC_ELT (CLASSTYPE_TI_ARGS (totype), 0);
tree new_ctor = build_constructor (init_list_type_node, NULL);
unsigned len = CONSTRUCTOR_NELTS (expr);
- tree array, parms, val;
+ tree array, val;
+ VEC(tree,gc) *parms;
unsigned ix;
/* Convert all the elements. */
@@ -4659,12 +4842,14 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
array = build_array_of_n_type (elttype, len);
array = finish_compound_literal (array, new_ctor);
- parms = build_tree_list (NULL_TREE, size_int (len));
- parms = tree_cons (NULL_TREE, decay_conversion (array), parms);
+ parms = make_tree_vector ();
+ VEC_safe_push (tree, gc, parms, decay_conversion (array));
+ VEC_safe_push (tree, gc, parms, size_int (len));
/* Call the private constructor. */
push_deferring_access_checks (dk_no_check);
new_ctor = build_special_member_call
- (NULL_TREE, complete_ctor_identifier, parms, totype, 0, complain);
+ (NULL_TREE, complete_ctor_identifier, &parms, totype, 0, complain);
+ release_tree_vector (parms);
pop_deferring_access_checks ();
return build_cplus_new (totype, new_ctor);
}
@@ -4879,7 +5064,7 @@ convert_arg_to_ellipsis (tree arg)
If the call appears in the context of a sizeof expression,
there is no need to emit a warning, since the expression won't be
evaluated. We keep the builtin_trap just as a safety check. */
- if (!skip_evaluation)
+ if (cp_unevaluated_operand == 0)
warning (0, "cannot pass objects of non-POD type %q#T through %<...%>; "
"call will abort at runtime", TREE_TYPE (arg));
arg = call_builtin_trap ();
@@ -4917,7 +5102,7 @@ build_x_va_arg (tree expr, tree type)
return expr;
}
- return build_va_arg (expr, type);
+ return build_va_arg (input_location, expr, type);
}
/* TYPE has been given to va_arg. Apply the default conversions which
@@ -5121,14 +5306,16 @@ static tree
build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
{
tree fn = cand->fn;
- tree args = cand->args;
+ const VEC(tree,gc) *args = cand->args;
+ tree first_arg = cand->first_arg;
conversion **convs = cand->convs;
conversion *conv;
tree parm = TYPE_ARG_TYPES (TREE_TYPE (fn));
int parmlen;
- tree arg, val;
+ tree val;
int i = 0;
int j = 0;
+ unsigned int arg_index = 0;
int is_method = 0;
int nargs;
tree *argarray;
@@ -5142,8 +5329,28 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
{
tree expr;
tree return_type;
+ const tree *argarray;
+ unsigned int nargs;
+
return_type = TREE_TYPE (TREE_TYPE (fn));
- expr = build_call_list (return_type, build_addr_func (fn), args);
+ nargs = VEC_length (tree, args);
+ if (first_arg == NULL_TREE)
+ argarray = VEC_address (tree, CONST_CAST (VEC(tree,gc) *, args));
+ else
+ {
+ tree *alcarray;
+ unsigned int ix;
+ tree arg;
+
+ ++nargs;
+ alcarray = XALLOCAVEC (tree, nargs);
+ alcarray[0] = first_arg;
+ for (ix = 0; VEC_iterate (tree, args, ix, arg); ++ix)
+ alcarray[ix + 1] = arg;
+ argarray = alcarray;
+ }
+ expr = build_call_array (return_type, build_addr_func (fn), nargs,
+ argarray);
if (TREE_THIS_VOLATILE (fn) && cfun)
current_function_returns_abnormally = 1;
if (!VOID_TYPE_P (return_type))
@@ -5198,13 +5405,9 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
perform_or_defer_access_check (cand->access_path, fn, fn);
}
- if (args && TREE_CODE (args) != TREE_LIST)
- args = build_tree_list (NULL_TREE, args);
- arg = args;
-
/* Find maximum size of vector to hold converted arguments. */
parmlen = list_length (parm);
- nargs = list_length (args);
+ nargs = VEC_length (tree, args) + (first_arg != NULL_TREE ? 1 : 0);
if (parmlen > nargs)
nargs = parmlen;
argarray = (tree *) alloca (nargs * sizeof (tree));
@@ -5213,16 +5416,24 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
resolution, and must be of the proper type. */
if (DECL_CONSTRUCTOR_P (fn))
{
- argarray[j++] = TREE_VALUE (arg);
- arg = TREE_CHAIN (arg);
+ if (first_arg != NULL_TREE)
+ {
+ argarray[j++] = first_arg;
+ first_arg = NULL_TREE;
+ }
+ else
+ {
+ argarray[j++] = VEC_index (tree, args, arg_index);
+ ++arg_index;
+ }
parm = TREE_CHAIN (parm);
/* We should never try to call the abstract constructor. */
gcc_assert (!DECL_HAS_IN_CHARGE_PARM_P (fn));
if (DECL_HAS_VTT_PARM_P (fn))
{
- argarray[j++] = TREE_VALUE (arg);
- arg = TREE_CHAIN (arg);
+ argarray[j++] = VEC_index (tree, args, arg_index);
+ ++arg_index;
parm = TREE_CHAIN (parm);
}
}
@@ -5230,7 +5441,10 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
else if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE)
{
tree parmtype = TREE_VALUE (parm);
- tree argtype = TREE_TYPE (TREE_VALUE (arg));
+ tree arg = (first_arg != NULL_TREE
+ ? first_arg
+ : VEC_index (tree, args, arg_index));
+ tree argtype = TREE_TYPE (arg);
tree converted_arg;
tree base_binfo;
@@ -5253,7 +5467,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
/* Convert to the base in which the function was declared. */
gcc_assert (cand->conversion_path != NULL_TREE);
converted_arg = build_base_path (PLUS_EXPR,
- TREE_VALUE (arg),
+ arg,
cand->conversion_path,
1);
/* Check that the base class is accessible. */
@@ -5272,13 +5486,17 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
argarray[j++] = converted_arg;
parm = TREE_CHAIN (parm);
- arg = TREE_CHAIN (arg);
+ if (first_arg != NULL_TREE)
+ first_arg = NULL_TREE;
+ else
+ ++arg_index;
++i;
is_method = 1;
}
- for (; arg && parm;
- parm = TREE_CHAIN (parm), arg = TREE_CHAIN (arg), ++i)
+ gcc_assert (first_arg == NULL_TREE);
+ for (; arg_index < VEC_length (tree, args) && parm;
+ parm = TREE_CHAIN (parm), ++arg_index, ++i)
{
tree type = TREE_VALUE (parm);
@@ -5291,7 +5509,8 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
conv = conv->u.next;
val = convert_like_with_context
- (conv, TREE_VALUE (arg), fn, i - is_method, complain);
+ (conv, VEC_index (tree, args, arg_index), fn, i - is_method,
+ complain);
val = convert_for_arg_passing (type, val);
if (val == error_mark_node)
@@ -5306,9 +5525,9 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
TREE_PURPOSE (parm),
fn, i - is_method);
/* Ellipsis */
- for (; arg; arg = TREE_CHAIN (arg))
+ for (; arg_index < VEC_length (tree, args); ++arg_index)
{
- tree a = TREE_VALUE (arg);
+ tree a = VEC_index (tree, args, arg_index);
if (magic_varargs_p (fn))
/* Do no conversions for magic varargs. */;
else
@@ -5332,7 +5551,8 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
|| DECL_MOVE_CONSTRUCTOR_P (fn)))
{
tree targ;
- arg = argarray[num_artificial_parms_for (fn)];
+ tree arg = argarray[num_artificial_parms_for (fn)];
+ tree fa;
/* Pull out the real argument, disregarding const-correctness. */
targ = arg;
@@ -5373,7 +5593,10 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
INIT_EXPR to collapse the temp into our target. Otherwise, if the
ctor is trivial, do a bitwise copy with a simple TARGET_EXPR for a
temp or an INIT_EXPR otherwise. */
- if (integer_zerop (TREE_VALUE (args)))
+ fa = (cand->first_arg != NULL_TREE
+ ? cand->first_arg
+ : VEC_index (tree, args, 0));
+ if (integer_zerop (fa))
{
if (TREE_CODE (arg) == TARGET_EXPR)
return arg;
@@ -5384,8 +5607,8 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
|| (TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn))
&& !move_fn_p (fn)))
{
- tree to = stabilize_reference
- (cp_build_indirect_ref (TREE_VALUE (args), 0, complain));
+ tree to = stabilize_reference (cp_build_indirect_ref (fa, 0,
+ complain));
val = build2 (INIT_EXPR, DECL_CONTEXT (fn), to, arg);
return val;
@@ -5399,8 +5622,8 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
(cp_build_indirect_ref (argarray[0], 0, complain));
tree type = TREE_TYPE (to);
tree as_base = CLASSTYPE_AS_BASE (type);
+ tree arg = argarray[1];
- arg = argarray[1];
if (tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (as_base)))
{
arg = cp_build_indirect_ref (arg, 0, complain);
@@ -5606,9 +5829,10 @@ in_charge_arg_for_name (tree name)
/* Build a call to a constructor, destructor, or an assignment
operator for INSTANCE, an expression with class type. NAME
- indicates the special member function to call; ARGS are the
- arguments. BINFO indicates the base of INSTANCE that is to be
- passed as the `this' parameter to the member function called.
+ indicates the special member function to call; *ARGS are the
+ arguments. ARGS may be NULL. This may change ARGS. BINFO
+ indicates the base of INSTANCE that is to be passed as the `this'
+ parameter to the member function called.
FLAGS are the LOOKUP_* flags to use when processing the call.
@@ -5617,12 +5841,14 @@ in_charge_arg_for_name (tree name)
store the newly constructed object into a VAR_DECL. */
tree
-build_special_member_call (tree instance, tree name, tree args,
+build_special_member_call (tree instance, tree name, VEC(tree,gc) **args,
tree binfo, int flags, tsubst_flags_t complain)
{
tree fns;
/* The type of the subobject to be constructed or destroyed. */
tree class_type;
+ VEC(tree,gc) *allocated = NULL;
+ tree ret;
gcc_assert (name == complete_ctor_identifier
|| name == base_ctor_identifier
@@ -5654,7 +5880,7 @@ build_special_member_call (tree instance, tree name, tree args,
if (name == complete_dtor_identifier
|| name == base_dtor_identifier
|| name == deleting_dtor_identifier)
- gcc_assert (args == NULL_TREE);
+ gcc_assert (args == NULL || VEC_empty (tree, *args));
/* Convert to the base class, if necessary. */
if (!same_type_ignoring_top_level_qualifiers_p
@@ -5703,13 +5929,24 @@ build_special_member_call (tree instance, tree name, tree args,
sub_vtt = build2 (POINTER_PLUS_EXPR, TREE_TYPE (vtt), vtt,
BINFO_SUBVTT_INDEX (binfo));
- args = tree_cons (NULL_TREE, sub_vtt, args);
+ if (args == NULL)
+ {
+ allocated = make_tree_vector ();
+ args = &allocated;
+ }
+
+ VEC_safe_insert (tree, gc, *args, 0, sub_vtt);
}
- return build_new_method_call (instance, fns, args,
- TYPE_BINFO (BINFO_TYPE (binfo)),
- flags, /*fn=*/NULL,
- complain);
+ ret = build_new_method_call (instance, fns, args,
+ TYPE_BINFO (BINFO_TYPE (binfo)),
+ flags, /*fn=*/NULL,
+ complain);
+
+ if (allocated != NULL)
+ release_tree_vector (allocated);
+
+ return ret;
}
/* Return the NAME, as a C string. The NAME indicates a function that
@@ -5758,10 +5995,11 @@ name_as_c_string (tree name, tree type, bool *free_p)
}
/* Build a call to "INSTANCE.FN (ARGS)". If FN_P is non-NULL, it will
- be set, upon return, to the function called. */
+ be set, upon return, to the function called. ARGS may be NULL.
+ This may change ARGS. */
tree
-build_new_method_call (tree instance, tree fns, tree args,
+build_new_method_call (tree instance, tree fns, VEC(tree,gc) **args,
tree conversion_path, int flags,
tree *fn_p, tsubst_flags_t complain)
{
@@ -5770,9 +6008,11 @@ build_new_method_call (tree instance, tree fns, tree args,
tree basetype = NULL_TREE;
tree access_binfo;
tree optype;
- tree mem_args = NULL_TREE, instance_ptr;
+ tree first_mem_arg = NULL_TREE;
+ tree instance_ptr;
tree name;
- tree user_args;
+ bool skip_first_for_error;
+ VEC(tree,gc) *user_args;
tree call;
tree fn;
tree class_type;
@@ -5780,7 +6020,7 @@ build_new_method_call (tree instance, tree fns, tree args,
bool any_viable_p;
tree orig_instance;
tree orig_fns;
- tree orig_args;
+ VEC(tree,gc) *orig_args = NULL;
void *p;
gcc_assert (instance != NULL_TREE);
@@ -5790,8 +6030,7 @@ build_new_method_call (tree instance, tree fns, tree args,
*fn_p = NULL_TREE;
if (error_operand_p (instance)
- || error_operand_p (fns)
- || args == error_mark_node)
+ || error_operand_p (fns))
return error_mark_node;
if (!BASELINK_P (fns))
@@ -5803,7 +6042,6 @@ build_new_method_call (tree instance, tree fns, tree args,
orig_instance = instance;
orig_fns = fns;
- orig_args = args;
/* Dismantle the baselink to collect all the information we need. */
if (!conversion_path)
@@ -5828,16 +6066,20 @@ build_new_method_call (tree instance, tree fns, tree args,
if (processing_template_decl)
{
+ orig_args = args == NULL ? NULL : make_tree_vector_copy (*args);
instance = build_non_dependent_expr (instance);
- args = build_non_dependent_args (orig_args);
- }
-
- /* The USER_ARGS are the arguments we will display to users if an
- error occurs. The USER_ARGS should not include any
- compiler-generated arguments. The "this" pointer hasn't been
- added yet. However, we must remove the VTT pointer if this is a
- call to a base-class constructor or destructor. */
- user_args = args;
+ if (args != NULL)
+ make_args_non_dependent (*args);
+ }
+
+ /* Figure out whether to skip the first argument for the error
+ message we will display to users if an error occurs. We don't
+ want to display any compiler-generated arguments. The "this"
+ pointer hasn't been added yet. However, we must remove the VTT
+ pointer if this is a call to a base-class constructor or
+ destructor. */
+ skip_first_for_error = false;
+ user_args = args == NULL ? NULL : *args;
if (IDENTIFIER_CTOR_OR_DTOR_P (name))
{
/* Callers should explicitly indicate whether they want to construct
@@ -5848,13 +6090,16 @@ build_new_method_call (tree instance, tree fns, tree args,
/* Remove the VTT pointer, if present. */
if ((name == base_ctor_identifier || name == base_dtor_identifier)
&& CLASSTYPE_VBASECLASSES (basetype))
- user_args = TREE_CHAIN (user_args);
+ skip_first_for_error = true;
}
/* Process the argument list. */
- args = resolve_args (args);
- if (args == error_mark_node)
- return error_mark_node;
+ if (args != NULL && *args != NULL)
+ {
+ *args = resolve_args (*args);
+ if (*args == NULL)
+ return error_mark_node;
+ }
instance_ptr = build_this (instance);
@@ -5874,17 +6119,17 @@ build_new_method_call (tree instance, tree fns, tree args,
/* If CONSTRUCTOR_IS_DIRECT_INIT is set, this was a T{ } form
initializer, not T({ }). If the type doesn't have a list ctor,
break apart the list into separate ctor args. */
- if (DECL_CONSTRUCTOR_P (fn) && args
- && BRACE_ENCLOSED_INITIALIZER_P (TREE_VALUE (args))
- && CONSTRUCTOR_IS_DIRECT_INIT (TREE_VALUE (args))
+ if (DECL_CONSTRUCTOR_P (fn) && args != NULL && !VEC_empty (tree, *args)
+ && BRACE_ENCLOSED_INITIALIZER_P (VEC_index (tree, *args, 0))
+ && CONSTRUCTOR_IS_DIRECT_INIT (VEC_index (tree, *args, 0))
&& !TYPE_HAS_LIST_CTOR (basetype))
{
- gcc_assert (TREE_CHAIN (args) == NULL_TREE);
- args = ctor_to_list (TREE_VALUE (args));
+ gcc_assert (VEC_length (tree, *args) == 1);
+ *args = ctor_to_vec (VEC_index (tree, *args, 0));
}
class_type = (conversion_path ? BINFO_TYPE (conversion_path) : NULL_TREE);
- mem_args = tree_cons (NULL_TREE, instance_ptr, args);
+ first_mem_arg = instance_ptr;
/* Get the high-water mark for the CONVERSION_OBSTACK. */
p = conversion_obstack_alloc (0);
@@ -5892,7 +6137,7 @@ build_new_method_call (tree instance, tree fns, tree args,
for (fn = fns; fn; fn = OVL_NEXT (fn))
{
tree t = OVL_CURRENT (fn);
- tree this_arglist;
+ tree this_first_arg;
/* We can end up here for copy-init of same or base class. */
if ((flags & LOOKUP_ONLYCONVERTING)
@@ -5900,16 +6145,18 @@ build_new_method_call (tree instance, tree fns, tree args,
continue;
if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
- this_arglist = mem_args;
+ this_first_arg = first_mem_arg;
else
- this_arglist = args;
+ this_first_arg = NULL_TREE;
if (TREE_CODE (t) == TEMPLATE_DECL)
/* A member template. */
add_template_candidate (&candidates, t,
class_type,
explicit_targs,
- this_arglist, optype,
+ this_first_arg,
+ args == NULL ? NULL : *args,
+ optype,
access_binfo,
conversion_path,
flags,
@@ -5917,7 +6164,8 @@ build_new_method_call (tree instance, tree fns, tree args,
else if (! template_only)
add_function_candidate (&candidates, t,
class_type,
- this_arglist,
+ this_first_arg,
+ args == NULL ? NULL : *args,
access_binfo,
conversion_path,
flags);
@@ -5934,10 +6182,14 @@ build_new_method_call (tree instance, tree fns, tree args,
{
char *pretty_name;
bool free_p;
+ tree arglist;
pretty_name = name_as_c_string (name, basetype, &free_p);
+ arglist = build_tree_list_vec (user_args);
+ if (skip_first_for_error)
+ arglist = TREE_CHAIN (arglist);
error ("no matching function for call to %<%T::%s(%A)%#V%>",
- basetype, pretty_name, user_args,
+ basetype, pretty_name, arglist,
TREE_TYPE (TREE_TYPE (instance_ptr)));
if (free_p)
free (pretty_name);
@@ -5953,12 +6205,16 @@ build_new_method_call (tree instance, tree fns, tree args,
{
char *pretty_name;
bool free_p;
+ tree arglist;
if (complain & tf_error)
{
pretty_name = name_as_c_string (name, basetype, &free_p);
+ arglist = build_tree_list_vec (user_args);
+ if (skip_first_for_error)
+ arglist = TREE_CHAIN (arglist);
error ("call of overloaded %<%s(%A)%> is ambiguous", pretty_name,
- user_args);
+ arglist);
print_z_candidates (candidates);
if (free_p)
free (pretty_name);
@@ -6039,7 +6295,7 @@ build_new_method_call (tree instance, tree fns, tree args,
}
if (TREE_CODE (call) == INDIRECT_REF)
call = TREE_OPERAND (call, 0);
- call = (build_min_non_dep_call_list
+ call = (build_min_non_dep_call_vec
(call,
build_min (COMPONENT_REF, TREE_TYPE (CALL_EXPR_FN (call)),
orig_instance, orig_fns, NULL_TREE),
@@ -6052,6 +6308,9 @@ build_new_method_call (tree instance, tree fns, tree args,
/* Free all the conversions we allocated. */
obstack_free (&conversion_obstack, p);
+ if (orig_args != NULL)
+ release_tree_vector (orig_args);
+
return call;
}
@@ -6974,7 +7233,7 @@ tourney (struct z_candidate *candidates)
bool
can_convert (tree to, tree from)
{
- return can_convert_arg (to, from, NULL_TREE, LOOKUP_NORMAL);
+ return can_convert_arg (to, from, NULL_TREE, LOOKUP_IMPLICIT);
}
/* Returns nonzero if ARG (of type FROM) can be converted to TO. */
@@ -7002,7 +7261,7 @@ can_convert_arg (tree to, tree from, tree arg, int flags)
/* Like can_convert_arg, but allows dubious conversions as well. */
bool
-can_convert_arg_bad (tree to, tree from, tree arg)
+can_convert_arg_bad (tree to, tree from, tree arg, int flags)
{
conversion *t;
void *p;
@@ -7011,7 +7270,7 @@ can_convert_arg_bad (tree to, tree from, tree arg)
p = conversion_obstack_alloc (0);
/* Try to perform the conversion. */
t = implicit_conversion (to, from, arg, /*c_cast_p=*/false,
- LOOKUP_NORMAL);
+ flags);
/* Free all the conversions we allocated. */
obstack_free (&conversion_obstack, p);
@@ -7025,7 +7284,7 @@ can_convert_arg_bad (tree to, tree from, tree arg)
doing a bad conversion, convert_like will complain. */
tree
-perform_implicit_conversion (tree type, tree expr, tsubst_flags_t complain)
+perform_implicit_conversion_flags (tree type, tree expr, tsubst_flags_t complain, int flags)
{
conversion *conv;
void *p;
@@ -7038,11 +7297,21 @@ perform_implicit_conversion (tree type, tree expr, tsubst_flags_t complain)
conv = implicit_conversion (type, TREE_TYPE (expr), expr,
/*c_cast_p=*/false,
- LOOKUP_NORMAL);
+ flags);
+
if (!conv)
{
if (complain & tf_error)
- error ("could not convert %qE to %qT", expr, type);
+ {
+ /* If expr has unknown type, then it is an overloaded function.
+ Call instantiate_type to get good error messages. */
+ if (TREE_TYPE (expr) == unknown_type_node)
+ instantiate_type (type, expr, complain);
+ else if (invalid_nonstatic_memfn_p (expr, complain))
+ /* We gave an error. */;
+ else
+ error ("could not convert %qE to %qT", expr, type);
+ }
expr = error_mark_node;
}
else if (processing_template_decl)
@@ -7062,6 +7331,12 @@ perform_implicit_conversion (tree type, tree expr, tsubst_flags_t complain)
return expr;
}
+tree
+perform_implicit_conversion (tree type, tree expr, tsubst_flags_t complain)
+{
+ return perform_implicit_conversion_flags (type, expr, complain, LOOKUP_IMPLICIT);
+}
+
/* Convert EXPR to TYPE (as a direct-initialization) if that is
permitted. If the conversion is valid, the converted expression is
returned. Otherwise, NULL_TREE is returned, except in the case
@@ -7091,9 +7366,10 @@ perform_direct_initialization_if_possible (tree type,
ill-formed. */
if (CLASS_TYPE_P (type))
{
+ VEC(tree,gc) *args = make_tree_vector_single (expr);
expr = build_special_member_call (NULL_TREE, complete_ctor_identifier,
- build_tree_list (NULL_TREE, expr),
- type, LOOKUP_NORMAL, complain);
+ &args, type, LOOKUP_NORMAL, complain);
+ release_tree_vector (args);
return build_cplus_new (type, expr);
}
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 6ad941510ba..b762019cf83 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -295,7 +295,7 @@ build_base_path (enum tree_code code,
/* Don't bother with the calculations inside sizeof; they'll ICE if the
source type is incomplete and the pointer value doesn't matter. */
- if (skip_evaluation)
+ if (cp_unevaluated_operand != 0)
{
expr = build_nop (build_pointer_type (target_type), expr);
if (!want_pointer)
@@ -626,7 +626,7 @@ build_vtbl_ref_1 (tree instance, tree idx)
vtbl = build_vfield_ref (instance, basetype);
- aref = build_array_ref (vtbl, idx, input_location);
+ aref = build_array_ref (input_location, vtbl, idx);
TREE_CONSTANT (aref) |= TREE_CONSTANT (vtbl) && TREE_CONSTANT (idx);
return aref;
@@ -2705,7 +2705,7 @@ check_bitfield_decl (tree field)
DECL_INITIAL (field) = NULL_TREE;
/* Detect invalid bit-field type. */
- if (!INTEGRAL_TYPE_P (type))
+ if (!INTEGRAL_OR_ENUMERATION_TYPE_P (type))
{
error ("bit-field %q+#D with non-integral type", field);
w = error_mark_node;
@@ -3636,7 +3636,8 @@ build_base_field (record_layout_info rli, tree binfo,
CLASSTYPE_EMPTY_P (t) = 0;
/* Create the FIELD_DECL. */
- decl = build_decl (FIELD_DECL, NULL_TREE, CLASSTYPE_AS_BASE (basetype));
+ decl = build_decl (input_location,
+ FIELD_DECL, NULL_TREE, CLASSTYPE_AS_BASE (basetype));
DECL_ARTIFICIAL (decl) = 1;
DECL_IGNORED_P (decl) = 1;
DECL_FIELD_CONTEXT (decl) = t;
@@ -4428,7 +4429,8 @@ create_vtable_ptr (tree t, tree* virtuals_p)
stores cannot alias stores to void*! */
tree field;
- field = build_decl (FIELD_DECL, get_vfield_name (t), vtbl_ptr_type_node);
+ field = build_decl (input_location,
+ FIELD_DECL, get_vfield_name (t), vtbl_ptr_type_node);
DECL_VIRTUAL_P (field) = 1;
DECL_ARTIFICIAL (field) = 1;
DECL_FIELD_CONTEXT (field) = t;
@@ -4864,7 +4866,7 @@ layout_class_type (tree t, tree *virtuals_p)
if (DECL_C_BIT_FIELD (field)
&& INT_CST_LT (TYPE_SIZE (type), DECL_SIZE (field)))
{
- integer_type_kind itk;
+ unsigned int itk;
tree integer_type;
bool was_unnamed_p = false;
/* We must allocate the bits as if suitably aligned for the
@@ -5008,7 +5010,8 @@ layout_class_type (tree t, tree *virtuals_p)
{
tree padding_field;
- padding_field = build_decl (FIELD_DECL,
+ padding_field = build_decl (input_location,
+ FIELD_DECL,
NULL_TREE,
char_type_node);
DECL_BIT_FIELD (padding_field) = 1;
@@ -5096,7 +5099,8 @@ layout_class_type (tree t, tree *virtuals_p)
for (field = TYPE_FIELDS (t); field; field = TREE_CHAIN (field))
if (TREE_CODE (field) == FIELD_DECL)
{
- *next_field = build_decl (FIELD_DECL,
+ *next_field = build_decl (input_location,
+ FIELD_DECL,
DECL_NAME (field),
TREE_TYPE (field));
DECL_CONTEXT (*next_field) = base_t;
@@ -5137,7 +5141,8 @@ layout_class_type (tree t, tree *virtuals_p)
/* Make sure not to create any structures with zero size. */
if (integer_zerop (rli_size_unit_so_far (rli)) && CLASSTYPE_EMPTY_P (t))
place_field (rli,
- build_decl (FIELD_DECL, NULL_TREE, char_type_node));
+ build_decl (input_location,
+ FIELD_DECL, NULL_TREE, char_type_node));
/* Let the back end lay out the type. */
finish_record_layout (rli, /*free_p=*/true);
@@ -6072,6 +6077,9 @@ resolve_address_of_overloaded_function (tree target_type,
tree target_arg_types;
tree target_ret_type;
tree fns;
+ tree *args;
+ unsigned int nargs, ia;
+ tree arg;
if (is_ptrmem)
target_fn_type
@@ -6085,6 +6093,14 @@ resolve_address_of_overloaded_function (tree target_type,
if (TREE_CODE (target_fn_type) == METHOD_TYPE)
target_arg_types = TREE_CHAIN (target_arg_types);
+ nargs = list_length (target_arg_types);
+ args = XALLOCAVEC (tree, nargs);
+ for (arg = target_arg_types, ia = 0;
+ arg != NULL_TREE && arg != void_list_node;
+ arg = TREE_CHAIN (arg), ++ia)
+ args[ia] = TREE_VALUE (arg);
+ nargs = ia;
+
for (fns = overload; fns; fns = OVL_NEXT (fns))
{
tree fn = OVL_CURRENT (fns);
@@ -6104,9 +6120,9 @@ resolve_address_of_overloaded_function (tree target_type,
/* Try to do argument deduction. */
targs = make_tree_vec (DECL_NTPARMS (fn));
- if (fn_type_unification (fn, explicit_targs, targs,
- target_arg_types, target_ret_type,
- DEDUCE_EXACT, LOOKUP_NORMAL))
+ if (fn_type_unification (fn, explicit_targs, targs, args, nargs,
+ target_ret_type, DEDUCE_EXACT,
+ LOOKUP_NORMAL))
/* Argument deduction failed. */
continue;
diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
index 466415752ea..29f4f382e5c 100644
--- a/gcc/cp/cp-gimplify.c
+++ b/gcc/cp/cp-gimplify.c
@@ -50,7 +50,7 @@ static tree bc_label[2];
static tree
begin_bc_block (enum bc_t bc)
{
- tree label = create_artificial_label ();
+ tree label = create_artificial_label (input_location);
TREE_CHAIN (label) = bc_label[bc];
bc_label[bc] = label;
return label;
@@ -169,9 +169,9 @@ genericize_if_stmt (tree *stmt_p)
else_ = ELSE_CLAUSE (stmt);
if (!then_)
- then_ = build_empty_stmt ();
+ then_ = build_empty_stmt (locus);
if (!else_)
- else_ = build_empty_stmt ();
+ else_ = build_empty_stmt (locus);
if (integer_nonzerop (cond) && !TREE_SIDE_EFFECTS (else_))
stmt = then_;
@@ -226,7 +226,7 @@ gimplify_cp_loop (tree cond, tree body, tree incr, bool cond_is_first)
back through the main gimplifier to lower it. Given that we
have to gimplify the loop body NOW so that we can resolve
break/continue stmts, seems easier to just expand to gotos. */
- top = gimple_build_label (create_artificial_label ());
+ top = gimple_build_label (create_artificial_label (stmt_locus));
/* If we have an exit condition, then we build an IF with gotos either
out of the loop, or to the top of it. If there's no exit condition,
@@ -247,7 +247,8 @@ gimplify_cp_loop (tree cond, tree body, tree incr, bool cond_is_first)
{
if (incr)
{
- entry = gimple_build_label (create_artificial_label ());
+ entry = gimple_build_label
+ (create_artificial_label (stmt_locus));
stmt = gimple_build_goto (gimple_label_label (entry));
}
else
@@ -334,7 +335,7 @@ gimplify_switch_stmt (tree *stmt_p, gimple_seq *pre_p)
body = SWITCH_STMT_BODY (stmt);
if (!body)
- body = build_empty_stmt ();
+ body = build_empty_stmt (stmt_locus);
t = build3 (SWITCH_EXPR, SWITCH_STMT_TYPE (stmt),
SWITCH_STMT_COND (stmt), body, NULL_TREE);
@@ -939,7 +940,7 @@ cxx_omp_clause_apply_fn (tree fn, tree arg1, tree arg2)
append_to_statement_list (t, &ret);
}
- lab = create_artificial_label ();
+ lab = create_artificial_label (input_location);
t = build1 (LABEL_EXPR, void_type_node, lab);
append_to_statement_list (t, &ret);
diff --git a/gcc/cp/cp-objcp-common.h b/gcc/cp/cp-objcp-common.h
index 1ce9d36a652..6723a853ced 100644
--- a/gcc/cp/cp-objcp-common.h
+++ b/gcc/cp/cp-objcp-common.h
@@ -78,8 +78,6 @@ extern bool cp_function_decl_explicit_p (tree decl);
#define LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL cxx_warn_unused_global_decl
#undef LANG_HOOKS_WRITE_GLOBALS
#define LANG_HOOKS_WRITE_GLOBALS cp_write_global_declarations
-#undef LANG_HOOKS_COMDAT_GROUP
-#define LANG_HOOKS_COMDAT_GROUP cxx_comdat_group
#undef LANG_HOOKS_BUILTIN_FUNCTION
#define LANG_HOOKS_BUILTIN_FUNCTION cxx_builtin_function
#undef LANG_HOOKS_BUILTIN_FUNCTION_EXT_SCOPE
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index f3f71c51602..5e200a28c93 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -755,7 +755,9 @@ struct GTY(()) saved_scope {
int x_processing_specialization;
BOOL_BITFIELD x_processing_explicit_instantiation : 1;
BOOL_BITFIELD need_pop_function_context : 1;
- BOOL_BITFIELD skip_evaluation : 1;
+
+ int unevaluated_operand;
+ int inhibit_evaluation_warnings;
struct stmt_tree_s x_stmt_tree;
@@ -1963,8 +1965,8 @@ struct GTY(()) lang_decl {
is mutable. */
#define DECL_MUTABLE_P(NODE) (DECL_LANG_FLAG_0 (NODE))
-/* Nonzero for _DECL means that this constructor is a non-converting
- constructor. */
+/* Nonzero for _DECL means that this constructor or conversion function is
+ non-converting. */
#define DECL_NONCONVERTING_P(NODE) \
(DECL_LANG_SPECIFIC (NODE)->decl_flags.nonconverting)
@@ -2232,6 +2234,9 @@ extern void decl_shadowed_for_var_insert (tree, tree);
#define TI_TEMPLATE(NODE) (TREE_PURPOSE (NODE))
#define TI_ARGS(NODE) (TREE_VALUE (NODE))
#define TI_PENDING_TEMPLATE_FLAG(NODE) TREE_LANG_FLAG_1 (NODE)
+/* The list of typedefs - used in the template - that need
+ access checking at template instantiation time. */
+#define TI_TYPEDEFS_NEEDING_ACCESS_CHECKING(NODE) (TREE_CHAIN (NODE))
/* We use TREE_VECs to hold template arguments. If there is only one
level of template arguments, then the TREE_VEC contains the
@@ -3160,11 +3165,6 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
&& TREE_CODE (DECL_TEMPLATE_RESULT (NODE)) == TYPE_DECL \
&& !DECL_TEMPLATE_TEMPLATE_PARM_P (NODE))
-/* The chained list of typedefs that are referenced in templates.
- These typedefs need to be access checked at template instantiation time.
- There are put here at parsing time. */
-#define MEMBER_TYPES_NEEDING_ACCESS_CHECK(NODE) DECL_ACCESS (NODE)
-
/* Nonzero if NODE which declares a type. */
#define DECL_DECLARES_TYPE_P(NODE) \
(TREE_CODE (NODE) == TYPE_DECL || DECL_CLASS_TEMPLATE_P (NODE))
@@ -3466,7 +3466,7 @@ enum tag_types {
};
/* The various kinds of lvalues we distinguish. */
-enum cp_lvalue_kind {
+enum cp_lvalue_kind_flags {
clk_none = 0, /* Things that are not an lvalue. */
clk_ordinary = 1, /* An ordinary lvalue. */
clk_class = 2, /* An rvalue of class-type. */
@@ -3475,7 +3475,7 @@ enum cp_lvalue_kind {
};
/* This type is used for parameters and variables which hold
- combinations of the flags in enum cp_lvalue_kind. */
+ combinations of the flags in enum cp_lvalue_kind_flags. */
typedef int cp_lvalue_kind;
/* Various kinds of template specialization, instantiation, etc. */
@@ -3575,7 +3575,7 @@ enum tsubst_flags {
typedef int tsubst_flags_t;
/* The kind of checking we can do looking in a class hierarchy. */
-enum base_access {
+enum base_access_flags {
ba_any = 0, /* Do not check access, allow an ambiguous base,
prefer a non-virtual base */
ba_unique = 1 << 0, /* Must be a unique base. */
@@ -3586,7 +3586,7 @@ enum base_access {
};
/* This type is used for parameters and variables which hold
- combinations of the flags in enum base_access. */
+ combinations of the flags in enum base_access_flags. */
typedef int base_access;
/* The various kinds of access check during parsing. */
@@ -3623,6 +3623,14 @@ extern GTY(()) tree integer_three_node;
function, two inside the body of a function in a local class, etc.) */
extern int function_depth;
+/* In parser.c. */
+
+/* Nonzero if we are parsing an unevaluated operand: an operand to
+ sizeof, typeof, or alignof. This is a count since operands to
+ sizeof can be nested. */
+
+extern int cp_unevaluated_operand;
+
/* in pt.c */
/* These values are used for the `STRICT' parameter to type_unification and
@@ -3758,8 +3766,10 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, OP_FLAG, TYPENAME_FLAG };
/* Even if the function found by lookup is a virtual function, it
should be called directly. */
#define LOOKUP_NONVIRTUAL (1 << 2)
-/* Non-converting (i.e., "explicit") constructors are not tried. */
+/* Non-converting (i.e., "explicit") constructors are not tried. This flag
+ indicates that we are not performing direct-initialization. */
#define LOOKUP_ONLYCONVERTING (1 << 3)
+#define LOOKUP_IMPLICIT (LOOKUP_NORMAL | LOOKUP_ONLYCONVERTING)
/* If a temporary is created, it should be created so that it lives
as long as the current variable bindings; otherwise it only lives
until the end of the complete-expression. It also forces
@@ -3793,6 +3803,8 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, OP_FLAG, TYPENAME_FLAG };
/* Avoid user-defined conversions for the first parameter of a copy
constructor. */
#define LOOKUP_NO_COPY_CTOR_CONVERSION (LOOKUP_NO_NARROWING << 1)
+/* This is the first parameter of a copy constructor. */
+#define LOOKUP_COPY_PARM (LOOKUP_NO_COPY_CTOR_CONVERSION << 1)
#define LOOKUP_NAMESPACES_ONLY(F) \
(((F) & LOOKUP_PREFER_NAMESPACES) && !((F) & LOOKUP_PREFER_TYPES))
@@ -4175,21 +4187,24 @@ extern bool null_ptr_cst_p (tree);
extern bool sufficient_parms_p (const_tree);
extern tree type_decays_to (tree);
extern tree build_user_type_conversion (tree, tree, int);
-extern tree build_new_function_call (tree, tree, bool,
+extern tree build_new_function_call (tree, VEC(tree,gc) **, bool,
tsubst_flags_t);
-extern tree build_operator_new_call (tree, tree, tree *, tree *,
- tree *);
-extern tree build_new_method_call (tree, tree, tree, tree, int,
- tree *, tsubst_flags_t);
-extern tree build_special_member_call (tree, tree, tree, tree, int,
- tsubst_flags_t);
+extern tree build_operator_new_call (tree, VEC(tree,gc) **, tree *,
+ tree *, tree *);
+extern tree build_new_method_call (tree, tree, VEC(tree,gc) **,
+ tree, int, tree *,
+ tsubst_flags_t);
+extern tree build_special_member_call (tree, tree, VEC(tree,gc) **,
+ tree, int, tsubst_flags_t);
extern tree build_new_op (enum tree_code, int, tree,
tree, tree, bool *,
tsubst_flags_t);
+extern tree build_op_call (tree, VEC(tree,gc) **,
+ tsubst_flags_t);
extern tree build_op_delete_call (enum tree_code, tree, tree, bool, tree, tree);
extern bool can_convert (tree, tree);
extern bool can_convert_arg (tree, tree, tree, int);
-extern bool can_convert_arg_bad (tree, tree, tree);
+extern bool can_convert_arg_bad (tree, tree, tree, int);
extern bool enforce_access (tree, tree, tree);
extern tree convert_default_arg (tree, tree, tree, int);
extern tree convert_arg_to_ellipsis (tree);
@@ -4203,6 +4218,7 @@ extern tree initialize_reference (tree, tree, tree, tree *);
extern tree make_temporary_var_for_ref_to_temp (tree, tree);
extern tree strip_top_quals (tree);
extern tree perform_implicit_conversion (tree, tree, tsubst_flags_t);
+extern tree perform_implicit_conversion_flags (tree, tree, tsubst_flags_t, int);
extern tree perform_direct_initialization_if_possible (tree, tree, bool,
tsubst_flags_t);
extern tree in_charge_arg_for_name (tree);
@@ -4369,7 +4385,7 @@ extern tree cxx_builtin_function (tree decl);
extern tree cxx_builtin_function_ext_scope (tree decl);
extern tree check_elaborated_type_specifier (enum tag_types, tree, bool);
extern void warn_extern_redeclared_static (tree, tree);
-extern const char *cxx_comdat_group (tree);
+extern tree cxx_comdat_group (tree);
extern bool cp_missing_noreturn_ok_p (tree);
extern void initialize_artificial_var (tree, tree);
extern tree check_var_type (tree, tree);
@@ -4377,7 +4393,7 @@ extern tree reshape_init (tree, tree);
extern bool defer_mark_used_calls;
extern GTY(()) VEC(tree, gc) *deferred_mark_used_calls;
-extern tree finish_case_label (tree, tree);
+extern tree finish_case_label (location_t, tree, tree);
extern tree cxx_maybe_build_cleanup (tree);
/* in decl2.c */
@@ -4406,7 +4422,7 @@ extern void determine_visibility (tree);
extern void constrain_class_visibility (tree);
extern void import_export_decl (tree);
extern tree build_cleanup (tree);
-extern tree build_offset_ref_call_from_tree (tree, tree);
+extern tree build_offset_ref_call_from_tree (tree, VEC(tree,gc) **);
extern void check_default_args (tree);
extern void mark_used (tree);
extern void finish_static_data_member_decl (tree, tree, bool, tree, int);
@@ -4470,7 +4486,8 @@ extern tree build_zero_init (tree, tree, bool);
extern tree build_value_init (tree);
extern tree build_value_init_noctor (tree);
extern tree build_offset_ref (tree, tree, bool);
-extern tree build_new (tree, tree, tree, tree, int,
+extern tree build_new (VEC(tree,gc) **, tree, tree,
+ VEC(tree,gc) **, int,
tsubst_flags_t);
extern tree build_vec_init (tree, tree, tree, bool, int,
tsubst_flags_t);
@@ -4538,7 +4555,8 @@ extern tree type_uses_auto (tree);
extern void append_type_to_template_for_access_check (tree, tree, tree);
extern tree splice_late_return_type (tree, tree);
extern bool is_auto (const_tree);
-extern tree process_template_parm (tree, tree, bool, bool);
+extern tree process_template_parm (tree, location_t, tree,
+ bool, bool);
extern tree end_template_parm_list (tree);
extern void end_template_decl (void);
extern bool check_default_tmpl_args (tree, tree, int, int, int);
@@ -4552,7 +4570,8 @@ extern int uses_template_parms (tree);
extern int uses_template_parms_level (tree, int);
extern tree instantiate_class_template (tree);
extern tree instantiate_template (tree, tree, tsubst_flags_t);
-extern int fn_type_unification (tree, tree, tree, tree,
+extern int fn_type_unification (tree, tree, tree,
+ const tree *, unsigned int,
tree, unification_kind_t, int);
extern void mark_decl_instantiated (tree, int);
extern int more_specialized_fn (tree, tree, int);
@@ -4565,6 +4584,7 @@ extern bool template_parameter_pack_p (const_tree);
extern tree make_pack_expansion (tree);
extern bool check_for_bare_parameter_packs (tree);
extern tree get_template_info (tree);
+extern tree get_types_needing_access_check (tree);
extern int template_class_depth (tree);
extern int is_specialization_of (tree, tree);
extern bool is_specialization_of_friend (tree, tree);
@@ -4590,7 +4610,7 @@ extern bool any_dependent_template_arguments_p (const_tree);
extern bool dependent_template_p (tree);
extern bool dependent_template_id_p (tree, tree);
extern bool type_dependent_expression_p (tree);
-extern bool any_type_dependent_arguments_p (const_tree);
+extern bool any_type_dependent_arguments_p (const VEC(tree,gc) *);
extern bool type_dependent_expression_p_push (tree);
extern bool value_dependent_expression_p (tree);
extern bool any_value_dependent_elements_p (const_tree);
@@ -4598,7 +4618,7 @@ extern bool dependent_omp_for_p (tree, tree, tree, tree);
extern tree resolve_typename_type (tree, bool);
extern tree template_for_substitution (tree);
extern tree build_non_dependent_expr (tree);
-extern tree build_non_dependent_args (tree);
+extern void make_args_non_dependent (VEC(tree,gc) *);
extern bool reregister_specialization (tree, tree, tree);
extern tree fold_non_dependent_expr (tree);
extern bool explicit_class_specialization_p (tree);
@@ -4746,9 +4766,9 @@ extern tree begin_stmt_expr (void);
extern tree finish_stmt_expr_expr (tree, tree);
extern tree finish_stmt_expr (tree, bool);
extern tree stmt_expr_value_expr (tree);
-extern tree perform_koenig_lookup (tree, tree);
-extern tree finish_call_expr (tree, tree, bool, bool,
- tsubst_flags_t);
+extern tree perform_koenig_lookup (tree, VEC(tree,gc) *);
+extern tree finish_call_expr (tree, VEC(tree,gc) **, bool,
+ bool, tsubst_flags_t);
extern tree finish_increment_expr (tree, enum tree_code);
extern tree finish_this_expr (void);
extern tree finish_pseudo_destructor_expr (tree, tree, tree);
@@ -4821,7 +4841,7 @@ extern void init_tree (void);
extern int pod_type_p (const_tree);
extern bool class_tmpl_impl_spec_p (const_tree);
extern int zero_init_p (const_tree);
-extern tree canonical_type_variant (tree);
+extern tree strip_typedefs (tree);
extern tree copy_binfo (tree, tree, tree,
tree *, int);
extern int member_p (const_tree);
@@ -4830,7 +4850,7 @@ extern bool builtin_valid_in_constant_expr_p (const_tree);
extern tree build_min (enum tree_code, tree, ...);
extern tree build_min_nt (enum tree_code, ...);
extern tree build_min_non_dep (enum tree_code, tree, ...);
-extern tree build_min_non_dep_call_list (tree, tree, tree);
+extern tree build_min_non_dep_call_vec (tree, tree, VEC(tree,gc) *);
extern tree build_cplus_new (tree, tree);
extern tree build_aggr_init_expr (tree, tree);
extern tree get_target_expr (tree);
@@ -4927,9 +4947,11 @@ extern tree build_x_indirect_ref (tree, const char *,
tsubst_flags_t);
extern tree cp_build_indirect_ref (tree, const char *,
tsubst_flags_t);
-extern tree build_array_ref (tree, tree, location_t);
+extern tree build_array_ref (location_t, tree, tree);
extern tree get_member_function_from_ptrfunc (tree *, tree);
extern tree cp_build_function_call (tree, tree, tsubst_flags_t);
+extern tree cp_build_function_call_vec (tree, VEC(tree,gc) **,
+ tsubst_flags_t);
extern tree build_x_binary_op (enum tree_code, tree,
enum tree_code, tree,
enum tree_code, bool *,
@@ -4943,13 +4965,14 @@ extern tree unary_complex_lvalue (enum tree_code, tree);
extern tree build_x_conditional_expr (tree, tree, tree,
tsubst_flags_t);
extern tree build_x_compound_expr_from_list (tree, const char *);
+extern tree build_x_compound_expr_from_vec (VEC(tree,gc) *, const char *);
extern tree build_x_compound_expr (tree, tree, tsubst_flags_t);
-extern tree build_compound_expr (tree, tree);
+extern tree build_compound_expr (location_t, tree, tree);
extern tree cp_build_compound_expr (tree, tree, tsubst_flags_t);
extern tree build_static_cast (tree, tree, tsubst_flags_t);
extern tree build_reinterpret_cast (tree, tree, tsubst_flags_t);
extern tree build_const_cast (tree, tree, tsubst_flags_t);
-extern tree build_c_cast (tree, tree);
+extern tree build_c_cast (location_t, tree, tree);
extern tree cp_build_c_cast (tree, tree, tsubst_flags_t);
extern tree build_x_modify_expr (tree, enum tree_code, tree,
tsubst_flags_t);
@@ -5004,9 +5027,10 @@ extern void readonly_error (tree, const char *);
extern void complete_type_check_abstract (tree);
extern int abstract_virtuals_error (tree, tree);
-extern tree store_init_value (tree, tree);
+extern tree store_init_value (tree, tree, int);
extern void check_narrowing (tree, tree);
extern tree digest_init (tree, tree);
+extern tree digest_init_flags (tree, tree, int);
extern tree build_scoped_ref (tree, tree, tree *);
extern tree build_x_arrow (tree);
extern tree build_m_component_ref (tree, tree);
diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
index c86fbdfe0da..dfd0ea81e75 100644
--- a/gcc/cp/cvt.c
+++ b/gcc/cp/cvt.c
@@ -1,6 +1,6 @@
/* Language-level data type conversion for GNU C++.
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
@@ -508,7 +508,7 @@ convert_from_reference (tree val)
{
if (TREE_CODE (TREE_TYPE (val)) == REFERENCE_TYPE)
{
- tree t = canonical_type_variant (TREE_TYPE (TREE_TYPE (val)));
+ tree t = TREE_TYPE (TREE_TYPE (val));
tree ref = build1 (INDIRECT_REF, t, val);
/* We *must* set TREE_READONLY when dereferencing a pointer to const,
@@ -565,7 +565,9 @@ cp_convert_and_check (tree type, tree expr)
result = cp_convert (type, expr);
- if (!skip_evaluation && !TREE_OVERFLOW_P (expr) && result != error_mark_node)
+ if (c_inhibit_evaluation_warnings == 0
+ && !TREE_OVERFLOW_P (expr)
+ && result != error_mark_node)
warnings_for_convert_and_check (type, expr, result);
return result;
@@ -581,6 +583,7 @@ ocp_convert (tree type, tree expr, int convtype, int flags)
tree e = expr;
enum tree_code code = TREE_CODE (type);
const char *invalid_conv_diag;
+ tree e1;
if (error_operand_p (e) || type == error_mark_node)
return error_mark_node;
@@ -629,6 +632,10 @@ ocp_convert (tree type, tree expr, int convtype, int flags)
}
}
+ e1 = targetm.convert_to_type (type, e);
+ if (e1)
+ return e1;
+
if (code == VOID_TYPE && (convtype & CONV_STATIC))
{
e = convert_to_void (e, /*implicit=*/NULL, tf_warning_or_error);
@@ -750,11 +757,15 @@ ocp_convert (tree type, tree expr, int convtype, int flags)
the target with the temp (see [dcl.init]). */
ctor = build_user_type_conversion (type, ctor, flags);
else
- ctor = build_special_member_call (NULL_TREE,
- complete_ctor_identifier,
- build_tree_list (NULL_TREE, ctor),
- type, flags,
- tf_warning_or_error);
+ {
+ VEC(tree,gc) *ctor_vec = make_tree_vector_single (ctor);
+ ctor = build_special_member_call (NULL_TREE,
+ complete_ctor_identifier,
+ &ctor_vec,
+ type, flags,
+ tf_warning_or_error);
+ release_tree_vector (ctor_vec);
+ }
if (ctor)
return build_cplus_new (type, ctor);
}
@@ -1181,6 +1192,9 @@ build_expr_type_conversion (int desires, tree expr, bool complain)
if (winner && winner == cand)
continue;
+ if (DECL_NONCONVERTING_P (cand))
+ continue;
+
candidate = non_reference (TREE_TYPE (TREE_TYPE (cand)));
switch (TREE_CODE (candidate))
@@ -1248,11 +1262,18 @@ build_expr_type_conversion (int desires, tree expr, bool complain)
tree
type_promotes_to (tree type)
{
+ tree promoted_type;
+
if (type == error_mark_node)
return error_mark_node;
type = TYPE_MAIN_VARIANT (type);
+ /* Check for promotions of target-defined types first. */
+ promoted_type = targetm.promoted_type (type);
+ if (promoted_type)
+ return promoted_type;
+
/* bool always promotes to int (not unsigned), even if it's the same
size. */
if (type == boolean_type_node)
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index fd944f713db..296d1438515 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -94,7 +94,7 @@ static tree get_atexit_node (void);
static tree get_dso_handle_node (void);
static tree start_cleanup_fn (void);
static void end_cleanup_fn (void);
-static tree cp_make_fname_decl (tree, int);
+static tree cp_make_fname_decl (location_t, tree, int);
static void initialize_predefined_identifiers (void);
static tree check_special_function_return_type
(special_function_kind, tree, tree);
@@ -743,7 +743,7 @@ poplevel (int keep, int reverse, int functionbody)
have pushed a statement list level. Pop that, create a new
BIND_EXPR for the block, and insert it into the stream. */
stmt = pop_stmt_list (current_binding_level->statement_list);
- stmt = c_build_bind_expr (block, stmt);
+ stmt = c_build_bind_expr (input_location, block, stmt);
add_stmt (stmt);
}
@@ -842,7 +842,7 @@ create_implicit_typedef (tree name, tree type)
{
tree decl;
- decl = build_decl (TYPE_DECL, name, type);
+ decl = build_decl (input_location, TYPE_DECL, name, type);
DECL_ARTIFICIAL (decl) = 1;
/* There are other implicit type declarations, like the one *within*
a class that allows you to write `S::S'. We must distinguish
@@ -1835,7 +1835,9 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
/* Merge the storage class information. */
merge_weak (newdecl, olddecl);
- DECL_ONE_ONLY (newdecl) |= DECL_ONE_ONLY (olddecl);
+ if (DECL_ONE_ONLY (olddecl))
+ DECL_COMDAT_GROUP (newdecl) = DECL_COMDAT_GROUP (olddecl);
+
DECL_DEFER_OUTPUT (newdecl) |= DECL_DEFER_OUTPUT (olddecl);
TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl);
TREE_STATIC (olddecl) = TREE_STATIC (newdecl) |= TREE_STATIC (olddecl);
@@ -1913,6 +1915,17 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
{
tree parm;
+ /* Merge parameter attributes. */
+ tree oldarg, newarg;
+ for (oldarg = DECL_ARGUMENTS(olddecl),
+ newarg = DECL_ARGUMENTS(newdecl);
+ oldarg && newarg;
+ oldarg = TREE_CHAIN(oldarg), newarg = TREE_CHAIN(newarg)) {
+ DECL_ATTRIBUTES (newarg)
+ = (*targetm.merge_decl_attributes) (oldarg, newarg);
+ DECL_ATTRIBUTES (oldarg) = DECL_ATTRIBUTES (newarg);
+ }
+
if (DECL_TEMPLATE_INSTANTIATION (olddecl)
&& !DECL_TEMPLATE_INSTANTIATION (newdecl))
{
@@ -2357,7 +2370,7 @@ make_label_decl (tree id, int local_p)
void **slot;
tree decl;
- decl = build_decl (LABEL_DECL, id, void_type_node);
+ decl = build_decl (input_location, LABEL_DECL, id, void_type_node);
DECL_CONTEXT (decl) = current_function_decl;
DECL_MODE (decl) = VOIDmode;
@@ -2784,7 +2797,7 @@ pop_switch (void)
is a bad place for one. */
tree
-finish_case_label (tree low_value, tree high_value)
+finish_case_label (location_t loc, tree low_value, tree high_value)
{
tree cond, r;
struct cp_binding_level *p;
@@ -2795,8 +2808,8 @@ finish_case_label (tree low_value, tree high_value)
/* For templates, just add the case label; we'll do semantic
analysis at instantiation-time. */
- label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
- return add_stmt (build_case_label (low_value, high_value, label));
+ label = build_decl (loc, LABEL_DECL, NULL_TREE, NULL_TREE);
+ return add_stmt (build_case_label (loc, low_value, high_value, label));
}
/* Find the condition on which this switch statement depends. */
@@ -2807,7 +2820,7 @@ finish_case_label (tree low_value, tree high_value)
if (!check_switch_goto (switch_stack->level))
return error_mark_node;
- r = c_add_case_label (switch_stack->cases, cond,
+ r = c_add_case_label (loc, switch_stack->cases, cond,
SWITCH_STMT_TYPE (switch_stack->switch_stmt),
low_value, high_value);
@@ -2904,7 +2917,7 @@ build_typename_type (tree context, tree name, tree fullname,
TYPENAME_IS_CLASS_P (t) = ti.class_p;
/* Build the corresponding TYPE_DECL. */
- d = build_decl (TYPE_DECL, name, t);
+ d = build_decl (input_location, TYPE_DECL, name, t);
TYPE_NAME (TREE_TYPE (d)) = d;
TYPE_STUB_DECL (TREE_TYPE (d)) = d;
DECL_CONTEXT (d) = FROB_CONTEXT (context);
@@ -3102,7 +3115,7 @@ make_unbound_class_template (tree context, tree name, tree parm_list,
SET_TYPE_STRUCTURAL_EQUALITY (t);
/* Build the corresponding TEMPLATE_DECL. */
- d = build_decl (TEMPLATE_DECL, name, t);
+ d = build_decl (input_location, TEMPLATE_DECL, name, t);
TYPE_NAME (TREE_TYPE (d)) = d;
TYPE_STUB_DECL (TREE_TYPE (d)) = d;
DECL_CONTEXT (d) = FROB_CONTEXT (context);
@@ -3139,7 +3152,7 @@ record_builtin_type (enum rid rid_index,
up built-in types by name. */
if (tname)
{
- tdecl = build_decl (TYPE_DECL, tname, type);
+ tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, tname, type);
DECL_ARTIFICIAL (tdecl) = 1;
SET_IDENTIFIER_GLOBAL_VALUE (tname, tdecl);
}
@@ -3147,7 +3160,7 @@ record_builtin_type (enum rid rid_index,
{
if (!tdecl)
{
- tdecl = build_decl (TYPE_DECL, rname, type);
+ tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, rname, type);
DECL_ARTIFICIAL (tdecl) = 1;
}
SET_IDENTIFIER_GLOBAL_VALUE (rname, tdecl);
@@ -3207,7 +3220,8 @@ record_builtin_java_type (const char* name, int size)
static void
record_unknown_type (tree type, const char* name)
{
- tree decl = pushdecl (build_decl (TYPE_DECL, get_identifier (name), type));
+ tree decl = pushdecl (build_decl (UNKNOWN_LOCATION,
+ TYPE_DECL, get_identifier (name), type));
/* Make sure the "unknown type" typedecl gets ignored for debug info. */
DECL_IGNORED_P (decl) = 1;
TYPE_DECL_SUPPRESS_DEBUG (decl) = 1;
@@ -3481,20 +3495,21 @@ cp_fname_init (const char* name, tree *type_p)
return init;
}
-/* Create the VAR_DECL for __FUNCTION__ etc. ID is the name to give the
- decl, NAME is the initialization string and TYPE_DEP indicates whether
- NAME depended on the type of the function. We make use of that to detect
- __PRETTY_FUNCTION__ inside a template fn. This is being done
- lazily at the point of first use, so we mustn't push the decl now. */
+/* Create the VAR_DECL for __FUNCTION__ etc. ID is the name to give
+ the decl, LOC is the location to give the decl, NAME is the
+ initialization string and TYPE_DEP indicates whether NAME depended
+ on the type of the function. We make use of that to detect
+ __PRETTY_FUNCTION__ inside a template fn. This is being done lazily
+ at the point of first use, so we mustn't push the decl now. */
static tree
-cp_make_fname_decl (tree id, int type_dep)
+cp_make_fname_decl (location_t loc, tree id, int type_dep)
{
const char *const name = (type_dep && processing_template_decl
? NULL : fname_as_string (type_dep));
tree type;
tree init = cp_fname_init (name, &type);
- tree decl = build_decl (VAR_DECL, id, type);
+ tree decl = build_decl (loc, VAR_DECL, id, type);
if (name)
free (CONST_CAST (char *, name));
@@ -4491,7 +4506,7 @@ maybe_deduce_size_from_array_init (tree decl, tree init)
cp_apply_type_quals_to_decl (cp_type_quals (TREE_TYPE (decl)), decl);
- layout_decl (decl, 0);
+ relayout_decl (decl);
}
}
@@ -5165,7 +5180,7 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup)
return build_aggr_init_full_exprs (decl, init, flags);
else if (TREE_CODE (init) != TREE_VEC)
{
- init_code = store_init_value (decl, init);
+ init_code = store_init_value (decl, init, flags);
if (pedantic && TREE_CODE (type) == ARRAY_TYPE
&& DECL_INITIAL (decl)
&& TREE_CODE (DECL_INITIAL (decl)) == STRING_CST
@@ -5520,7 +5535,9 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
TREE_TYPE (decl) = error_mark_node;
return;
}
- else if (describable_type (init))
+ if (TREE_CODE (init) == TREE_LIST)
+ init = build_x_compound_expr_from_list (init, "initializer");
+ if (describable_type (init))
{
type = TREE_TYPE (decl) = do_auto_deduction (type, init, auto_node);
if (type == error_mark_node)
@@ -5885,7 +5902,7 @@ declare_global_var (tree name, tree type)
tree decl;
push_to_top_level ();
- decl = build_decl (VAR_DECL, name, type);
+ decl = build_decl (input_location, VAR_DECL, name, type);
TREE_PUBLIC (decl) = 1;
DECL_EXTERNAL (decl) = 1;
DECL_ARTIFICIAL (decl) = 1;
@@ -6939,7 +6956,7 @@ grokvardecl (tree type,
|| TYPE_P (scope)))
decl = build_lang_decl (VAR_DECL, name, type);
else
- decl = build_decl (VAR_DECL, name, type);
+ decl = build_decl (input_location, VAR_DECL, name, type);
if (explicit_scope && TREE_CODE (explicit_scope) == NAMESPACE_DECL)
set_decl_namespace (decl, explicit_scope, 0);
@@ -7050,10 +7067,11 @@ build_ptrmemfunc_type (tree type)
/* ... and not really a class type. */
SET_CLASS_TYPE_P (t, 0);
- field = build_decl (FIELD_DECL, pfn_identifier, type);
+ field = build_decl (input_location, FIELD_DECL, pfn_identifier, type);
fields = field;
- field = build_decl (FIELD_DECL, delta_identifier, delta_type_node);
+ field = build_decl (input_location, FIELD_DECL, delta_identifier,
+ delta_type_node);
TREE_CHAIN (field) = fields;
fields = field;
@@ -7143,7 +7161,7 @@ check_static_variable_definition (tree decl, tree type)
error ("ISO C++ forbids in-class initialization of non-const "
"static member %qD",
decl);
- else if (!INTEGRAL_TYPE_P (type))
+ else if (!INTEGRAL_OR_ENUMERATION_TYPE_P (type))
pedwarn (input_location, OPT_pedantic, "ISO C++ forbids initialization of member constant "
"%qD of non-integral type %qT", decl, type);
@@ -7166,7 +7184,7 @@ compute_array_index_type (tree name, tree size)
type = TREE_TYPE (size);
/* The array bound must be an integer type. */
- if (!dependent_type_p (type) && !INTEGRAL_TYPE_P (type))
+ if (!dependent_type_p (type) && !INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type))
{
if (name)
error ("size of array %qD has non-integral type %qT", name, type);
@@ -7595,6 +7613,7 @@ grokdeclarator (const cp_declarator *declarator,
bool parameter_pack_p = declarator? declarator->parameter_pack_p : false;
bool set_no_warning = false;
bool template_type_arg = false;
+ const char *errmsg;
signed_p = declspecs->specs[(int)ds_signed];
unsigned_p = declspecs->specs[(int)ds_unsigned];
@@ -8274,6 +8293,12 @@ grokdeclarator (const cp_declarator *declarator,
type_quals = TYPE_UNQUALIFIED;
set_no_warning = true;
}
+ errmsg = targetm.invalid_return_type (type);
+ if (errmsg)
+ {
+ error (errmsg);
+ type = integer_type_node;
+ }
/* Error about some types functions can't return. */
@@ -8402,6 +8427,14 @@ grokdeclarator (const cp_declarator *declarator,
"class definition",
name);
}
+ else if (ctype && sfk == sfk_conversion)
+ {
+ if (explicitp == 1)
+ {
+ maybe_warn_cpp0x ("explicit conversion operators");
+ explicitp = 2;
+ }
+ }
arg_types = grokparms (declarator->u.function.parameters,
&parms);
@@ -8776,7 +8809,7 @@ grokdeclarator (const cp_declarator *declarator,
if (decl_context == FIELD)
decl = build_lang_decl (TYPE_DECL, unqualified_id, type);
else
- decl = build_decl (TYPE_DECL, unqualified_id, type);
+ decl = build_decl (input_location, TYPE_DECL, unqualified_id, type);
if (id_declarator && declarator->u.id.qualifying_scope) {
error ("%Jtypedef name may not be a nested-name-specifier", decl);
TREE_TYPE (decl) = error_mark_node;
@@ -9282,7 +9315,8 @@ grokdeclarator (const cp_declarator *declarator,
}
else
{
- decl = build_decl (FIELD_DECL, unqualified_id, type);
+ decl = build_decl (input_location,
+ FIELD_DECL, unqualified_id, type);
DECL_NONADDRESSABLE_P (decl) = bitfield;
if (bitfield && !unqualified_id)
TREE_NO_WARNING (decl) = 1;
@@ -9658,6 +9692,7 @@ grokparms (tree parmlist, tree *parms)
tree type = NULL_TREE;
tree init = TREE_PURPOSE (parm);
tree decl = TREE_VALUE (parm);
+ const char *errmsg;
if (parm == void_list_node)
break;
@@ -9691,6 +9726,14 @@ grokparms (tree parmlist, tree *parms)
init = NULL_TREE;
}
+ if (type != error_mark_node
+ && (errmsg = targetm.invalid_parameter_type (type)))
+ {
+ error (errmsg);
+ type = error_mark_node;
+ TREE_TYPE (decl) = error_mark_node;
+ }
+
if (type != error_mark_node)
{
if (deprecated_state != DEPRECATED_SUPPRESS)
@@ -11022,7 +11065,7 @@ finish_enum (tree enumtype)
int lowprec;
int highprec;
int precision;
- integer_type_kind itk;
+ unsigned int itk;
tree underlying_type = NULL_TREE;
bool fixed_underlying_type_p
= ENUM_UNDERLYING_TYPE (enumtype) != NULL_TREE;
@@ -11350,7 +11393,7 @@ build_enumerator (tree name, tree value, tree enumtype)
else
/* It's a global enum, or it's local to a function. (Note local to
a function could mean local to a class method. */
- decl = build_decl (CONST_DECL, name, type);
+ decl = build_decl (input_location, CONST_DECL, name, type);
DECL_CONTEXT (decl) = FROB_CONTEXT (context);
TREE_CONSTANT (decl) = 1;
@@ -11577,7 +11620,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
{
tree resdecl;
- resdecl = build_decl (RESULT_DECL, 0, restype);
+ resdecl = build_decl (input_location, RESULT_DECL, 0, restype);
DECL_ARTIFICIAL (resdecl) = 1;
DECL_IGNORED_P (resdecl) = 1;
DECL_RESULT (decl1) = resdecl;
@@ -11820,7 +11863,8 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
|| (DECL_CONSTRUCTOR_P (decl1)
&& targetm.cxx.cdtor_returns_this ()))
{
- cdtor_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
+ cdtor_label = build_decl (input_location,
+ LABEL_DECL, NULL_TREE, NULL_TREE);
DECL_CONTEXT (cdtor_label) = current_function_decl;
}
@@ -12002,13 +12046,13 @@ finish_constructor_body (void)
&& (! TYPE_FOR_JAVA (current_class_type)))
{
/* Any return from a constructor will end up here. */
- add_stmt (build_stmt (LABEL_EXPR, cdtor_label));
+ add_stmt (build_stmt (input_location, LABEL_EXPR, cdtor_label));
val = DECL_ARGUMENTS (current_function_decl);
val = build2 (MODIFY_EXPR, TREE_TYPE (val),
DECL_RESULT (current_function_decl), val);
/* Return the address of the object. */
- exprstmt = build_stmt (RETURN_EXPR, val);
+ exprstmt = build_stmt (input_location, RETURN_EXPR, val);
add_stmt (exprstmt);
}
}
@@ -12050,7 +12094,7 @@ finish_destructor_body (void)
/* Any return from a destructor will end up here; that way all base
and member cleanups will be run when the function returns. */
- add_stmt (build_stmt (LABEL_EXPR, cdtor_label));
+ add_stmt (build_stmt (input_location, LABEL_EXPR, cdtor_label));
/* In a virtual destructor, we must call delete. */
if (DECL_VIRTUAL_P (current_function_decl))
@@ -12088,7 +12132,7 @@ finish_destructor_body (void)
val = build2 (MODIFY_EXPR, TREE_TYPE (val),
DECL_RESULT (current_function_decl), val);
/* Return the address of the object. */
- exprstmt = build_stmt (RETURN_EXPR, val);
+ exprstmt = build_stmt (input_location, RETURN_EXPR, val);
add_stmt (exprstmt);
}
}
@@ -12672,7 +12716,7 @@ cxx_maybe_build_cleanup (tree decl)
call = build_delete (TREE_TYPE (addr), addr,
sfk_complete_destructor, flags, 0);
if (cleanup)
- cleanup = build_compound_expr (cleanup, call);
+ cleanup = build_compound_expr (input_location, cleanup, call);
else
cleanup = call;
}
@@ -12750,7 +12794,7 @@ cp_missing_noreturn_ok_p (tree decl)
/* Return the COMDAT group into which DECL should be placed. */
-const char *
+tree
cxx_comdat_group (tree decl)
{
tree name;
@@ -12780,7 +12824,7 @@ cxx_comdat_group (tree decl)
name = DECL_ASSEMBLER_NAME (decl);
}
- return IDENTIFIER_POINTER (name);
+ return name;
}
#include "gt-cp-decl.h"
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 1f8e848bf2e..308f767cc09 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -132,7 +132,8 @@ build_memfn_type (tree fntype, tree ctype, cp_cv_quals quals)
tree
cp_build_parm_decl (tree name, tree type)
{
- tree parm = build_decl (PARM_DECL, name, type);
+ tree parm = build_decl (input_location,
+ PARM_DECL, name, type);
/* DECL_ARG_TYPE is only used by the back end and the back end never
sees templates. */
if (!processing_template_decl)
@@ -354,7 +355,7 @@ grok_array_decl (tree array_expr, tree index_exp)
if (array_expr == error_mark_node || index_exp == error_mark_node)
error ("ambiguous conversion for array subscript");
- expr = build_array_ref (array_expr, index_exp, input_location);
+ expr = build_array_ref (input_location, array_expr, index_exp);
}
if (processing_template_decl && expr != error_mark_node)
return build_min_non_dep (ARRAY_REF, expr, orig_array_expr, orig_index_exp,
@@ -964,7 +965,7 @@ grokbitfield (const cp_declarator *declarator,
if (TREE_CODE (value) == VOID_TYPE)
return void_type_node;
- if (!INTEGRAL_TYPE_P (TREE_TYPE (value))
+ if (!INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (value))
&& (POINTER_TYPE_P (value)
|| !dependent_type_p (TREE_TYPE (value))))
{
@@ -1287,7 +1288,8 @@ build_anon_union_vars (tree type, tree object)
{
tree base;
- decl = build_decl (VAR_DECL, DECL_NAME (field), TREE_TYPE (field));
+ decl = build_decl (input_location,
+ VAR_DECL, DECL_NAME (field), TREE_TYPE (field));
DECL_ANON_UNION_VAR_P (decl) = 1;
base = get_base_address (object);
@@ -1508,7 +1510,7 @@ void
comdat_linkage (tree decl)
{
if (flag_weak)
- make_decl_one_only (decl);
+ make_decl_one_only (decl, cxx_comdat_group (decl));
else if (TREE_CODE (decl) == FUNCTION_DECL
|| (TREE_CODE (decl) == VAR_DECL && DECL_ARTIFICIAL (decl)))
/* We can just emit function and compiler-generated variables
@@ -1580,7 +1582,7 @@ maybe_make_one_only (tree decl)
|| (! DECL_EXPLICIT_INSTANTIATION (decl)
&& ! DECL_TEMPLATE_SPECIALIZATION (decl)))
{
- make_decl_one_only (decl);
+ make_decl_one_only (decl, cxx_comdat_group (decl));
if (TREE_CODE (decl) == VAR_DECL)
{
@@ -1707,6 +1709,10 @@ decl_needed_p (tree decl)
|| (DECL_ASSEMBLER_NAME_SET_P (decl)
&& TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))))
return true;
+ /* Functions marked "dllexport" must be emitted so that they are
+ visible to other DLLs. */
+ if (lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl)))
+ return true;
/* Otherwise, DECL does not need to be emitted -- yet. A subsequent
reference to DECL might cause it to be emitted later. */
return false;
@@ -1764,7 +1770,7 @@ maybe_emit_vtables (tree ctype)
if (TREE_TYPE (DECL_INITIAL (vtbl)) == 0)
{
- tree expr = store_init_value (vtbl, DECL_INITIAL (vtbl));
+ tree expr = store_init_value (vtbl, DECL_INITIAL (vtbl), LOOKUP_NORMAL);
/* It had better be all done at compile-time. */
gcc_assert (!expr);
@@ -1839,7 +1845,7 @@ constrain_visibility (tree decl, int visibility)
if (!DECL_EXTERN_C_P (decl))
{
TREE_PUBLIC (decl) = 0;
- DECL_ONE_ONLY (decl) = 0;
+ DECL_COMDAT_GROUP (decl) = NULL_TREE;
DECL_INTERFACE_KNOWN (decl) = 1;
if (DECL_LANG_SPECIFIC (decl))
DECL_NOT_REALLY_EXTERN (decl) = 1;
@@ -2491,13 +2497,14 @@ get_guard (tree decl)
/* We use a type that is big enough to contain a mutex as well
as an integer counter. */
guard_type = targetm.cxx.guard_type ();
- guard = build_decl (VAR_DECL, sname, guard_type);
+ guard = build_decl (DECL_SOURCE_LOCATION (decl),
+ VAR_DECL, sname, guard_type);
/* The guard should have the same linkage as what it guards. */
TREE_PUBLIC (guard) = TREE_PUBLIC (decl);
TREE_STATIC (guard) = TREE_STATIC (decl);
DECL_COMMON (guard) = DECL_COMMON (decl);
- DECL_ONE_ONLY (guard) = DECL_ONE_ONLY (decl);
+ DECL_COMDAT_GROUP (guard) = DECL_COMDAT_GROUP (decl);
if (TREE_PUBLIC (decl))
DECL_WEAK (guard) = DECL_WEAK (decl);
DECL_VISIBILITY (guard) = DECL_VISIBILITY (decl);
@@ -3680,18 +3687,18 @@ cp_write_global_declarations (void)
/* FN is an OFFSET_REF, DOTSTAR_EXPR or MEMBER_REF indicating the
function to call in parse-tree form; it has not yet been
semantically analyzed. ARGS are the arguments to the function.
- They have already been semantically analyzed. */
+ They have already been semantically analyzed. This may change
+ ARGS. */
tree
-build_offset_ref_call_from_tree (tree fn, tree args)
+build_offset_ref_call_from_tree (tree fn, VEC(tree,gc) **args)
{
tree orig_fn;
- tree orig_args;
+ VEC(tree,gc) *orig_args = NULL;
tree expr;
tree object;
orig_fn = fn;
- orig_args = args;
object = TREE_OPERAND (fn, 0);
if (processing_template_decl)
@@ -3699,17 +3706,19 @@ build_offset_ref_call_from_tree (tree fn, tree args)
gcc_assert (TREE_CODE (fn) == DOTSTAR_EXPR
|| TREE_CODE (fn) == MEMBER_REF);
if (type_dependent_expression_p (fn)
- || any_type_dependent_arguments_p (args))
- return build_nt_call_list (fn, args);
+ || any_type_dependent_arguments_p (*args))
+ return build_nt_call_vec (fn, *args);
+
+ orig_args = make_tree_vector_copy (*args);
/* Transform the arguments and add the implicit "this"
parameter. That must be done before the FN is transformed
because we depend on the form of FN. */
- args = build_non_dependent_args (args);
+ make_args_non_dependent (*args);
object = build_non_dependent_expr (object);
if (TREE_CODE (fn) == DOTSTAR_EXPR)
object = cp_build_unary_op (ADDR_EXPR, object, 0, tf_warning_or_error);
- args = tree_cons (NULL_TREE, object, args);
+ VEC_safe_insert (tree, gc, *args, 0, object);
/* Now that the arguments are done, transform FN. */
fn = build_non_dependent_expr (fn);
}
@@ -3726,12 +3735,16 @@ build_offset_ref_call_from_tree (tree fn, tree args)
tf_warning_or_error);
fn = TREE_OPERAND (fn, 1);
fn = get_member_function_from_ptrfunc (&object_addr, fn);
- args = tree_cons (NULL_TREE, object_addr, args);
+ VEC_safe_insert (tree, gc, *args, 0, object_addr);
}
- expr = cp_build_function_call (fn, args, tf_warning_or_error);
+ expr = cp_build_function_call_vec (fn, args, tf_warning_or_error);
if (processing_template_decl && expr != error_mark_node)
- return build_min_non_dep_call_list (expr, orig_fn, orig_args);
+ expr = build_min_non_dep_call_vec (expr, orig_fn, orig_args);
+
+ if (orig_args != NULL)
+ release_tree_vector (orig_args);
+
return expr;
}
@@ -3799,9 +3812,10 @@ mark_used (tree decl)
{
error ("deleted function %q+D", decl);
error ("used here");
+ return;
}
/* If we don't need a value, then we don't need to synthesize DECL. */
- if (skip_evaluation)
+ if (cp_unevaluated_operand != 0)
return;
/* If within finish_function, defer the rest until that function
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index 62347c86ea2..048364422ea 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -329,7 +329,7 @@ dump_template_bindings (tree parms, tree args, VEC(tree,gc)* typenames)
t = tsubst (t, args, tf_none, NULL_TREE);
/* Strip typedefs. We can't just use TFF_CHASE_TYPEDEF because
pp_simple_type_specifier doesn't know about it. */
- t = canonical_type_variant (t);
+ t = strip_typedefs (t);
dump_type (t, TFF_PLAIN_IDENTIFIER);
}
}
@@ -2712,19 +2712,30 @@ print_instantiation_partial_context (diagnostic_context *context,
struct tinst_level *t, location_t loc)
{
expanded_location xloc;
+ const char *str;
for (; ; t = t->next)
{
xloc = expand_location (loc);
if (t == NULL)
break;
- pp_verbatim (context->printer, _("%s:%d: instantiated from %qs\n"),
- xloc.file, xloc.line,
- decl_as_string_translate (t->decl,
- TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE));
+ str = decl_as_string_translate (t->decl,
+ TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE);
+ if (flag_show_column)
+ pp_verbatim (context->printer,
+ _("%s:%d:%d: instantiated from %qs\n"),
+ xloc.file, xloc.line, xloc.column, str);
+ else
+ pp_verbatim (context->printer,
+ _("%s:%d: instantiated from %qs\n"),
+ xloc.file, xloc.line, str);
loc = t->locus;
}
- pp_verbatim (context->printer, _("%s:%d: instantiated from here"),
- xloc.file, xloc.line);
+ if (flag_show_column)
+ pp_verbatim (context->printer, _("%s:%d:%d: instantiated from here"),
+ xloc.file, xloc.line, xloc.column);
+ else
+ pp_verbatim (context->printer, _("%s:%d: instantiated from here"),
+ xloc.file, xloc.line);
pp_base_newline (context->printer);
}
@@ -2768,8 +2779,8 @@ cp_printer (pretty_printer *pp, text_info *text, const char *spec,
const char *result;
tree t = NULL;
#define next_tree (t = va_arg (*text->args_ptr, tree))
-#define next_tcode va_arg (*text->args_ptr, enum tree_code)
-#define next_lang va_arg (*text->args_ptr, enum languages)
+#define next_tcode ((enum tree_code) va_arg (*text->args_ptr, int))
+#define next_lang ((enum languages) va_arg (*text->args_ptr, int))
#define next_int va_arg (*text->args_ptr, int)
if (precision != 0 || wide)
diff --git a/gcc/cp/except.c b/gcc/cp/except.c
index 2638ccc90d9..92def0f72d0 100644
--- a/gcc/cp/except.c
+++ b/gcc/cp/except.c
@@ -1,6 +1,6 @@
/* Handle exceptional things in C++.
Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008
+ 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009
Free Software Foundation, Inc.
Contributed by Michael Tiemann <tiemann@cygnus.com>
Rewritten by Mike Stump <mrs@cygnus.com>, based upon an
@@ -521,7 +521,7 @@ expand_end_catch_block (void)
tree
begin_eh_spec_block (void)
{
- tree r = build_stmt (EH_SPEC_BLOCK, NULL_TREE, NULL_TREE);
+ tree r = build_stmt (input_location, EH_SPEC_BLOCK, NULL_TREE, NULL_TREE);
add_stmt (r);
EH_SPEC_STMTS (r) = push_stmt_list ();
return r;
@@ -736,6 +736,7 @@ build_throw (tree exp)
if (CLASS_TYPE_P (temp_type))
{
int flags = LOOKUP_NORMAL | LOOKUP_ONLYCONVERTING;
+ VEC(tree,gc) *exp_vec;
/* Under C++0x [12.8/16 class.copy], a thrown lvalue is sometimes
treated as an rvalue for the purposes of overload resolution
@@ -749,11 +750,11 @@ build_throw (tree exp)
flags = flags | LOOKUP_PREFER_RVALUE;
/* Call the copy constructor. */
+ exp_vec = make_tree_vector_single (exp);
exp = (build_special_member_call
- (object, complete_ctor_identifier,
- build_tree_list (NULL_TREE, exp),
- TREE_TYPE (object),
- flags, tf_warning_or_error));
+ (object, complete_ctor_identifier, &exp_vec,
+ TREE_TYPE (object), flags, tf_warning_or_error));
+ release_tree_vector (exp_vec);
if (exp == error_mark_node)
{
error (" in thrown expression");
diff --git a/gcc/cp/g++spec.c b/gcc/cp/g++spec.c
index 8828573ef54..f49d699c832 100644
--- a/gcc/cp/g++spec.c
+++ b/gcc/cp/g++spec.c
@@ -45,7 +45,7 @@ along with GCC; see the file COPYING3. If not see
#define LIBSTDCXX_PROFILE LIBSTDCXX
#endif
#ifndef LIBSTDCXX_STATIC
-#define LIBSTDCXX_STATIC LIBSTDCXX
+#define LIBSTDCXX_STATIC NULL
#endif
void
@@ -259,8 +259,9 @@ lang_specific_driver (int *in_argc, const char *const **in_argv,
shared_libgcc = 0;
#endif
- /* Make sure to have room for the trailing NULL argument. */
- num_args = argc + added + need_math + shared_libgcc + (library > 0) + 1;
+ /* Make sure to have room for the trailing NULL argument.
+ Add one for shared_libgcc or extra static library. */
+ num_args = argc + added + need_math + (library > 0) + 2;
arglist = XNEWVEC (const char *, num_args);
i = 0;
@@ -318,8 +319,15 @@ lang_specific_driver (int *in_argc, const char *const **in_argv,
/* Add `-lstdc++' if we haven't already done so. */
if (library > 0)
{
- arglist[j] = shared_libgcc == 0 ? LIBSTDCXX_STATIC
- : saw_profile_flag ? LIBSTDCXX_PROFILE : LIBSTDCXX;
+ arglist[j] = saw_profile_flag ? LIBSTDCXX_PROFILE : LIBSTDCXX;
+ if (arglist[j][0] != '-' || arglist[j][1] == 'l')
+ added_libraries++;
+ j++;
+ }
+ /* Add target-dependent static library, if necessary. */
+ if (shared_libgcc == 0 && LIBSTDCXX_STATIC != NULL)
+ {
+ arglist[j] = LIBSTDCXX_STATIC;
if (arglist[j][0] != '-' || arglist[j][1] == 'l')
added_libraries++;
j++;
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index d40a5e7e53f..26089965d0c 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -302,7 +302,7 @@ build_value_init (tree type)
return build_aggr_init_expr
(type,
build_special_member_call (NULL_TREE, complete_ctor_identifier,
- NULL_TREE, type, LOOKUP_NORMAL,
+ NULL, type, LOOKUP_NORMAL,
tf_warning_or_error));
else if (TREE_CODE (type) != UNION_TYPE && TYPE_NEEDS_CONSTRUCTING (type))
{
@@ -312,7 +312,7 @@ build_value_init (tree type)
This will be handled in simplify_aggr_init_expr. */
tree ctor = build_special_member_call
(NULL_TREE, complete_ctor_identifier,
- NULL_TREE, type, LOOKUP_NORMAL, tf_warning_or_error);
+ NULL, type, LOOKUP_NORMAL, tf_warning_or_error);
ctor = build_aggr_init_expr (type, ctor);
AGGR_INIT_ZERO_FIRST (ctor) = 1;
@@ -951,7 +951,7 @@ expand_cleanup_for_base (tree binfo, tree flag)
/* Call the destructor. */
expr = build_special_member_call (current_class_ref,
base_dtor_identifier,
- NULL_TREE,
+ NULL,
binfo,
LOOKUP_NORMAL | LOOKUP_NONVIRTUAL,
tf_warning_or_error);
@@ -1285,7 +1285,7 @@ expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags,
followed by initialization by X. If neither of these work
out, then look hard. */
tree rval;
- tree parms;
+ VEC(tree,gc) *parms;
if (init && TREE_CODE (init) != TREE_LIST
&& (flags & LOOKUP_ONLYCONVERTING))
@@ -1325,23 +1325,28 @@ expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags,
return;
}
- if (init == NULL_TREE
- || (TREE_CODE (init) == TREE_LIST && ! TREE_TYPE (init)))
+ if (init == NULL_TREE)
+ parms = NULL;
+ else if (TREE_CODE (init) == TREE_LIST && !TREE_TYPE (init))
{
- parms = init;
- if (parms)
- init = TREE_VALUE (parms);
+ parms = make_tree_vector ();
+ for (; init != NULL_TREE; init = TREE_CHAIN (init))
+ VEC_safe_push (tree, gc, parms, TREE_VALUE (init));
}
else
- parms = build_tree_list (NULL_TREE, init);
+ parms = make_tree_vector_single (init);
if (true_exp == exp)
ctor_name = complete_ctor_identifier;
else
ctor_name = base_ctor_identifier;
- rval = build_special_member_call (exp, ctor_name, parms, binfo, flags,
+ rval = build_special_member_call (exp, ctor_name, &parms, binfo, flags,
complain);
+
+ if (parms != NULL)
+ release_tree_vector (parms);
+
if (TREE_SIDE_EFFECTS (rval))
finish_expr_stmt (convert_to_void (rval, NULL, complain));
}
@@ -1387,7 +1392,7 @@ expand_aggr_init_1 (tree binfo, tree true_exp, tree exp, tree init, int flags,
/* If store_init_value returns NULL_TREE, the INIT has been
recorded as the DECL_INITIAL for EXP. That means there's
nothing more we have to do. */
- init = store_init_value (exp, init);
+ init = store_init_value (exp, init, flags);
if (init)
finish_expr_stmt (init);
return;
@@ -1706,81 +1711,46 @@ build_builtin_delete_call (tree addr)
the type of the object being allocated; otherwise, it's just TYPE.
INIT is the initializer, if any. USE_GLOBAL_NEW is true if the
user explicitly wrote "::operator new". PLACEMENT, if non-NULL, is
- the TREE_LIST of arguments to be provided as arguments to a
- placement new operator. This routine performs no semantic checks;
- it just creates and returns a NEW_EXPR. */
+ a vector of arguments to be provided as arguments to a placement
+ new operator. This routine performs no semantic checks; it just
+ creates and returns a NEW_EXPR. */
static tree
-build_raw_new_expr (tree placement, tree type, tree nelts, tree init,
- int use_global_new)
+build_raw_new_expr (VEC(tree,gc) *placement, tree type, tree nelts,
+ VEC(tree,gc) *init, int use_global_new)
{
+ tree init_list;
tree new_expr;
- new_expr = build4 (NEW_EXPR, build_pointer_type (type), placement, type,
- nelts, init);
+ /* If INIT is NULL, the we want to store NULL_TREE in the NEW_EXPR.
+ If INIT is not NULL, then we want to store VOID_ZERO_NODE. This
+ permits us to distinguish the case of a missing initializer "new
+ int" from an empty initializer "new int()". */
+ if (init == NULL)
+ init_list = NULL_TREE;
+ else if (VEC_empty (tree, init))
+ init_list = void_zero_node;
+ else
+ init_list = build_tree_list_vec (init);
+
+ new_expr = build4 (NEW_EXPR, build_pointer_type (type),
+ build_tree_list_vec (placement), type, nelts,
+ init_list);
NEW_EXPR_USE_GLOBAL (new_expr) = use_global_new;
TREE_SIDE_EFFECTS (new_expr) = 1;
return new_expr;
}
-/* Make sure that there are no aliasing issues with T, a placement new
- expression applied to PLACEMENT, by recording the change in dynamic
- type. If placement new is inlined, as it is with libstdc++, and if
- the type of the placement new differs from the type of the
- placement location itself, then alias analysis may think it is OK
- to interchange writes to the location from before the placement new
- and from after the placement new. We have to prevent type-based
- alias analysis from applying. PLACEMENT may be NULL, which means
- that we couldn't capture it in a temporary variable, in which case
- we use a memory clobber. */
-
-static tree
-avoid_placement_new_aliasing (tree t, tree placement)
-{
- tree type_change;
-
- if (processing_template_decl)
- return t;
-
- /* If we are not using type based aliasing, we don't have to do
- anything. */
- if (!flag_strict_aliasing)
- return t;
-
- /* If we have a pointer and a location, record the change in dynamic
- type. Otherwise we need a general memory clobber. */
- if (TREE_CODE (TREE_TYPE (t)) == POINTER_TYPE
- && placement != NULL_TREE
- && TREE_CODE (TREE_TYPE (placement)) == POINTER_TYPE)
- type_change = build_stmt (CHANGE_DYNAMIC_TYPE_EXPR,
- TREE_TYPE (t),
- placement);
- else
- {
- /* Build a memory clobber. */
- type_change = build_stmt (ASM_EXPR,
- build_string (0, ""),
- NULL_TREE,
- NULL_TREE,
- tree_cons (NULL_TREE,
- build_string (6, "memory"),
- NULL_TREE));
-
- ASM_VOLATILE_P (type_change) = 1;
- }
-
- return build2 (COMPOUND_EXPR, TREE_TYPE (t), type_change, t);
-}
-
/* Generate code for a new-expression, including calling the "operator
new" function, initializing the object, and, if an exception occurs
during construction, cleaning up. The arguments are as for
- build_raw_new_expr. */
+ build_raw_new_expr. This may change PLACEMENT and INIT. */
static tree
-build_new_1 (tree placement, tree type, tree nelts, tree init,
- bool globally_qualified_p, tsubst_flags_t complain)
+build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts,
+ VEC(tree,gc) **init, bool globally_qualified_p,
+ tsubst_flags_t complain)
{
tree size, rval;
/* True iff this is a call to "operator new[]" instead of just
@@ -1807,11 +1777,11 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
beginning of the storage allocated for an array-new expression in
order to store the number of elements. */
tree cookie_size = NULL_TREE;
+ tree placement_first;
tree placement_expr = NULL_TREE;
/* True if the function we are calling is a placement allocation
function. */
bool placement_allocation_fn_p;
- tree args = NULL_TREE;
/* True if the storage must be initialized, either by a constructor
or due to an explicit new-initializer. */
bool is_initialized;
@@ -1855,9 +1825,9 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
if (abstract_virtuals_error (NULL_TREE, elt_type))
return error_mark_node;
- is_initialized = (TYPE_NEEDS_CONSTRUCTING (elt_type) || init);
+ is_initialized = (TYPE_NEEDS_CONSTRUCTING (elt_type) || *init != NULL);
- if (CP_TYPE_CONST_P (elt_type) && !init
+ if (CP_TYPE_CONST_P (elt_type) && *init == NULL
&& !type_has_user_provided_default_constructor (elt_type))
{
if (complain & tf_error)
@@ -1871,8 +1841,17 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
alloc_fn = NULL_TREE;
+ /* If PLACEMENT is a single simple pointer type not passed by
+ reference, prepare to capture it in a temporary variable. Do
+ this now, since PLACEMENT will change in the calls below. */
+ placement_first = NULL_TREE;
+ if (VEC_length (tree, *placement) == 1
+ && (TREE_CODE (TREE_TYPE (VEC_index (tree, *placement, 0)))
+ == POINTER_TYPE))
+ placement_first = VEC_index (tree, *placement, 0);
+
/* Allocate the object. */
- if (! placement && TYPE_FOR_JAVA (elt_type))
+ if (VEC_empty (tree, *placement) && TYPE_FOR_JAVA (elt_type))
{
tree class_addr;
tree class_decl = build_java_class_ref (elt_type);
@@ -1928,7 +1907,7 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
size = size_binop (PLUS_EXPR, size, cookie_size);
}
/* Create the argument list. */
- args = tree_cons (NULL_TREE, size, placement);
+ VEC_safe_insert (tree, gc, *placement, 0, size);
/* Do name-lookup to find the appropriate operator. */
fns = lookup_fnfields (elt_type, fnname, /*protect=*/2);
if (fns == NULL_TREE)
@@ -1947,7 +1926,7 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
return error_mark_node;
}
alloc_call = build_new_method_call (build_dummy_object (elt_type),
- fns, args,
+ fns, placement,
/*conversion_path=*/NULL_TREE,
LOOKUP_NORMAL,
&alloc_fn,
@@ -1973,12 +1952,10 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
gcc_assert (alloc_fn != NULL_TREE);
- /* If PLACEMENT is a simple pointer type and is not passed by reference,
- then copy it into PLACEMENT_EXPR. */
+ /* If we found a simple case of PLACEMENT_EXPR above, then copy it
+ into a temporary variable. */
if (!processing_template_decl
- && placement != NULL_TREE
- && TREE_CHAIN (placement) == NULL_TREE
- && TREE_CODE (TREE_TYPE (TREE_VALUE (placement))) == POINTER_TYPE
+ && placement_first != NULL_TREE
&& TREE_CODE (alloc_call) == CALL_EXPR
&& call_expr_nargs (alloc_call) == 2
&& TREE_CODE (TREE_TYPE (CALL_EXPR_ARG (alloc_call, 0))) == INTEGER_TYPE
@@ -1986,10 +1963,10 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
{
tree placement_arg = CALL_EXPR_ARG (alloc_call, 1);
- if (INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (placement_arg)))
+ if (INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (TREE_TYPE (placement_arg)))
|| VOID_TYPE_P (TREE_TYPE (TREE_TYPE (placement_arg))))
{
- placement_expr = get_target_expr (TREE_VALUE (placement));
+ placement_expr = get_target_expr (placement_first);
CALL_EXPR_ARG (alloc_call, 1)
= convert (TREE_TYPE (placement_arg), placement_expr);
}
@@ -1998,12 +1975,7 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
/* In the simple case, we can stop now. */
pointer_type = build_pointer_type (type);
if (!cookie_size && !is_initialized)
- {
- rval = build_nop (pointer_type, alloc_call);
- if (placement != NULL)
- rval = avoid_placement_new_aliasing (rval, placement_expr);
- return rval;
- }
+ return build_nop (pointer_type, alloc_call);
/* Store the result of the allocation call in a variable so that we can
use it more than once. */
@@ -2109,15 +2081,15 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
bool stable;
bool explicit_value_init_p = false;
- if (init == void_zero_node)
+ if (*init != NULL && VEC_empty (tree, *init))
{
- init = NULL_TREE;
+ *init = NULL;
explicit_value_init_p = true;
}
if (array_p)
{
- if (init)
+ if (*init)
{
if (complain & tf_error)
permerror (input_location, "ISO C++ forbids initialization in array new");
@@ -2130,7 +2102,7 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
MINUS_EXPR, outer_nelts,
integer_one_node,
complain),
- init,
+ build_tree_list_vec (*init),
explicit_value_init_p,
/*from_array=*/0,
complain);
@@ -2160,17 +2132,13 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
}
else
{
+ tree ie;
+
/* We are processing something like `new int (10)', which
means allocate an int, and initialize it with 10. */
- if (TREE_CODE (init) == TREE_LIST)
- init = build_x_compound_expr_from_list (init,
- "new initializer");
- else
- gcc_assert (TREE_CODE (init) != CONSTRUCTOR
- || TREE_TYPE (init) != NULL_TREE);
-
- init_expr = cp_build_modify_expr (init_expr, INIT_EXPR, init,
+ ie = build_x_compound_expr_from_vec (*init, "new initializer");
+ init_expr = cp_build_modify_expr (init_expr, INIT_EXPR, ie,
complain);
}
stable = stabilize_init (init_expr, &init_preeval_expr);
@@ -2283,60 +2251,55 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
/* A new-expression is never an lvalue. */
gcc_assert (!lvalue_p (rval));
- if (placement != NULL)
- rval = avoid_placement_new_aliasing (rval, placement_expr);
-
return rval;
}
-/* Generate a representation for a C++ "new" expression. PLACEMENT is
- a TREE_LIST of placement-new arguments (or NULL_TREE if none). If
- NELTS is NULL, TYPE is the type of the storage to be allocated. If
- NELTS is not NULL, then this is an array-new allocation; TYPE is
- the type of the elements in the array and NELTS is the number of
- elements in the array. INIT, if non-NULL, is the initializer for
- the new object, or void_zero_node to indicate an initializer of
- "()". If USE_GLOBAL_NEW is true, then the user explicitly wrote
- "::new" rather than just "new". */
+/* Generate a representation for a C++ "new" expression. *PLACEMENT
+ is a vector of placement-new arguments (or NULL if none). If NELTS
+ is NULL, TYPE is the type of the storage to be allocated. If NELTS
+ is not NULL, then this is an array-new allocation; TYPE is the type
+ of the elements in the array and NELTS is the number of elements in
+ the array. *INIT, if non-NULL, is the initializer for the new
+ object, or an empty vector to indicate an initializer of "()". If
+ USE_GLOBAL_NEW is true, then the user explicitly wrote "::new"
+ rather than just "new". This may change PLACEMENT and INIT. */
tree
-build_new (tree placement, tree type, tree nelts, tree init,
- int use_global_new, tsubst_flags_t complain)
+build_new (VEC(tree,gc) **placement, tree type, tree nelts,
+ VEC(tree,gc) **init, int use_global_new, tsubst_flags_t complain)
{
tree rval;
- tree orig_placement;
- tree orig_nelts;
- tree orig_init;
+ VEC(tree,gc) *orig_placement = NULL;
+ tree orig_nelts = NULL_TREE;
+ VEC(tree,gc) *orig_init = NULL;
- if (placement == error_mark_node || type == error_mark_node
- || init == error_mark_node)
+ if (type == error_mark_node)
return error_mark_node;
- orig_placement = placement;
- orig_nelts = nelts;
- orig_init = init;
-
- if (nelts == NULL_TREE && init != void_zero_node && list_length (init) == 1)
+ if (nelts == NULL_TREE && VEC_length (tree, *init) == 1)
{
tree auto_node = type_uses_auto (type);
- if (auto_node && describable_type (TREE_VALUE (init)))
- type = do_auto_deduction (type, TREE_VALUE (init), auto_node);
+ if (auto_node && describable_type (VEC_index (tree, *init, 0)))
+ type = do_auto_deduction (type, VEC_index (tree, *init, 0), auto_node);
}
if (processing_template_decl)
{
if (dependent_type_p (type)
- || any_type_dependent_arguments_p (placement)
+ || any_type_dependent_arguments_p (*placement)
|| (nelts && type_dependent_expression_p (nelts))
- || (init != void_zero_node
- && any_type_dependent_arguments_p (init)))
- return build_raw_new_expr (placement, type, nelts, init,
+ || any_type_dependent_arguments_p (*init))
+ return build_raw_new_expr (*placement, type, nelts, *init,
use_global_new);
- placement = build_non_dependent_args (placement);
+
+ orig_placement = make_tree_vector_copy (*placement);
+ orig_nelts = nelts;
+ orig_init = make_tree_vector_copy (*init);
+
+ make_args_non_dependent (*placement);
if (nelts)
nelts = build_non_dependent_expr (nelts);
- if (init != void_zero_node)
- init = build_non_dependent_args (init);
+ make_args_non_dependent (*init);
}
if (nelts)
@@ -2381,8 +2344,13 @@ build_new (tree placement, tree type, tree nelts, tree init,
return error_mark_node;
if (processing_template_decl)
- return build_raw_new_expr (orig_placement, type, orig_nelts, orig_init,
- use_global_new);
+ {
+ tree ret = build_raw_new_expr (orig_placement, type, orig_nelts,
+ orig_init, use_global_new);
+ release_tree_vector (orig_placement);
+ release_tree_vector (orig_init);
+ return ret;
+ }
/* Wrap it in a NOP_EXPR so warn_if_unused_value doesn't complain. */
rval = build1 (NOP_EXPR, TREE_TYPE (rval), rval);
@@ -2431,7 +2399,8 @@ build_java_class_ref (tree type)
class_decl = IDENTIFIER_GLOBAL_VALUE (name);
if (class_decl == NULL_TREE)
{
- class_decl = build_decl (VAR_DECL, name, TREE_TYPE (jclass_node));
+ class_decl = build_decl (input_location,
+ VAR_DECL, name, TREE_TYPE (jclass_node));
TREE_STATIC (class_decl) = 1;
DECL_EXTERNAL (class_decl) = 1;
TREE_PUBLIC (class_decl) = 1;
@@ -2497,15 +2466,17 @@ build_vec_delete_1 (tree base, tree maxindex, tree type,
fold_convert (ptype, base)));
tmp = fold_build1 (NEGATE_EXPR, sizetype, size_exp);
body = build_compound_expr
- (body, cp_build_modify_expr (tbase, NOP_EXPR,
+ (input_location,
+ body, cp_build_modify_expr (tbase, NOP_EXPR,
build2 (POINTER_PLUS_EXPR, ptype, tbase, tmp),
tf_warning_or_error));
body = build_compound_expr
- (body, build_delete (ptype, tbase, sfk_complete_destructor,
+ (input_location,
+ body, build_delete (ptype, tbase, sfk_complete_destructor,
LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 1));
loop = build1 (LOOP_EXPR, void_type_node, body);
- loop = build_compound_expr (tbase_init, loop);
+ loop = build_compound_expr (input_location, tbase_init, loop);
no_destructor:
/* If the delete flag is one, or anything else with the low bit set,
@@ -2552,7 +2523,7 @@ build_vec_delete_1 (tree base, tree maxindex, tree type,
else if (!body)
body = deallocate_expr;
else
- body = build_compound_expr (body, deallocate_expr);
+ body = build_compound_expr (input_location, body, deallocate_expr);
if (!body)
body = integer_zero_node;
@@ -2585,11 +2556,11 @@ create_temporary_var (tree type)
{
tree decl;
- decl = build_decl (VAR_DECL, NULL_TREE, type);
+ decl = build_decl (input_location,
+ VAR_DECL, NULL_TREE, type);
TREE_USED (decl) = 1;
DECL_ARTIFICIAL (decl) = 1;
DECL_IGNORED_P (decl) = 1;
- DECL_SOURCE_LOCATION (decl) = input_location;
DECL_CONTEXT (decl) = current_function_decl;
return decl;
@@ -2954,7 +2925,7 @@ build_dtor_call (tree exp, special_function_kind dtor_kind, int flags)
}
fn = lookup_fnfields (TREE_TYPE (exp), name, /*protect=*/2);
return build_new_method_call (exp, fn,
- /*args=*/NULL_TREE,
+ /*args=*/NULL,
/*conversion_path=*/NULL_TREE,
flags,
/*fn_p=*/NULL,
@@ -3172,7 +3143,7 @@ push_base_cleanups (void)
{
expr = build_special_member_call (current_class_ref,
base_dtor_identifier,
- NULL_TREE,
+ NULL,
base_binfo,
(LOOKUP_NORMAL
| LOOKUP_NONVIRTUAL),
@@ -3194,7 +3165,7 @@ push_base_cleanups (void)
expr = build_special_member_call (current_class_ref,
base_dtor_identifier,
- NULL_TREE, base_binfo,
+ NULL, base_binfo,
LOOKUP_NORMAL | LOOKUP_NONVIRTUAL,
tf_warning_or_error);
finish_decl_cleanup (NULL_TREE, expr);
diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c
index 66377ff1564..bf507411d6f 100644
--- a/gcc/cp/lex.c
+++ b/gcc/cp/lex.c
@@ -454,7 +454,8 @@ unqualified_name_lookup_error (tree name)
if (current_function_decl)
{
tree decl;
- decl = build_decl (VAR_DECL, name, error_mark_node);
+ decl = build_decl (input_location,
+ VAR_DECL, name, error_mark_node);
DECL_CONTEXT (decl) = current_function_decl;
push_local_binding (name, decl, 0);
/* Mark the variable as used so that we do not get warnings
@@ -511,7 +512,8 @@ build_lang_decl (enum tree_code code, tree name, tree type)
{
tree t;
- t = build_decl (code, name, type);
+ t = build_decl (input_location,
+ code, name, type);
retrofit_lang_decl (t);
/* All nesting of C++ functions is lexical; there is never a "static
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index ff77981c264..f7d9d416988 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -338,9 +338,14 @@ canonicalize_for_substitution (tree node)
/* For a TYPE_DECL, use the type instead. */
if (TREE_CODE (node) == TYPE_DECL)
node = TREE_TYPE (node);
- if (TYPE_P (node))
- node = canonical_type_variant (node);
-
+ if (TYPE_P (node)
+ && TYPE_CANONICAL (node) != node
+ && TYPE_MAIN_VARIANT (node) != node)
+ /* Here we want to strip the topmost typedef only.
+ We need to do that so is_std_substitution can do proper
+ name matching. */
+ node = cp_build_qualified_type (TYPE_MAIN_VARIANT (node),
+ cp_type_quals (node));
return node;
}
@@ -1679,9 +1684,9 @@ write_type (tree type)
write_char ('t');
else
write_char ('T');
- ++skip_evaluation;
+ ++cp_unevaluated_operand;
write_expression (DECLTYPE_TYPE_EXPR (type));
- --skip_evaluation;
+ --cp_unevaluated_operand;
write_char ('E');
break;
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index e632fe0c9e6..af58afe135e 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -1,7 +1,7 @@
/* Handle the hair of processing (but not expanding) inline functions.
Also manage function and variable name overloading.
Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009
Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com)
@@ -126,7 +126,8 @@ make_thunk (tree function, bool this_adjusting,
gcc_assert (TYPE_SIZE (DECL_CONTEXT (function))
&& TYPE_BEING_DEFINED (DECL_CONTEXT (function)));
- thunk = build_decl (FUNCTION_DECL, NULL_TREE, TREE_TYPE (function));
+ thunk = build_decl (DECL_SOURCE_LOCATION (function),
+ FUNCTION_DECL, NULL_TREE, TREE_TYPE (function));
DECL_LANG_SPECIFIC (thunk) = DECL_LANG_SPECIFIC (function);
cxx_dup_lang_specific_decl (thunk);
DECL_THUNKS (thunk) = NULL_TREE;
@@ -262,7 +263,8 @@ static GTY (()) int thunk_labelno;
tree
make_alias_for (tree function, tree newid)
{
- tree alias = build_decl (FUNCTION_DECL, newid, TREE_TYPE (function));
+ tree alias = build_decl (DECL_SOURCE_LOCATION (function),
+ FUNCTION_DECL, newid, TREE_TYPE (function));
DECL_LANG_SPECIFIC (alias) = DECL_LANG_SPECIFIC (function);
cxx_dup_lang_specific_decl (alias);
DECL_CONTEXT (alias) = NULL;
@@ -381,7 +383,7 @@ use_thunk (tree thunk_fndecl, bool emit_p)
DECL_VISIBILITY_SPECIFIED (thunk_fndecl)
= DECL_VISIBILITY_SPECIFIED (function);
if (DECL_ONE_ONLY (function))
- make_decl_one_only (thunk_fndecl);
+ make_decl_one_only (thunk_fndecl, cxx_comdat_group (thunk_fndecl));
if (flag_syntax_only)
{
@@ -428,7 +430,8 @@ use_thunk (tree thunk_fndecl, bool emit_p)
current_function_decl = thunk_fndecl;
DECL_RESULT (thunk_fndecl)
- = build_decl (RESULT_DECL, 0, integer_type_node);
+ = build_decl (DECL_SOURCE_LOCATION (thunk_fndecl),
+ RESULT_DECL, 0, integer_type_node);
fnname = IDENTIFIER_POINTER (DECL_NAME (thunk_fndecl));
/* The back end expects DECL_INITIAL to contain a BLOCK, so we
create one. */
@@ -661,19 +664,21 @@ do_build_assign_ref (tree fndecl)
BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
{
tree converted_parm;
+ VEC(tree,gc) *parmvec;
/* We must convert PARM directly to the base class
explicitly since the base class may be ambiguous. */
converted_parm = build_base_path (PLUS_EXPR, parm, base_binfo, 1);
/* Call the base class assignment operator. */
+ parmvec = make_tree_vector_single (converted_parm);
finish_expr_stmt
(build_special_member_call (current_class_ref,
ansi_assopname (NOP_EXPR),
- build_tree_list (NULL_TREE,
- converted_parm),
+ &parmvec,
base_binfo,
LOOKUP_NORMAL | LOOKUP_NONVIRTUAL,
tf_warning_or_error));
+ release_tree_vector (parmvec);
}
/* Assign to each of the non-static data members. */
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index e499edeabba..143fcf31568 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -3491,7 +3491,7 @@ do_using_directive (tree name_space)
gcc_assert (TREE_CODE (name_space) == NAMESPACE_DECL);
if (building_stmt_tree ())
- add_stmt (build_stmt (USING_STMT, name_space));
+ add_stmt (build_stmt (input_location, USING_STMT, name_space));
name_space = ORIGINAL_NAMESPACE (name_space);
if (!toplevel_bindings_p ())
@@ -4235,7 +4235,7 @@ lookup_name_nonclass (tree name)
}
tree
-lookup_function_nonclass (tree name, tree args, bool block_p)
+lookup_function_nonclass (tree name, VEC(tree,gc) *args, bool block_p)
{
return
lookup_arg_dependent (name,
@@ -4427,7 +4427,7 @@ lookup_type_current_level (tree name)
struct arg_lookup
{
tree name;
- tree args;
+ VEC(tree,gc) *args;
tree namespaces;
tree classes;
tree functions;
@@ -4435,6 +4435,7 @@ struct arg_lookup
static bool arg_assoc (struct arg_lookup*, tree);
static bool arg_assoc_args (struct arg_lookup*, tree);
+static bool arg_assoc_args_vec (struct arg_lookup*, VEC(tree,gc) *);
static bool arg_assoc_type (struct arg_lookup*, tree);
static bool add_function (struct arg_lookup *, tree);
static bool arg_assoc_namespace (struct arg_lookup *, tree);
@@ -4589,13 +4590,13 @@ arg_assoc_namespace (struct arg_lookup *k, tree scope)
classes. */
if (hidden_name_p (OVL_CURRENT (value)))
{
- tree args;
+ unsigned int ix;
+ tree arg;
- for (args = k->args; args; args = TREE_CHAIN (args))
- if (friend_of_associated_class_p (TREE_VALUE (args),
- OVL_CURRENT (value)))
+ for (ix = 0; VEC_iterate (tree, k->args, ix, arg); ++ix)
+ if (friend_of_associated_class_p (arg, OVL_CURRENT (value)))
break;
- if (!args)
+ if (ix >= VEC_length (tree, k->args))
continue;
}
@@ -4805,6 +4806,21 @@ arg_assoc_args (struct arg_lookup *k, tree args)
return false;
}
+/* Adds everything associated with an argument vector. Returns true
+ on error. */
+
+static bool
+arg_assoc_args_vec (struct arg_lookup *k, VEC(tree,gc) *args)
+{
+ unsigned int ix;
+ tree arg;
+
+ for (ix = 0; VEC_iterate (tree, args, ix, arg); ++ix)
+ if (arg_assoc (k, arg))
+ return true;
+ return false;
+}
+
/* Adds everything associated with a given tree_node. Returns 1 on error. */
static bool
@@ -4884,7 +4900,7 @@ arg_assoc (struct arg_lookup *k, tree n)
are the functions found in normal lookup. */
tree
-lookup_arg_dependent (tree name, tree fns, tree args)
+lookup_arg_dependent (tree name, tree fns, VEC(tree,gc) *args)
{
struct arg_lookup k;
@@ -4907,7 +4923,7 @@ lookup_arg_dependent (tree name, tree fns, tree args)
picking up later definitions) in the second stage. */
k.namespaces = NULL_TREE;
- arg_assoc_args (&k, args);
+ arg_assoc_args_vec (&k, args);
fns = k.functions;
@@ -5303,7 +5319,8 @@ push_to_top_level (void)
s->bindings = b;
s->need_pop_function_context = need_pop;
s->function_decl = current_function_decl;
- s->skip_evaluation = skip_evaluation;
+ s->unevaluated_operand = cp_unevaluated_operand;
+ s->inhibit_evaluation_warnings = c_inhibit_evaluation_warnings;
scope_chain = s;
current_function_decl = NULL_TREE;
@@ -5311,7 +5328,8 @@ push_to_top_level (void)
current_lang_name = lang_name_cplusplus;
current_namespace = global_namespace;
push_class_stack ();
- skip_evaluation = 0;
+ cp_unevaluated_operand = 0;
+ c_inhibit_evaluation_warnings = 0;
timevar_pop (TV_NAME_LOOKUP);
}
@@ -5344,7 +5362,8 @@ pop_from_top_level (void)
if (s->need_pop_function_context)
pop_function_context ();
current_function_decl = s->function_decl;
- skip_evaluation = s->skip_evaluation;
+ cp_unevaluated_operand = s->unevaluated_operand;
+ c_inhibit_evaluation_warnings = s->inhibit_evaluation_warnings;
timevar_pop (TV_NAME_LOOKUP);
}
@@ -5399,7 +5418,7 @@ cp_emit_debug_info_for_using (tree t, tree context)
if (TREE_CODE (t) != TEMPLATE_DECL)
{
if (building_stmt_tree ())
- add_stmt (build_stmt (USING_STMT, t));
+ add_stmt (build_stmt (input_location, USING_STMT, t));
else
(*debug_hooks->imported_module_or_decl) (t, NULL_TREE, context, false);
}
diff --git a/gcc/cp/name-lookup.h b/gcc/cp/name-lookup.h
index 6de4cfa7d43..2203a8400bf 100644
--- a/gcc/cp/name-lookup.h
+++ b/gcc/cp/name-lookup.h
@@ -1,5 +1,6 @@
/* Declarations for C++ name lookup routines.
- Copyright (C) 2003, 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009
+ Free Software Foundation, Inc.
Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
This file is part of GCC.
@@ -317,7 +318,7 @@ extern tree remove_hidden_names (tree);
extern tree lookup_qualified_name (tree, tree, bool, bool);
extern tree lookup_name_nonclass (tree);
extern tree lookup_name_innermost_nonclass_level (tree);
-extern tree lookup_function_nonclass (tree, tree, bool);
+extern tree lookup_function_nonclass (tree, VEC(tree,gc) *, bool);
extern void push_local_binding (tree, tree, int);
extern bool pushdecl_class_level (tree);
extern tree pushdecl_namespace_level (tree, bool);
@@ -332,7 +333,7 @@ extern void do_toplevel_using_decl (tree, tree, tree);
extern void do_local_using_decl (tree, tree, tree);
extern tree do_class_using_decl (tree, tree);
extern void do_using_directive (tree);
-extern tree lookup_arg_dependent (tree, tree, tree);
+extern tree lookup_arg_dependent (tree, tree, VEC(tree,gc) *);
extern bool is_associated_namespace (tree, tree);
extern void parse_using_directive (tree, tree);
extern tree innermost_non_namespace_value (tree);
diff --git a/gcc/cp/optimize.c b/gcc/cp/optimize.c
index 8c7b9e82ccb..9d4a8c5f8e4 100644
--- a/gcc/cp/optimize.c
+++ b/gcc/cp/optimize.c
@@ -141,7 +141,12 @@ maybe_clone_body (tree fn)
DECL_DECLARED_INLINE_P (clone) = DECL_DECLARED_INLINE_P (fn);
DECL_COMDAT (clone) = DECL_COMDAT (fn);
DECL_WEAK (clone) = DECL_WEAK (fn);
- DECL_ONE_ONLY (clone) = DECL_ONE_ONLY (fn);
+
+ /* We don't copy the comdat group from fn to clone because the assembler
+ name of fn was corrupted by write_mangled_name by adding *INTERNAL*
+ to it. By doing so, it also corrupted the comdat group. */
+ if (DECL_ONE_ONLY (fn))
+ DECL_COMDAT_GROUP (clone) = cxx_comdat_group (clone);
DECL_SECTION_NAME (clone) = DECL_SECTION_NAME (fn);
DECL_USE_TEMPLATE (clone) = DECL_USE_TEMPLATE (fn);
DECL_EXTERNAL (clone) = DECL_EXTERNAL (fn);
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 1fc9469fcdf..bdf305827f0 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -247,6 +247,10 @@ static void cp_parser_initial_pragma
static FILE *cp_lexer_debug_stream;
#endif /* ENABLE_CHECKING */
+/* Nonzero if we are parsing an unevaluated operand: an operand to
+ sizeof, typeof, or alignof. */
+int cp_unevaluated_operand;
+
/* Create a new main C++ lexer, the lexer that gets tokens from the
preprocessor. */
@@ -1183,7 +1187,7 @@ function_declarator_p (const cp_declarator *declarator)
/* Flags that are passed to some parsing functions. These values can
be bitwise-ored together. */
-enum cp_parser_flags
+enum
{
/* No flags. */
CP_PARSER_FLAGS_NONE = 0x0,
@@ -1195,7 +1199,7 @@ enum cp_parser_flags
};
/* This type is used for parameters and variables which hold
- combinations of the flags in enum cp_parser_flags. */
+ combinations of the above flags. */
typedef int cp_parser_flags;
/* The different kinds of declarators we want to parse. */
@@ -1584,7 +1588,7 @@ static tree cp_parser_postfix_open_square_expression
(cp_parser *, tree, bool);
static tree cp_parser_postfix_dot_deref_expression
(cp_parser *, enum cpp_ttype, tree, bool, cp_id_kind *, location_t);
-static tree cp_parser_parenthesized_expression_list
+static VEC(tree,gc) *cp_parser_parenthesized_expression_list
(cp_parser *, bool, bool, bool, bool *);
static void cp_parser_pseudo_destructor_name
(cp_parser *, tree *, tree *);
@@ -1594,7 +1598,7 @@ static enum tree_code cp_parser_unary_operator
(cp_token *);
static tree cp_parser_new_expression
(cp_parser *);
-static tree cp_parser_new_placement
+static VEC(tree,gc) *cp_parser_new_placement
(cp_parser *);
static tree cp_parser_new_type_id
(cp_parser *, tree *);
@@ -1602,7 +1606,7 @@ static cp_declarator *cp_parser_new_declarator_opt
(cp_parser *);
static cp_declarator *cp_parser_direct_new_declarator
(cp_parser *);
-static tree cp_parser_new_initializer
+static VEC(tree,gc) *cp_parser_new_initializer
(cp_parser *);
static tree cp_parser_delete_expression
(cp_parser *);
@@ -2149,11 +2153,11 @@ static void
cp_parser_check_decl_spec (cp_decl_specifier_seq *decl_specs,
location_t location)
{
- cp_decl_spec ds;
+ int ds;
for (ds = ds_first; ds != ds_last; ++ds)
{
- unsigned count = decl_specs->specs[(int)ds];
+ unsigned count = decl_specs->specs[ds];
if (count < 2)
continue;
/* The "long" specifier is a special case because of "long long". */
@@ -2183,7 +2187,7 @@ cp_parser_check_decl_spec (cp_decl_specifier_seq *decl_specs,
"__complex",
"__thread"
};
- error ("%Hduplicate %qs", &location, decl_spec_names[(int)ds]);
+ error ("%Hduplicate %qs", &location, decl_spec_names[ds]);
}
}
}
@@ -4685,7 +4689,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
bool is_builtin_constant_p;
bool saved_integral_constant_expression_p = false;
bool saved_non_integral_constant_expression_p = false;
- tree args;
+ VEC(tree,gc) *args;
is_member_access = false;
@@ -4713,7 +4717,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
= saved_non_integral_constant_expression_p;
}
- if (args == error_mark_node)
+ if (args == NULL)
{
postfix_expression = error_mark_node;
break;
@@ -4726,6 +4730,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
"a function call"))
{
postfix_expression = error_mark_node;
+ release_tree_vector (args);
break;
}
@@ -4735,7 +4740,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
{
if (TREE_CODE (postfix_expression) == IDENTIFIER_NODE)
{
- if (args)
+ if (!VEC_empty (tree, args))
{
koenig_p = true;
if (!any_type_dependent_arguments_p (args))
@@ -4749,7 +4754,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
/* We do not perform argument-dependent lookup if
normal lookup finds a non-function, in accordance
with the expected resolution of DR 218. */
- else if (args && is_overloaded_fn (postfix_expression))
+ else if (!VEC_empty (tree, args)
+ && is_overloaded_fn (postfix_expression))
{
tree fn = get_first_fn (postfix_expression);
@@ -4782,7 +4788,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
|| any_type_dependent_arguments_p (args)))
{
postfix_expression
- = build_nt_call_list (postfix_expression, args);
+ = build_nt_call_vec (postfix_expression, args);
+ release_tree_vector (args);
break;
}
@@ -4790,7 +4797,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
{
postfix_expression
= (build_new_method_call
- (instance, fn, args, NULL_TREE,
+ (instance, fn, &args, NULL_TREE,
(idk == CP_ID_KIND_QUALIFIED
? LOOKUP_NONVIRTUAL : LOOKUP_NORMAL),
/*fn_p=*/NULL,
@@ -4798,7 +4805,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
}
else
postfix_expression
- = finish_call_expr (postfix_expression, args,
+ = finish_call_expr (postfix_expression, &args,
/*disallow_virtual=*/false,
/*koenig_p=*/false,
tf_warning_or_error);
@@ -4807,25 +4814,27 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
|| TREE_CODE (postfix_expression) == MEMBER_REF
|| TREE_CODE (postfix_expression) == DOTSTAR_EXPR)
postfix_expression = (build_offset_ref_call_from_tree
- (postfix_expression, args));
+ (postfix_expression, &args));
else if (idk == CP_ID_KIND_QUALIFIED)
/* A call to a static class member, or a namespace-scope
function. */
postfix_expression
- = finish_call_expr (postfix_expression, args,
+ = finish_call_expr (postfix_expression, &args,
/*disallow_virtual=*/true,
koenig_p,
tf_warning_or_error);
else
/* All other function calls. */
postfix_expression
- = finish_call_expr (postfix_expression, args,
+ = finish_call_expr (postfix_expression, &args,
/*disallow_virtual=*/false,
koenig_p,
tf_warning_or_error);
/* The POSTFIX_EXPRESSION is certainly no longer an id. */
idk = CP_ID_KIND_NONE;
+
+ release_tree_vector (args);
}
break;
@@ -5132,24 +5141,22 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
ALLOW_EXPANSION_P is true if this expression allows expansion of an
argument pack.
- Returns a TREE_LIST. The TREE_VALUE of each node is a
- representation of an assignment-expression. Note that a TREE_LIST
- is returned even if there is only a single expression in the list.
- error_mark_node is returned if the ( and or ) are
- missing. NULL_TREE is returned on no expressions. The parentheses
- are eaten. IS_ATTRIBUTE_LIST is true if this is really an attribute
- list being parsed. If NON_CONSTANT_P is non-NULL, *NON_CONSTANT_P
- indicates whether or not all of the expressions in the list were
- constant. */
+ Returns a vector of trees. Each element is a representation of an
+ assignment-expression. NULL is returned if the ( and or ) are
+ missing. An empty, but allocated, vector is returned on no
+ expressions. The parentheses are eaten. IS_ATTRIBUTE_LIST is true
+ if this is really an attribute list being parsed. If
+ NON_CONSTANT_P is non-NULL, *NON_CONSTANT_P indicates whether or
+ not all of the expressions in the list were constant. */
-static tree
+static VEC(tree,gc) *
cp_parser_parenthesized_expression_list (cp_parser* parser,
bool is_attribute_list,
bool cast_p,
bool allow_expansion_p,
bool *non_constant_p)
{
- tree expression_list = NULL_TREE;
+ VEC(tree,gc) *expression_list;
bool fold_expr_p = is_attribute_list;
tree identifier = NULL_TREE;
bool saved_greater_than_is_operator_p;
@@ -5159,7 +5166,9 @@ cp_parser_parenthesized_expression_list (cp_parser* parser,
*non_constant_p = false;
if (!cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"))
- return error_mark_node;
+ return NULL;
+
+ expression_list = make_tree_vector ();
/* Within a parenthesized expression, a `>' token is always
the greater-than operator. */
@@ -5228,7 +5237,7 @@ cp_parser_parenthesized_expression_list (cp_parser* parser,
expressions to the list, so that we can still tell if
the correct form for a parenthesized expression-list
is found. That gives better errors. */
- expression_list = tree_cons (NULL_TREE, expr, expression_list);
+ VEC_safe_push (tree, gc, expression_list, expr);
if (expr == error_mark_node)
goto skip_comma;
@@ -5264,17 +5273,15 @@ cp_parser_parenthesized_expression_list (cp_parser* parser,
{
parser->greater_than_is_operator_p
= saved_greater_than_is_operator_p;
- return error_mark_node;
+ return NULL;
}
}
parser->greater_than_is_operator_p
= saved_greater_than_is_operator_p;
- /* We built up the list in reverse order so we must reverse it now. */
- expression_list = nreverse (expression_list);
if (identifier)
- expression_list = tree_cons (NULL_TREE, identifier, expression_list);
+ VEC_safe_insert (tree, gc, expression_list, 0, identifier);
return expression_list;
}
@@ -5618,10 +5625,11 @@ static tree
cp_parser_new_expression (cp_parser* parser)
{
bool global_scope_p;
- tree placement;
+ VEC(tree,gc) *placement;
tree type;
- tree initializer;
+ VEC(tree,gc) *initializer;
tree nelts;
+ tree ret;
/* Look for the optional `::' operator. */
global_scope_p
@@ -5637,7 +5645,11 @@ cp_parser_new_expression (cp_parser* parser)
placement = cp_parser_new_placement (parser);
/* If that didn't work out, there's no new-placement. */
if (!cp_parser_parse_definitely (parser))
- placement = NULL_TREE;
+ {
+ if (placement != NULL)
+ release_tree_vector (placement);
+ placement = NULL;
+ }
/* If the next token is a `(', then we have a parenthesized
type-id. */
@@ -5673,16 +5685,25 @@ cp_parser_new_expression (cp_parser* parser)
|| cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
initializer = cp_parser_new_initializer (parser);
else
- initializer = NULL_TREE;
+ initializer = NULL;
/* A new-expression may not appear in an integral constant
expression. */
if (cp_parser_non_integral_constant_expression (parser, "%<new%>"))
- return error_mark_node;
+ ret = error_mark_node;
+ else
+ {
+ /* Create a representation of the new-expression. */
+ ret = build_new (&placement, type, nelts, &initializer, global_scope_p,
+ tf_warning_or_error);
+ }
- /* Create a representation of the new-expression. */
- return build_new (placement, type, nelts, initializer, global_scope_p,
- tf_warning_or_error);
+ if (placement != NULL)
+ release_tree_vector (placement);
+ if (initializer != NULL)
+ release_tree_vector (initializer);
+
+ return ret;
}
/* Parse a new-placement.
@@ -5692,10 +5713,10 @@ cp_parser_new_expression (cp_parser* parser)
Returns the same representation as for an expression-list. */
-static tree
+static VEC(tree,gc) *
cp_parser_new_placement (cp_parser* parser)
{
- tree expression_list;
+ VEC(tree,gc) *expression_list;
/* Parse the expression-list. */
expression_list = (cp_parser_parenthesized_expression_list
@@ -5885,28 +5906,26 @@ cp_parser_direct_new_declarator (cp_parser* parser)
( expression-list [opt] )
braced-init-list
- Returns a representation of the expression-list. If there is no
- expression-list, VOID_ZERO_NODE is returned. */
+ Returns a representation of the expression-list. */
-static tree
+static VEC(tree,gc) *
cp_parser_new_initializer (cp_parser* parser)
{
- tree expression_list;
+ VEC(tree,gc) *expression_list;
if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
{
+ tree t;
bool expr_non_constant_p;
maybe_warn_cpp0x ("extended initializer lists");
- expression_list = cp_parser_braced_list (parser, &expr_non_constant_p);
- CONSTRUCTOR_IS_DIRECT_INIT (expression_list) = 1;
- expression_list = build_tree_list (NULL_TREE, expression_list);
+ t = cp_parser_braced_list (parser, &expr_non_constant_p);
+ CONSTRUCTOR_IS_DIRECT_INIT (t) = 1;
+ expression_list = make_tree_vector_single (t);
}
else
expression_list = (cp_parser_parenthesized_expression_list
(parser, false, /*cast_p=*/false, /*allow_expansion_p=*/true,
/*non_constant_p=*/NULL));
- if (!expression_list)
- expression_list = void_zero_node;
return expression_list;
}
@@ -6120,7 +6139,7 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p,
return error_mark_node;
/* Perform the cast. */
- expr = build_c_cast (type, expr);
+ expr = build_c_cast (input_location, type, expr);
return expr;
}
else
@@ -6370,16 +6389,26 @@ cp_parser_question_colon_clause (cp_parser* parser, tree logical_or_expr)
cp_lexer_consume_token (parser->lexer);
if (cp_parser_allow_gnu_extensions_p (parser)
&& cp_lexer_next_token_is (parser->lexer, CPP_COLON))
- /* Implicit true clause. */
- expr = NULL_TREE;
+ {
+ /* Implicit true clause. */
+ expr = NULL_TREE;
+ c_inhibit_evaluation_warnings += logical_or_expr == truthvalue_true_node;
+ }
else
- /* Parse the expression. */
- expr = cp_parser_expression (parser, /*cast_p=*/false, NULL);
+ {
+ /* Parse the expression. */
+ c_inhibit_evaluation_warnings += logical_or_expr == truthvalue_false_node;
+ expr = cp_parser_expression (parser, /*cast_p=*/false, NULL);
+ c_inhibit_evaluation_warnings +=
+ ((logical_or_expr == truthvalue_true_node)
+ - (logical_or_expr == truthvalue_false_node));
+ }
/* The next token should be a `:'. */
cp_parser_require (parser, CPP_COLON, "%<:%>");
/* Parse the assignment-expression. */
assignment_expr = cp_parser_assignment_expression (parser, /*cast_p=*/false, NULL);
+ c_inhibit_evaluation_warnings -= logical_or_expr == truthvalue_true_node;
/* Build the conditional-expression. */
return build_x_conditional_expr (logical_or_expr,
@@ -7037,6 +7066,7 @@ static void
cp_parser_label_for_labeled_statement (cp_parser* parser)
{
cp_token *token;
+ tree label = NULL_TREE;
/* The next token should be an identifier. */
token = cp_lexer_peek_token (parser->lexer);
@@ -7077,7 +7107,7 @@ cp_parser_label_for_labeled_statement (cp_parser* parser)
expr_hi = NULL_TREE;
if (parser->in_switch_statement_p)
- finish_case_label (expr, expr_hi);
+ finish_case_label (token->location, expr, expr_hi);
else
error ("%Hcase label %qE not within a switch statement",
&token->location, expr);
@@ -7089,19 +7119,41 @@ cp_parser_label_for_labeled_statement (cp_parser* parser)
cp_lexer_consume_token (parser->lexer);
if (parser->in_switch_statement_p)
- finish_case_label (NULL_TREE, NULL_TREE);
+ finish_case_label (token->location, NULL_TREE, NULL_TREE);
else
error ("%Hcase label not within a switch statement", &token->location);
break;
default:
/* Anything else must be an ordinary label. */
- finish_label_stmt (cp_parser_identifier (parser));
+ label = finish_label_stmt (cp_parser_identifier (parser));
break;
}
/* Require the `:' token. */
cp_parser_require (parser, CPP_COLON, "%<:%>");
+
+ /* An ordinary label may optionally be followed by attributes.
+ However, this is only permitted if the attributes are then
+ followed by a semicolon. This is because, for backward
+ compatibility, when parsing
+ lab: __attribute__ ((unused)) int i;
+ we want the attribute to attach to "i", not "lab". */
+ if (label != NULL_TREE
+ && cp_lexer_next_token_is_keyword (parser->lexer, RID_ATTRIBUTE))
+ {
+ tree attrs;
+
+ cp_parser_parse_tentatively (parser);
+ attrs = cp_parser_attributes_opt (parser);
+ if (attrs == NULL_TREE
+ || cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
+ cp_parser_abort_tentative_parse (parser);
+ else if (!cp_parser_parse_definitely (parser))
+ ;
+ else
+ cplus_decl_attributes (&label, attrs, 0);
+ }
}
/* Parse an expression-statement.
@@ -7288,7 +7340,7 @@ cp_parser_selection_statement (cp_parser* parser, bool *if_p)
if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
{
location_t loc = cp_lexer_peek_token (parser->lexer)->location;
- add_stmt (build_empty_stmt ());
+ add_stmt (build_empty_stmt (loc));
cp_lexer_consume_token (parser->lexer);
if (!cp_lexer_next_token_is_keyword (parser->lexer, RID_ELSE))
warning_at (loc, OPT_Wempty_body, "suggest braces around "
@@ -7311,10 +7363,12 @@ cp_parser_selection_statement (cp_parser* parser, bool *if_p)
/* Parse the else-clause. */
if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
{
- warning_at (cp_lexer_peek_token (parser->lexer)->location,
+ location_t loc;
+ loc = cp_lexer_peek_token (parser->lexer)->location;
+ warning_at (loc,
OPT_Wempty_body, "suggest braces around "
"empty body in an %<else%> statement");
- add_stmt (build_empty_stmt ());
+ add_stmt (build_empty_stmt (loc));
cp_lexer_consume_token (parser->lexer);
}
else
@@ -7822,8 +7876,9 @@ cp_parser_implicitly_scoped_statement (cp_parser* parser, bool *if_p)
/* Mark if () ; with a special NOP_EXPR. */
if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
{
+ location_t loc = cp_lexer_peek_token (parser->lexer)->location;
cp_lexer_consume_token (parser->lexer);
- statement = add_stmt (build_empty_stmt ());
+ statement = add_stmt (build_empty_stmt (loc));
}
/* if a compound is opened, we simply parse the statement directly. */
else if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
@@ -8816,7 +8871,10 @@ cp_parser_decltype (cp_parser *parser)
parser->integral_constant_expression_p = false;
/* Do not actually evaluate the expression. */
- ++skip_evaluation;
+ ++cp_unevaluated_operand;
+
+ /* Do not warn about problems with the expression. */
+ ++c_inhibit_evaluation_warnings;
/* Parse the opening `('. */
if (!cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"))
@@ -8920,7 +8978,8 @@ cp_parser_decltype (cp_parser *parser)
}
/* Go back to evaluating expressions. */
- --skip_evaluation;
+ --cp_unevaluated_operand;
+ --c_inhibit_evaluation_warnings;
/* Restore the old message and the integral constant expression
flags. */
@@ -9225,11 +9284,18 @@ cp_parser_mem_initializer (cp_parser* parser)
expression_list = build_tree_list (NULL_TREE, expression_list);
}
else
- expression_list
- = cp_parser_parenthesized_expression_list (parser, false,
- /*cast_p=*/false,
- /*allow_expansion_p=*/true,
- /*non_constant_p=*/NULL);
+ {
+ VEC(tree,gc)* vec;
+ vec = cp_parser_parenthesized_expression_list (parser, false,
+ /*cast_p=*/false,
+ /*allow_expansion_p=*/true,
+ /*non_constant_p=*/NULL);
+ if (vec == NULL)
+ return error_mark_node;
+ expression_list = build_tree_list_vec (vec);
+ release_tree_vector (vec);
+ }
+
if (expression_list == error_mark_node)
return error_mark_node;
if (!expression_list)
@@ -9635,14 +9701,17 @@ cp_parser_template_parameter_list (cp_parser* parser)
tree parameter;
bool is_non_type;
bool is_parameter_pack;
+ location_t parm_loc;
/* Parse the template-parameter. */
+ parm_loc = cp_lexer_peek_token (parser->lexer)->location;
parameter = cp_parser_template_parameter (parser,
&is_non_type,
&is_parameter_pack);
/* Add it to the list. */
if (parameter != error_mark_node)
parameter_list = process_template_parm (parameter_list,
+ parm_loc,
parameter,
is_non_type,
is_parameter_pack);
@@ -13291,13 +13360,6 @@ cp_parser_direct_declarator (cp_parser* parser,
&non_constant_p);
if (!non_constant_p)
bounds = fold_non_dependent_expr (bounds);
- else if (processing_template_decl)
- {
- /* Remember this wasn't a constant-expression. */
- bounds = build_nop (TREE_TYPE (bounds), bounds);
- TREE_SIDE_EFFECTS (bounds) = 1;
- }
-
/* Normally, the array bound must be an integral constant
expression. However, as an extension, we allow VLAs
in function scopes. */
@@ -13307,6 +13369,12 @@ cp_parser_direct_declarator (cp_parser* parser,
&token->location);
bounds = error_mark_node;
}
+ else if (processing_template_decl && !error_operand_p (bounds))
+ {
+ /* Remember this wasn't a constant-expression. */
+ bounds = build_nop (TREE_TYPE (bounds), bounds);
+ TREE_SIDE_EFFECTS (bounds) = 1;
+ }
}
else
bounds = NULL_TREE;
@@ -13321,181 +13389,183 @@ cp_parser_direct_declarator (cp_parser* parser,
}
else if (first && dcl_kind != CP_PARSER_DECLARATOR_ABSTRACT)
{
- tree qualifying_scope;
- tree unqualified_name;
- special_function_kind sfk;
- bool abstract_ok;
- bool pack_expansion_p = false;
- cp_token *declarator_id_start_token;
-
- /* Parse a declarator-id */
- abstract_ok = (dcl_kind == CP_PARSER_DECLARATOR_EITHER);
- if (abstract_ok)
- {
- cp_parser_parse_tentatively (parser);
+ {
+ tree qualifying_scope;
+ tree unqualified_name;
+ special_function_kind sfk;
+ bool abstract_ok;
+ bool pack_expansion_p = false;
+ cp_token *declarator_id_start_token;
+
+ /* Parse a declarator-id */
+ abstract_ok = (dcl_kind == CP_PARSER_DECLARATOR_EITHER);
+ if (abstract_ok)
+ {
+ cp_parser_parse_tentatively (parser);
- /* If we see an ellipsis, we should be looking at a
- parameter pack. */
- if (token->type == CPP_ELLIPSIS)
- {
- /* Consume the `...' */
- cp_lexer_consume_token (parser->lexer);
+ /* If we see an ellipsis, we should be looking at a
+ parameter pack. */
+ if (token->type == CPP_ELLIPSIS)
+ {
+ /* Consume the `...' */
+ cp_lexer_consume_token (parser->lexer);
- pack_expansion_p = true;
- }
- }
+ pack_expansion_p = true;
+ }
+ }
- declarator_id_start_token = cp_lexer_peek_token (parser->lexer);
- unqualified_name
- = cp_parser_declarator_id (parser, /*optional_p=*/abstract_ok);
- qualifying_scope = parser->scope;
- if (abstract_ok)
- {
- bool okay = false;
-
- if (!unqualified_name && pack_expansion_p)
- {
- /* Check whether an error occurred. */
- okay = !cp_parser_error_occurred (parser);
-
- /* We already consumed the ellipsis to mark a
- parameter pack, but we have no way to report it,
- so abort the tentative parse. We will be exiting
- immediately anyway. */
- cp_parser_abort_tentative_parse (parser);
- }
- else
- okay = cp_parser_parse_definitely (parser);
-
- if (!okay)
- unqualified_name = error_mark_node;
- else if (unqualified_name
- && (qualifying_scope
- || (TREE_CODE (unqualified_name)
- != IDENTIFIER_NODE)))
- {
- cp_parser_error (parser, "expected unqualified-id");
- unqualified_name = error_mark_node;
- }
- }
+ declarator_id_start_token = cp_lexer_peek_token (parser->lexer);
+ unqualified_name
+ = cp_parser_declarator_id (parser, /*optional_p=*/abstract_ok);
+ qualifying_scope = parser->scope;
+ if (abstract_ok)
+ {
+ bool okay = false;
- if (!unqualified_name)
- return NULL;
- if (unqualified_name == error_mark_node)
- {
- declarator = cp_error_declarator;
- pack_expansion_p = false;
- declarator->parameter_pack_p = false;
- break;
- }
+ if (!unqualified_name && pack_expansion_p)
+ {
+ /* Check whether an error occurred. */
+ okay = !cp_parser_error_occurred (parser);
+
+ /* We already consumed the ellipsis to mark a
+ parameter pack, but we have no way to report it,
+ so abort the tentative parse. We will be exiting
+ immediately anyway. */
+ cp_parser_abort_tentative_parse (parser);
+ }
+ else
+ okay = cp_parser_parse_definitely (parser);
- if (qualifying_scope && at_namespace_scope_p ()
- && TREE_CODE (qualifying_scope) == TYPENAME_TYPE)
- {
- /* In the declaration of a member of a template class
- outside of the class itself, the SCOPE will sometimes
- be a TYPENAME_TYPE. For example, given:
-
- template <typename T>
- int S<T>::R::i = 3;
-
- the SCOPE will be a TYPENAME_TYPE for `S<T>::R'. In
- this context, we must resolve S<T>::R to an ordinary
- type, rather than a typename type.
-
- The reason we normally avoid resolving TYPENAME_TYPEs
- is that a specialization of `S' might render
- `S<T>::R' not a type. However, if `S' is
- specialized, then this `i' will not be used, so there
- is no harm in resolving the types here. */
- tree type;
+ if (!okay)
+ unqualified_name = error_mark_node;
+ else if (unqualified_name
+ && (qualifying_scope
+ || (TREE_CODE (unqualified_name)
+ != IDENTIFIER_NODE)))
+ {
+ cp_parser_error (parser, "expected unqualified-id");
+ unqualified_name = error_mark_node;
+ }
+ }
- /* Resolve the TYPENAME_TYPE. */
- type = resolve_typename_type (qualifying_scope,
- /*only_current_p=*/false);
- /* If that failed, the declarator is invalid. */
- if (TREE_CODE (type) == TYPENAME_TYPE)
- error ("%H%<%T::%E%> is not a type",
- &declarator_id_start_token->location,
- TYPE_CONTEXT (qualifying_scope),
- TYPE_IDENTIFIER (qualifying_scope));
- qualifying_scope = type;
- }
+ if (!unqualified_name)
+ return NULL;
+ if (unqualified_name == error_mark_node)
+ {
+ declarator = cp_error_declarator;
+ pack_expansion_p = false;
+ declarator->parameter_pack_p = false;
+ break;
+ }
- sfk = sfk_none;
+ if (qualifying_scope && at_namespace_scope_p ()
+ && TREE_CODE (qualifying_scope) == TYPENAME_TYPE)
+ {
+ /* In the declaration of a member of a template class
+ outside of the class itself, the SCOPE will sometimes
+ be a TYPENAME_TYPE. For example, given:
+
+ template <typename T>
+ int S<T>::R::i = 3;
+
+ the SCOPE will be a TYPENAME_TYPE for `S<T>::R'. In
+ this context, we must resolve S<T>::R to an ordinary
+ type, rather than a typename type.
+
+ The reason we normally avoid resolving TYPENAME_TYPEs
+ is that a specialization of `S' might render
+ `S<T>::R' not a type. However, if `S' is
+ specialized, then this `i' will not be used, so there
+ is no harm in resolving the types here. */
+ tree type;
+
+ /* Resolve the TYPENAME_TYPE. */
+ type = resolve_typename_type (qualifying_scope,
+ /*only_current_p=*/false);
+ /* If that failed, the declarator is invalid. */
+ if (TREE_CODE (type) == TYPENAME_TYPE)
+ error ("%H%<%T::%E%> is not a type",
+ &declarator_id_start_token->location,
+ TYPE_CONTEXT (qualifying_scope),
+ TYPE_IDENTIFIER (qualifying_scope));
+ qualifying_scope = type;
+ }
- if (unqualified_name)
- {
- tree class_type;
+ sfk = sfk_none;
- if (qualifying_scope
- && CLASS_TYPE_P (qualifying_scope))
- class_type = qualifying_scope;
- else
- class_type = current_class_type;
+ if (unqualified_name)
+ {
+ tree class_type;
- if (TREE_CODE (unqualified_name) == TYPE_DECL)
- {
- tree name_type = TREE_TYPE (unqualified_name);
- if (class_type && same_type_p (name_type, class_type))
- {
- if (qualifying_scope
- && CLASSTYPE_USE_TEMPLATE (name_type))
- {
- error ("%Hinvalid use of constructor as a template",
- &declarator_id_start_token->location);
- inform (input_location, "use %<%T::%D%> instead of %<%T::%D%> to "
- "name the constructor in a qualified name",
- class_type,
- DECL_NAME (TYPE_TI_TEMPLATE (class_type)),
- class_type, name_type);
- declarator = cp_error_declarator;
- break;
- }
- else
- unqualified_name = constructor_name (class_type);
- }
- else
- {
- /* We do not attempt to print the declarator
- here because we do not have enough
- information about its original syntactic
- form. */
- cp_parser_error (parser, "invalid declarator");
- declarator = cp_error_declarator;
- break;
- }
- }
+ if (qualifying_scope
+ && CLASS_TYPE_P (qualifying_scope))
+ class_type = qualifying_scope;
+ else
+ class_type = current_class_type;
- if (class_type)
- {
- if (TREE_CODE (unqualified_name) == BIT_NOT_EXPR)
- sfk = sfk_destructor;
- else if (IDENTIFIER_TYPENAME_P (unqualified_name))
- sfk = sfk_conversion;
- else if (/* There's no way to declare a constructor
- for an anonymous type, even if the type
- got a name for linkage purposes. */
- !TYPE_WAS_ANONYMOUS (class_type)
- && constructor_name_p (unqualified_name,
- class_type))
- {
- unqualified_name = constructor_name (class_type);
- sfk = sfk_constructor;
- }
+ if (TREE_CODE (unqualified_name) == TYPE_DECL)
+ {
+ tree name_type = TREE_TYPE (unqualified_name);
+ if (class_type && same_type_p (name_type, class_type))
+ {
+ if (qualifying_scope
+ && CLASSTYPE_USE_TEMPLATE (name_type))
+ {
+ error ("%Hinvalid use of constructor as a template",
+ &declarator_id_start_token->location);
+ inform (input_location, "use %<%T::%D%> instead of %<%T::%D%> to "
+ "name the constructor in a qualified name",
+ class_type,
+ DECL_NAME (TYPE_TI_TEMPLATE (class_type)),
+ class_type, name_type);
+ declarator = cp_error_declarator;
+ break;
+ }
+ else
+ unqualified_name = constructor_name (class_type);
+ }
+ else
+ {
+ /* We do not attempt to print the declarator
+ here because we do not have enough
+ information about its original syntactic
+ form. */
+ cp_parser_error (parser, "invalid declarator");
+ declarator = cp_error_declarator;
+ break;
+ }
+ }
- if (ctor_dtor_or_conv_p && sfk != sfk_none)
- *ctor_dtor_or_conv_p = -1;
- }
- }
- declarator = make_id_declarator (qualifying_scope,
- unqualified_name,
- sfk);
- declarator->id_loc = token->location;
- declarator->parameter_pack_p = pack_expansion_p;
+ if (class_type)
+ {
+ if (TREE_CODE (unqualified_name) == BIT_NOT_EXPR)
+ sfk = sfk_destructor;
+ else if (IDENTIFIER_TYPENAME_P (unqualified_name))
+ sfk = sfk_conversion;
+ else if (/* There's no way to declare a constructor
+ for an anonymous type, even if the type
+ got a name for linkage purposes. */
+ !TYPE_WAS_ANONYMOUS (class_type)
+ && constructor_name_p (unqualified_name,
+ class_type))
+ {
+ unqualified_name = constructor_name (class_type);
+ sfk = sfk_constructor;
+ }
- if (pack_expansion_p)
- maybe_warn_variadic_templates ();
+ if (ctor_dtor_or_conv_p && sfk != sfk_none)
+ *ctor_dtor_or_conv_p = -1;
+ }
+ }
+ declarator = make_id_declarator (qualifying_scope,
+ unqualified_name,
+ sfk);
+ declarator->id_loc = token->location;
+ declarator->parameter_pack_p = pack_expansion_p;
+
+ if (pack_expansion_p)
+ maybe_warn_variadic_templates ();
+ }
handle_declarator:;
scope = get_scope_of_declarator (declarator);
@@ -13804,8 +13874,17 @@ cp_parser_type_id_1 (cp_parser* parser, bool is_template_arg)
if (type_specifier_seq.type
&& type_uses_auto (type_specifier_seq.type))
{
- error ("invalid use of %<auto%>");
- return error_mark_node;
+ /* A type-id with type 'auto' is only ok if the abstract declarator
+ is a function declarator with a late-specified return type. */
+ if (abstract_declarator
+ && abstract_declarator->kind == cdk_function
+ && abstract_declarator->u.function.late_return_type)
+ /* OK */;
+ else
+ {
+ error ("invalid use of %<auto%>");
+ return error_mark_node;
+ }
}
return groktypename (&type_specifier_seq, abstract_declarator,
@@ -14585,10 +14664,17 @@ cp_parser_initializer (cp_parser* parser, bool* is_direct_init,
init = cp_parser_initializer_clause (parser, non_constant_p);
}
else if (token->type == CPP_OPEN_PAREN)
- init = cp_parser_parenthesized_expression_list (parser, false,
- /*cast_p=*/false,
- /*allow_expansion_p=*/true,
- non_constant_p);
+ {
+ VEC(tree,gc) *vec;
+ vec = cp_parser_parenthesized_expression_list (parser, false,
+ /*cast_p=*/false,
+ /*allow_expansion_p=*/true,
+ non_constant_p);
+ if (vec == NULL)
+ return error_mark_node;
+ init = build_tree_list_vec (vec);
+ release_tree_vector (vec);
+ }
else if (token->type == CPP_OPEN_BRACE)
{
maybe_warn_cpp0x ("extended initializer lists");
@@ -15802,7 +15888,8 @@ cp_parser_member_declaration (cp_parser* parser)
know it is an anonymous aggregate. */
fixup_anonymous_aggr (type);
/* And make the corresponding data member. */
- decl = build_decl (FIELD_DECL, NULL_TREE, type);
+ decl = build_decl (decl_spec_token_start->location,
+ FIELD_DECL, NULL_TREE, type);
/* Add it to the class. */
finish_member_declaration (decl);
}
@@ -16850,10 +16937,18 @@ cp_parser_attribute_list (cp_parser* parser)
/* If it's an `(', then parse the attribute arguments. */
if (token->type == CPP_OPEN_PAREN)
{
- arguments = cp_parser_parenthesized_expression_list
- (parser, true, /*cast_p=*/false,
- /*allow_expansion_p=*/false,
- /*non_constant_p=*/NULL);
+ VEC(tree,gc) *vec;
+ vec = cp_parser_parenthesized_expression_list
+ (parser, true, /*cast_p=*/false,
+ /*allow_expansion_p=*/false,
+ /*non_constant_p=*/NULL);
+ if (vec == NULL)
+ arguments = error_mark_node;
+ else
+ {
+ arguments = build_tree_list_vec (vec);
+ release_tree_vector (vec);
+ }
/* Save the arguments away. */
TREE_VALUE (attribute) = arguments;
}
@@ -17981,6 +18076,7 @@ cp_parser_simple_cast_expression (cp_parser *parser)
static tree
cp_parser_functional_cast (cp_parser* parser, tree type)
{
+ VEC(tree,gc) *vec;
tree expression_list;
tree cast;
bool nonconst_p;
@@ -17995,11 +18091,18 @@ cp_parser_functional_cast (cp_parser* parser, tree type)
return finish_compound_literal (type, expression_list);
}
- expression_list
- = cp_parser_parenthesized_expression_list (parser, false,
- /*cast_p=*/true,
- /*allow_expansion_p=*/true,
- /*non_constant_p=*/NULL);
+
+ vec = cp_parser_parenthesized_expression_list (parser, false,
+ /*cast_p=*/true,
+ /*allow_expansion_p=*/true,
+ /*non_constant_p=*/NULL);
+ if (vec == NULL)
+ expression_list = error_mark_node;
+ else
+ {
+ expression_list = build_tree_list_vec (vec);
+ release_tree_vector (vec);
+ }
cast = build_functional_cast (type, expression_list,
tf_warning_or_error);
@@ -18103,7 +18206,8 @@ cp_parser_enclosed_template_argument_list (cp_parser* parser)
tree saved_qualifying_scope;
tree saved_object_scope;
bool saved_greater_than_is_operator_p;
- bool saved_skip_evaluation;
+ int saved_unevaluated_operand;
+ int saved_inhibit_evaluation_warnings;
/* [temp.names]
@@ -18120,8 +18224,10 @@ cp_parser_enclosed_template_argument_list (cp_parser* parser)
saved_object_scope = parser->object_scope;
/* We need to evaluate the template arguments, even though this
template-id may be nested within a "sizeof". */
- saved_skip_evaluation = skip_evaluation;
- skip_evaluation = false;
+ saved_unevaluated_operand = cp_unevaluated_operand;
+ cp_unevaluated_operand = 0;
+ saved_inhibit_evaluation_warnings = c_inhibit_evaluation_warnings;
+ c_inhibit_evaluation_warnings = 0;
/* Parse the template-argument-list itself. */
if (cp_lexer_next_token_is (parser->lexer, CPP_GREATER)
|| cp_lexer_next_token_is (parser->lexer, CPP_RSHIFT))
@@ -18188,7 +18294,8 @@ cp_parser_enclosed_template_argument_list (cp_parser* parser)
parser->scope = saved_scope;
parser->qualifying_scope = saved_qualifying_scope;
parser->object_scope = saved_object_scope;
- skip_evaluation = saved_skip_evaluation;
+ cp_unevaluated_operand = saved_unevaluated_operand;
+ c_inhibit_evaluation_warnings = saved_inhibit_evaluation_warnings;
return arguments;
}
@@ -18422,7 +18529,8 @@ cp_parser_sizeof_operand (cp_parser* parser, enum rid keyword)
}
/* Do not actually evaluate the expression. */
- ++skip_evaluation;
+ ++cp_unevaluated_operand;
+ ++c_inhibit_evaluation_warnings;
/* If it's a `(', then we might be looking at the type-id
construction. */
if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
@@ -18471,7 +18579,8 @@ cp_parser_sizeof_operand (cp_parser* parser, enum rid keyword)
expr = make_pack_expansion (expr);
/* Go back to evaluating expressions. */
- --skip_evaluation;
+ --cp_unevaluated_operand;
+ --c_inhibit_evaluation_warnings;
/* Free the message we created. */
free (tmp);
@@ -19356,6 +19465,7 @@ cp_parser_objc_selector_expression (cp_parser* parser)
tree sel_seq = NULL_TREE;
bool maybe_unary_selector_p = true;
cp_token *token;
+ location_t loc = cp_lexer_peek_token (parser->lexer)->location;
cp_lexer_consume_token (parser->lexer); /* Eat '@selector'. */
cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>");
@@ -19407,7 +19517,7 @@ cp_parser_objc_selector_expression (cp_parser* parser)
finish_selector:
cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>");
- return objc_build_selector_expr (sel_seq);
+ return objc_build_selector_expr (loc, sel_seq);
}
/* Parse a list of identifiers.
@@ -20180,6 +20290,7 @@ cp_parser_objc_synchronized_statement (cp_parser *parser) {
static tree
cp_parser_objc_throw_statement (cp_parser *parser) {
tree expr = NULL_TREE;
+ location_t loc = cp_lexer_peek_token (parser->lexer)->location;
cp_parser_require_keyword (parser, RID_AT_THROW, "%<@throw%>");
@@ -20188,7 +20299,7 @@ cp_parser_objc_throw_statement (cp_parser *parser) {
cp_parser_consume_semicolon_at_end_of_statement (parser);
- return objc_build_throw_stmt (expr);
+ return objc_build_throw_stmt (loc, expr);
}
/* Parse an Objective-C statement. */
@@ -20342,7 +20453,7 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind,
cp_parser_name_lookup_error (parser, name, decl, NULL, token->location);
else if (kind != 0)
{
- tree u = build_omp_clause (kind);
+ tree u = build_omp_clause (token->location, kind);
OMP_CLAUSE_DECL (u) = decl;
OMP_CLAUSE_CHAIN (u) = list;
list = u;
@@ -20420,7 +20531,7 @@ cp_parser_omp_clause_collapse (cp_parser *parser, tree list, location_t location
}
check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse", location);
- c = build_omp_clause (OMP_CLAUSE_COLLAPSE);
+ c = build_omp_clause (loc, OMP_CLAUSE_COLLAPSE);
OMP_CLAUSE_CHAIN (c) = list;
OMP_CLAUSE_COLLAPSE_EXPR (c) = num;
@@ -20478,7 +20589,7 @@ cp_parser_omp_clause_default (cp_parser *parser, tree list, location_t location)
return list;
check_no_duplicate_clause (list, OMP_CLAUSE_DEFAULT, "default", location);
- c = build_omp_clause (OMP_CLAUSE_DEFAULT);
+ c = build_omp_clause (location, OMP_CLAUSE_DEFAULT);
OMP_CLAUSE_CHAIN (c) = list;
OMP_CLAUSE_DEFAULT_KIND (c) = kind;
@@ -20506,7 +20617,7 @@ cp_parser_omp_clause_if (cp_parser *parser, tree list, location_t location)
check_no_duplicate_clause (list, OMP_CLAUSE_IF, "if", location);
- c = build_omp_clause (OMP_CLAUSE_IF);
+ c = build_omp_clause (location, OMP_CLAUSE_IF);
OMP_CLAUSE_IF_EXPR (c) = t;
OMP_CLAUSE_CHAIN (c) = list;
@@ -20524,7 +20635,7 @@ cp_parser_omp_clause_nowait (cp_parser *parser ATTRIBUTE_UNUSED,
check_no_duplicate_clause (list, OMP_CLAUSE_NOWAIT, "nowait", location);
- c = build_omp_clause (OMP_CLAUSE_NOWAIT);
+ c = build_omp_clause (location, OMP_CLAUSE_NOWAIT);
OMP_CLAUSE_CHAIN (c) = list;
return c;
}
@@ -20552,7 +20663,7 @@ cp_parser_omp_clause_num_threads (cp_parser *parser, tree list,
check_no_duplicate_clause (list, OMP_CLAUSE_NUM_THREADS,
"num_threads", location);
- c = build_omp_clause (OMP_CLAUSE_NUM_THREADS);
+ c = build_omp_clause (location, OMP_CLAUSE_NUM_THREADS);
OMP_CLAUSE_NUM_THREADS_EXPR (c) = t;
OMP_CLAUSE_CHAIN (c) = list;
@@ -20571,7 +20682,7 @@ cp_parser_omp_clause_ordered (cp_parser *parser ATTRIBUTE_UNUSED,
check_no_duplicate_clause (list, OMP_CLAUSE_ORDERED,
"ordered", location);
- c = build_omp_clause (OMP_CLAUSE_ORDERED);
+ c = build_omp_clause (location, OMP_CLAUSE_ORDERED);
OMP_CLAUSE_CHAIN (c) = list;
return c;
}
@@ -20653,7 +20764,7 @@ cp_parser_omp_clause_schedule (cp_parser *parser, tree list, location_t location
if (!cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"))
return list;
- c = build_omp_clause (OMP_CLAUSE_SCHEDULE);
+ c = build_omp_clause (location, OMP_CLAUSE_SCHEDULE);
if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
{
@@ -20741,7 +20852,7 @@ cp_parser_omp_clause_untied (cp_parser *parser ATTRIBUTE_UNUSED,
check_no_duplicate_clause (list, OMP_CLAUSE_UNTIED, "untied", location);
- c = build_omp_clause (OMP_CLAUSE_UNTIED);
+ c = build_omp_clause (location, OMP_CLAUSE_UNTIED);
OMP_CLAUSE_CHAIN (c) = list;
return c;
}
@@ -21034,7 +21145,7 @@ cp_parser_omp_critical (cp_parser *parser, cp_token *pragma_tok)
cp_parser_require_pragma_eol (parser, pragma_tok);
stmt = cp_parser_omp_structured_block (parser);
- return c_finish_omp_critical (stmt, name);
+ return c_finish_omp_critical (input_location, stmt, name);
}
/* OpenMP 2.5:
@@ -21411,7 +21522,7 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses)
{
/* Add lastprivate (decl) clause to OMP_FOR_CLAUSES,
change it to shared (decl) in OMP_PARALLEL_CLAUSES. */
- tree l = build_omp_clause (OMP_CLAUSE_LASTPRIVATE);
+ tree l = build_omp_clause (loc, OMP_CLAUSE_LASTPRIVATE);
OMP_CLAUSE_DECL (l) = real_decl;
OMP_CLAUSE_CHAIN (l) = clauses;
CP_OMP_CLAUSE_INFO (l) = CP_OMP_CLAUSE_INFO (*c);
@@ -21449,7 +21560,7 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses)
}
if (c == NULL)
{
- c = build_omp_clause (OMP_CLAUSE_PRIVATE);
+ c = build_omp_clause (loc, OMP_CLAUSE_PRIVATE);
OMP_CLAUSE_DECL (c) = decl;
c = finish_omp_clauses (c);
if (c)
@@ -21616,7 +21727,8 @@ static tree
cp_parser_omp_master (cp_parser *parser, cp_token *pragma_tok)
{
cp_parser_require_pragma_eol (parser, pragma_tok);
- return c_finish_omp_master (cp_parser_omp_structured_block (parser));
+ return c_finish_omp_master (input_location,
+ cp_parser_omp_structured_block (parser));
}
/* OpenMP 2.5:
@@ -21626,8 +21738,9 @@ cp_parser_omp_master (cp_parser *parser, cp_token *pragma_tok)
static tree
cp_parser_omp_ordered (cp_parser *parser, cp_token *pragma_tok)
{
+ location_t loc = cp_lexer_peek_token (parser->lexer)->location;
cp_parser_require_pragma_eol (parser, pragma_tok);
- return c_finish_omp_ordered (cp_parser_omp_structured_block (parser));
+ return c_finish_omp_ordered (loc, cp_parser_omp_structured_block (parser));
}
/* OpenMP 2.5:
@@ -21762,6 +21875,7 @@ cp_parser_omp_parallel (cp_parser *parser, cp_token *pragma_tok)
tree stmt, clauses, par_clause, ws_clause, block;
unsigned int mask = OMP_PARALLEL_CLAUSE_MASK;
unsigned int save;
+ location_t loc = cp_lexer_peek_token (parser->lexer)->location;
if (cp_lexer_next_token_is_keyword (parser->lexer, RID_FOR))
{
@@ -21797,12 +21911,12 @@ cp_parser_omp_parallel (cp_parser *parser, cp_token *pragma_tok)
break;
case PRAGMA_OMP_PARALLEL_FOR:
- c_split_parallel_clauses (clauses, &par_clause, &ws_clause);
+ c_split_parallel_clauses (loc, clauses, &par_clause, &ws_clause);
cp_parser_omp_for_loop (parser, ws_clause, &par_clause);
break;
case PRAGMA_OMP_PARALLEL_SECTIONS:
- c_split_parallel_clauses (clauses, &par_clause, &ws_clause);
+ c_split_parallel_clauses (loc, clauses, &par_clause, &ws_clause);
stmt = cp_parser_omp_sections_scope (parser);
if (stmt)
OMP_SECTIONS_CLAUSES (stmt) = ws_clause;
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index e100d6b116c..5645b23e27f 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -118,8 +118,8 @@ static tree add_outermost_template_args (tree, tree);
static bool check_instantiated_args (tree, tree, tsubst_flags_t);
static int maybe_adjust_types_for_deduction (unification_kind_t, tree*, tree*,
tree);
-static int type_unification_real (tree, tree, tree, tree,
- int, unification_kind_t, int);
+static int type_unification_real (tree, tree, tree, const tree *,
+ unsigned int, int, unification_kind_t, int);
static void note_template_header (int);
static tree convert_nontype_argument_function (tree, tree);
static tree convert_nontype_argument (tree, tree);
@@ -175,6 +175,7 @@ static tree tsubst_copy (tree, tree, tsubst_flags_t, tree);
static tree tsubst_pack_expansion (tree, tree, tsubst_flags_t, tree);
static tree tsubst_decl (tree, tree, tsubst_flags_t);
static void perform_typedefs_access_check (tree tmpl, tree targs);
+static void append_type_to_template_for_access_check_1 (tree, tree, tree);
/* Make the current scope suitable for access checking when we are
processing T. T can be FUNCTION_DECL for instantiated function
@@ -382,7 +383,8 @@ push_inline_template_parms_recursive (tree parmlist, int levels)
It is ugly that we recreate this here; the original
version built in process_template_parm is no longer
available. */
- tree decl = build_decl (CONST_DECL, DECL_NAME (parm),
+ tree decl = build_decl (DECL_SOURCE_LOCATION (parm),
+ CONST_DECL, DECL_NAME (parm),
TREE_TYPE (parm));
DECL_ARTIFICIAL (decl) = 1;
TREE_CONSTANT (decl) = 1;
@@ -1315,7 +1317,7 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend)
template it is specializing. */
if (DECL_TEMPLATE_SPECIALIZATION (spec)
&& !check_specialization_namespace (tmpl))
- DECL_CONTEXT (spec) = FROB_CONTEXT (decl_namespace_context (tmpl));
+ DECL_CONTEXT (spec) = DECL_CONTEXT (tmpl);
if (!optimize_specialization_lookup_p (tmpl))
DECL_TEMPLATE_SPECIALIZATIONS (tmpl)
@@ -2930,7 +2932,8 @@ reduce_template_parm_level (tree index, tree type, int levels, tree args,
tree orig_decl = TEMPLATE_PARM_DECL (index);
tree decl, t;
- decl = build_decl (TREE_CODE (orig_decl), DECL_NAME (orig_decl), type);
+ decl = build_decl (DECL_SOURCE_LOCATION (orig_decl),
+ TREE_CODE (orig_decl), DECL_NAME (orig_decl), type);
TREE_CONSTANT (decl) = TREE_CONSTANT (orig_decl);
TREE_READONLY (decl) = TREE_READONLY (orig_decl);
DECL_ARTIFICIAL (decl) = 1;
@@ -2957,10 +2960,11 @@ reduce_template_parm_level (tree index, tree type, int levels, tree args,
/* Process information from new template parameter PARM and append it to the
LIST being built. This new parameter is a non-type parameter iff
IS_NON_TYPE is true. This new parameter is a parameter
- pack iff IS_PARAMETER_PACK is true. */
+ pack iff IS_PARAMETER_PACK is true. The location of PARM is in
+ PARM_LOC. */
tree
-process_template_parm (tree list, tree parm, bool is_non_type,
+process_template_parm (tree list, location_t parm_loc, tree parm, bool is_non_type,
bool is_parameter_pack)
{
tree decl = 0;
@@ -3029,7 +3033,8 @@ process_template_parm (tree list, tree parm, bool is_non_type,
/* A template parameter is not modifiable. */
TREE_CONSTANT (parm) = 1;
TREE_READONLY (parm) = 1;
- decl = build_decl (CONST_DECL, DECL_NAME (parm), TREE_TYPE (parm));
+ decl = build_decl (parm_loc,
+ CONST_DECL, DECL_NAME (parm), TREE_TYPE (parm));
TREE_CONSTANT (decl) = 1;
TREE_READONLY (decl) = 1;
DECL_INITIAL (parm) = DECL_INITIAL (decl)
@@ -3058,7 +3063,8 @@ process_template_parm (tree list, tree parm, bool is_non_type,
{
t = cxx_make_type (TEMPLATE_TYPE_PARM);
/* parm is either IDENTIFIER_NODE or NULL_TREE. */
- decl = build_decl (TYPE_DECL, parm, t);
+ decl = build_decl (parm_loc,
+ TYPE_DECL, parm, t);
}
TYPE_NAME (t) = decl;
@@ -4415,9 +4421,9 @@ convert_nontype_argument (tree type, tree expr)
For a non-type template-parameter of integral or enumeration type,
integral promotions (_conv.prom_) and integral conversions
(_conv.integral_) are applied. */
- if (INTEGRAL_TYPE_P (type))
+ if (INTEGRAL_OR_ENUMERATION_TYPE_P (type))
{
- if (!INTEGRAL_TYPE_P (expr_type))
+ if (!INTEGRAL_OR_ENUMERATION_TYPE_P (expr_type))
return error_mark_node;
expr = fold_decl_constant_value (expr);
@@ -5072,7 +5078,7 @@ convert_template_argument (tree parm,
the typedef, which is confusing if those future uses do not
themselves also use the typedef. */
if (TYPE_P (val))
- val = canonical_type_variant (val);
+ val = strip_typedefs (val);
}
else
{
@@ -5258,7 +5264,8 @@ coerce_template_parms (tree parms,
tree inner_args;
tree new_args;
tree new_inner_args;
- bool saved_skip_evaluation;
+ int saved_unevaluated_operand;
+ int saved_inhibit_evaluation_warnings;
/* When used as a boolean value, indicates whether this is a
variadic template parameter list. Since it's an int, we can also
@@ -5316,8 +5323,10 @@ coerce_template_parms (tree parms,
/* We need to evaluate the template arguments, even though this
template-id may be nested within a "sizeof". */
- saved_skip_evaluation = skip_evaluation;
- skip_evaluation = false;
+ saved_unevaluated_operand = cp_unevaluated_operand;
+ cp_unevaluated_operand = 0;
+ saved_inhibit_evaluation_warnings = c_inhibit_evaluation_warnings;
+ c_inhibit_evaluation_warnings = 0;
new_inner_args = make_tree_vec (nparms);
new_args = add_outermost_template_args (args, new_inner_args);
for (parm_idx = 0, arg_idx = 0; parm_idx < nparms; parm_idx++, arg_idx++)
@@ -5410,7 +5419,8 @@ coerce_template_parms (tree parms,
lost++;
TREE_VEC_ELT (new_inner_args, arg_idx) = arg;
}
- skip_evaluation = saved_skip_evaluation;
+ cp_unevaluated_operand = saved_unevaluated_operand;
+ c_inhibit_evaluation_warnings = saved_inhibit_evaluation_warnings;
if (lost)
return error_mark_node;
@@ -6941,10 +6951,12 @@ perform_typedefs_access_check (tree tmpl, tree targs)
{
tree t;
- if (!tmpl || TREE_CODE (tmpl) != TEMPLATE_DECL)
+ if (!tmpl
+ || (TREE_CODE (tmpl) != RECORD_TYPE
+ && TREE_CODE (tmpl) != FUNCTION_DECL))
return;
- for (t = MEMBER_TYPES_NEEDING_ACCESS_CHECK (tmpl); t; t = TREE_CHAIN (t))
+ for (t = get_types_needing_access_check (tmpl); t; t = TREE_CHAIN (t))
{
tree type_decl = TREE_PURPOSE (t);
tree type_scope = TREE_VALUE (t);
@@ -6957,7 +6969,8 @@ perform_typedefs_access_check (tree tmpl, tree targs)
if (uses_template_parms (type_scope))
type_scope = tsubst (type_scope, targs, tf_error, NULL_TREE);
- perform_or_defer_access_check (TYPE_BINFO (type_scope), type_decl, type_decl);
+ perform_or_defer_access_check (TYPE_BINFO (type_scope),
+ type_decl, type_decl);
}
}
@@ -7031,9 +7044,9 @@ instantiate_class_template (tree type)
SET_CLASSTYPE_INTERFACE_UNKNOWN (type);
- /* Set the input location to the template definition. This is needed
- if tsubsting causes an error. */
- typedecl = TYPE_MAIN_DECL (type);
+ /* Set the input location to the most specialized template definition.
+ This is needed if tsubsting causes an error. */
+ typedecl = TYPE_MAIN_DECL (pattern);
input_location = DECL_SOURCE_LOCATION (typedecl);
TYPE_HAS_USER_CONSTRUCTOR (type) = TYPE_HAS_USER_CONSTRUCTOR (pattern);
@@ -7439,8 +7452,8 @@ instantiate_class_template (tree type)
/* Some typedefs referenced from within the template code need to be access
checked at template instantiation time, i.e now. These types were
added to the template at parsing time. Let's get those and perform
- the acces checks then. */
- perform_typedefs_access_check (templ, args);
+ the access checks then. */
+ perform_typedefs_access_check (pattern, args);
perform_deferred_access_checks ();
pop_nested_class ();
pop_from_top_level ();
@@ -7544,7 +7557,7 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain,
/* This can happen for a parameter name used later in a function
declaration (such as in a late-specified return type). Just
make a dummy decl, since it's only used for its type. */
- gcc_assert (skip_evaluation);
+ gcc_assert (cp_unevaluated_operand != 0);
arg_pack = tsubst_decl (parm_pack, args, complain);
arg_pack = make_fnparm_pack (arg_pack);
}
@@ -7935,11 +7948,14 @@ tsubst_aggr_type (tree t,
tree argvec;
tree context;
tree r;
- bool saved_skip_evaluation;
+ int saved_unevaluated_operand;
+ int saved_inhibit_evaluation_warnings;
/* In "sizeof(X<I>)" we need to evaluate "I". */
- saved_skip_evaluation = skip_evaluation;
- skip_evaluation = false;
+ saved_unevaluated_operand = cp_unevaluated_operand;
+ cp_unevaluated_operand = 0;
+ saved_inhibit_evaluation_warnings = c_inhibit_evaluation_warnings;
+ c_inhibit_evaluation_warnings = 0;
/* First, determine the context for the type we are looking
up. */
@@ -7974,7 +7990,8 @@ tsubst_aggr_type (tree t,
r = cp_build_qualified_type_real (r, TYPE_QUALS (t), complain);
}
- skip_evaluation = saved_skip_evaluation;
+ cp_unevaluated_operand = saved_unevaluated_operand;
+ c_inhibit_evaluation_warnings = saved_inhibit_evaluation_warnings;
return r;
}
@@ -8108,7 +8125,8 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
TREE_CHAIN (r) = NULL_TREE;
TREE_TYPE (r) = new_type;
DECL_TEMPLATE_RESULT (r)
- = build_decl (TYPE_DECL, DECL_NAME (decl), new_type);
+ = build_decl (DECL_SOURCE_LOCATION (decl),
+ TYPE_DECL, DECL_NAME (decl), new_type);
DECL_TEMPLATE_PARMS (r)
= tsubst_template_parms (DECL_TEMPLATE_PARMS (t), args,
complain);
@@ -9772,13 +9790,15 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
{
tree type;
- ++skip_evaluation;
+ ++cp_unevaluated_operand;
+ ++c_inhibit_evaluation_warnings;
type = tsubst_expr (DECLTYPE_TYPE_EXPR (t), args,
complain, in_decl,
/*integral_constant_expression_p=*/false);
- --skip_evaluation;
+ --cp_unevaluated_operand;
+ --c_inhibit_evaluation_warnings;
type =
finish_decltype_type (type,
@@ -9930,16 +9950,29 @@ tsubst_qualified_id (tree qualified_id, tree args,
expr = name;
if (dependent_type_p (scope))
- return build_qualified_name (/*type=*/NULL_TREE,
- scope, expr,
- QUALIFIED_NAME_IS_TEMPLATE (qualified_id));
+ {
+ tree type = NULL_TREE;
+ if (DECL_P (expr) && !dependent_scope_p (scope))
+ type = TREE_TYPE (expr);
+ return build_qualified_name (type, scope, expr,
+ QUALIFIED_NAME_IS_TEMPLATE (qualified_id));
+ }
if (!BASELINK_P (name) && !DECL_P (expr))
{
if (TREE_CODE (expr) == BIT_NOT_EXPR)
- /* If this were actually a destructor call, it would have been
- parsed as such by the parser. */
- expr = error_mark_node;
+ {
+ /* A BIT_NOT_EXPR is used to represent a destructor. */
+ if (!check_dtor_name (scope, TREE_OPERAND (expr, 0)))
+ {
+ error ("qualifying type %qT does not match destructor name ~%qT",
+ scope, TREE_OPERAND (expr, 0));
+ expr = error_mark_node;
+ }
+ else
+ expr = lookup_qualified_name (scope, complete_dtor_identifier,
+ /*is_type_p=*/0, false);
+ }
else
expr = lookup_qualified_name (scope, expr, /*is_type_p=*/0, false);
if (TREE_CODE (TREE_CODE (expr) == TEMPLATE_DECL
@@ -10024,7 +10057,7 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
/* This can happen for a parameter name used later in a function
declaration (such as in a late-specified return type). Just
make a dummy decl, since it's only used for its type. */
- gcc_assert (skip_evaluation);
+ gcc_assert (cp_unevaluated_operand != 0);
/* We copy T because want to tsubst the PARM_DECL only,
not the following PARM_DECLs that are chained to T. */
c = copy_node (t);
@@ -10588,7 +10621,7 @@ tsubst_omp_for_iterator (tree t, int i, tree declv, tree initv,
}
if (c == NULL)
{
- c = build_omp_clause (OMP_CLAUSE_PRIVATE);
+ c = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
OMP_CLAUSE_DECL (c) = decl;
c = finish_omp_clauses (c);
if (c)
@@ -10873,12 +10906,20 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
break;
case CASE_LABEL_EXPR:
- finish_case_label (RECUR (CASE_LOW (t)),
+ finish_case_label (EXPR_LOCATION (t),
+ RECUR (CASE_LOW (t)),
RECUR (CASE_HIGH (t)));
break;
case LABEL_EXPR:
- finish_label_stmt (DECL_NAME (LABEL_EXPR_LABEL (t)));
+ {
+ tree decl = LABEL_EXPR_LABEL (t);
+ tree label;
+
+ label = finish_label_stmt (DECL_NAME (decl));
+ if (DECL_ATTRIBUTES (decl) != NULL_TREE)
+ cplus_decl_attributes (&label, DECL_ATTRIBUTES (decl), 0);
+ }
break;
case GOTO_EXPR:
@@ -11376,11 +11417,13 @@ tsubst_copy_and_build (tree t,
}
else
{
- ++skip_evaluation;
+ ++cp_unevaluated_operand;
+ ++c_inhibit_evaluation_warnings;
op1 = tsubst_copy_and_build (op1, args, complain, in_decl,
/*function_p=*/false,
/*integral_constant_expression_p=*/false);
- --skip_evaluation;
+ --cp_unevaluated_operand;
+ --c_inhibit_evaluation_warnings;
}
if (TYPE_P (op1))
return cxx_sizeof_or_alignof_type (op1, TREE_CODE (t),
@@ -11417,24 +11460,54 @@ tsubst_copy_and_build (tree t,
case NEW_EXPR:
{
+ tree placement = RECUR (TREE_OPERAND (t, 0));
tree init = RECUR (TREE_OPERAND (t, 3));
+ VEC(tree,gc) *placement_vec;
+ VEC(tree,gc) *init_vec;
+ tree ret;
+
+ if (placement == NULL_TREE)
+ placement_vec = NULL;
+ else
+ {
+ placement_vec = make_tree_vector ();
+ for (; placement != NULL_TREE; placement = TREE_CHAIN (placement))
+ VEC_safe_push (tree, gc, placement_vec, TREE_VALUE (placement));
+ }
+
+ /* If there was an initializer in the original tree, but it
+ instantiated to an empty list, then we should pass a
+ non-NULL empty vector to tell build_new that it was an
+ empty initializer() rather than no initializer. This can
+ only happen when the initializer is a pack expansion whose
+ parameter packs are of length zero. */
+ if (init == NULL_TREE && TREE_OPERAND (t, 3) == NULL_TREE)
+ init_vec = NULL;
+ else
+ {
+ init_vec = make_tree_vector ();
+ if (init == void_zero_node)
+ gcc_assert (init_vec != NULL);
+ else
+ {
+ for (; init != NULL_TREE; init = TREE_CHAIN (init))
+ VEC_safe_push (tree, gc, init_vec, TREE_VALUE (init));
+ }
+ }
- if (TREE_OPERAND (t, 3) && !init)
- /* If there was an initializer in the original tree, but
- it instantiated to an empty list, then we should pass on
- VOID_ZERO_NODE to tell build_new that it was an empty
- initializer () rather than no initializer. This can only
- happen when the initializer is a pack expansion whose
- parameter packs are of length zero. */
- init = void_zero_node;
+ ret = build_new (&placement_vec,
+ RECUR (TREE_OPERAND (t, 1)),
+ RECUR (TREE_OPERAND (t, 2)),
+ &init_vec,
+ NEW_EXPR_USE_GLOBAL (t),
+ complain);
- return build_new
- (RECUR (TREE_OPERAND (t, 0)),
- RECUR (TREE_OPERAND (t, 1)),
- RECUR (TREE_OPERAND (t, 2)),
- init,
- NEW_EXPR_USE_GLOBAL (t),
- complain);
+ if (placement_vec != NULL)
+ release_tree_vector (placement_vec);
+ if (init_vec != NULL)
+ release_tree_vector (init_vec);
+
+ return ret;
}
case DELETE_EXPR:
@@ -11452,9 +11525,11 @@ tsubst_copy_and_build (tree t,
case CALL_EXPR:
{
tree function;
- tree call_args;
+ VEC(tree,gc) *call_args;
+ unsigned int nargs, i;
bool qualified_p;
bool koenig_p;
+ tree ret;
function = CALL_EXPR_FN (t);
/* When we parsed the expression, we determined whether or
@@ -11489,8 +11564,40 @@ tsubst_copy_and_build (tree t,
qualified_p = true;
}
- /* FIXME: Rewrite this so as not to construct an arglist. */
- call_args = RECUR (CALL_EXPR_ARGS (t));
+ nargs = call_expr_nargs (t);
+ call_args = make_tree_vector ();
+ for (i = 0; i < nargs; ++i)
+ {
+ tree arg = CALL_EXPR_ARG (t, i);
+
+ if (!PACK_EXPANSION_P (arg))
+ VEC_safe_push (tree, gc, call_args,
+ RECUR (CALL_EXPR_ARG (t, i)));
+ else
+ {
+ /* Expand the pack expansion and push each entry onto
+ CALL_ARGS. */
+ arg = tsubst_pack_expansion (arg, args, complain, in_decl);
+ if (TREE_CODE (arg) == TREE_VEC)
+ {
+ unsigned int len, j;
+
+ len = TREE_VEC_LENGTH (arg);
+ for (j = 0; j < len; ++j)
+ {
+ tree value = TREE_VEC_ELT (arg, j);
+ if (value != NULL_TREE)
+ value = convert_from_reference (value);
+ VEC_safe_push (tree, gc, call_args, value);
+ }
+ }
+ else
+ {
+ /* A partial substitution. Add one entry. */
+ VEC_safe_push (tree, gc, call_args, arg);
+ }
+ }
+ }
/* We do not perform argument-dependent lookup if normal
lookup finds a non-function, in accordance with the
@@ -11511,6 +11618,7 @@ tsubst_copy_and_build (tree t,
if (TREE_CODE (function) == IDENTIFIER_NODE)
{
unqualified_name_lookup_error (function);
+ release_tree_vector (call_args);
return error_mark_node;
}
@@ -11519,27 +11627,32 @@ tsubst_copy_and_build (tree t,
mark_used (function);
if (TREE_CODE (function) == OFFSET_REF)
- return build_offset_ref_call_from_tree (function, call_args);
- if (TREE_CODE (function) == COMPONENT_REF)
+ ret = build_offset_ref_call_from_tree (function, &call_args);
+ else if (TREE_CODE (function) == COMPONENT_REF)
{
if (!BASELINK_P (TREE_OPERAND (function, 1)))
- return finish_call_expr (function, call_args,
+ ret = finish_call_expr (function, &call_args,
/*disallow_virtual=*/false,
/*koenig_p=*/false,
complain);
else
- return (build_new_method_call
+ ret = (build_new_method_call
(TREE_OPERAND (function, 0),
TREE_OPERAND (function, 1),
- call_args, NULL_TREE,
+ &call_args, NULL_TREE,
qualified_p ? LOOKUP_NONVIRTUAL : LOOKUP_NORMAL,
/*fn_p=*/NULL,
complain));
}
- return finish_call_expr (function, call_args,
- /*disallow_virtual=*/qualified_p,
- koenig_p,
- complain);
+ else
+ ret = finish_call_expr (function, &call_args,
+ /*disallow_virtual=*/qualified_p,
+ koenig_p,
+ complain);
+
+ release_tree_vector (call_args);
+
+ return ret;
}
case COND_EXPR:
@@ -12080,7 +12193,7 @@ instantiate_template (tree tmpl, tree targ_ptr, tsubst_flags_t complain)
checked at template instantiation time, i.e now. These types were
added to the template at parsing time. Let's get those and perfom
the acces checks then. */
- perform_typedefs_access_check (tmpl, targ_ptr);
+ perform_typedefs_access_check (DECL_TEMPLATE_RESULT (tmpl), targ_ptr);
perform_deferred_access_checks ();
pop_access_scope (fndecl);
pop_deferring_access_checks ();
@@ -12099,9 +12212,10 @@ instantiate_template (tree tmpl, tree targ_ptr, tsubst_flags_t complain)
return fndecl;
}
-/* The FN is a TEMPLATE_DECL for a function. The ARGS are the
- arguments that are being used when calling it. TARGS is a vector
- into which the deduced template arguments are placed.
+/* The FN is a TEMPLATE_DECL for a function. ARGS is an array with
+ NARGS elements of the arguments that are being used when calling
+ it. TARGS is a vector into which the deduced template arguments
+ are placed.
Return zero for success, 2 for an incomplete match that doesn't resolve
all the types, and 1 for complete failure. An error message will be
@@ -12133,7 +12247,8 @@ int
fn_type_unification (tree fn,
tree explicit_targs,
tree targs,
- tree args,
+ const tree *args,
+ unsigned int nargs,
tree return_type,
unification_kind_t strict,
int flags)
@@ -12250,8 +12365,14 @@ fn_type_unification (tree fn,
if (return_type)
{
+ tree *new_args;
+
parms = tree_cons (NULL_TREE, TREE_TYPE (fntype), parms);
- args = tree_cons (NULL_TREE, return_type, args);
+ new_args = XALLOCAVEC (tree, nargs + 1);
+ new_args[0] = return_type;
+ memcpy (new_args + 1, args, nargs * sizeof (tree));
+ args = new_args;
+ ++nargs;
}
/* We allow incomplete unification without an error message here
@@ -12259,7 +12380,7 @@ fn_type_unification (tree fn,
callers must be ready to deal with unification failures in any
event. */
result = type_unification_real (DECL_INNERMOST_TEMPLATE_PARMS (fn),
- targs, parms, args, /*subr=*/0,
+ targs, parms, args, nargs, /*subr=*/0,
strict, flags);
if (result == 0 && incomplete_argument_packs_p)
@@ -12324,14 +12445,14 @@ fn_type_unification (tree fn,
parameters are used in non-deduced contexts. */
if (strict == DEDUCE_EXACT)
{
+ unsigned int i;
+
tree sarg
= skip_artificial_parms_for (fn, TYPE_ARG_TYPES (substed));
- tree arg = args;
if (return_type)
sarg = tree_cons (NULL_TREE, TREE_TYPE (substed), sarg);
- for (; arg && sarg;
- arg = TREE_CHAIN (arg), sarg = TREE_CHAIN (sarg))
- if (!same_type_p (TREE_VALUE (arg), TREE_VALUE (sarg)))
+ for (i = 0; i < nargs && sarg; ++i, sarg = TREE_CHAIN (sarg))
+ if (!same_type_p (args[i], TREE_VALUE (sarg)))
return 1;
}
}
@@ -12446,7 +12567,8 @@ static int
type_unification_real (tree tparms,
tree targs,
tree xparms,
- tree xargs,
+ const tree *xargs,
+ unsigned int xnargs,
int subr,
unification_kind_t strict,
int flags)
@@ -12456,11 +12578,13 @@ type_unification_real (tree tparms,
int ntparms = TREE_VEC_LENGTH (tparms);
int sub_strict;
int saw_undeduced = 0;
- tree parms, args;
+ tree parms;
+ const tree *args;
+ unsigned int nargs;
+ unsigned int ia;
gcc_assert (TREE_CODE (tparms) == TREE_VEC);
gcc_assert (xparms == NULL_TREE || TREE_CODE (xparms) == TREE_LIST);
- gcc_assert (!xargs || TREE_CODE (xargs) == TREE_LIST);
gcc_assert (ntparms > 0);
switch (strict)
@@ -12485,17 +12609,19 @@ type_unification_real (tree tparms,
again:
parms = xparms;
args = xargs;
+ nargs = xnargs;
+ ia = 0;
while (parms && parms != void_list_node
- && args && args != void_list_node)
+ && ia < nargs)
{
if (TREE_CODE (TREE_VALUE (parms)) == TYPE_PACK_EXPANSION)
break;
parm = TREE_VALUE (parms);
parms = TREE_CHAIN (parms);
- arg = TREE_VALUE (args);
- args = TREE_CHAIN (args);
+ arg = args[ia];
+ ++ia;
arg_expr = NULL;
if (arg == error_mark_node)
@@ -12574,20 +12700,11 @@ type_unification_real (tree tparms,
/* Unify the remaining arguments with the pack expansion type. */
tree argvec;
tree parmvec = make_tree_vec (1);
- int len = 0;
- tree t;
- /* Count the number of arguments that remain. */
- for (t = args; t && t != void_list_node; t = TREE_CHAIN (t))
- len++;
-
/* Allocate a TREE_VEC and copy in all of the arguments */
- argvec = make_tree_vec (len);
- for (i = 0; args && args != void_list_node; args = TREE_CHAIN (args))
- {
- TREE_VEC_ELT (argvec, i) = TREE_VALUE (args);
- ++i;
- }
+ argvec = make_tree_vec (nargs - ia);
+ for (i = 0; ia < nargs; ++ia, ++i)
+ TREE_VEC_ELT (argvec, i) = args[ia];
/* Copy the parameter into parmvec. */
TREE_VEC_ELT (parmvec, 0) = TREE_VALUE (parms);
@@ -12601,7 +12718,7 @@ type_unification_real (tree tparms,
/* Fail if we've reached the end of the parm list, and more args
are present, and the parm list isn't variadic. */
- if (args && args != void_list_node && parms == void_list_node)
+ if (ia < nargs && parms == void_list_node)
return 1;
/* Fail if parms are left and they don't have default values. */
if (parms && parms != void_list_node
@@ -13584,7 +13701,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
return 1;
/* Strip typedefs as in convert_template_argument. */
- arg = canonical_type_variant (arg);
+ arg = strip_typedefs (arg);
}
/* If ARG is a parameter pack or an expansion, we cannot unify
@@ -13883,26 +14000,42 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
case METHOD_TYPE:
case FUNCTION_TYPE:
- if (TREE_CODE (arg) != TREE_CODE (parm))
- return 1;
+ {
+ unsigned int nargs;
+ tree *args;
+ tree a;
+ unsigned int i;
- /* CV qualifications for methods can never be deduced, they must
- match exactly. We need to check them explicitly here,
- because type_unification_real treats them as any other
- cv-qualified parameter. */
- if (TREE_CODE (parm) == METHOD_TYPE
- && (!check_cv_quals_for_unify
- (UNIFY_ALLOW_NONE,
- TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (arg))),
- TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (parm))))))
- return 1;
+ if (TREE_CODE (arg) != TREE_CODE (parm))
+ return 1;
- if (unify (tparms, targs, TREE_TYPE (parm),
- TREE_TYPE (arg), UNIFY_ALLOW_NONE))
- return 1;
- return type_unification_real (tparms, targs, TYPE_ARG_TYPES (parm),
- TYPE_ARG_TYPES (arg), 1, DEDUCE_EXACT,
- LOOKUP_NORMAL);
+ /* CV qualifications for methods can never be deduced, they must
+ match exactly. We need to check them explicitly here,
+ because type_unification_real treats them as any other
+ cv-qualified parameter. */
+ if (TREE_CODE (parm) == METHOD_TYPE
+ && (!check_cv_quals_for_unify
+ (UNIFY_ALLOW_NONE,
+ TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (arg))),
+ TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (parm))))))
+ return 1;
+
+ if (unify (tparms, targs, TREE_TYPE (parm),
+ TREE_TYPE (arg), UNIFY_ALLOW_NONE))
+ return 1;
+
+ nargs = list_length (TYPE_ARG_TYPES (arg));
+ args = XALLOCAVEC (tree, nargs);
+ for (a = TYPE_ARG_TYPES (arg), i = 0;
+ a != NULL_TREE && a != void_list_node;
+ a = TREE_CHAIN (a), ++i)
+ args[i] = TREE_VALUE (a);
+ nargs = i;
+
+ return type_unification_real (tparms, targs, TYPE_ARG_TYPES (parm),
+ args, nargs, 1, DEDUCE_EXACT,
+ LOOKUP_NORMAL);
+ }
case OFFSET_TYPE:
/* Unify a pointer to member with a pointer to member function, which
@@ -14456,6 +14589,9 @@ get_bindings (tree fn, tree decl, tree explicit_args, bool check_rettype)
tree targs = make_tree_vec (ntparms);
tree decl_type;
tree decl_arg_types;
+ tree *args;
+ unsigned int nargs, ix;
+ tree arg;
/* Substitute the explicit template arguments into the type of DECL.
The call to fn_type_unification will handle substitution into the
@@ -14490,8 +14626,15 @@ get_bindings (tree fn, tree decl, tree explicit_args, bool check_rettype)
decl_arg_types = skip_artificial_parms_for (decl,
TYPE_ARG_TYPES (decl_type));
+ nargs = list_length (decl_arg_types);
+ args = XALLOCAVEC (tree, nargs);
+ for (arg = decl_arg_types, ix = 0;
+ arg != NULL_TREE && arg != void_list_node;
+ arg = TREE_CHAIN (arg), ++ix)
+ args[ix] = TREE_VALUE (arg);
+
if (fn_type_unification (fn, explicit_args, targs,
- decl_arg_types,
+ args, ix,
(check_rettype || DECL_CONV_FN_P (fn)
? TREE_TYPE (decl_type) : NULL_TREE),
DEDUCE_EXACT, LOOKUP_NORMAL))
@@ -16040,7 +16183,7 @@ current_instantiation (void)
static int
invalid_nontype_parm_type_p (tree type, tsubst_flags_t complain)
{
- if (INTEGRAL_TYPE_P (type))
+ if (INTEGRAL_OR_ENUMERATION_TYPE_P (type))
return 0;
else if (POINTER_TYPE_P (type))
return 0;
@@ -16567,19 +16710,18 @@ type_dependent_expression_p_push (tree expr)
return b;
}
-/* Returns TRUE if ARGS (a TREE_LIST of arguments to a function call)
- contains a type-dependent expression. */
+/* Returns TRUE if ARGS contains a type-dependent expression. */
bool
-any_type_dependent_arguments_p (const_tree args)
+any_type_dependent_arguments_p (const VEC(tree,gc) *args)
{
- while (args)
- {
- tree arg = TREE_VALUE (args);
+ unsigned int i;
+ tree arg;
+ for (i = 0; VEC_iterate (tree, args, i, arg); ++i)
+ {
if (type_dependent_expression_p (arg))
return true;
- args = TREE_CHAIN (args);
}
return false;
}
@@ -16999,22 +17141,22 @@ build_non_dependent_expr (tree expr)
return build1 (NON_DEPENDENT_EXPR, non_reference (TREE_TYPE (expr)), expr);
}
-/* ARGS is a TREE_LIST of expressions as arguments to a function call.
- Return a new TREE_LIST with the various arguments replaced with
- equivalent non-dependent expressions. */
+/* ARGS is a vector of expressions as arguments to a function call.
+ Replace the arguments with equivalent non-dependent expressions.
+ This modifies ARGS in place. */
-tree
-build_non_dependent_args (tree args)
+void
+make_args_non_dependent (VEC(tree,gc) *args)
{
- tree a;
- tree new_args;
+ unsigned int ix;
+ tree arg;
- new_args = NULL_TREE;
- for (a = args; a; a = TREE_CHAIN (a))
- new_args = tree_cons (NULL_TREE,
- build_non_dependent_expr (TREE_VALUE (a)),
- new_args);
- return nreverse (new_args);
+ for (ix = 0; VEC_iterate (tree, args, ix, arg); ++ix)
+ {
+ tree newarg = build_non_dependent_expr (arg);
+ if (newarg != arg)
+ VEC_replace (tree, args, ix, newarg);
+ }
}
/* Returns a type which represents 'auto'. We use a TEMPLATE_TYPE_PARM
@@ -17027,7 +17169,8 @@ make_auto (void)
/* ??? Is it worth caching this for multiple autos at the same level? */
au = cxx_make_type (TEMPLATE_TYPE_PARM);
- TYPE_NAME (au) = build_decl (TYPE_DECL, get_identifier ("auto"), au);
+ TYPE_NAME (au) = build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier ("auto"), au);
TYPE_STUB_DECL (au) = TYPE_NAME (au);
TEMPLATE_TYPE_PARM_INDEX (au) = build_template_parm_index
(0, processing_template_decl + 1, processing_template_decl + 1,
@@ -17071,7 +17214,8 @@ listify_autos (tree type, tree auto_node)
tree
do_auto_deduction (tree type, tree init, tree auto_node)
{
- tree parms, args, tparms, targs;
+ tree parms, tparms, targs;
+ tree args[1];
int val;
/* [dcl.spec.auto]: Obtain P from T by replacing the occurrences of auto
@@ -17082,12 +17226,12 @@ do_auto_deduction (tree type, tree init, tree auto_node)
type = listify_autos (type, auto_node);
parms = build_tree_list (NULL_TREE, type);
- args = build_tree_list (NULL_TREE, init);
+ args[0] = init;
tparms = make_tree_vec (1);
targs = make_tree_vec (1);
TREE_VEC_ELT (tparms, 0)
= build_tree_list (NULL_TREE, TYPE_NAME (auto_node));
- val = type_unification_real (tparms, targs, parms, args, 0,
+ val = type_unification_real (tparms, targs, parms, args, 1, 0,
DEDUCE_CALL, LOOKUP_NORMAL);
if (val > 0)
{
@@ -17154,33 +17298,108 @@ type_uses_auto (tree type)
return NULL_TREE;
}
+/* For a given template T, return the list of typedefs referenced
+ in T for which access check is needed at T instantiation time.
+ T is either a FUNCTION_DECL or a RECORD_TYPE.
+ Those typedefs were added to T by the function
+ append_type_to_template_for_access_check. */
+
+tree
+get_types_needing_access_check (tree t)
+{
+ tree ti, result = NULL_TREE;
+
+ if (!t || t == error_mark_node)
+ return t;
+
+ if (!(ti = get_template_info (t)))
+ return NULL_TREE;
+
+ if (TREE_CODE (t) == RECORD_TYPE || TREE_CODE (t) == FUNCTION_DECL)
+ {
+ if (!TI_TEMPLATE (ti))
+ return NULL_TREE;
+
+ result = TI_TYPEDEFS_NEEDING_ACCESS_CHECKING (ti);
+ }
+
+ return result;
+}
+
+/* Append the typedef TYPE_DECL used in template T to a list of typedefs
+ tied to T. That list of typedefs will be access checked at
+ T instantiation time.
+ T is either a FUNCTION_DECL or a RECORD_TYPE.
+ TYPE_DECL is a TYPE_DECL node representing a typedef.
+ SCOPE is the scope through which TYPE_DECL is accessed.
+
+ This function is a subroutine of
+ append_type_to_template_for_access_check. */
+
+static void
+append_type_to_template_for_access_check_1 (tree t,
+ tree type_decl,
+ tree scope)
+{
+ tree ti;
+
+ if (!t || t == error_mark_node)
+ return;
+
+ gcc_assert ((TREE_CODE (t) == FUNCTION_DECL
+ || TREE_CODE (t) == RECORD_TYPE)
+ && type_decl
+ && TREE_CODE (type_decl) == TYPE_DECL
+ && scope);
+
+ if (!(ti = get_template_info (t)))
+ return;
+
+ gcc_assert (TI_TEMPLATE (ti));
+
+ TI_TYPEDEFS_NEEDING_ACCESS_CHECKING (ti) =
+ tree_cons (type_decl, scope, TI_TYPEDEFS_NEEDING_ACCESS_CHECKING (ti));
+}
+
/* Append TYPE_DECL to the template TEMPL.
- TEMPL is either a class type or a FUNCTION_DECL associated
- to a TEMPLATE_DECL.
+ TEMPL is either a class type, a FUNCTION_DECL or a a TEMPLATE_DECL.
At TEMPL instanciation time, TYPE_DECL will be checked to see
- if it can be accessed through SCOPE. */
+ if it can be accessed through SCOPE.
+
+ e.g. consider the following code snippet:
+
+ class C
+ {
+ typedef int myint;
+ };
+
+ template<class U> struct S
+ {
+ C::myint mi;
+ };
+
+ S<char> s;
+
+ At S<char> instantiation time, we need to check the access of C::myint
+ In other words, we need to check the access of the myint typedef through
+ the C scope. For that purpose, this function will add the myint typedef
+ and the scope C through which its being accessed to a list of typedefs
+ tied to the template S. That list will be walked at template instantiation
+ time and access check performed on each typedefs it contains.
+ Note that this particular code snippet should yield an error because
+ myint is private to C. */
void
append_type_to_template_for_access_check (tree templ,
tree type_decl,
tree scope)
{
- tree node, templ_decl;
-
- gcc_assert (templ
- && get_template_info (templ)
- && TI_TEMPLATE (get_template_info (templ))
- && type_decl
- && (TREE_CODE (type_decl) == TYPE_DECL));
+ tree node;
- templ_decl = TI_TEMPLATE (get_template_info (templ));
- gcc_assert (templ_decl);
+ gcc_assert (type_decl && (TREE_CODE (type_decl) == TYPE_DECL));
- /* Make sure we don't append the type to the template twice.
- If this appears to be too slow, the
- MEMBER_TYPE_NEEDING_ACCESS_CHECK property
- of templ should be a hash table instead. */
- for (node = MEMBER_TYPES_NEEDING_ACCESS_CHECK (templ_decl);
+ /* Make sure we don't append the type to the template twice. */
+ for (node = get_types_needing_access_check (templ);
node;
node = TREE_CHAIN (node))
{
@@ -17191,9 +17410,7 @@ append_type_to_template_for_access_check (tree templ,
return;
}
- MEMBER_TYPES_NEEDING_ACCESS_CHECK (templ_decl) =
- tree_cons (type_decl, scope,
- MEMBER_TYPES_NEEDING_ACCESS_CHECK (templ_decl));
+ append_type_to_template_for_access_check_1 (templ, type_decl, scope);
}
#include "gt-cp-pt.h"
diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c
index 9246fc2854d..c26caa9cb3d 100644
--- a/gcc/cp/rtti.c
+++ b/gcc/cp/rtti.c
@@ -1161,7 +1161,8 @@ create_pseudo_type_info (int tk, const char *real_name, ...)
sprintf (pseudo_name + strlen (pseudo_name), "%d", tk - TK_FIXED);
/* First field is the pseudo type_info base class. */
- fields = build_decl (FIELD_DECL, NULL_TREE,
+ fields = build_decl (input_location,
+ FIELD_DECL, NULL_TREE,
VEC_index (tinfo_s, tinfo_descs,
TK_TYPE_INFO_TYPE)->type);
@@ -1290,9 +1291,12 @@ get_pseudo_ti_index (tree type)
push_abi_namespace ();
create_pseudo_type_info
(ix, "__vmi_class_type_info",
- build_decl (FIELD_DECL, NULL_TREE, integer_type_node),
- build_decl (FIELD_DECL, NULL_TREE, integer_type_node),
- build_decl (FIELD_DECL, NULL_TREE, base_array),
+ build_decl (input_location,
+ FIELD_DECL, NULL_TREE, integer_type_node),
+ build_decl (input_location,
+ FIELD_DECL, NULL_TREE, integer_type_node),
+ build_decl (input_location,
+ FIELD_DECL, NULL_TREE, base_array),
NULL);
pop_abi_namespace ();
break;
@@ -1324,10 +1328,12 @@ create_tinfo_types (void)
{
tree field, fields;
- field = build_decl (FIELD_DECL, NULL_TREE, const_ptr_type_node);
+ field = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, NULL_TREE, const_ptr_type_node);
fields = field;
- field = build_decl (FIELD_DECL, NULL_TREE, const_string_type_node);
+ field = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, NULL_TREE, const_string_type_node);
TREE_CHAIN (field) = fields;
fields = field;
@@ -1353,7 +1359,8 @@ create_tinfo_types (void)
/* Single public non-virtual base class. Add pointer to base class.
This is really a descendant of __class_type_info. */
create_pseudo_type_info (TK_SI_CLASS_TYPE, "__si_class_type_info",
- build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type),
+ build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, NULL_TREE, type_info_ptr_type),
NULL);
/* Base class internal helper. Pointer to base type, offset to base,
@@ -1361,10 +1368,12 @@ create_tinfo_types (void)
{
tree field, fields;
- field = build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type);
+ field = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, NULL_TREE, type_info_ptr_type);
fields = field;
- field = build_decl (FIELD_DECL, NULL_TREE, integer_types[itk_long]);
+ field = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, NULL_TREE, integer_types[itk_long]);
TREE_CHAIN (field) = fields;
fields = field;
@@ -1381,8 +1390,10 @@ create_tinfo_types (void)
and pointer to the pointed to type. This is really a descendant of
__pbase_type_info. */
create_pseudo_type_info (TK_POINTER_TYPE, "__pointer_type_info",
- build_decl (FIELD_DECL, NULL_TREE, integer_type_node),
- build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type),
+ build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, NULL_TREE, integer_type_node),
+ build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, NULL_TREE, type_info_ptr_type),
NULL);
/* Pointer to member data type_info. Add qualifications flags,
@@ -1390,9 +1401,12 @@ create_tinfo_types (void)
This is really a descendant of __pbase_type_info. */
create_pseudo_type_info (TK_POINTER_MEMBER_TYPE,
"__pointer_to_member_type_info",
- build_decl (FIELD_DECL, NULL_TREE, integer_type_node),
- build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type),
- build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type),
+ build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, NULL_TREE, integer_type_node),
+ build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, NULL_TREE, type_info_ptr_type),
+ build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, NULL_TREE, type_info_ptr_type),
NULL);
pop_abi_namespace ();
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 8c0a1e510ce..9a43863c6bb 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -420,7 +420,7 @@ maybe_cleanup_point_expr_void (tree expr)
void
add_decl_expr (tree decl)
{
- tree r = build_stmt (DECL_EXPR, decl);
+ tree r = build_stmt (input_location, DECL_EXPR, decl);
if (DECL_INITIAL (decl)
|| (DECL_SIZE (decl) && TREE_SIDE_EFFECTS (DECL_SIZE (decl))))
r = maybe_cleanup_point_expr_void (r);
@@ -441,7 +441,7 @@ do_poplevel (tree stmt_list)
if (!processing_template_decl)
{
- stmt_list = c_build_bind_expr (block, stmt_list);
+ stmt_list = c_build_bind_expr (input_location, block, stmt_list);
/* ??? See c_end_compound_stmt re statement expressions. */
}
@@ -466,7 +466,7 @@ do_pushlevel (scope_kind sk)
void
push_cleanup (tree decl, tree cleanup, bool eh_only)
{
- tree stmt = build_stmt (CLEANUP_STMT, NULL, cleanup, decl);
+ tree stmt = build_stmt (input_location, CLEANUP_STMT, NULL, cleanup, decl);
CLEANUP_EH_ONLY (stmt) = eh_only;
add_stmt (stmt);
CLEANUP_BODY (stmt) = push_stmt_list ();
@@ -561,7 +561,7 @@ finish_goto_stmt (tree destination)
check_goto (destination);
- return add_stmt (build_stmt (GOTO_EXPR, destination));
+ return add_stmt (build_stmt (input_location, GOTO_EXPR, destination));
}
/* COND is the condition-expression for an if, while, etc.,
@@ -624,7 +624,7 @@ finish_expr_stmt (tree expr)
if (TREE_CODE (expr) != CLEANUP_POINT_EXPR)
{
if (TREE_CODE (expr) != EXPR_STMT)
- expr = build_stmt (EXPR_STMT, expr);
+ expr = build_stmt (input_location, EXPR_STMT, expr);
expr = maybe_cleanup_point_expr_void (expr);
}
@@ -645,7 +645,7 @@ begin_if_stmt (void)
{
tree r, scope;
scope = do_pushlevel (sk_block);
- r = build_stmt (IF_STMT, NULL_TREE, NULL_TREE, NULL_TREE);
+ r = build_stmt (input_location, IF_STMT, NULL_TREE, NULL_TREE, NULL_TREE);
TREE_CHAIN (r) = scope;
begin_cond (&IF_COND (r));
return r;
@@ -707,7 +707,7 @@ tree
begin_while_stmt (void)
{
tree r;
- r = build_stmt (WHILE_STMT, NULL_TREE, NULL_TREE);
+ r = build_stmt (input_location, WHILE_STMT, NULL_TREE, NULL_TREE);
add_stmt (r);
WHILE_BODY (r) = do_pushlevel (sk_block);
begin_cond (&WHILE_COND (r));
@@ -739,7 +739,7 @@ finish_while_stmt (tree while_stmt)
tree
begin_do_stmt (void)
{
- tree r = build_stmt (DO_STMT, NULL_TREE, NULL_TREE);
+ tree r = build_stmt (input_location, DO_STMT, NULL_TREE, NULL_TREE);
add_stmt (r);
DO_BODY (r) = push_stmt_list ();
return r;
@@ -801,7 +801,7 @@ finish_return_stmt (tree expr)
}
}
- r = build_stmt (RETURN_EXPR, expr);
+ r = build_stmt (input_location, RETURN_EXPR, expr);
TREE_NO_WARNING (r) |= no_warning;
r = maybe_cleanup_point_expr_void (r);
r = add_stmt (r);
@@ -817,7 +817,7 @@ begin_for_stmt (void)
{
tree r;
- r = build_stmt (FOR_STMT, NULL_TREE, NULL_TREE,
+ r = build_stmt (input_location, FOR_STMT, NULL_TREE, NULL_TREE,
NULL_TREE, NULL_TREE);
if (flag_new_for_scope > 0)
@@ -908,7 +908,7 @@ finish_for_stmt (tree for_stmt)
tree
finish_break_stmt (void)
{
- return add_stmt (build_stmt (BREAK_STMT));
+ return add_stmt (build_stmt (input_location, BREAK_STMT));
}
/* Finish a continue-statement. */
@@ -916,7 +916,7 @@ finish_break_stmt (void)
tree
finish_continue_stmt (void)
{
- return add_stmt (build_stmt (CONTINUE_STMT));
+ return add_stmt (build_stmt (input_location, CONTINUE_STMT));
}
/* Begin a switch-statement. Returns a new SWITCH_STMT if
@@ -927,7 +927,7 @@ begin_switch_stmt (void)
{
tree r, scope;
- r = build_stmt (SWITCH_STMT, NULL_TREE, NULL_TREE, NULL_TREE);
+ r = build_stmt (input_location, SWITCH_STMT, NULL_TREE, NULL_TREE, NULL_TREE);
scope = do_pushlevel (sk_block);
TREE_CHAIN (r) = scope;
@@ -997,7 +997,7 @@ finish_switch_stmt (tree switch_stmt)
tree
begin_try_block (void)
{
- tree r = build_stmt (TRY_BLOCK, NULL_TREE, NULL_TREE);
+ tree r = build_stmt (input_location, TRY_BLOCK, NULL_TREE, NULL_TREE);
add_stmt (r);
TRY_STMTS (r) = push_stmt_list ();
return r;
@@ -1087,7 +1087,7 @@ begin_handler (void)
{
tree r;
- r = build_stmt (HANDLER, NULL_TREE, NULL_TREE);
+ r = build_stmt (input_location, HANDLER, NULL_TREE, NULL_TREE);
add_stmt (r);
/* Create a binding level for the eh_info and the exception object
@@ -1307,7 +1307,7 @@ finish_asm_stmt (int volatile_p, tree string, tree output_operands,
}
}
- r = build_stmt (ASM_EXPR, string,
+ r = build_stmt (input_location, ASM_EXPR, string,
output_operands, input_operands,
clobbers);
ASM_VOLATILE_P (r) = volatile_p || noutputs == 0;
@@ -1315,17 +1315,19 @@ finish_asm_stmt (int volatile_p, tree string, tree output_operands,
return add_stmt (r);
}
-/* Finish a label with the indicated NAME. */
+/* Finish a label with the indicated NAME. Returns the new label. */
tree
finish_label_stmt (tree name)
{
tree decl = define_label (input_location, name);
- if (decl == error_mark_node)
+ if (decl == error_mark_node)
return error_mark_node;
- return add_stmt (build_stmt (LABEL_EXPR, decl));
+ add_stmt (build_stmt (input_location, LABEL_EXPR, decl));
+
+ return decl;
}
/* Finish a series of declarations for local labels. G++ allows users
@@ -1421,7 +1423,7 @@ finish_non_static_data_member (tree decl, tree object, tree qualifying_scope)
{
gcc_assert (TREE_CODE (decl) == FIELD_DECL);
- if (!object && skip_evaluation)
+ if (!object && cp_unevaluated_operand != 0)
{
/* DR 613: Can use non-static data members without an associated
object in sizeof/decltype/alignof. */
@@ -1664,11 +1666,10 @@ finish_qualified_id_expr (tree qualifying_class,
fns = BASELINK_FUNCTIONS (expr);
if (TREE_CODE (fns) == TEMPLATE_ID_EXPR)
fns = TREE_OPERAND (fns, 0);
- /* If so, the expression may be relative to the current
- class. */
+ /* If so, the expression may be relative to 'this'. */
if (!shared_member_p (fns)
- && current_class_type
- && DERIVED_FROM_P (qualifying_class, current_class_type))
+ && current_class_ref
+ && DERIVED_FROM_P (qualifying_class, TREE_TYPE (current_class_ref)))
expr = (build_class_member_access_expr
(maybe_dummy_object (qualifying_class, NULL),
expr,
@@ -1717,7 +1718,7 @@ finish_stmt_expr_expr (tree expr, tree stmt_expr)
if (processing_template_decl)
{
- expr = build_stmt (EXPR_STMT, expr);
+ expr = build_stmt (input_location, EXPR_STMT, expr);
expr = add_stmt (expr);
/* Mark the last statement so that we can recognize it as such at
template-instantiation time. */
@@ -1821,7 +1822,7 @@ stmt_expr_value_expr (tree stmt_expr)
resolution. */
tree
-perform_koenig_lookup (tree fn, tree args)
+perform_koenig_lookup (tree fn, VEC(tree,gc) *args)
{
tree identifier = NULL_TREE;
tree functions = NULL_TREE;
@@ -1866,7 +1867,8 @@ perform_koenig_lookup (tree fn, tree args)
return fn;
}
-/* Generate an expression for `FN (ARGS)'.
+/* Generate an expression for `FN (ARGS)'. This may change the
+ contents of ARGS.
If DISALLOW_VIRTUAL is true, the call to FN will be not generated
as a virtual call, even if FN is virtual. (This flag is set when
@@ -1877,29 +1879,26 @@ perform_koenig_lookup (tree fn, tree args)
Returns code for the call. */
tree
-finish_call_expr (tree fn, tree args, bool disallow_virtual, bool koenig_p,
- tsubst_flags_t complain)
+finish_call_expr (tree fn, VEC(tree,gc) **args, bool disallow_virtual,
+ bool koenig_p, tsubst_flags_t complain)
{
tree result;
tree orig_fn;
- tree orig_args;
+ VEC(tree,gc) *orig_args = NULL;
- if (fn == error_mark_node || args == error_mark_node)
+ if (fn == error_mark_node)
return error_mark_node;
- /* ARGS should be a list of arguments. */
- gcc_assert (!args || TREE_CODE (args) == TREE_LIST);
gcc_assert (!TYPE_P (fn));
orig_fn = fn;
- orig_args = args;
if (processing_template_decl)
{
if (type_dependent_expression_p (fn)
- || any_type_dependent_arguments_p (args))
+ || any_type_dependent_arguments_p (*args))
{
- result = build_nt_call_list (fn, args);
+ result = build_nt_call_vec (fn, *args);
KOENIG_LOOKUP_P (result) = koenig_p;
if (cfun)
{
@@ -1917,11 +1916,12 @@ finish_call_expr (tree fn, tree args, bool disallow_virtual, bool koenig_p,
}
return result;
}
+ orig_args = make_tree_vector_copy (*args);
if (!BASELINK_P (fn)
&& TREE_CODE (fn) != PSEUDO_DTOR_EXPR
&& TREE_TYPE (fn) != unknown_type_node)
fn = build_non_dependent_expr (fn);
- args = build_non_dependent_args (orig_args);
+ make_args_non_dependent (*args);
}
if (is_overloaded_fn (fn))
@@ -1970,7 +1970,11 @@ finish_call_expr (tree fn, tree args, bool disallow_virtual, bool koenig_p,
if (processing_template_decl)
{
if (type_dependent_expression_p (object))
- return build_nt_call_list (orig_fn, orig_args);
+ {
+ tree ret = build_nt_call_vec (orig_fn, orig_args);
+ release_tree_vector (orig_args);
+ return ret;
+ }
object = build_non_dependent_expr (object);
}
@@ -1986,15 +1990,7 @@ finish_call_expr (tree fn, tree args, bool disallow_virtual, bool koenig_p,
if (TREE_CODE (fn) == FUNCTION_DECL
&& (DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL
|| DECL_BUILT_IN_CLASS (fn) == BUILT_IN_MD))
- {
- VEC(tree,gc)* vec = VEC_alloc (tree, gc, list_length (args));
- tree p;
-
- for (p = args; p != NULL_TREE; p = TREE_CHAIN (p))
- VEC_quick_push (tree, vec, TREE_VALUE (p));
- result = resolve_overloaded_builtin (fn, vec);
- VEC_free (tree, gc, vec);
- }
+ result = resolve_overloaded_builtin (input_location, fn, *args);
if (!result)
/* A call to a namespace-scope function. */
@@ -2002,7 +1998,7 @@ finish_call_expr (tree fn, tree args, bool disallow_virtual, bool koenig_p,
}
else if (TREE_CODE (fn) == PSEUDO_DTOR_EXPR)
{
- if (args)
+ if (!VEC_empty (tree, *args))
error ("arguments to destructor are not allowed");
/* Mark the pseudo-destructor call as having side-effects so
that we do not issue warnings about its use. */
@@ -2014,18 +2010,19 @@ finish_call_expr (tree fn, tree args, bool disallow_virtual, bool koenig_p,
else if (CLASS_TYPE_P (TREE_TYPE (fn)))
/* If the "function" is really an object of class type, it might
have an overloaded `operator ()'. */
- result = build_new_op (CALL_EXPR, LOOKUP_NORMAL, fn, args, NULL_TREE,
- /*overloaded_p=*/NULL, complain);
+ result = build_op_call (fn, args, complain);
if (!result)
/* A call where the function is unknown. */
- result = cp_build_function_call (fn, args, complain);
+ result = cp_build_function_call_vec (fn, args, complain);
if (processing_template_decl)
{
- result = build_call_list (TREE_TYPE (result), orig_fn, orig_args);
+ result = build_call_vec (TREE_TYPE (result), orig_fn, orig_args);
KOENIG_LOOKUP_P (result) = koenig_p;
+ release_tree_vector (orig_args);
}
+
return result;
}
@@ -2140,7 +2137,7 @@ finish_unary_op_expr (enum tree_code code, tree expr)
TREE_NEGATED_INT (result) = 1;
}
if (TREE_OVERFLOW_P (result) && !TREE_OVERFLOW_P (expr))
- overflow_warning (result);
+ overflow_warning (input_location, result);
return result;
}
@@ -2253,7 +2250,8 @@ finish_template_type_parm (tree aggr, tree identifier)
tree
finish_template_template_parm (tree aggr, tree identifier)
{
- tree decl = build_decl (TYPE_DECL, identifier, NULL_TREE);
+ tree decl = build_decl (input_location,
+ TYPE_DECL, identifier, NULL_TREE);
tree tmpl = build_lang_decl (TEMPLATE_DECL, identifier, NULL_TREE);
DECL_TEMPLATE_PARMS (tmpl) = current_template_parms;
DECL_TEMPLATE_RESULT (tmpl) = decl;
@@ -2871,16 +2869,16 @@ finish_id_expression (tree id_expression,
done, address_p,
template_p,
template_arg_p);
- else if (dependent_scope_p (scope))
- decl = build_qualified_name (/*type=*/NULL_TREE,
- scope,
- id_expression,
- template_p);
- else if (DECL_P (decl))
- decl = build_qualified_name (TREE_TYPE (decl),
- scope,
- id_expression,
- template_p);
+ else
+ {
+ tree type = NULL_TREE;
+ if (DECL_P (decl) && !dependent_scope_p (scope))
+ type = TREE_TYPE (decl);
+ decl = build_qualified_name (type,
+ scope,
+ id_expression,
+ template_p);
+ }
}
if (TREE_TYPE (decl))
decl = convert_from_reference (decl);
@@ -3273,8 +3271,10 @@ expand_or_defer_fn (tree fn)
/* If the user wants us to keep all inline functions, then mark
this function as needed so that finish_file will make sure to
- output it later. */
- if (flag_keep_inline_functions && DECL_DECLARED_INLINE_P (fn))
+ output it later. Similarly, all dllexport'd functions must
+ be emitted; there may be callers in other DLLs. */
+ if ((flag_keep_inline_functions && DECL_DECLARED_INLINE_P (fn))
+ || lookup_attribute ("dllexport", DECL_ATTRIBUTES (fn)))
mark_needed (fn);
}
@@ -3331,7 +3331,7 @@ finalize_nrv_r (tree* tp, int* walk_subtrees, void* data)
init = build2 (INIT_EXPR, void_type_node, dp->result,
DECL_INITIAL (dp->var));
else
- init = build_empty_stmt ();
+ init = build_empty_stmt (EXPR_LOCATION (*tp));
DECL_INITIAL (dp->var) = NULL_TREE;
SET_EXPR_LOCUS (init, EXPR_LOCUS (*tp));
*tp = init;
@@ -3424,18 +3424,23 @@ cxx_omp_create_clause_info (tree c, tree type, bool need_default_ctor,
if (need_default_ctor
|| (need_copy_ctor && !TYPE_HAS_TRIVIAL_INIT_REF (type)))
{
+ VEC(tree,gc) *vec;
+
if (need_default_ctor)
- t = NULL;
+ vec = NULL;
else
{
t = build_int_cst (build_pointer_type (type), 0);
t = build1 (INDIRECT_REF, type, t);
- t = build_tree_list (NULL, t);
+ vec = make_tree_vector_single (t);
}
t = build_special_member_call (NULL_TREE, complete_ctor_identifier,
- t, type, LOOKUP_NORMAL,
+ &vec, type, LOOKUP_NORMAL,
tf_warning_or_error);
+ if (vec != NULL)
+ release_tree_vector (vec);
+
if (targetm.cxx.cdtor_returns_this () || errorcount)
/* Because constructors and destructors return this,
the call will have been cast to "void". Remove the
@@ -3473,12 +3478,15 @@ cxx_omp_create_clause_info (tree c, tree type, bool need_default_ctor,
if (need_copy_assignment && !TYPE_HAS_TRIVIAL_ASSIGN_REF (type))
{
+ VEC(tree,gc) *vec;
+
t = build_int_cst (build_pointer_type (type), 0);
t = build1 (INDIRECT_REF, type, t);
+ vec = make_tree_vector_single (t);
t = build_special_member_call (t, ansi_assopname (NOP_EXPR),
- build_tree_list (NULL, t),
- type, LOOKUP_NORMAL,
+ &vec, type, LOOKUP_NORMAL,
tf_warning_or_error);
+ release_tree_vector (vec);
/* We'll have called convert_from_reference on the call, which
may well have added an indirect_ref. It's unneeded here,
@@ -4129,7 +4137,7 @@ handle_omp_for_class_iterator (int i, location_t locus, tree declv, tree initv,
TREE_CODE (cond), decl, diff,
tf_warning_or_error);
incr = build_modify_expr (elocus, decl, NULL_TREE, PLUS_EXPR,
- incr, NULL_TREE);
+ elocus, incr, NULL_TREE);
orig_body = *body;
*body = push_stmt_list ();
@@ -4420,7 +4428,7 @@ finish_omp_atomic (enum tree_code code, tree lhs, tree rhs)
}
if (!dependent_p)
{
- stmt = c_finish_omp_atomic (code, lhs, rhs);
+ stmt = c_finish_omp_atomic (input_location, code, lhs, rhs);
if (stmt == error_mark_node)
return;
}
@@ -4434,7 +4442,9 @@ void
finish_omp_barrier (void)
{
tree fn = built_in_decls[BUILT_IN_GOMP_BARRIER];
- tree stmt = finish_call_expr (fn, NULL, false, false, tf_warning_or_error);
+ VEC(tree,gc) *vec = make_tree_vector ();
+ tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error);
+ release_tree_vector (vec);
finish_expr_stmt (stmt);
}
@@ -4442,7 +4452,9 @@ void
finish_omp_flush (void)
{
tree fn = built_in_decls[BUILT_IN_SYNCHRONIZE];
- tree stmt = finish_call_expr (fn, NULL, false, false, tf_warning_or_error);
+ VEC(tree,gc) *vec = make_tree_vector ();
+ tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error);
+ release_tree_vector (vec);
finish_expr_stmt (stmt);
}
@@ -4450,7 +4462,9 @@ void
finish_omp_taskwait (void)
{
tree fn = built_in_decls[BUILT_IN_GOMP_TASKWAIT];
- tree stmt = finish_call_expr (fn, NULL, false, false, tf_warning_or_error);
+ VEC(tree,gc) *vec = make_tree_vector ();
+ tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error);
+ release_tree_vector (vec);
finish_expr_stmt (stmt);
}
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 9cc767da07c..7c48a3257b3 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -302,7 +302,8 @@ build_target_expr (tree decl, tree value)
static tree
build_local_temp (tree type)
{
- tree slot = build_decl (VAR_DECL, NULL_TREE, type);
+ tree slot = build_decl (input_location,
+ VAR_DECL, NULL_TREE, type);
DECL_ARTIFICIAL (slot) = 1;
DECL_IGNORED_P (slot) = 1;
DECL_CONTEXT (slot) = current_function_decl;
@@ -911,19 +912,111 @@ cp_build_qualified_type_real (tree type,
return result;
}
-/* Returns the canonical version of TYPE. In other words, if TYPE is
- a typedef, returns the underlying type. The cv-qualification of
- the type returned matches the type input; they will always be
- compatible types. */
+/* Builds a qualified variant of T that is not a typedef variant.
+ E.g. consider the following declarations:
+ typedef const int ConstInt;
+ typedef ConstInt* PtrConstInt;
+ If T is PtrConstInt, this function returns a type representing
+ const int*.
+ In other words, if T is a typedef, the function returns the underlying type.
+ The cv-qualification and attributes of the type returned match the
+ input type.
+ They will always be compatible types.
+ The returned type is built so that all of its subtypes
+ recursively have their typedefs stripped as well.
+
+ This is different from just returning TYPE_CANONICAL (T)
+ Because of several reasons:
+ * If T is a type that needs structural equality
+ its TYPE_CANONICAL (T) will be NULL.
+ * TYPE_CANONICAL (T) desn't carry type attributes
+ and looses template parameter names. */
tree
-canonical_type_variant (tree t)
+strip_typedefs (tree t)
{
- if (t == error_mark_node)
- return error_mark_node;
+ tree result = NULL, type = NULL, t0 = NULL;
+
+ if (!t || t == error_mark_node || t == TYPE_CANONICAL (t))
+ return t;
+
+ gcc_assert (TYPE_P (t));
+
+ switch (TREE_CODE (t))
+ {
+ case POINTER_TYPE:
+ type = strip_typedefs (TREE_TYPE (t));
+ result = build_pointer_type (type);
+ break;
+ case REFERENCE_TYPE:
+ type = strip_typedefs (TREE_TYPE (t));
+ result = cp_build_reference_type (type, TYPE_REF_IS_RVALUE (t));
+ break;
+ case OFFSET_TYPE:
+ t0 = strip_typedefs (TYPE_OFFSET_BASETYPE (t));
+ type = strip_typedefs (TREE_TYPE (t));
+ result = build_offset_type (t0, type);
+ break;
+ case RECORD_TYPE:
+ if (TYPE_PTRMEMFUNC_P (t))
+ {
+ t0 = strip_typedefs (TYPE_PTRMEMFUNC_FN_TYPE (t));
+ result = build_ptrmemfunc_type (t0);
+ }
+ break;
+ case ARRAY_TYPE:
+ type = strip_typedefs (TREE_TYPE (t));
+ t0 = strip_typedefs (TYPE_DOMAIN (t));;
+ result = build_cplus_array_type (type, t0);
+ break;
+ case FUNCTION_TYPE:
+ case METHOD_TYPE:
+ {
+ tree arg_types = NULL, arg_node, arg_type;
+ for (arg_node = TYPE_ARG_TYPES (t);
+ arg_node;
+ arg_node = TREE_CHAIN (arg_node))
+ {
+ if (arg_node == void_list_node)
+ break;
+ arg_type = strip_typedefs (TREE_VALUE (arg_node));
+ gcc_assert (arg_type);
- return cp_build_qualified_type (TYPE_MAIN_VARIANT (t), cp_type_quals (t));
+ arg_types =
+ tree_cons (TREE_PURPOSE (arg_node), arg_type, arg_types);
+ }
+
+ if (arg_types)
+ arg_types = nreverse (arg_types);
+
+ /* A list of parameters not ending with an ellipsis
+ must end with void_list_node. */
+ if (arg_node)
+ arg_types = chainon (arg_types, void_list_node);
+
+ type = strip_typedefs (TREE_TYPE (t));
+ if (TREE_CODE (t) == METHOD_TYPE)
+ {
+ tree class_type = TREE_TYPE (TREE_VALUE (arg_types));
+ gcc_assert (class_type);
+ result =
+ build_method_type_directly (class_type, type,
+ TREE_CHAIN (arg_types));
+ }
+ else
+ result = build_function_type (type,
+ arg_types);
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (!result)
+ result = TYPE_MAIN_VARIANT (t);
+ return cp_build_qualified_type (result, cp_type_quals (t));
}
+
/* Makes a copy of BINFO and TYPE, which is to be inherited into a
graph dominated by T. If BINFO is NULL, TYPE is a dependent base,
@@ -1200,7 +1293,8 @@ get_first_fn (tree from)
{
gcc_assert (is_overloaded_fn (from));
/* A baselink is also considered an overloaded function. */
- if (TREE_CODE (from) == COMPONENT_REF)
+ if (TREE_CODE (from) == OFFSET_REF
+ || TREE_CODE (from) == COMPONENT_REF)
from = TREE_OPERAND (from, 1);
if (BASELINK_P (from))
from = BASELINK_FUNCTIONS (from);
@@ -1264,10 +1358,15 @@ cxx_printable_name_internal (tree decl, int v, bool translate)
if (current_function_decl != NULL_TREE)
{
- if (uid_ring[ring_counter] == DECL_UID (current_function_decl))
- ring_counter += 1;
- if (ring_counter == PRINT_RING_SIZE)
- ring_counter = 0;
+ /* There may be both translated and untranslated versions of the
+ name cached. */
+ for (i = 0; i < 2; i++)
+ {
+ if (uid_ring[ring_counter] == DECL_UID (current_function_decl))
+ ring_counter += 1;
+ if (ring_counter == PRINT_RING_SIZE)
+ ring_counter = 0;
+ }
gcc_assert (uid_ring[ring_counter] != DECL_UID (current_function_decl));
}
@@ -1323,7 +1422,8 @@ bind_template_template_parm (tree t, tree newargs)
tree t2;
t2 = cxx_make_type (BOUND_TEMPLATE_TEMPLATE_PARM);
- decl = build_decl (TYPE_DECL, DECL_NAME (decl), NULL_TREE);
+ decl = build_decl (input_location,
+ TYPE_DECL, DECL_NAME (decl), NULL_TREE);
/* These nodes have to be created to reflect new TYPE_DECL and template
arguments. */
@@ -1713,9 +1813,9 @@ build_min_non_dep (enum tree_code code, tree non_dep, ...)
built. */
tree
-build_min_non_dep_call_list (tree non_dep, tree fn, tree arglist)
+build_min_non_dep_call_vec (tree non_dep, tree fn, VEC(tree,gc) *argvec)
{
- tree t = build_nt_call_list (fn, arglist);
+ tree t = build_nt_call_vec (fn, argvec);
TREE_TYPE (t) = TREE_TYPE (non_dep);
TREE_SIDE_EFFECTS (t) = TREE_SIDE_EFFECTS (non_dep);
return t;
@@ -2150,7 +2250,7 @@ pod_type_p (const_tree t)
if (t == error_mark_node)
return 1;
- if (INTEGRAL_TYPE_P (t))
+ if (INTEGRAL_OR_ENUMERATION_TYPE_P (t))
return 1; /* integral, character or enumeral type */
if (FLOAT_TYPE_P (t))
return 1;
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 4486b9065a1..e3ed871f718 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -48,7 +48,7 @@ along with GCC; see the file COPYING3. If not see
static tree pfn_from_ptrmemfunc (tree);
static tree delta_from_ptrmemfunc (tree);
static tree convert_for_assignment (tree, tree, const char *, tree, int,
- tsubst_flags_t);
+ tsubst_flags_t, int);
static tree cp_pointer_int_sum (enum tree_code, tree, tree);
static tree rationalize_conditional_expr (enum tree_code, tree,
tsubst_flags_t);
@@ -61,7 +61,7 @@ static void casts_away_constness_r (tree *, tree *);
static bool casts_away_constness (tree, tree);
static void maybe_warn_about_returning_address_of_local (tree);
static tree lookup_destructor (tree, tree, tree);
-static int convert_arguments (int, tree *, tree, tree, tree, int,
+static int convert_arguments (tree, VEC(tree,gc) **, tree, int,
tsubst_flags_t);
/* Do `exp = require_complete_type (exp);' to make sure exp
@@ -260,6 +260,19 @@ cp_common_type (tree t1, tree t2)
enum tree_code code2 = TREE_CODE (t2);
tree attributes;
+ /* In what follows, we slightly generalize the rules given in [expr] so
+ as to deal with `long long' and `complex'. First, merge the
+ attributes. */
+ attributes = (*targetm.merge_type_attributes) (t1, t2);
+
+ if (SCOPED_ENUM_P (t1) || SCOPED_ENUM_P (t2))
+ {
+ if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
+ return build_type_attribute_variant (t1, attributes);
+ else
+ return NULL_TREE;
+ }
+
/* FIXME: Attributes. */
gcc_assert (ARITHMETIC_TYPE_P (t1)
|| TREE_CODE (t1) == VECTOR_TYPE
@@ -268,11 +281,6 @@ cp_common_type (tree t1, tree t2)
|| TREE_CODE (t2) == VECTOR_TYPE
|| UNSCOPED_ENUM_P (t2));
- /* In what follows, we slightly generalize the rules given in [expr] so
- as to deal with `long long' and `complex'. First, merge the
- attributes. */
- attributes = (*targetm.merge_type_attributes) (t1, t2);
-
/* If one type is complex, form the common type of the non-complex
components, then make that complex. Use T1 or T2 if it is the
required type. */
@@ -1341,7 +1349,7 @@ cxx_sizeof_or_alignof_type (tree type, enum tree_code op, bool complain)
return value;
}
- return c_sizeof_or_alignof_type (complete_type (type),
+ return c_sizeof_or_alignof_type (input_location, complete_type (type),
op == SIZEOF_EXPR,
complain);
}
@@ -1699,10 +1707,14 @@ decay_conversion (tree exp)
tree
default_conversion (tree exp)
{
+ /* Check for target-specific promotions. */
+ tree promoted_type = targetm.promoted_type (TREE_TYPE (exp));
+ if (promoted_type)
+ exp = cp_convert (promoted_type, exp);
/* Perform the integral promotions first so that bitfield
expressions (which may promote to "int", even if the bitfield is
declared "unsigned") are promoted correctly. */
- if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (exp)))
+ else if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (exp)))
exp = perform_integral_promotions (exp);
/* Perform the other conversions. */
exp = decay_conversion (exp);
@@ -2007,7 +2019,7 @@ build_class_member_access_expr (tree object, tree member,
if (null_object_p && warn_invalid_offsetof
&& CLASSTYPE_NON_POD_P (object_type)
&& !DECL_FIELD_IS_BASE (member)
- && !skip_evaluation
+ && cp_unevaluated_operand == 0
&& (complain & tf_warning))
{
warning (OPT_Winvalid_offsetof,
@@ -2437,6 +2449,10 @@ build_x_indirect_ref (tree expr, const char *errorstring,
if (processing_template_decl)
{
+ /* Retain the type if we know the operand is a pointer so that
+ describable_type doesn't make auto deduction break. */
+ if (TREE_TYPE (expr) && POINTER_TYPE_P (TREE_TYPE (expr)))
+ return build_min (INDIRECT_REF, TREE_TYPE (TREE_TYPE (expr)), expr);
if (type_dependent_expression_p (expr))
return build_min_nt (INDIRECT_REF, expr);
expr = build_non_dependent_expr (expr);
@@ -2482,12 +2498,8 @@ cp_build_indirect_ref (tree ptr, const char *errorstring,
/* [expr.unary.op]
If the type of the expression is "pointer to T," the type
- of the result is "T."
-
- We must use the canonical variant because certain parts of
- the back end, like fold, do pointer comparisons between
- types. */
- tree t = canonical_type_variant (TREE_TYPE (type));
+ of the result is "T." */
+ tree t = TREE_TYPE (type);
if (CONVERT_EXPR_P (ptr)
|| TREE_CODE (ptr) == VIEW_CONVERT_EXPR)
@@ -2561,7 +2573,7 @@ cp_build_indirect_ref (tree ptr, const char *errorstring,
LOC is the location to use in building the array reference. */
tree
-build_array_ref (tree array, tree idx, location_t loc)
+build_array_ref (location_t loc, tree array, tree idx)
{
tree ret;
@@ -2581,7 +2593,7 @@ build_array_ref (tree array, tree idx, location_t loc)
{
case COMPOUND_EXPR:
{
- tree value = build_array_ref (TREE_OPERAND (array, 1), idx, loc);
+ tree value = build_array_ref (loc, TREE_OPERAND (array, 1), idx);
ret = build2 (COMPOUND_EXPR, TREE_TYPE (value),
TREE_OPERAND (array, 0), value);
SET_EXPR_LOCATION (ret, loc);
@@ -2591,9 +2603,9 @@ build_array_ref (tree array, tree idx, location_t loc)
case COND_EXPR:
ret = build_conditional_expr
(TREE_OPERAND (array, 0),
- build_array_ref (TREE_OPERAND (array, 1), idx, loc),
- build_array_ref (TREE_OPERAND (array, 2), idx, loc),
- tf_warning_or_error);
+ build_array_ref (loc, TREE_OPERAND (array, 1), idx),
+ build_array_ref (loc, TREE_OPERAND (array, 2), idx),
+ tf_warning_or_error);
protected_set_expr_location (ret, loc);
return ret;
@@ -2852,48 +2864,69 @@ get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function)
/* Used by the C-common bits. */
tree
-build_function_call (tree function, tree params)
+build_function_call (location_t loc ATTRIBUTE_UNUSED,
+ tree function, tree params)
{
return cp_build_function_call (function, params, tf_warning_or_error);
}
/* Used by the C-common bits. */
tree
-build_function_call_vec (tree function, VEC(tree,gc) *params,
+build_function_call_vec (location_t loc ATTRIBUTE_UNUSED,
+ tree function, VEC(tree,gc) *params,
VEC(tree,gc) *origtypes ATTRIBUTE_UNUSED)
{
- tree p;
- tree *pp;
- unsigned int i;
- tree t;
+ VEC(tree,gc) *orig_params = params;
+ tree ret = cp_build_function_call_vec (function, &params,
+ tf_warning_or_error);
- /* FIXME: Should just change cp_build_function_call to use a
- VEC. */
- p = NULL_TREE;
- pp = &p;
- for (i = 0; VEC_iterate (tree, params, i, t); ++i)
- {
- *pp = build_tree_list (NULL, t);
- pp = &TREE_CHAIN (*pp);
- }
- return cp_build_function_call (function, p, tf_warning_or_error);
+ /* cp_build_function_call_vec can reallocate PARAMS by adding
+ default arguments. That should never happen here. Verify
+ that. */
+ gcc_assert (params == orig_params);
+
+ return ret;
}
+/* Build a function call using a tree list of arguments. */
+
tree
cp_build_function_call (tree function, tree params, tsubst_flags_t complain)
{
+ VEC(tree,gc) *vec;
+ tree ret;
+
+ vec = make_tree_vector ();
+ for (; params != NULL_TREE; params = TREE_CHAIN (params))
+ VEC_safe_push (tree, gc, vec, TREE_VALUE (params));
+ ret = cp_build_function_call_vec (function, &vec, complain);
+ release_tree_vector (vec);
+ return ret;
+}
+
+/* Build a function call using a vector of arguments. PARAMS may be
+ NULL if there are no parameters. This changes the contents of
+ PARAMS. */
+
+tree
+cp_build_function_call_vec (tree function, VEC(tree,gc) **params,
+ tsubst_flags_t complain)
+{
tree fntype, fndecl;
tree name = NULL_TREE;
int is_method;
tree original = function;
- int nargs, parm_types_len;
+ int nargs;
tree *argarray;
tree parm_types;
+ VEC(tree,gc) *allocated = NULL;
+ tree ret;
/* For Objective-C, convert any calls via a cast to OBJC_TYPE_REF
expressions, like those used for ObjC messenger dispatches. */
- if (params != NULL_TREE)
- function = objc_rewrite_function_call (function, TREE_VALUE (params));
+ if (params != NULL && !VEC_empty (tree, *params))
+ function = objc_rewrite_function_call (function,
+ VEC_index (tree, *params, 0));
/* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
Strip such NOP_EXPRs, since FUNCTION is used in non-lvalue context. */
@@ -2953,57 +2986,55 @@ cp_build_function_call (tree function, tree params, tsubst_flags_t complain)
fntype = TREE_TYPE (fntype);
parm_types = TYPE_ARG_TYPES (fntype);
- /* Allocate storage for converted arguments. */
- parm_types_len = list_length (parm_types);
- nargs = list_length (params);
- if (parm_types_len > nargs)
- nargs = parm_types_len;
- argarray = (tree *) alloca (nargs * sizeof (tree));
-
- /* Convert the parameters to the types declared in the
- function prototype, or apply default promotions. */
- nargs = convert_arguments (nargs, argarray, parm_types,
- params, fndecl, LOOKUP_NORMAL,
- complain);
+ if (params == NULL)
+ {
+ allocated = make_tree_vector ();
+ params = &allocated;
+ }
+
+ nargs = convert_arguments (parm_types, params, fndecl, LOOKUP_NORMAL,
+ complain);
if (nargs < 0)
return error_mark_node;
+ argarray = VEC_address (tree, *params);
+
/* Check for errors in format strings and inappropriately
null parameters. */
check_function_arguments (TYPE_ATTRIBUTES (fntype), nargs, argarray,
parm_types);
- return build_cxx_call (function, nargs, argarray);
+ ret = build_cxx_call (function, nargs, argarray);
+
+ if (allocated != NULL)
+ release_tree_vector (allocated);
+
+ return ret;
}
-/* Convert the actual parameter expressions in the list VALUES
- to the types in the list TYPELIST.
+/* Convert the actual parameter expressions in the list VALUES to the
+ types in the list TYPELIST. The converted expressions are stored
+ back in the VALUES vector.
If parmdecls is exhausted, or when an element has NULL as its type,
perform the default conversions.
- Store the converted arguments in ARGARRAY. NARGS is the size of this array.
-
NAME is an IDENTIFIER_NODE or 0. It is used only for error messages.
This is also where warnings about wrong number of args are generated.
Returns the actual number of arguments processed (which might be less
- than NARGS), or -1 on error.
-
- VALUES is a chain of TREE_LIST nodes with the elements of the list
- in the TREE_VALUE slots of those nodes.
+ than the length of the vector), or -1 on error.
In C++, unspecified trailing parameters can be filled in with their
default arguments, if such were specified. Do so here. */
static int
-convert_arguments (int nargs, tree *argarray,
- tree typelist, tree values, tree fndecl, int flags,
- tsubst_flags_t complain)
+convert_arguments (tree typelist, VEC(tree,gc) **values, tree fndecl,
+ int flags, tsubst_flags_t complain)
{
- tree typetail, valtail;
+ tree typetail;
const char *called_thing = 0;
- int i = 0;
+ unsigned int i;
/* Argument passing is always copy-initialization. */
flags |= LOOKUP_ONLYCONVERTING;
@@ -3022,12 +3053,12 @@ convert_arguments (int nargs, tree *argarray,
called_thing = "function";
}
- for (valtail = values, typetail = typelist;
- valtail;
- valtail = TREE_CHAIN (valtail), i++)
+ for (i = 0, typetail = typelist;
+ i < VEC_length (tree, *values);
+ i++)
{
tree type = typetail ? TREE_VALUE (typetail) : 0;
- tree val = TREE_VALUE (valtail);
+ tree val = VEC_index (tree, *values, i);
if (val == error_mark_node || type == error_mark_node)
return -1;
@@ -3096,7 +3127,7 @@ convert_arguments (int nargs, tree *argarray,
if (parmval == error_mark_node)
return -1;
- argarray[i] = parmval;
+ VEC_replace (tree, *values, i, parmval);
}
else
{
@@ -3109,7 +3140,7 @@ convert_arguments (int nargs, tree *argarray,
else
val = convert_arg_to_ellipsis (val);
- argarray[i] = val;
+ VEC_replace (tree, *values, i, val);
}
if (typetail)
@@ -3138,7 +3169,7 @@ convert_arguments (int nargs, tree *argarray,
if (parmval == error_mark_node)
return -1;
- argarray[i] = parmval;
+ VEC_safe_push (tree, gc, *values, parmval);
typetail = TREE_CHAIN (typetail);
/* ends with `...'. */
if (typetail == NULL_TREE)
@@ -3162,8 +3193,7 @@ convert_arguments (int nargs, tree *argarray,
}
}
- gcc_assert (i <= nargs);
- return i;
+ return (int) i;
}
/* Build a binary-operation expression, after performing default
@@ -3492,7 +3522,11 @@ cp_build_binary_op (location_t location,
case FLOOR_MOD_EXPR:
warn_for_div_by_zero (location, op1);
- if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
+ if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE
+ && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE
+ && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE)
+ common = 1;
+ else if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
{
/* Although it would be tempting to shorten always here, that loses
on some targets, since the modulo instruction is undefined if the
@@ -3525,13 +3559,15 @@ cp_build_binary_op (location_t location,
{
if (tree_int_cst_lt (op1, integer_zero_node))
{
- if (complain & tf_warning)
+ if ((complain & tf_warning)
+ && c_inhibit_evaluation_warnings == 0)
warning (0, "right shift count is negative");
}
else
{
if (compare_tree_int (op1, TYPE_PRECISION (type0)) >= 0
- && (complain & tf_warning))
+ && (complain & tf_warning)
+ && c_inhibit_evaluation_warnings == 0)
warning (0, "right shift count >= width of type");
}
}
@@ -3552,12 +3588,14 @@ cp_build_binary_op (location_t location,
{
if (tree_int_cst_lt (op1, integer_zero_node))
{
- if (complain & tf_warning)
+ if ((complain & tf_warning)
+ && c_inhibit_evaluation_warnings == 0)
warning (0, "left shift count is negative");
}
else if (compare_tree_int (op1, TYPE_PRECISION (type0)) >= 0)
{
- if (complain & tf_warning)
+ if ((complain & tf_warning)
+ && c_inhibit_evaluation_warnings == 0)
warning (0, "left shift count >= width of type");
}
}
@@ -3612,9 +3650,9 @@ cp_build_binary_op (location_t location,
build_type = boolean_type_node;
if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
- || code0 == COMPLEX_TYPE)
+ || code0 == COMPLEX_TYPE || code0 == ENUMERAL_TYPE)
&& (code1 == INTEGER_TYPE || code1 == REAL_TYPE
- || code1 == COMPLEX_TYPE))
+ || code1 == COMPLEX_TYPE || code1 == ENUMERAL_TYPE))
short_compare = 1;
else if ((code0 == POINTER_TYPE && code1 == POINTER_TYPE)
|| (TYPE_PTRMEM_P (type0) && TYPE_PTRMEM_P (type1)))
@@ -3886,9 +3924,10 @@ cp_build_binary_op (location_t location,
break;
}
- if (((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == COMPLEX_TYPE)
+ if (((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == COMPLEX_TYPE
+ || code0 == ENUMERAL_TYPE)
&& (code1 == INTEGER_TYPE || code1 == REAL_TYPE
- || code1 == COMPLEX_TYPE)))
+ || code1 == COMPLEX_TYPE || code1 == ENUMERAL_TYPE)))
arithmetic_types_p = 1;
else
{
@@ -4034,7 +4073,7 @@ cp_build_binary_op (location_t location,
if (TREE_OVERFLOW_P (result)
&& !TREE_OVERFLOW_P (op0)
&& !TREE_OVERFLOW_P (op1))
- overflow_warning (result);
+ overflow_warning (location, result);
return result;
}
@@ -4141,8 +4180,20 @@ build_x_unary_op (enum tree_code code, tree xarg, tsubst_flags_t complain)
/*overloaded_p=*/NULL, complain);
if (!exp && code == ADDR_EXPR)
{
- /* A pointer to member-function can be formed only by saying
- &X::mf. */
+ if (is_overloaded_fn (xarg))
+ {
+ tree fn = get_first_fn (xarg);
+ if (DECL_CONSTRUCTOR_P (fn) || DECL_DESTRUCTOR_P (fn))
+ {
+ const char *type =
+ (DECL_CONSTRUCTOR_P (fn) ? "constructor" : "destructor");
+ error ("taking address of %s %qE", type, xarg);
+ return error_mark_node;
+ }
+ }
+
+ /* A pointer to member-function can be formed only by saying
+ &X::mf. */
if (!flag_ms_extensions && TREE_CODE (TREE_TYPE (xarg)) == METHOD_TYPE
&& (TREE_CODE (xarg) != OFFSET_REF || !PTRMEM_OK_P (xarg)))
{
@@ -4974,6 +5025,34 @@ tree build_x_compound_expr_from_list (tree list, const char *msg)
return expr;
}
+/* Like build_x_compound_expr_from_list, but using a VEC. */
+
+tree
+build_x_compound_expr_from_vec (VEC(tree,gc) *vec, const char *msg)
+{
+ if (VEC_empty (tree, vec))
+ return NULL_TREE;
+ else if (VEC_length (tree, vec) == 1)
+ return VEC_index (tree, vec, 0);
+ else
+ {
+ tree expr;
+ unsigned int ix;
+ tree t;
+
+ if (msg != NULL)
+ permerror (input_location,
+ "%s expression list treated as compound expression",
+ msg);
+
+ expr = VEC_index (tree, vec, 0);
+ for (ix = 1; VEC_iterate (tree, vec, ix, t); ++ix)
+ expr = build_x_compound_expr (expr, t, tf_warning_or_error);
+
+ return expr;
+ }
+}
+
/* Handle overloading of the ',' operator when needed. */
tree
@@ -5006,7 +5085,7 @@ build_x_compound_expr (tree op1, tree op2, tsubst_flags_t complain)
/* Like cp_build_compound_expr, but for the c-common bits. */
tree
-build_compound_expr (tree lhs, tree rhs)
+build_compound_expr (location_t loc ATTRIBUTE_UNUSED, tree lhs, tree rhs)
{
return cp_build_compound_expr (lhs, rhs, tf_warning_or_error);
}
@@ -5284,8 +5363,10 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p,
/* The effect of all that is that any conversion between any two
types which are integral, floating, or enumeration types can be
performed. */
- if ((INTEGRAL_TYPE_P (type) || SCALAR_FLOAT_TYPE_P (type))
- && (INTEGRAL_TYPE_P (intype) || SCALAR_FLOAT_TYPE_P (intype)))
+ if ((INTEGRAL_OR_ENUMERATION_TYPE_P (type)
+ || SCALAR_FLOAT_TYPE_P (type))
+ && (INTEGRAL_OR_ENUMERATION_TYPE_P (intype)
+ || SCALAR_FLOAT_TYPE_P (intype)))
{
expr = ocp_convert (type, expr, CONV_C_CAST, LOOKUP_NORMAL);
@@ -5585,7 +5666,8 @@ build_reinterpret_cast_1 (tree type, tree expr, bool c_cast_p,
}
else if (TREE_CODE (type) == VECTOR_TYPE)
return fold_if_not_in_template (convert_to_vector (type, expr));
- else if (TREE_CODE (intype) == VECTOR_TYPE && INTEGRAL_TYPE_P (type))
+ else if (TREE_CODE (intype) == VECTOR_TYPE
+ && INTEGRAL_OR_ENUMERATION_TYPE_P (type))
return fold_if_not_in_template (convert_to_integer (type, expr));
else
{
@@ -5760,7 +5842,7 @@ build_const_cast (tree type, tree expr, tsubst_flags_t complain)
/* Like cp_build_c_cast, but for the c-common bits. */
tree
-build_c_cast (tree type, tree expr)
+build_c_cast (location_t loc ATTRIBUTE_UNUSED, tree type, tree expr)
{
return cp_build_c_cast (type, expr, tf_warning_or_error);
}
@@ -5877,7 +5959,8 @@ cp_build_c_cast (tree type, tree expr, tsubst_flags_t complain)
tree
build_modify_expr (location_t location ATTRIBUTE_UNUSED,
tree lhs, tree lhs_origtype ATTRIBUTE_UNUSED,
- enum tree_code modifycode, tree rhs,
+ enum tree_code modifycode,
+ location_t rhs_location ATTRIBUTE_UNUSED, tree rhs,
tree rhs_origtype ATTRIBUTE_UNUSED)
{
return cp_build_modify_expr (lhs, modifycode, rhs, tf_warning_or_error);
@@ -6005,8 +6088,11 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
if (modifycode == INIT_EXPR)
{
- if (TREE_CODE (rhs) == CONSTRUCTOR)
+ if (BRACE_ENCLOSED_INITIALIZER_P (rhs))
+ /* Do the default thing. */;
+ else if (TREE_CODE (rhs) == CONSTRUCTOR)
{
+ /* Compound literal. */
if (! same_type_p (TREE_TYPE (rhs), lhstype))
/* Call convert to generate an error; see PR 11063. */
rhs = convert (lhstype, rhs);
@@ -6018,10 +6104,11 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
/* Do the default thing. */;
else
{
+ VEC(tree,gc) *rhs_vec = make_tree_vector_single (rhs);
result = build_special_member_call (lhs, complete_ctor_identifier,
- build_tree_list (NULL_TREE, rhs),
- lhstype, LOOKUP_NORMAL,
+ &rhs_vec, lhstype, LOOKUP_NORMAL,
complain);
+ release_tree_vector (rhs_vec);
if (result == NULL_TREE)
return error_mark_node;
return result;
@@ -6145,12 +6232,14 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
}
if (modifycode == INIT_EXPR)
+ /* Calls with INIT_EXPR are all direct-initialization, so don't set
+ LOOKUP_ONLYCONVERTING. */
newrhs = convert_for_initialization (lhs, olhstype, newrhs, LOOKUP_NORMAL,
"initialization", NULL_TREE, 0,
complain);
else
newrhs = convert_for_assignment (olhstype, newrhs, "assignment",
- NULL_TREE, 0, complain);
+ NULL_TREE, 0, complain, LOOKUP_IMPLICIT);
if (!same_type_p (lhstype, olhstype))
newrhs = cp_convert_and_check (lhstype, newrhs);
@@ -6419,7 +6508,7 @@ build_ptrmemfunc (tree type, tree pfn, int force, bool c_cast_p)
/* Handle null pointer to member function conversions. */
if (integer_zerop (pfn))
{
- pfn = build_c_cast (type, integer_zero_node);
+ pfn = build_c_cast (input_location, type, integer_zero_node);
return build_ptrmemfunc1 (to_type,
integer_zero_node,
pfn);
@@ -6556,7 +6645,7 @@ delta_from_ptrmemfunc (tree t)
static tree
convert_for_assignment (tree type, tree rhs,
const char *errtype, tree fndecl, int parmnum,
- tsubst_flags_t complain)
+ tsubst_flags_t complain, int flags)
{
tree rhstype;
enum tree_code coder;
@@ -6623,7 +6712,7 @@ convert_for_assignment (tree type, tree rhs,
We allow bad conversions here because by the time we get to this point
we are committed to doing the conversion. If we end up doing a bad
conversion, convert_like will complain. */
- if (!can_convert_arg_bad (type, rhstype, rhs))
+ if (!can_convert_arg_bad (type, rhstype, rhs, flags))
{
/* When -Wno-pmf-conversions is use, we just silently allow
conversions from pointers-to-members to plain pointers. If
@@ -6677,7 +6766,8 @@ convert_for_assignment (tree type, tree rhs,
TREE_NO_WARNING (rhs) = 1;
}
- return perform_implicit_conversion (strip_top_quals (type), rhs, complain);
+ return perform_implicit_conversion_flags (strip_top_quals (type), rhs,
+ complain, flags);
}
/* Convert RHS to be of type TYPE.
@@ -6768,7 +6858,7 @@ convert_for_initialization (tree exp, tree type, tree rhs, int flags,
return ocp_convert (type, rhs, CONV_IMPLICIT|CONV_FORCE_TEMP, flags);
return convert_for_assignment (type, rhs, errtype, fndecl, parmnum,
- complain);
+ complain, flags);
}
/* If RETVAL is the address of, or a reference to, a local variable or
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index 5ed7818732f..8bec2217189 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -516,7 +516,7 @@ split_nonconstant_init_1 (tree dest, tree init)
NULL_TREE);
code = build2 (INIT_EXPR, inner_type, sub, value);
- code = build_stmt (EXPR_STMT, code);
+ code = build_stmt (input_location, EXPR_STMT, code);
add_stmt (code);
continue;
}
@@ -530,7 +530,7 @@ split_nonconstant_init_1 (tree dest, tree init)
tree cons = copy_node (init);
CONSTRUCTOR_ELTS (init) = NULL;
code = build2 (MODIFY_EXPR, type, dest, cons);
- code = build_stmt (EXPR_STMT, code);
+ code = build_stmt (input_location, EXPR_STMT, code);
add_stmt (code);
}
break;
@@ -586,7 +586,7 @@ split_nonconstant_init (tree dest, tree init)
for static variable. In that case, caller must emit the code. */
tree
-store_init_value (tree decl, tree init)
+store_init_value (tree decl, tree init, int flags)
{
tree value, type;
@@ -628,7 +628,7 @@ store_init_value (tree decl, tree init)
/* End of special C++ code. */
/* Digest the specified initializer into an expression. */
- value = digest_init (type, init);
+ value = digest_init_flags (type, init, flags);
/* If the initializer is not a constant, fill in DECL_INITIAL with
the bits that are constant, and then return an expression that
will perform the dynamic initialization. */
@@ -717,7 +717,7 @@ check_narrowing (tree type, tree init)
NESTED is true iff we are being called for an element of a CONSTRUCTOR. */
static tree
-digest_init_r (tree type, tree init, bool nested)
+digest_init_r (tree type, tree init, bool nested, int flags)
{
enum tree_code code = TREE_CODE (type);
@@ -796,9 +796,9 @@ digest_init_r (tree type, tree init, bool nested)
if (cxx_dialect != cxx98 && nested)
check_narrowing (type, init);
- init = convert_for_initialization (0, type, init, LOOKUP_NORMAL,
+ init = convert_for_initialization (0, type, init, flags,
"initialization", NULL_TREE, 0,
- tf_warning_or_error);
+ tf_warning_or_error);
exp = &init;
/* Skip any conversions since we'll be outputting the underlying
@@ -842,7 +842,7 @@ digest_init_r (tree type, tree init, bool nested)
}
return convert_for_initialization (NULL_TREE, type, init,
- LOOKUP_NORMAL | LOOKUP_ONLYCONVERTING,
+ flags,
"initialization", NULL_TREE, 0,
tf_warning_or_error);
}
@@ -851,7 +851,13 @@ digest_init_r (tree type, tree init, bool nested)
tree
digest_init (tree type, tree init)
{
- return digest_init_r (type, init, false);
+ return digest_init_r (type, init, false, LOOKUP_IMPLICIT);
+}
+
+tree
+digest_init_flags (tree type, tree init, int flags)
+{
+ return digest_init_r (type, init, false, flags);
}
/* Set of flags used within process_init_constructor to describe the
@@ -924,7 +930,7 @@ process_init_constructor_array (tree type, tree init)
else
ce->index = size_int (i);
gcc_assert (ce->value);
- ce->value = digest_init_r (TREE_TYPE (type), ce->value, true);
+ ce->value = digest_init_r (TREE_TYPE (type), ce->value, true, LOOKUP_IMPLICIT);
if (ce->value != error_mark_node)
gcc_assert (same_type_ignoring_top_level_qualifiers_p
@@ -1031,7 +1037,7 @@ process_init_constructor_record (tree type, tree init)
}
gcc_assert (ce->value);
- next = digest_init_r (type, ce->value, true);
+ next = digest_init_r (type, ce->value, true, LOOKUP_IMPLICIT);
++idx;
}
else if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (field)))
@@ -1046,7 +1052,7 @@ process_init_constructor_record (tree type, tree init)
else
next = build_constructor (init_list_type_node, NULL);
- next = digest_init_r (TREE_TYPE (field), next, true);
+ next = digest_init_r (TREE_TYPE (field), next, true, LOOKUP_IMPLICIT);
/* Warn when some struct elements are implicitly initialized. */
warning (OPT_Wmissing_field_initializers,
@@ -1156,7 +1162,7 @@ process_init_constructor_union (tree type, tree init)
}
if (ce->value && ce->value != error_mark_node)
- ce->value = digest_init_r (TREE_TYPE (ce->index), ce->value, true);
+ ce->value = digest_init_r (TREE_TYPE (ce->index), ce->value, true, LOOKUP_IMPLICIT);
return picflag_from_initializer (ce->value);
}
@@ -1436,6 +1442,7 @@ build_functional_cast (tree exp, tree parms, tsubst_flags_t complain)
/* The type to which we are casting. */
tree type;
+ VEC(tree,gc) *parmvec;
if (exp == error_mark_node || parms == error_mark_node)
return error_mark_node;
@@ -1506,8 +1513,12 @@ build_functional_cast (tree exp, tree parms, tsubst_flags_t complain)
}
/* Call the constructor. */
- exp = build_special_member_call (NULL_TREE, complete_ctor_identifier, parms,
- type, LOOKUP_NORMAL, complain);
+ parmvec = make_tree_vector ();
+ for (; parms != NULL_TREE; parms = TREE_CHAIN (parms))
+ VEC_safe_push (tree, gc, parmvec, TREE_VALUE (parms));
+ exp = build_special_member_call (NULL_TREE, complete_ctor_identifier,
+ &parmvec, type, LOOKUP_NORMAL, complain);
+ release_tree_vector (parmvec);
if (exp == error_mark_node)
return error_mark_node;
diff --git a/gcc/cse.c b/gcc/cse.c
index 0497f77ebbd..108f9e19127 100644
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -502,6 +502,11 @@ struct table_elt
#define REGNO_QTY_VALID_P(N) (REG_QTY (N) >= 0)
+/* Compare table_elt X and Y and return true iff X is cheaper than Y. */
+
+#define CHEAPER(X, Y) \
+ (preferable ((X)->cost, (X)->regcost, (Y)->cost, (Y)->regcost) < 0)
+
static struct table_elt *table[HASH_SIZE];
/* Chain of `struct table_elt's made so far for this function
@@ -563,6 +568,8 @@ static void remove_pseudo_from_table (rtx, unsigned);
static struct table_elt *lookup (rtx, unsigned, enum machine_mode);
static struct table_elt *lookup_for_remove (rtx, unsigned, enum machine_mode);
static rtx lookup_as_function (rtx, enum rtx_code);
+static struct table_elt *insert_with_costs (rtx, struct table_elt *, unsigned,
+ enum machine_mode, int, int);
static struct table_elt *insert (rtx, struct table_elt *, unsigned,
enum machine_mode);
static void merge_equiv_classes (struct table_elt *, struct table_elt *);
@@ -1213,6 +1220,174 @@ insert_regs (rtx x, struct table_elt *classp, int modified)
return mention_regs (x);
}
+
+/* Compute upper and lower anchors for CST. Also compute the offset of CST
+ from these anchors/bases such that *_BASE + *_OFFS = CST. Return false iff
+ CST is equal to an anchor. */
+
+static bool
+compute_const_anchors (rtx cst,
+ HOST_WIDE_INT *lower_base, HOST_WIDE_INT *lower_offs,
+ HOST_WIDE_INT *upper_base, HOST_WIDE_INT *upper_offs)
+{
+ HOST_WIDE_INT n = INTVAL (cst);
+
+ *lower_base = n & ~(targetm.const_anchor - 1);
+ if (*lower_base == n)
+ return false;
+
+ *upper_base =
+ (n + (targetm.const_anchor - 1)) & ~(targetm.const_anchor - 1);
+ *upper_offs = n - *upper_base;
+ *lower_offs = n - *lower_base;
+ return true;
+}
+
+/* Insert the equivalence between ANCHOR and (REG + OFF) in mode MODE. */
+
+static void
+insert_const_anchor (HOST_WIDE_INT anchor, rtx reg, HOST_WIDE_INT offs,
+ enum machine_mode mode)
+{
+ struct table_elt *elt;
+ unsigned hash;
+ rtx anchor_exp;
+ rtx exp;
+
+ anchor_exp = GEN_INT (anchor);
+ hash = HASH (anchor_exp, mode);
+ elt = lookup (anchor_exp, hash, mode);
+ if (!elt)
+ elt = insert (anchor_exp, NULL, hash, mode);
+
+ exp = plus_constant (reg, offs);
+ /* REG has just been inserted and the hash codes recomputed. */
+ mention_regs (exp);
+ hash = HASH (exp, mode);
+
+ /* Use the cost of the register rather than the whole expression. When
+ looking up constant anchors we will further offset the corresponding
+ expression therefore it does not make sense to prefer REGs over
+ reg-immediate additions. Prefer instead the oldest expression. Also
+ don't prefer pseudos over hard regs so that we derive constants in
+ argument registers from other argument registers rather than from the
+ original pseudo that was used to synthesize the constant. */
+ insert_with_costs (exp, elt, hash, mode, COST (reg), 1);
+}
+
+/* The constant CST is equivalent to the register REG. Create
+ equivalences between the two anchors of CST and the corresponding
+ register-offset expressions using REG. */
+
+static void
+insert_const_anchors (rtx reg, rtx cst, enum machine_mode mode)
+{
+ HOST_WIDE_INT lower_base, lower_offs, upper_base, upper_offs;
+
+ if (!compute_const_anchors (cst, &lower_base, &lower_offs,
+ &upper_base, &upper_offs))
+ return;
+
+ /* Ignore anchors of value 0. Constants accessible from zero are
+ simple. */
+ if (lower_base != 0)
+ insert_const_anchor (lower_base, reg, -lower_offs, mode);
+
+ if (upper_base != 0)
+ insert_const_anchor (upper_base, reg, -upper_offs, mode);
+}
+
+/* We need to express ANCHOR_ELT->exp + OFFS. Walk the equivalence list of
+ ANCHOR_ELT and see if offsetting any of the entries by OFFS would create a
+ valid expression. Return the cheapest and oldest of such expressions. In
+ *OLD, return how old the resulting expression is compared to the other
+ equivalent expressions. */
+
+static rtx
+find_reg_offset_for_const (struct table_elt *anchor_elt, HOST_WIDE_INT offs,
+ unsigned *old)
+{
+ struct table_elt *elt;
+ unsigned idx;
+ struct table_elt *match_elt;
+ rtx match;
+
+ /* Find the cheapest and *oldest* expression to maximize the chance of
+ reusing the same pseudo. */
+
+ match_elt = NULL;
+ match = NULL_RTX;
+ for (elt = anchor_elt->first_same_value, idx = 0;
+ elt;
+ elt = elt->next_same_value, idx++)
+ {
+ if (match_elt && CHEAPER (match_elt, elt))
+ return match;
+
+ if (REG_P (elt->exp)
+ || (GET_CODE (elt->exp) == PLUS
+ && REG_P (XEXP (elt->exp, 0))
+ && GET_CODE (XEXP (elt->exp, 1)) == CONST_INT))
+ {
+ rtx x;
+
+ /* Ignore expressions that are no longer valid. */
+ if (!REG_P (elt->exp) && !exp_equiv_p (elt->exp, elt->exp, 1, false))
+ continue;
+
+ x = plus_constant (elt->exp, offs);
+ if (REG_P (x)
+ || (GET_CODE (x) == PLUS
+ && IN_RANGE (INTVAL (XEXP (x, 1)),
+ -targetm.const_anchor,
+ targetm.const_anchor - 1)))
+ {
+ match = x;
+ match_elt = elt;
+ *old = idx;
+ }
+ }
+ }
+
+ return match;
+}
+
+/* Try to express the constant SRC_CONST using a register+offset expression
+ derived from a constant anchor. Return it if successful or NULL_RTX,
+ otherwise. */
+
+static rtx
+try_const_anchors (rtx src_const, enum machine_mode mode)
+{
+ struct table_elt *lower_elt, *upper_elt;
+ HOST_WIDE_INT lower_base, lower_offs, upper_base, upper_offs;
+ rtx lower_anchor_rtx, upper_anchor_rtx;
+ rtx lower_exp = NULL_RTX, upper_exp = NULL_RTX;
+ unsigned lower_old, upper_old;
+
+ if (!compute_const_anchors (src_const, &lower_base, &lower_offs,
+ &upper_base, &upper_offs))
+ return NULL_RTX;
+
+ lower_anchor_rtx = GEN_INT (lower_base);
+ upper_anchor_rtx = GEN_INT (upper_base);
+ lower_elt = lookup (lower_anchor_rtx, HASH (lower_anchor_rtx, mode), mode);
+ upper_elt = lookup (upper_anchor_rtx, HASH (upper_anchor_rtx, mode), mode);
+
+ if (lower_elt)
+ lower_exp = find_reg_offset_for_const (lower_elt, lower_offs, &lower_old);
+ if (upper_elt)
+ upper_exp = find_reg_offset_for_const (upper_elt, upper_offs, &upper_old);
+
+ if (!lower_exp)
+ return upper_exp;
+ if (!upper_exp)
+ return lower_exp;
+
+ /* Return the older expression. */
+ return (upper_old > lower_old ? upper_exp : lower_exp);
+}
+
/* Look in or update the hash table. */
/* Remove table element ELT from use in the table.
@@ -1380,11 +1555,11 @@ lookup_as_function (rtx x, enum rtx_code code)
return 0;
}
-/* Insert X in the hash table, assuming HASH is its hash code
- and CLASSP is an element of the class it should go in
- (or 0 if a new class should be made).
- It is inserted at the proper position to keep the class in
- the order cheapest first.
+/* Insert X in the hash table, assuming HASH is its hash code and
+ CLASSP is an element of the class it should go in (or 0 if a new
+ class should be made). COST is the code of X and reg_cost is the
+ cost of registers in X. It is inserted at the proper position to
+ keep the class in the order cheapest first.
MODE is the machine-mode of X, or if X is an integer constant
with VOIDmode then MODE is the mode with which X will be used.
@@ -1404,11 +1579,9 @@ lookup_as_function (rtx x, enum rtx_code code)
If necessary, update table showing constant values of quantities. */
-#define CHEAPER(X, Y) \
- (preferable ((X)->cost, (X)->regcost, (Y)->cost, (Y)->regcost) < 0)
-
static struct table_elt *
-insert (rtx x, struct table_elt *classp, unsigned int hash, enum machine_mode mode)
+insert_with_costs (rtx x, struct table_elt *classp, unsigned int hash,
+ enum machine_mode mode, int cost, int reg_cost)
{
struct table_elt *elt;
@@ -1430,8 +1603,8 @@ insert (rtx x, struct table_elt *classp, unsigned int hash, enum machine_mode mo
elt->exp = x;
elt->canon_exp = NULL_RTX;
- elt->cost = COST (x);
- elt->regcost = approx_reg_cost (x);
+ elt->cost = cost;
+ elt->regcost = reg_cost;
elt->next_same_value = 0;
elt->prev_same_value = 0;
elt->next_same_hash = table[hash];
@@ -1566,6 +1739,17 @@ insert (rtx x, struct table_elt *classp, unsigned int hash, enum machine_mode mo
return elt;
}
+
+/* Wrap insert_with_costs by passing the default costs. */
+
+static struct table_elt *
+insert (rtx x, struct table_elt *classp, unsigned int hash,
+ enum machine_mode mode)
+{
+ return
+ insert_with_costs (x, classp, hash, mode, COST (x), approx_reg_cost (x));
+}
+
/* Given two equivalence classes, CLASS1 and CLASS2, put all the entries from
CLASS2 into CLASS1. This is done when we have reached an insn which makes
@@ -4255,6 +4439,7 @@ cse_insn (rtx insn)
rtx src_eqv_here;
rtx src_const = 0;
rtx src_related = 0;
+ bool src_related_is_const_anchor = false;
struct table_elt *src_const_elt = 0;
int src_cost = MAX_COST;
int src_eqv_cost = MAX_COST;
@@ -4604,6 +4789,19 @@ cse_insn (rtx insn)
}
#endif /* LOAD_EXTEND_OP */
+ /* Try to express the constant using a register+offset expression
+ derived from a constant anchor. */
+
+ if (targetm.const_anchor
+ && !src_related
+ && src_const
+ && GET_CODE (src_const) == CONST_INT)
+ {
+ src_related = try_const_anchors (src_const, mode);
+ src_related_is_const_anchor = src_related != NULL_RTX;
+ }
+
+
if (src == src_folded)
src_folded = 0;
@@ -4708,6 +4906,18 @@ cse_insn (rtx insn)
{
src_related_cost = COST (src_related);
src_related_regcost = approx_reg_cost (src_related);
+
+ /* If a const-anchor is used to synthesize a constant that
+ normally requires multiple instructions then slightly prefer
+ it over the original sequence. These instructions are likely
+ to become redundant now. We can't compare against the cost
+ of src_eqv_here because, on MIPS for example, multi-insn
+ constants have zero cost; they are assumed to be hoisted from
+ loops. */
+ if (src_related_is_const_anchor
+ && src_related_cost == src_cost
+ && src_eqv_here)
+ src_related_cost--;
}
}
@@ -5442,6 +5652,14 @@ cse_insn (rtx insn)
elt = insert (dest, sets[i].src_elt,
sets[i].dest_hash, GET_MODE (dest));
+ /* If this is a constant, insert the constant anchors with the
+ equivalent register-offset expressions using register DEST. */
+ if (targetm.const_anchor
+ && REG_P (dest)
+ && SCALAR_INT_MODE_P (GET_MODE (dest))
+ && GET_CODE (sets[i].src_elt->exp) == CONST_INT)
+ insert_const_anchors (dest, sets[i].src_elt->exp, GET_MODE (dest));
+
elt->in_memory = (MEM_P (sets[i].inner_dest)
&& !MEM_READONLY_P (sets[i].inner_dest));
diff --git a/gcc/dbxout.c b/gcc/dbxout.c
index dd05076bb63..17fdf6efed1 100644
--- a/gcc/dbxout.c
+++ b/gcc/dbxout.c
@@ -275,8 +275,6 @@ static const char *base_input_file;
#include "gstab.h"
-#define STAB_CODE_TYPE enum __stab_debug_code
-
/* 1 if PARM is passed to this function in memory. */
#define PARM_PASSED_IN_MEMORY(PARM) \
@@ -318,15 +316,15 @@ static void dbxout_args (tree);
static void dbxout_type_fields (tree);
static void dbxout_type_method_1 (tree);
static void dbxout_type_methods (tree);
-static void dbxout_range_type (tree);
+static void dbxout_range_type (tree, tree, tree);
static void dbxout_type (tree, int);
-static bool print_int_cst_bounds_in_octal_p (tree);
+static bool print_int_cst_bounds_in_octal_p (tree, tree, tree);
static bool is_fortran (void);
static void dbxout_type_name (tree);
static void dbxout_class_name_qualifiers (tree);
static int dbxout_symbol_location (tree, tree, const char *, rtx);
static void dbxout_symbol_name (tree, const char *, int);
-static void dbxout_common_name (tree, const char *, STAB_CODE_TYPE);
+static void dbxout_common_name (tree, const char *, stab_code_type);
static const char *dbxout_common_check (tree, int *);
static void dbxout_global_decl (tree);
static void dbxout_type_decl (tree, int);
@@ -335,7 +333,7 @@ static void dbxout_handle_pch (unsigned);
/* The debug hooks structure. */
#if defined (DBX_DEBUGGING_INFO)
-static void dbxout_source_line (unsigned int, const char *);
+static void dbxout_source_line (unsigned int, const char *, int);
static void dbxout_begin_prologue (unsigned int, const char *);
static void dbxout_source_file (const char *);
static void dbxout_function_end (tree);
@@ -842,7 +840,7 @@ do { \
to DBX_FINISH_STABS; see above for details. */
static void
-dbxout_finish_complex_stabs (tree sym, STAB_CODE_TYPE code,
+dbxout_finish_complex_stabs (tree sym, stab_code_type code,
rtx addr, const char *label, int number)
{
int line ATTRIBUTE_UNUSED;
@@ -1267,7 +1265,7 @@ dbxout_begin_prologue (unsigned int lineno, const char *filename)
/* pre-increment the scope counter */
scope_labelno++;
- dbxout_source_line (lineno, filename);
+ dbxout_source_line (lineno, filename, 0);
/* Output function begin block at function scope, referenced
by dbxout_block, dbxout_source_line and dbxout_function_end. */
emit_pending_bincls_if_required ();
@@ -1278,7 +1276,8 @@ dbxout_begin_prologue (unsigned int lineno, const char *filename)
number LINENO. */
static void
-dbxout_source_line (unsigned int lineno, const char *filename)
+dbxout_source_line (unsigned int lineno, const char *filename,
+ int discriminator ATTRIBUTE_UNUSED)
{
dbxout_source_file (filename);
@@ -1593,10 +1592,10 @@ dbxout_type_methods (tree type)
/* Emit a "range" type specification, which has the form:
"r<index type>;<lower bound>;<upper bound>;".
- TYPE is an INTEGER_TYPE. */
+ TYPE is an INTEGER_TYPE, LOW and HIGH are the bounds. */
static void
-dbxout_range_type (tree type)
+dbxout_range_type (tree type, tree low, tree high)
{
stabstr_C ('r');
if (TREE_TYPE (type))
@@ -1624,25 +1623,23 @@ dbxout_range_type (tree type)
}
stabstr_C (';');
- if (TYPE_MIN_VALUE (type) != 0
- && host_integerp (TYPE_MIN_VALUE (type), 0))
+ if (low && host_integerp (low, 0))
{
- if (print_int_cst_bounds_in_octal_p (type))
- stabstr_O (TYPE_MIN_VALUE (type));
+ if (print_int_cst_bounds_in_octal_p (type, low, high))
+ stabstr_O (low);
else
- stabstr_D (tree_low_cst (TYPE_MIN_VALUE (type), 0));
+ stabstr_D (tree_low_cst (low, 0));
}
else
stabstr_C ('0');
stabstr_C (';');
- if (TYPE_MAX_VALUE (type) != 0
- && host_integerp (TYPE_MAX_VALUE (type), 0))
+ if (high && host_integerp (high, 0))
{
- if (print_int_cst_bounds_in_octal_p (type))
- stabstr_O (TYPE_MAX_VALUE (type));
+ if (print_int_cst_bounds_in_octal_p (type, low, high))
+ stabstr_O (high);
else
- stabstr_D (tree_low_cst (TYPE_MAX_VALUE (type), 0));
+ stabstr_D (tree_low_cst (high, 0));
stabstr_C (';');
}
else
@@ -1663,10 +1660,9 @@ dbxout_range_type (tree type)
static void
dbxout_type (tree type, int full)
{
- tree tem;
- tree main_variant;
static int anonymous_type_number = 0;
bool vector_type = false;
+ tree tem, main_variant, low, high;
if (TREE_CODE (type) == VECTOR_TYPE)
{
@@ -1676,6 +1672,27 @@ dbxout_type (tree type, int full)
vector_type = true;
}
+ if (TREE_CODE (type) == INTEGER_TYPE)
+ {
+ if (TREE_TYPE (type) == 0)
+ {
+ low = TYPE_MIN_VALUE (type);
+ high = TYPE_MAX_VALUE (type);
+ }
+
+ else if (subrange_type_for_debug_p (type, &low, &high))
+ ;
+
+ /* If this is a subtype that should not be emitted as a subrange type,
+ use the base type. */
+ else
+ {
+ type = TREE_TYPE (type);
+ low = TYPE_MIN_VALUE (type);
+ high = TYPE_MAX_VALUE (type);
+ }
+ }
+
/* If there was an input error and we don't really have a type,
avoid crashing and write something that is at least valid
by assuming `int'. */
@@ -1877,7 +1894,7 @@ dbxout_type (tree type, int full)
stabstr_C (';');
}
- dbxout_range_type (type);
+ dbxout_range_type (type, low, high);
}
else
@@ -1893,7 +1910,7 @@ dbxout_type (tree type, int full)
stabstr_C (';');
}
- if (print_int_cst_bounds_in_octal_p (type))
+ if (print_int_cst_bounds_in_octal_p (type, low, high))
{
stabstr_C ('r');
@@ -1908,15 +1925,15 @@ dbxout_type (tree type, int full)
dbxout_type_index (type);
stabstr_C (';');
- stabstr_O (TYPE_MIN_VALUE (type));
+ stabstr_O (low);
stabstr_C (';');
- stabstr_O (TYPE_MAX_VALUE (type));
+ stabstr_O (high);
stabstr_C (';');
}
else
/* Output other integer types as subranges of `int'. */
- dbxout_range_type (type);
+ dbxout_range_type (type, low, high);
}
break;
@@ -2010,7 +2027,7 @@ dbxout_type (tree type, int full)
else
{
stabstr_C ('a');
- dbxout_range_type (tem);
+ dbxout_range_type (tem, TYPE_MIN_VALUE (tem), TYPE_MAX_VALUE (tem));
}
dbxout_type (TREE_TYPE (type), 0);
@@ -2258,7 +2275,7 @@ dbxout_type (tree type, int full)
should be printed in octal format. */
static bool
-print_int_cst_bounds_in_octal_p (tree type)
+print_int_cst_bounds_in_octal_p (tree type, tree low, tree high)
{
/* If we can use GDB extensions and the size is wider than a long
(the size used by GDB to read them) or we may have trouble writing
@@ -2272,10 +2289,8 @@ print_int_cst_bounds_in_octal_p (tree type)
can't span same size unsigned types. */
if (use_gnu_debug_info_extensions
- && TYPE_MIN_VALUE (type) != 0
- && TREE_CODE (TYPE_MIN_VALUE (type)) == INTEGER_CST
- && TYPE_MAX_VALUE (type) != 0
- && TREE_CODE (TYPE_MAX_VALUE (type)) == INTEGER_CST
+ && low && TREE_CODE (low) == INTEGER_CST
+ && high && TREE_CODE (high) == INTEGER_CST
&& (TYPE_PRECISION (type) > TYPE_PRECISION (integer_type_node)
|| ((TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node))
&& TYPE_UNSIGNED (type))
@@ -2836,7 +2851,7 @@ static int
dbxout_symbol_location (tree decl, tree type, const char *suffix, rtx home)
{
int letter = 0;
- STAB_CODE_TYPE code;
+ stab_code_type code;
rtx addr = 0;
int number = 0;
int regno = -1;
@@ -3141,7 +3156,7 @@ dbxout_symbol_name (tree decl, const char *suffix, int letter)
emits the N_BCOMM and N_ECOMM stabs. */
static void
-dbxout_common_name (tree decl, const char *name, STAB_CODE_TYPE op)
+dbxout_common_name (tree decl, const char *name, stab_code_type op)
{
dbxout_begin_complex_stabs ();
stabstr_S (name);
@@ -3309,7 +3324,7 @@ dbxout_parms (tree parms)
{
tree eff_type;
char letter;
- STAB_CODE_TYPE code;
+ stab_code_type code;
int number;
/* Perform any necessary register eliminations on the parameter's rtl,
diff --git a/gcc/dce.c b/gcc/dce.c
index a1fa276927b..3e1dd47f3a4 100644
--- a/gcc/dce.c
+++ b/gcc/dce.c
@@ -355,8 +355,8 @@ find_call_stack_args (rtx call_insn, bool do_mark, bool fast,
}
for (byte = off; byte < off + INTVAL (MEM_SIZE (mem)); byte++)
{
- gcc_assert (!bitmap_bit_p (sp_bytes, byte - min_sp_off));
- bitmap_set_bit (sp_bytes, byte - min_sp_off);
+ if (!bitmap_set_bit (sp_bytes, byte - min_sp_off))
+ gcc_unreachable ();
}
}
@@ -443,9 +443,8 @@ find_call_stack_args (rtx call_insn, bool do_mark, bool fast,
{
if (byte < min_sp_off
|| byte >= max_sp_off
- || !bitmap_bit_p (sp_bytes, byte - min_sp_off))
+ || !bitmap_clear_bit (sp_bytes, byte - min_sp_off))
break;
- bitmap_clear_bit (sp_bytes, byte - min_sp_off);
}
if (!deletable_insn_p (insn, fast, NULL))
diff --git a/gcc/debug.c b/gcc/debug.c
index 3946debc519..c8e80a841c1 100644
--- a/gcc/debug.c
+++ b/gcc/debug.c
@@ -34,7 +34,7 @@ const struct gcc_debug_hooks do_nothing_debug_hooks =
debug_nothing_int_int, /* begin_block */
debug_nothing_int_int, /* end_block */
debug_true_const_tree, /* ignore_block */
- debug_nothing_int_charstar, /* source_line */
+ debug_nothing_int_charstar_int, /* source_line */
debug_nothing_int_charstar, /* begin_prologue */
debug_nothing_int_charstar, /* end_prologue */
debug_nothing_int_charstar, /* end_epilogue */
@@ -104,6 +104,13 @@ debug_nothing_int_charstar (unsigned int line ATTRIBUTE_UNUSED,
}
void
+debug_nothing_int_charstar_int (unsigned int line ATTRIBUTE_UNUSED,
+ const char *text ATTRIBUTE_UNUSED,
+ int discriminator ATTRIBUTE_UNUSED)
+{
+}
+
+void
debug_nothing_int (unsigned int line ATTRIBUTE_UNUSED)
{
}
diff --git a/gcc/debug.h b/gcc/debug.h
index 6d4911302d0..8f76aff04a4 100644
--- a/gcc/debug.h
+++ b/gcc/debug.h
@@ -59,8 +59,9 @@ struct gcc_debug_hooks
though the BLOCK information is messed up. Defaults to true. */
bool (* ignore_block) (const_tree);
- /* Record a source file location at (FILE, LINE). */
- void (* source_line) (unsigned int line, const char *file);
+ /* Record a source file location at (FILE, LINE, DISCRIMINATOR). */
+ void (* source_line) (unsigned int line, const char *file,
+ int discriminator);
/* Called at start of prologue code. LINE is the first line in the
function. This has been given the same prototype as source_line,
@@ -141,6 +142,7 @@ extern const struct gcc_debug_hooks *debug_hooks;
extern void debug_nothing_void (void);
extern void debug_nothing_charstar (const char *);
extern void debug_nothing_int_charstar (unsigned int, const char *);
+extern void debug_nothing_int_charstar_int (unsigned int, const char *, int);
extern void debug_nothing_int (unsigned int);
extern void debug_nothing_int_int (unsigned int, unsigned int);
extern void debug_nothing_tree (tree);
diff --git a/gcc/defaults.h b/gcc/defaults.h
index 8ed40d93b54..b41f60366d5 100644
--- a/gcc/defaults.h
+++ b/gcc/defaults.h
@@ -492,6 +492,181 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#define LONG_LONG_ACCUM_TYPE_SIZE (LONG_LONG_FRACT_TYPE_SIZE * 2)
#endif
+/* We let tm.h override the types used here, to handle trivial differences
+ such as the choice of unsigned int or long unsigned int for size_t.
+ When machines start needing nontrivial differences in the size type,
+ it would be best to do something here to figure out automatically
+ from other information what type to use. */
+
+#ifndef SIZE_TYPE
+#define SIZE_TYPE "long unsigned int"
+#endif
+
+#ifndef PID_TYPE
+#define PID_TYPE "int"
+#endif
+
+/* If GCC knows the exact uint_least16_t and uint_least32_t types from
+ <stdint.h>, use them for char16_t and char32_t. Otherwise, use
+ these guesses; getting the wrong type of a given width will not
+ affect C++ name mangling because in C++ these are distinct types
+ not typedefs. */
+
+#ifdef UINT_LEAST16_TYPE
+#define CHAR16_TYPE UINT_LEAST16_TYPE
+#else
+#define CHAR16_TYPE "short unsigned int"
+#endif
+
+#ifdef UINT_LEAST32_TYPE
+#define CHAR32_TYPE UINT_LEAST32_TYPE
+#else
+#define CHAR32_TYPE "unsigned int"
+#endif
+
+#ifndef WCHAR_TYPE
+#define WCHAR_TYPE "int"
+#endif
+
+/* WCHAR_TYPE gets overridden by -fshort-wchar. */
+#define MODIFIED_WCHAR_TYPE \
+ (flag_short_wchar ? "short unsigned int" : WCHAR_TYPE)
+
+#ifndef PTRDIFF_TYPE
+#define PTRDIFF_TYPE "long int"
+#endif
+
+#ifndef WINT_TYPE
+#define WINT_TYPE "unsigned int"
+#endif
+
+#ifndef INTMAX_TYPE
+#define INTMAX_TYPE ((INT_TYPE_SIZE == LONG_LONG_TYPE_SIZE) \
+ ? "int" \
+ : ((LONG_TYPE_SIZE == LONG_LONG_TYPE_SIZE) \
+ ? "long int" \
+ : "long long int"))
+#endif
+
+#ifndef UINTMAX_TYPE
+#define UINTMAX_TYPE ((INT_TYPE_SIZE == LONG_LONG_TYPE_SIZE) \
+ ? "unsigned int" \
+ : ((LONG_TYPE_SIZE == LONG_LONG_TYPE_SIZE) \
+ ? "long unsigned int" \
+ : "long long unsigned int"))
+#endif
+
+
+/* There are no default definitions of these <stdint.h> types. */
+
+#ifndef SIG_ATOMIC_TYPE
+#define SIG_ATOMIC_TYPE ((const char *) NULL)
+#endif
+
+#ifndef INT8_TYPE
+#define INT8_TYPE ((const char *) NULL)
+#endif
+
+#ifndef INT16_TYPE
+#define INT16_TYPE ((const char *) NULL)
+#endif
+
+#ifndef INT32_TYPE
+#define INT32_TYPE ((const char *) NULL)
+#endif
+
+#ifndef INT64_TYPE
+#define INT64_TYPE ((const char *) NULL)
+#endif
+
+#ifndef UINT8_TYPE
+#define UINT8_TYPE ((const char *) NULL)
+#endif
+
+#ifndef UINT16_TYPE
+#define UINT16_TYPE ((const char *) NULL)
+#endif
+
+#ifndef UINT32_TYPE
+#define UINT32_TYPE ((const char *) NULL)
+#endif
+
+#ifndef UINT64_TYPE
+#define UINT64_TYPE ((const char *) NULL)
+#endif
+
+#ifndef INT_LEAST8_TYPE
+#define INT_LEAST8_TYPE ((const char *) NULL)
+#endif
+
+#ifndef INT_LEAST16_TYPE
+#define INT_LEAST16_TYPE ((const char *) NULL)
+#endif
+
+#ifndef INT_LEAST32_TYPE
+#define INT_LEAST32_TYPE ((const char *) NULL)
+#endif
+
+#ifndef INT_LEAST64_TYPE
+#define INT_LEAST64_TYPE ((const char *) NULL)
+#endif
+
+#ifndef UINT_LEAST8_TYPE
+#define UINT_LEAST8_TYPE ((const char *) NULL)
+#endif
+
+#ifndef UINT_LEAST16_TYPE
+#define UINT_LEAST16_TYPE ((const char *) NULL)
+#endif
+
+#ifndef UINT_LEAST32_TYPE
+#define UINT_LEAST32_TYPE ((const char *) NULL)
+#endif
+
+#ifndef UINT_LEAST64_TYPE
+#define UINT_LEAST64_TYPE ((const char *) NULL)
+#endif
+
+#ifndef INT_FAST8_TYPE
+#define INT_FAST8_TYPE ((const char *) NULL)
+#endif
+
+#ifndef INT_FAST16_TYPE
+#define INT_FAST16_TYPE ((const char *) NULL)
+#endif
+
+#ifndef INT_FAST32_TYPE
+#define INT_FAST32_TYPE ((const char *) NULL)
+#endif
+
+#ifndef INT_FAST64_TYPE
+#define INT_FAST64_TYPE ((const char *) NULL)
+#endif
+
+#ifndef UINT_FAST8_TYPE
+#define UINT_FAST8_TYPE ((const char *) NULL)
+#endif
+
+#ifndef UINT_FAST16_TYPE
+#define UINT_FAST16_TYPE ((const char *) NULL)
+#endif
+
+#ifndef UINT_FAST32_TYPE
+#define UINT_FAST32_TYPE ((const char *) NULL)
+#endif
+
+#ifndef UINT_FAST64_TYPE
+#define UINT_FAST64_TYPE ((const char *) NULL)
+#endif
+
+#ifndef INTPTR_TYPE
+#define INTPTR_TYPE ((const char *) NULL)
+#endif
+
+#ifndef UINTPTR_TYPE
+#define UINTPTR_TYPE ((const char *) NULL)
+#endif
+
/* Width in bits of a pointer. Mind the value of the macro `Pmode'. */
#ifndef POINTER_SIZE
#define POINTER_SIZE BITS_PER_WORD
diff --git a/gcc/df-core.c b/gcc/df-core.c
index f842d742c62..8057b54df10 100644
--- a/gcc/df-core.c
+++ b/gcc/df-core.c
@@ -170,11 +170,6 @@ There are four ways of doing the incremental scanning:
d) If the pass modifies all of the insns, as does register
allocation, it is simply better to rescan the entire function.
- e) If the pass uses either non-standard or ancient techniques to
- modify insns, automatic detection of the insns that need to be
- rescanned may be impractical. Cse and regrename fall into this
- category.
-
2) Deferred rescanning - Calls to df_insn_rescan, df_notes_rescan, and
df_insn_delete do not immediately change the insn but instead make
a note that the insn needs to be rescanned. The next call to
@@ -182,27 +177,25 @@ There are four ways of doing the incremental scanning:
cause all of the pending rescans to be processed.
This is the technique of choice if either 1a, 1b, or 1c are issues
- in the pass. In the case of 1a or 1b, a call to df_remove_problem
- (df_chain) should be made before the next call to df_analyze or
- df_process_deferred_rescans.
+ in the pass. In the case of 1a or 1b, a call to df_finish_pass
+ (either manually or via TODO_df_finish) should be made before the
+ next call to df_analyze or df_process_deferred_rescans.
+
+ This mode is also used by a few passes that still rely on note_uses,
+ note_stores and for_each_rtx instead of using the DF data. This
+ can be said to fall under case 1c.
To enable this mode, call df_set_flags (DF_DEFER_INSN_RESCAN).
(This mode can be cleared by calling df_clear_flags
(DF_DEFER_INSN_RESCAN) but this does not cause the deferred insns to
be rescanned.
- 3) Total rescanning - In this mode the rescanning is disabled.
- However, the df information associated with deleted insn is delete
- at the time the insn is deleted. At the end of the pass, a call
- must be made to df_insn_rescan_all. This method is used by the
- register allocator since it generally changes each insn multiple
- times (once for each ref) and does not need to make use of the
- updated scanning information.
-
- It is also currently used by two older passes (cse, and regrename)
- which change insns in hard to track ways. It is hoped that this
- will be fixed soon since this it is expensive to rescan all of the
- insns when only a small number of them have really changed.
+3) Total rescanning - In this mode the rescanning is disabled.
+ Only when insns are deleted is the df information associated with
+ it also deleted. At the end of the pass, a call must be made to
+ df_insn_rescan_all. This method is used by the register allocator
+ since it generally changes each insn multiple times (once for each ref)
+ and does not need to make use of the updated scanning information.
4) Do it yourself - In this mechanism, the pass updates the insns
itself using the low level df primitives. Currently no pass does
diff --git a/gcc/df-problems.c b/gcc/df-problems.c
index 1e12c28e12a..4c6d6140122 100644
--- a/gcc/df-problems.c
+++ b/gcc/df-problems.c
@@ -2509,8 +2509,8 @@ df_byte_lr_alloc (bitmap all_blocks ATTRIBUTE_UNUSED)
unsigned int regno;
unsigned int index = 0;
unsigned int max_reg = max_reg_num();
- struct df_byte_lr_problem_data *problem_data
- = problem_data = XNEW (struct df_byte_lr_problem_data);
+ struct df_byte_lr_problem_data *problem_data
+ = XNEW (struct df_byte_lr_problem_data);
df_byte_lr->problem_data = problem_data;
@@ -3955,19 +3955,21 @@ df_simulate_one_insn_forwards (basic_block bb, rtx insn, bitmap live)
for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
{
switch (REG_NOTE_KIND (link))
+ {
case REG_DEAD:
case REG_UNUSED:
- {
- rtx reg = XEXP (link, 0);
- int regno = REGNO (reg);
- if (regno < FIRST_PSEUDO_REGISTER)
- {
- int n = hard_regno_nregs[regno][GET_MODE (reg)];
- while (--n >= 0)
- bitmap_clear_bit (live, regno + n);
- }
- else
- bitmap_clear_bit (live, regno);
+ {
+ rtx reg = XEXP (link, 0);
+ int regno = REGNO (reg);
+ if (regno < FIRST_PSEUDO_REGISTER)
+ {
+ int n = hard_regno_nregs[regno][GET_MODE (reg)];
+ while (--n >= 0)
+ bitmap_clear_bit (live, regno + n);
+ }
+ else
+ bitmap_clear_bit (live, regno);
+ }
break;
default:
break;
diff --git a/gcc/diagnostic.c b/gcc/diagnostic.c
index 42a40c6f337..3f7bab19d8b 100644
--- a/gcc/diagnostic.c
+++ b/gcc/diagnostic.c
@@ -162,7 +162,7 @@ diagnostic_build_prefix (diagnostic_info *diagnostic)
return
(s.file == NULL
? build_message_string ("%s: %s", progname, text)
- : flag_show_column && s.column != 0
+ : flag_show_column
? build_message_string ("%s:%d:%d: %s", s.file, s.line, s.column, text)
: build_message_string ("%s:%d: %s", s.file, s.line, text));
}
@@ -244,9 +244,15 @@ diagnostic_report_current_module (diagnostic_context *context)
if (! MAIN_FILE_P (map))
{
map = INCLUDED_FROM (line_table, map);
- pp_verbatim (context->printer,
- "In file included from %s:%d",
- map->to_file, LAST_SOURCE_LINE (map));
+ if (flag_show_column)
+ pp_verbatim (context->printer,
+ "In file included from %s:%d:%d",
+ map->to_file,
+ LAST_SOURCE_LINE (map), LAST_SOURCE_COLUMN (map));
+ else
+ pp_verbatim (context->printer,
+ "In file included from %s:%d",
+ map->to_file, LAST_SOURCE_LINE (map));
while (! MAIN_FILE_P (map))
{
map = INCLUDED_FROM (line_table, map);
diff --git a/gcc/diagnostic.h b/gcc/diagnostic.h
index 998c11ec1f6..aa9aaf8a9c2 100644
--- a/gcc/diagnostic.h
+++ b/gcc/diagnostic.h
@@ -226,6 +226,7 @@ extern void print_generic_expr (FILE *, tree, int);
extern void print_generic_decl (FILE *, tree, int);
extern void debug_c_tree (tree);
extern void dump_omp_clauses (pretty_printer *, tree, int, int);
+extern void print_call_name (pretty_printer *, tree);
/* In gimple-pretty-print.c */
extern void debug_generic_expr (tree);
diff --git a/gcc/doc/c-tree.texi b/gcc/doc/c-tree.texi
index 117b700ec08..35498583ccd 100644
--- a/gcc/doc/c-tree.texi
+++ b/gcc/doc/c-tree.texi
@@ -1995,7 +1995,6 @@ This macro returns the attributes on the type @var{type}.
@tindex TARGET_EXPR
@tindex AGGR_INIT_EXPR
@tindex VA_ARG_EXPR
-@tindex CHANGE_DYNAMIC_TYPE_EXPR
@tindex OMP_PARALLEL
@tindex OMP_FOR
@tindex OMP_SECTIONS
@@ -2708,13 +2707,6 @@ mechanism. It represents expressions like @code{va_arg (ap, type)}.
Its @code{TREE_TYPE} yields the tree representation for @code{type} and
its sole argument yields the representation for @code{ap}.
-@item CHANGE_DYNAMIC_TYPE_EXPR
-Indicates the special aliasing required by C++ placement new. It has
-two operands: a type and a location. It means that the dynamic type
-of the location is changing to be the specified type. The alias
-analysis code takes this into account when doing type based alias
-analysis.
-
@item OMP_PARALLEL
Represents @code{#pragma omp parallel [clause1 @dots{} clauseN]}. It
diff --git a/gcc/doc/contrib.texi b/gcc/doc/contrib.texi
index 2b9d735ab72..1545bcbcd60 100644
--- a/gcc/doc/contrib.texi
+++ b/gcc/doc/contrib.texi
@@ -156,6 +156,10 @@ Glenn Chambers for help with the GCJ FAQ@.
John-Marc Chandonia for various libgcj patches.
@item
+Denis Chertykov for contributed and maintain the AVR port, the first GCC port
+for an 8-bit architecture.
+
+@item
Scott Christley for his Objective-C contributions.
@item
@@ -312,7 +316,8 @@ support, improved leaf function register allocation, and his direction
via the steering committee.
@item
-Anthony Green for his @option{-Os} contributions and Java front end work.
+Anthony Green for his @option{-Os} contributions, the moxie port, and
+Java front end work.
@item
Stu Grossman for gdb hacking, allowing GCJ developers to debug Java code.
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 6b626e2add7..6817af5d6aa 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -3440,11 +3440,13 @@ feature is intended for code generated by programs which contains labels
that may be unused but which is compiled with @option{-Wall}. It would
not normally be appropriate to use in it human-written code, though it
could be useful in cases where the code that jumps to the label is
-contained within an @code{#ifdef} conditional. GNU C++ does not permit
-such placement of attribute lists, as it is permissible for a
-declaration, which could begin with an attribute list, to be labelled in
-C++. Declarations cannot be labelled in C90 or C99, so the ambiguity
-does not arise there.
+contained within an @code{#ifdef} conditional. GNU C++ only permits
+attributes on labels if the attribute specifier is immediately
+followed by a semicolon (i.e., the label applies to an empty
+statement). If the semicolon is missing, C++ label attributes are
+ambiguous, as it is permissible for a declaration, which could begin
+with an attribute list, to be labelled in C++. Declarations cannot be
+labelled in C90 or C99, so the ambiguity does not arise there.
An attribute specifier list may appear as part of a @code{struct},
@code{union} or @code{enum} specifier. It may go either immediately
@@ -5746,7 +5748,7 @@ produce code that uses 4 @code{SIs}.
The types defined in this manner can be used with a subset of normal C
operations. Currently, GCC will allow using the following operators
-on these types: @code{+, -, *, /, unary minus, ^, |, &, ~}@.
+on these types: @code{+, -, *, /, unary minus, ^, |, &, ~, %}@.
The operations behave like C++ @code{valarrays}. Addition is defined as
the addition of the corresponding elements of the operands. For
@@ -6813,6 +6815,61 @@ intentionally executing an illegal instruction) or by calling
you should not rely on any particular implementation.
@end deftypefn
+@deftypefn {Built-in Function} void __builtin_unreachable (void)
+If control flow reaches the point of the @code{__builtin_unreachable},
+the program is undefined. It is useful in situations where the
+compiler cannot deduce the unreachability of the code.
+
+One such case is immediately following an @code{asm} statement that
+will either never terminate, or one that transfers control elsewhere
+and never returns. In this example, without the
+@code{__builtin_unreachable}, GCC would issue a warning that control
+reaches the end of a non-void function. It would also generate code
+to return after the @code{asm}.
+
+@smallexample
+int f (int c, int v)
+@{
+ if (c)
+ @{
+ return v;
+ @}
+ else
+ @{
+ asm("jmp error_handler");
+ __builtin_unreachable ();
+ @}
+@}
+@end smallexample
+
+Because the @code{asm} statement unconditionally transfers control out
+of the function, control will never reach the end of the function
+body. The @code{__builtin_unreachable} is in fact unreachable and
+communicates this fact to the compiler.
+
+Another use for @code{__builtin_unreachable} is following a call a
+function that never returns but that is not declared
+@code{__attribute__((noreturn))}, as in this example:
+
+@smallexample
+void function_that_never_returns (void);
+
+int g (int c)
+@{
+ if (c)
+ @{
+ return 1;
+ @}
+ else
+ @{
+ function_that_never_returns ();
+ __builtin_unreachable ();
+ @}
+@}
+@end smallexample
+
+@end deftypefn
+
@deftypefn {Built-in Function} void __builtin___clear_cache (char *@var{begin}, char *@var{end})
This function is used to flush the processor's instruction cache for
the region of memory between @var{begin} inclusive and @var{end}
@@ -8357,6 +8414,7 @@ Generates the @code{crc32w} machine instruction.
@item unsigned int __builtin_ia32_crc32si (unsigned int, unsigned int)
Generates the @code{crc32l} machine instruction.
@item unsigned long long __builtin_ia32_crc32di (unsigned long long, unsigned long long)
+Generates the @code{crc32q} machine instruction.
@end table
The following built-in functions are changed to generate new SSE4.2
diff --git a/gcc/doc/gccint.texi b/gcc/doc/gccint.texi
index 265244b349e..4014d370da9 100644
--- a/gcc/doc/gccint.texi
+++ b/gcc/doc/gccint.texi
@@ -109,10 +109,10 @@ Additional tutorial information is linked to from
* Options:: Option specification files.
* Passes:: Order of passes, what they do, and what each file is for.
* Trees:: The source representation used by the C and C++ front ends.
-* RTL:: The intermediate representation that most passes work on.
* GENERIC:: Language-independent representation generated by Front Ends
* GIMPLE:: Tuple representation used by Tree SSA optimizers
* Tree SSA:: Analysis and optimization of GIMPLE
+* RTL:: Machine-dependent low-level intermediate representation.
* Control Flow:: Maintaining and manipulating the control flow graph.
* Loop Analysis and Representation:: Analysis and representation of loops
* Machine Desc:: How to write machine description instruction patterns.
diff --git a/gcc/doc/gimple.texi b/gcc/doc/gimple.texi
index a659419df7b..76cc269aefe 100644
--- a/gcc/doc/gimple.texi
+++ b/gcc/doc/gimple.texi
@@ -332,14 +332,13 @@ union gimple_statement_d
The following table briefly describes the GIMPLE instruction set.
-@multitable {@code{GIMPLE_CHANGE_DYNAMIC_TYPE}} {High GIMPLE} {Low GIMPLE}
+@multitable {@code{GIMPLE_OMP_SECTIONS_SWITCH}} {High GIMPLE} {Low GIMPLE}
@item Instruction @tab High GIMPLE @tab Low GIMPLE
@item @code{GIMPLE_ASM} @tab x @tab x
@item @code{GIMPLE_ASSIGN} @tab x @tab x
@item @code{GIMPLE_BIND} @tab x @tab
@item @code{GIMPLE_CALL} @tab x @tab x
@item @code{GIMPLE_CATCH} @tab x @tab
-@item @code{GIMPLE_CHANGE_DYNAMIC_TYPE} @tab x @tab x
@item @code{GIMPLE_COND} @tab x @tab x
@item @code{GIMPLE_EH_FILTER} @tab x @tab
@item @code{GIMPLE_GOTO} @tab x @tab x
@@ -894,7 +893,6 @@ Return a deep copy of statement @code{STMT}.
* @code{GIMPLE_BIND}::
* @code{GIMPLE_CALL}::
* @code{GIMPLE_CATCH}::
-* @code{GIMPLE_CHANGE_DYNAMIC_TYPE}::
* @code{GIMPLE_COND}::
* @code{GIMPLE_EH_FILTER}::
* @code{GIMPLE_LABEL}::
@@ -1304,45 +1302,6 @@ Set @code{T} to be the set of types handled by @code{GIMPLE_CATCH} @code{G}.
Set @code{HANDLER} to be the body of @code{GIMPLE_CATCH} @code{G}.
@end deftypefn
-@node @code{GIMPLE_CHANGE_DYNAMIC_TYPE}
-@subsection @code{GIMPLE_CHANGE_DYNAMIC_TYPE}
-@cindex @code{GIMPLE_CHANGE_DYNAMIC_TYPE}
-
-@deftypefn {GIMPLE function} gimple gimple_build_cdt (tree type, tree ptr)
-Build a @code{GIMPLE_CHANGE_DYNAMIC_TYPE} statement. @code{TYPE} is the new
-type for the location @code{PTR}.
-@end deftypefn
-
-@deftypefn {GIMPLE function} tree gimple_cdt_new_type (gimple g)
-Return the new type set by @code{GIMPLE_CHANGE_DYNAMIC_TYPE} statement
-@code{G}.
-@end deftypefn
-
-@deftypefn {GIMPLE function} tree *gimple_cdt_new_type_ptr (gimple g)
-Return a pointer to the new type set by
-@code{GIMPLE_CHANGE_DYNAMIC_TYPE} statement @code{G}.
-@end deftypefn
-
-@deftypefn {GIMPLE function} void gimple_cdt_set_new_type (gimple g, tree new_type)
-Set @code{NEW_TYPE} to be the type returned by
-@code{GIMPLE_CHANGE_DYNAMIC_TYPE} statement @code{G}.
-@end deftypefn
-
-@deftypefn {GIMPLE function} tree gimple_cdt_location (gimple g)
-Return the location affected by @code{GIMPLE_CHANGE_DYNAMIC_TYPE}
-statement @code{G}.
-@end deftypefn
-
-@deftypefn {GIMPLE function} tree *gimple_cdt_location_ptr (gimple g)
-Return a pointer to the location affected by
-@code{GIMPLE_CHANGE_DYNAMIC_TYPE} statement @code{G}.
-@end deftypefn
-
-@deftypefn {GIMPLE function} void gimple_cdt_set_location (gimple g, tree ptr)
-Set @code{PTR} to be the location affected by @code{GIMPLE_CHANGE_DYNAMIC_TYPE}
-statement @code{G}.
-@end deftypefn
-
@node @code{GIMPLE_COND}
@subsection @code{GIMPLE_COND}
diff --git a/gcc/doc/gty.texi b/gcc/doc/gty.texi
index ef7a5d42fdb..b59d5f3d35e 100644
--- a/gcc/doc/gty.texi
+++ b/gcc/doc/gty.texi
@@ -450,6 +450,14 @@ For language frontends, there is another file that needs to be included
somewhere. It will be called @file{gtype-@var{lang}.h}, where
@var{lang} is the name of the subdirectory the language is contained in.
+Plugins can add additional root tables. Run the @code{gengtype}
+utility in plugin mode as @code{gengtype -p @var{source-dir}
+@var{file-list} @var{plugin*.c}} with your plugin files
+@var{plugin*.c} using @code{GTY} to generate the corresponding
+@var{gt-plugin*.h} files. The GCC build tree is needed to be present in
+that mode.
+
+
@node Invoking the garbage collector
@section How to invoke the garbage collector
@cindex garbage collector, invocation
diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi
index 694bc29db17..5b25015e5bb 100644
--- a/gcc/doc/install.texi
+++ b/gcc/doc/install.texi
@@ -344,8 +344,19 @@ not installed in your default library search path.
Necessary to build libgcj, the GCJ runtime.
-@end table
+@item MPC Library version 0.6.0 (or later)
+
+Optional when building GCC@. Having this library will enable
+additional optimizations on complex numbers. It can be downloaded
+from @uref{http://www.multiprecision.org/mpc/}. The
+@option{--with-mpc} configure option should be used if your MPC
+Library is not installed in your default library search path. See
+also @option{--with-mpc-lib} and @option{--with-mpc-include}.
+Alternatively, if an MPC source distribution is found in a
+subdirectory of your GCC sources named @file{mpc}, it will be built
+together with GCC@.
+@end table
@heading Tools/packages necessary for modifying GCC
@table @asis
@@ -525,11 +536,11 @@ components of the binutils you intend to build alongside the compiler
(@file{bfd}, @file{binutils}, @file{gas}, @file{gprof}, @file{ld},
@file{opcodes}, @dots{}) to the directory containing the GCC sources.
-Likewise, the GMP and MPFR libraries can be automatically built together
-with GCC. Unpack the GMP and/or MPFR source distributions in the
-directory containing the GCC sources and rename their directories to
-@file{gmp} and @file{mpfr}, respectively (or use symbolic links with the
-same name).
+Likewise the GMP, MPFR and MPC libraries can be automatically built
+together with GCC. Unpack the GMP, MPFR and/or MPC source
+distributions in the directory containing the GCC sources and rename
+their directories to @file{gmp}, @file{mpfr} and @file{mpc},
+respectively (or use symbolic links with the same name).
@html
<hr />
@@ -1488,17 +1499,24 @@ When neither of these configure options are used, the default will be
@itemx --with-mpfr=@var{pathname}
@itemx --with-mpfr-include=@var{pathname}
@itemx --with-mpfr-lib=@var{pathname}
-If you do not have GMP (the GNU Multiple Precision library) and the
-MPFR Libraries installed in a standard location and you want to build
-GCC, you can explicitly specify the directory where they are installed
-(@samp{--with-gmp=@var{gmpinstalldir}},
-@samp{--with-mpfr=@var{mpfrinstalldir}}). The
+@itemx --with-mpc=@var{pathname}
+@itemx --with-mpc-include=@var{pathname}
+@itemx --with-mpc-lib=@var{pathname}
+If you do not have GMP (the GNU Multiple Precision library), the MPFR
+library and/or the MPC library installed in a standard location and
+you want to build GCC, you can explicitly specify the directory where
+they are installed (@samp{--with-gmp=@var{gmpinstalldir}},
+@samp{--with-mpfr=@var{mpfrinstalldir}},
+@samp{--with-mpc=@var{mpcinstalldir}}). The
@option{--with-gmp=@var{gmpinstalldir}} option is shorthand for
@option{--with-gmp-lib=@var{gmpinstalldir}/lib} and
@option{--with-gmp-include=@var{gmpinstalldir}/include}. Likewise the
@option{--with-mpfr=@var{mpfrinstalldir}} option is shorthand for
@option{--with-mpfr-lib=@var{mpfrinstalldir}/lib} and
-@option{--with-mpfr-include=@var{mpfrinstalldir}/include}. If these
+@option{--with-mpfr-include=@var{mpfrinstalldir}/include}, also the
+@option{--with-mpc=@var{mpcinstalldir}} option is shorthand for
+@option{--with-mpc-lib=@var{mpcinstalldir}/lib} and
+@option{--with-mpc-include=@var{mpcinstalldir}/include}. If these
shorthand assumptions are not correct, you can use the explicit
include and lib options directly.
@@ -3424,6 +3442,20 @@ Support for AIX version 4.2 and older was discontinued in GCC 4.5.
process resource limits (ulimit). Hard limits are configured in the
@file{/etc/security/limits} system configuration file.
+GCC can bootstrap with recent versions of IBM XLC, but bootstrapping
+with an earlier release of GCC is recommended. Bootstrapping with XLC
+requires a larger data segment, which can be enabled through the
+@var{LDR_CNTRL} environment variable, e.g.,
+
+@smallexample
+ % LDR_CNTRL=MAXDATA=0x50000000
+ % export LDR_CNTRL
+@end smallexample
+
+One can start with a pre-compiled version of GCC to build from
+sources. One may delete GCC's ``fixed'' header files when starting
+with a version of GCC built for an earlier release of AIX.
+
To speed up the configuration phases of bootstrapping and installing GCC,
one may use GNU Bash instead of AIX @command{/bin/sh}, e.g.,
@@ -3453,11 +3485,9 @@ If this error occurs during stage2 or later, then the problem most likely
is the version of Make (see above).
The native @command{as} and @command{ld} are recommended for bootstrapping
-on AIX 4 and required for bootstrapping on AIX 5L@. The GNU Assembler
-reports that it supports WEAK symbols on AIX 4, which causes GCC to try to
-utilize weak symbol functionality although it is not supported. The GNU
-Assembler and Linker do not support AIX 5L sufficiently to bootstrap GCC@.
-The native AIX tools do interoperate with GCC@.
+on AIX@. The GNU Assembler, GNU Linker, and GNU Binutils version 2.20
+is required to bootstrap on AIX 5@. The native AIX tools do
+interoperate with GCC@.
Building @file{libstdc++.a} requires a fix for an AIX Assembler bug
APAR IY26685 (AIX 4.3) or APAR IY25528 (AIX 5.1). It also requires a
@@ -3789,6 +3819,13 @@ information about using GCC on IRIX platforms.
@html
<hr />
@end html
+@heading @anchor{moxie-x-elf}moxie-*-elf
+The moxie processor. See @uref{http://moxielogic.org/} for more
+information about this processor.
+
+@html
+<hr />
+@end html
@heading @anchor{powerpc-x-x}powerpc-*-*
You can specify a default version for the @option{-mcpu=@var{cpu_type}}
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index e61a2f36915..f155447230f 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -238,7 +238,7 @@ Objective-C and Objective-C++ Dialects}.
-Wfatal-errors -Wfloat-equal -Wformat -Wformat=2 @gol
-Wno-format-contains-nul -Wno-format-extra-args -Wformat-nonliteral @gol
-Wformat-security -Wformat-y2k @gol
--Wframe-larger-than=@var{len} -Wignored-qualifiers @gol
+-Wframe-larger-than=@var{len} -Wjump-misses-init -Wignored-qualifiers @gol
-Wimplicit -Wimplicit-function-declaration -Wimplicit-int @gol
-Winit-self -Winline @gol
-Wno-int-to-pointer-cast -Wno-invalid-offsetof @gol
@@ -290,12 +290,14 @@ Objective-C and Objective-C++ Dialects}.
-fdump-tree-gimple@r{[}-raw@r{]} -fdump-tree-mudflap@r{[}-@var{n}@r{]} @gol
-fdump-tree-dom@r{[}-@var{n}@r{]} @gol
-fdump-tree-dse@r{[}-@var{n}@r{]} @gol
+-fdump-tree-phiprop@r{[}-@var{n}@r{]} @gol
-fdump-tree-phiopt@r{[}-@var{n}@r{]} @gol
-fdump-tree-forwprop@r{[}-@var{n}@r{]} @gol
-fdump-tree-copyrename@r{[}-@var{n}@r{]} @gol
-fdump-tree-nrv -fdump-tree-vect @gol
-fdump-tree-sink @gol
-fdump-tree-sra@r{[}-@var{n}@r{]} @gol
+-fdump-tree-forwprop@r{[}-@var{n}@r{]} @gol
-fdump-tree-fre@r{[}-@var{n}@r{]} @gol
-fdump-tree-vrp@r{[}-@var{n}@r{]} @gol
-ftree-vectorizer-verbose=@var{n} @gol
@@ -309,8 +311,8 @@ Objective-C and Objective-C++ Dialects}.
-fsel-sched-verbose -fsel-sched-dump-cfg -fsel-sched-pipelining-verbose @gol
-ftest-coverage -ftime-report -fvar-tracking @gol
-fvar-tracking-assigments -fvar-tracking-assignments-toggle @gol
--g -g@var{level} -gtoggle @gol
--gcoff -gdwarf-2 -ggdb -gstabs -gstabs+ -gvms -gxcoff -gxcoff+ @gol
+-g -g@var{level} -gtoggle -gcoff -gdwarf-@var{version} @gol
+-ggdb -gstabs -gstabs+ -gvms -gxcoff -gxcoff+ @gol
-fno-merge-debug-strings -fno-dwarf2-cfi-asm @gol
-fdebug-prefix-map=@var{old}=@var{new} @gol
-femit-struct-debug-baseonly -femit-struct-debug-reduced @gol
@@ -372,10 +374,10 @@ Objective-C and Objective-C++ Dialects}.
-ftree-builtin-call-dce -ftree-ccp -ftree-ch @gol
-ftree-coalesce-inline-vars -ftree-coalesce-vars @gol
-ftree-copy-prop -ftree-copyrename -ftree-dce @gol
--ftree-dominator-opts -ftree-dse -ftree-fre -ftree-loop-im @gol
--ftree-loop-distribution @gol
+-ftree-dominator-opts -ftree-dse -ftree-forwprop -ftree-fre -ftree-loop-im @gol
+-ftree-phiprop -ftree-loop-distribution @gol
-ftree-loop-ivcanon -ftree-loop-linear -ftree-loop-optimize @gol
--ftree-parallelize-loops=@var{n} -ftree-pre -ftree-reassoc @gol
+-ftree-parallelize-loops=@var{n} -ftree-pre -ftree-pta -ftree-reassoc @gol
-ftree-sink -ftree-sra -ftree-switch-conversion @gol
-ftree-ter -ftree-vect-loop-version -ftree-vectorize -ftree-vrp @gol
-funit-at-a-time -funroll-all-loops -funroll-loops @gol
@@ -579,7 +581,7 @@ Objective-C and Objective-C++ Dialects}.
-mno-wide-multiply -mrtd -malign-double @gol
-mpreferred-stack-boundary=@var{num}
-mincoming-stack-boundary=@var{num}
--mcld -mcx16 -msahf -mrecip @gol
+-mcld -mcx16 -msahf -mmovbe -mcrc32 -mrecip @gol
-mmmx -msse -msse2 -msse3 -mssse3 -msse4.1 -msse4.2 -msse4 -mavx @gol
-maes -mpclmul @gol
-msse4a -m3dnow -mpopcnt -mabm -msse5 @gol
@@ -595,21 +597,26 @@ Objective-C and Objective-C++ Dialects}.
@emph{IA-64 Options}
@gccoptlist{-mbig-endian -mlittle-endian -mgnu-as -mgnu-ld -mno-pic @gol
--mvolatile-asm-stop -mregister-names -mno-sdata @gol
--mconstant-gp -mauto-pic -minline-float-divide-min-latency @gol
+-mvolatile-asm-stop -mregister-names -msdata -mno-sdata @gol
+-mconstant-gp -mauto-pic -mfused-madd @gol
+-minline-float-divide-min-latency @gol
-minline-float-divide-max-throughput @gol
+-mno-inline-float-divide @gol
-minline-int-divide-min-latency @gol
-minline-int-divide-max-throughput @gol
+-mno-inline-int-divide @gol
-minline-sqrt-min-latency -minline-sqrt-max-throughput @gol
--mno-dwarf2-asm -mearly-stop-bits @gol
+-mno-inline-sqrt @gol
+-mdwarf2-asm -mearly-stop-bits @gol
-mfixed-range=@var{register-range} -mtls-size=@var{tls-size} @gol
--mtune=@var{cpu-type} -mt -pthread -milp32 -mlp64 @gol
--mno-sched-br-data-spec -msched-ar-data-spec -mno-sched-control-spec @gol
+-mtune=@var{cpu-type} -milp32 -mlp64 @gol
+-msched-br-data-spec -msched-ar-data-spec -msched-control-spec @gol
-msched-br-in-data-spec -msched-ar-in-data-spec -msched-in-control-spec @gol
--msched-ldc -mno-sched-control-ldc -mno-sched-spec-verbose @gol
--mno-sched-prefer-non-data-spec-insns @gol
--mno-sched-prefer-non-control-spec-insns @gol
--mno-sched-count-spec-in-critical-path}
+-msched-spec-ldc -msched-spec-control-ldc @gol
+-msched-prefer-non-data-spec-insns -msched-prefer-non-control-spec-insns @gol
+-msched-stop-bits-after-every-cycle -msched-count-spec-in-critical-path @gol
+-msel-sched-dont-check-control-spec -msched-fp-mem-deps-zero-cost @gol
+-msched-max-memory-insns-hard-limit -msched-max-memory-insns=@var{max-insns}}
@emph{M32R/D Options}
@gccoptlist{-m32r2 -m32rx -m32r @gol
@@ -1596,7 +1603,7 @@ freestanding and hosted environments.
Enable handling of OpenMP directives @code{#pragma omp} in C/C++ and
@code{!$omp} in Fortran. When @option{-fopenmp} is specified, the
compiler generates parallel code according to the OpenMP Application
-Program Interface v2.5 @w{@uref{http://www.openmp.org/}}. This option
+Program Interface v3.0 @w{@uref{http://www.openmp.org/}}. This option
implies @option{-pthread}, and thus is only supported on targets that
have support for @option{-pthread}.
@@ -2808,7 +2815,6 @@ name is still supported, but the newer name is more descriptive.)
@gccoptlist{-Wclobbered @gol
-Wempty-body @gol
-Wignored-qualifiers @gol
--Wlogical-op @gol
-Wmissing-field-initializers @gol
-Wmissing-parameter-type @r{(C only)} @gol
-Wold-style-declaration @r{(C only)} @gol
@@ -2969,6 +2975,20 @@ requiring a non-null value by the @code{nonnull} function attribute.
@option{-Wnonnull} is included in @option{-Wall} and @option{-Wformat}. It
can be disabled with the @option{-Wno-nonnull} option.
+@item -Wjump-misses-init @r{(C, Objective-C only)}
+@opindex Wjump-misses-init
+@opindex Wno-jump-misses-init
+Warn if a @code{goto} statement or a @code{switch} statement jumps
+forward across the initialization of a variable, or jumps backward to a
+label after the variable has been initialized. This only warns about
+variables which are initialized when they are declared. This warning is
+only supported for C and Objective C; in C++ this sort of branch is an
+error in any case.
+
+@option{-Wjump-misses-init} is included in @option{-Wall} and
+@option{-Wc++-compat}. It can be disabled with the
+@option{-Wno-jump-misses-init} option.
+
@item -Winit-self @r{(C, C++, Objective-C and Objective-C++ only)}
@opindex Winit-self
@opindex Wno-init-self
@@ -3172,7 +3192,8 @@ Warn whenever a @code{switch} statement has an index of enumerated type
and lacks a @code{case} for one or more of the named codes of that
enumeration. (The presence of a @code{default} label prevents this
warning.) @code{case} labels outside the enumeration range also
-provoke warnings when this option is used.
+provoke warnings when this option is used (even if there is a
+@code{default} label).
This warning is enabled by @option{-Wall}.
@item -Wswitch-default
@@ -3187,7 +3208,10 @@ case.
Warn whenever a @code{switch} statement has an index of enumerated type
and lacks a @code{case} for one or more of the named codes of that
enumeration. @code{case} labels outside the enumeration range also
-provoke warnings when this option is used.
+provoke warnings when this option is used. The only difference
+between @option{-Wswitch} and this option is that this option gives a
+warning about an omitted enumeration code even if there is a
+@code{default} label.
@item -Wsync-nand @r{(C and C++ only)}
@opindex Wsync-nand
@@ -3692,6 +3716,19 @@ Warn whenever a pointer is cast so as to remove a type qualifier from
the target type. For example, warn if a @code{const char *} is cast
to an ordinary @code{char *}.
+Also warn when making a cast which introduces a type qualifier in an
+unsafe way. For example, casting @code{char **} to @code{const char **}
+is unsafe, as in this example:
+
+@smallexample
+ /* p is char ** value. */
+ const char **q = (const char **) p;
+ /* Assignment of readonly string to const char * is OK. */
+ *q = "string";
+ /* Now char** pointer points to read-only memory. */
+ **p = 'b';
+@end smallexample
+
@item -Wcast-align
@opindex Wcast-align
@opindex Wno-cast-align
@@ -3795,8 +3832,7 @@ programmer intended to use @code{strcmp}. This warning is enabled by
@opindex Wno-logical-op
Warn about suspicious uses of logical operators in expressions.
This includes using logical operators in contexts where a
-bit-wise operator is likely to be expected. This warning is enabled by
-@option{-Wextra}.
+bit-wise operator is likely to be expected.
@item -Waggregate-return
@opindex Waggregate-return
@@ -4324,13 +4360,14 @@ use of these extensions is likely to make other debuggers crash or
refuse to read the program, and may cause assemblers other than the GNU
assembler (GAS) to fail with an error.
-@item -gdwarf-2
-@opindex gdwarf-2
-Produce debugging information in DWARF version 2 format (if that is
-supported). This is the format used by DBX on IRIX 6. With this
-option, GCC uses features of DWARF version 3 when they are useful;
-version 3 is upward compatible with version 2, but may still cause
-problems for older debuggers.
+@item -gdwarf-@var{version}
+@opindex gdwarf-@var{version}
+Produce debugging information in DWARF format (if that is
+supported). This is the format used by DBX on IRIX 6. The value
+of @var{version} may be either 2 or 3; the default version is 2.
+
+Note that with DWARF version 2 some ports require, and will always
+use, some non-conflicting DWARF 3 extensions in the unwind tables.
@item -gvms
@opindex gvms
@@ -4364,7 +4401,7 @@ debug information in version 1 of the DWARF format (which is very
different from version 2), and it would have been too confusing. That
debug format is long obsolete, but the option cannot be changed now.
Instead use an additional @option{-g@var{level}} option to change the
-debug level for DWARF2.
+debug level for DWARF.
@item -gtoggle
@opindex gtoggle
@@ -5034,7 +5071,7 @@ Dump after function inlining.
@end table
@item -fdump-statistics-@var{option}
-@opindex -fdump-statistics
+@opindex fdump-statistics
Enable and control dumping of pass statistics in a separate file. The
file name is generated by appending a suffix ending in
@samp{.statistics} to the source file name, and the file is created in
@@ -5093,9 +5130,11 @@ The following tree dumps are possible:
@table @samp
@item original
+@opindex fdump-tree-original
Dump before any tree based optimization, to @file{@var{file}.original}.
@item optimized
+@opindex fdump-tree-optimized
Dump after all tree based optimization, to @file{@var{file}.optimized}.
@item gimple
@@ -5254,7 +5293,7 @@ analysis and transformation is reported. This is the same verbosity level
that @option{-fdump-tree-vect-details} uses.
@item -frandom-seed=@var{string}
-@opindex frandom-string
+@opindex frandom-seed
This option provides a seed that GCC uses when it would otherwise use
random numbers. It is used to generate certain symbol names
that have to be different in every compiled file. It is also used to
@@ -5547,8 +5586,11 @@ compilation time.
-ftree-dce @gol
-ftree-dominator-opts @gol
-ftree-dse @gol
+-ftree-forwprop @gol
-ftree-fre @gol
+-ftree-phiprop @gol
-ftree-sra @gol
+-ftree-pta @gol
-ftree-ter @gol
-funit-at-a-time}
@@ -6261,6 +6303,11 @@ at @option{-O} and higher.
Perform partial redundancy elimination (PRE) on trees. This flag is
enabled by default at @option{-O2} and @option{-O3}.
+@item -ftree-forwprop
+@opindex ftree-forwprop
+Perform forward propagation on trees. This flag is enabled by default
+at @option{-O} and higher.
+
@item -ftree-fre
@opindex ftree-fre
Perform full redundancy elimination (FRE) on trees. The difference
@@ -6269,6 +6316,11 @@ that are computed on all paths leading to the redundant computation.
This analysis is faster than PRE, though it exposes fewer redundancies.
This flag is enabled by default at @option{-O} and higher.
+@item -ftree-phiprop
+@opindex ftree-phiprop
+Perform hoisting of loads from conditional pointers on trees. This
+pass is enabled by default at @option{-O} and higher.
+
@item -ftree-copy-prop
@opindex ftree-copy-prop
Perform copy propagation on trees. This pass eliminates unnecessary
@@ -6535,6 +6587,11 @@ rather than constrained e.g.@: by memory bandwidth. This option
implies @option{-pthread}, and thus is only supported on targets
that have support for @option{-pthread}.
+@item -ftree-pta
+@opindex ftree-pta
+Perform function-local points-to analysis on trees. This flag is
+enabled by default at @option{-O} and higher.
+
@item -ftree-sra
@opindex ftree-sra
Perform scalar replacement of aggregates. This pass replaces structure
@@ -6916,7 +6973,7 @@ programs consisting of a single file, in combination with option
programs since the functions and variables become local for the whole combined
compilation unit, not for the single source file itself.
-This option is not supported for Fortran programs.
+This option implies @option{-fwhole-file} for Fortran programs.
@item -fcprop-registers
@opindex fcprop-registers
@@ -7402,19 +7459,6 @@ In each case, the @var{value} is an integer. The allowable choices for
@var{name} are given in the following table:
@table @gcctabopt
-@item sra-max-structure-size
-The maximum structure size, in bytes, at which the scalar replacement
-of aggregates (SRA) optimization will perform block copies. The
-default value, 0, implies that GCC will select the most appropriate
-size itself.
-
-@item sra-field-structure-ratio
-The threshold ratio (as a percentage) between instantiated fields and
-the complete structure size. We say that if the ratio of the number
-of bytes in instantiated fields to the number of bytes in the complete
-structure exceeds this parameter, then block copies are not used. The
-default is 75.
-
@item struct-reorg-cold-struct-ratio
The threshold ratio (as a percentage) between a structure frequency
and the frequency of the hottest structure in the program. This parameter
@@ -7488,7 +7532,7 @@ This number sets the maximum number of instructions (counted in GCC's
internal representation) in a single function that the tree inliner
will consider for inlining. This only affects functions declared
inline and methods implemented in a class declaration (C++).
-The default value is 450.
+The default value is 300.
@item max-inline-insns-auto
When you use @option{-finline-functions} (included in @option{-O3}),
@@ -7496,7 +7540,7 @@ a lot of functions that would otherwise not be considered for inlining
by the compiler will be investigated. To those functions, a different
(more restrictive) limit compared to functions declared inline can
be applied.
-The default value is 90.
+The default value is 60.
@item large-function-insns
The limit specifying really large functions. For functions larger than this
@@ -7574,14 +7618,15 @@ given call expression. This parameter limits inlining only to call expression
whose probability exceeds given threshold (in percents). The default value is
10.
-@item inline-call-cost
-Specify cost of call instruction relative to simple arithmetics operations
-(having cost of 1). Increasing this cost disqualifies inlining of non-leaf
-functions and at the same time increases size of leaf function that is believed to
-reduce function size by being inlined. In effect it increases amount of
-inlining for code having large abstraction penalty (many functions that just
-pass the arguments to other functions) and decrease inlining for code with low
-abstraction penalty. The default value is 12.
+@item early-inlining-insns
+Specify growth that early inliner can make. In effect it increases amount of
+inlining for code having large abstraction penalty. The default value is 12.
+
+@item max-early-inliner-iterations
+@itemx max-early-inliner-iterations
+Limit of iterations of early inliner. This basically bounds number of nested
+indirect calls early inliner can resolve. Deeper chains are still handled by
+late inlining.
@item min-vect-loop-bound
The minimum number of iterations under which a loop will not get vectorized
@@ -7922,6 +7967,15 @@ The size of L1 cache, in kilobytes.
@item l2-cache-size
The size of L2 cache, in kilobytes.
+@item min-insn-to-prefetch-ratio
+The minimum ratio between the number of instructions and the
+number of prefetches to enable prefetching in a loop with an
+unknown trip count.
+
+@item prefetch-min-insn-to-mem-ratio
+The minimum ratio between the number of instructions and the
+number of memory references to enable prefetching in a loop.
+
@item use-canonical-types
Whether the compiler should use the ``canonical'' type system. By
default, this should always be 1, which uses a more efficient internal
@@ -7996,6 +8050,7 @@ they cause the preprocessor output to be unsuitable for actual
compilation.
@table @gcctabopt
+@item -Wp,@var{option}
@opindex Wp
You can use @option{-Wp,@var{option}} to bypass the compiler driver
and pass @var{option} directly through to the preprocessor. If
@@ -8008,7 +8063,7 @@ you should avoid using @option{-Wp} and let the driver handle the
options instead.
@item -Xpreprocessor @var{option}
-@opindex preprocessor
+@opindex Xpreprocessor
Pass @var{option} as an option to the preprocessor. You can use this to
supply system-specific preprocessor options which GCC does not know how to
recognize.
@@ -10593,12 +10648,12 @@ optimization option such as @option{-O3} or above is present in the
command line.
@item -mTLS
-@opindex TLS
+@opindex mTLS
Assume a large TLS segment when generating thread-local code.
@item -mtls
-@opindex tls
+@opindex mtls
Do not assume a large TLS segment when generating thread-local code.
@@ -10980,7 +11035,7 @@ Generate the predefine, @code{_SIO}, for server IO@. The default is
options are available under HP-UX and HI-UX@.
@item -mgnu-ld
-@opindex gnu-ld
+@opindex mgnu-ld
Use GNU ld specific options. This passes @option{-shared} to ld when
building a shared library. It is the default when GCC is configured,
explicitly or implicitly, with the GNU linker. This option does not
@@ -10992,7 +11047,7 @@ using @samp{which `gcc -print-prog-name=ld`}. This option is only available
on the 64 bit HP-UX GCC, i.e.@: configured with @samp{hppa*64*-*-hpux*}.
@item -mhp-ld
-@opindex hp-ld
+@opindex mhp-ld
Use HP ld specific options. This passes @option{-b} to ld when building
a shared library and passes @option{+Accept TypeMismatch} to ld on all
links. It is the default when GCC is configured, explicitly or
@@ -11558,6 +11613,17 @@ SAHF are load and store instructions, respectively, for certain status flags.
In 64-bit mode, SAHF instruction is used to optimize @code{fmod}, @code{drem}
or @code{remainder} built-in functions: see @ref{Other Builtins} for details.
+@item -mmovbe
+@opindex mmovbe
+This option will enable GCC to use movbe instruction to implement
+@code{__builtin_bswap32} and @code{__builtin_bswap64}.
+
+@item -mcrc32
+@opindex mcrc32
+This option will enable built-in functions, @code{__builtin_ia32_crc32qi},
+@code{__builtin_ia32_crc32hi}. @code{__builtin_ia32_crc32si} and
+@code{__builtin_ia32_crc32di} to generate the crc32 machine instruction.
+
@item -mrecip
@opindex mrecip
This option will enable GCC to use RCPSS and RSQRTSS instructions (and their
@@ -11706,7 +11772,7 @@ darwin only the -m64 option turns off the @option{-fno-pic} and
@option{-mdynamic-no-pic} options.
@item -mno-red-zone
-@opindex no-red-zone
+@opindex mno-red-zone
Do not use a so called red zone for x86-64 code. The red zone is mandated
by the x86-64 ABI, it is a 128-byte area beyond the location of the
stack pointer that will not be modified by signal or interrupt handlers
@@ -11818,6 +11884,10 @@ using the minimum latency algorithm.
Generate code for inline divides of floating point values
using the maximum throughput algorithm.
+@item -mno-inline-float-divide
+@opindex mno-inline-float-divide
+Do not generate inline code for divides of floating point values.
+
@item -minline-int-divide-min-latency
@opindex minline-int-divide-min-latency
Generate code for inline divides of integer values
@@ -11828,6 +11898,10 @@ using the minimum latency algorithm.
Generate code for inline divides of integer values
using the maximum throughput algorithm.
+@item -mno-inline-int-divide
+@opindex mno-inline-int-divide
+Do not generate inline code for divides of integer values.
+
@item -minline-sqrt-min-latency
@opindex minline-sqrt-min-latency
Generate code for inline square roots
@@ -11838,6 +11912,17 @@ using the minimum latency algorithm.
Generate code for inline square roots
using the maximum throughput algorithm.
+@item -mno-inline-sqrt
+@opindex mno-inline-sqrt
+Do not generate inline code for sqrt.
+
+@item -mfused-madd
+@itemx -mno-fused-madd
+@opindex mfused-madd
+@opindex mno-fused-madd
+Do (don't) generate code that uses the fused multiply/add or multiply/subtract
+instructions. The default is to use these instructions.
+
@item -mno-dwarf2-asm
@itemx -mdwarf2-asm
@opindex mno-dwarf2-asm
@@ -11871,15 +11956,6 @@ Specify bit size of immediate TLS offsets. Valid values are 14, 22, and
Tune the instruction scheduling for a particular CPU, Valid values are
itanium, itanium1, merced, itanium2, and mckinley.
-@item -mt
-@itemx -pthread
-@opindex mt
-@opindex pthread
-Add support for multithreading using the POSIX threads library. This
-option sets flags for both the preprocessor and linker. It does
-not affect the thread safety of object code produced by the compiler or
-that of libraries supplied with it. These are HP-UX specific flags.
-
@item -milp32
@itemx -mlp64
@opindex milp32
@@ -11944,31 +12020,6 @@ are dependent on the control speculative loads.
This is effective only with @option{-msched-control-spec} enabled.
The default is 'enable'.
-@item -msched-ldc
-@itemx -mno-sched-ldc
-@opindex msched-ldc
-@opindex mno-sched-ldc
-(En/Dis)able use of simple data speculation checks ld.c .
-If disabled, only chk.a instructions will be emitted to check
-data speculative loads.
-The default is 'enable'.
-
-@item -mno-sched-control-ldc
-@itemx -msched-control-ldc
-@opindex mno-sched-control-ldc
-@opindex msched-control-ldc
-(Dis/En)able use of ld.c instructions to check control speculative loads.
-If enabled, in case of control speculative load with no speculatively
-scheduled dependent instructions this load will be emitted as ld.sa and
-ld.c will be used to check it.
-The default is 'disable'.
-
-@item -mno-sched-spec-verbose
-@itemx -msched-spec-verbose
-@opindex mno-sched-spec-verbose
-@opindex msched-spec-verbose
-(Dis/En)able printing of the information about speculative motions.
-
@item -mno-sched-prefer-non-data-spec-insns
@itemx -msched-prefer-non-data-spec-insns
@opindex mno-sched-prefer-non-data-spec-insns
@@ -11996,6 +12047,43 @@ computation of the instructions priorities. This will make the use of the
speculation a bit more conservative.
The default is 'disable'.
+@item -msched-spec-ldc
+@opindex msched-spec-ldc
+Use a simple data speculation check. This option is on by default.
+
+@item -msched-control-spec-ldc
+@opindex msched-spec-ldc
+Use a simple check for control speculation. This option is on by default.
+
+@item -msched-stop-bits-after-every-cycle
+@opindex msched-stop-bits-after-every-cycle
+Place a stop bit after every cycle when scheduling. This option is on
+by default.
+
+@item -msched-fp-mem-deps-zero-cost
+@opindex msched-fp-mem-deps-zero-cost
+Assume that floating-point stores and loads are not likely to cause a conflict
+when placed into the same instruction group. This option is disabled by
+default.
+
+@item -msel-sched-dont-check-control-spec
+@opindex msel-sched-dont-check-control-spec
+Generate checks for control speculation in selective scheduling.
+This flag is disabled by default.
+
+@item -msched-max-memory-insns=@var{max-insns}
+@opindex msched-max-memory-insns
+Limit on the number of memory insns per instruction group, giving lower
+priority to subsequent memory insns attempting to schedule in the same
+instruction group. Frequently useful to prevent cache bank conflicts.
+The default value is 1.
+
+@item -msched-max-memory-insns-hard-limit
+@opindex msched-max-memory-insns-hard-limit
+Disallow more than `msched-max-memory-insns' in instruction group.
+Otherwise, limit is `soft' meaning that we would prefer non-memory operations
+when limit is reached but may still schedule memory operations.
+
@end table
@node M32C Options
@@ -12573,7 +12661,7 @@ Enable the use of 68HC12 pre and post auto-increment and auto-decrement
addressing modes.
@item -minmax
-@itemx -nominmax
+@itemx -mnominmax
@opindex minmax
@opindex mnominmax
Enable the use of 68HC12 min and max instructions.
@@ -12664,7 +12752,7 @@ Generate code for a little endian target.
Generate code for the 210 processor.
@item -mno-lsim
-@opindex no-lsim
+@opindex mno-lsim
Assume that run-time support has been provided and so omit the
simulator library (@file{libsim.a)} from the linker command line.
@@ -13484,7 +13572,7 @@ to the @code{rE} epsilon register.
@item -mabi=mmixware
@itemx -mabi=gnu
-@opindex mabi-mmixware
+@opindex mabi=mmixware
@opindex mabi=gnu
Generate code that passes function parameters and return values that (in
the called function) are seen as registers @code{$0} and up, as opposed to
@@ -13631,7 +13719,7 @@ Generate code for a PDP-11/45. This is the default.
Generate code for a PDP-11/10.
@item -mbcopy-builtin
-@opindex bcopy-builtin
+@opindex mbcopy-builtin
Use inline @code{movmemhi} patterns for copying memory. This is the
default.
@@ -15773,6 +15861,15 @@ This option is available for Cygwin and MinGW targets. It
specifies that a GUI application is to be generated by
instructing the linker to set the PE header subsystem type
appropriately.
+
+@item -mpe-aligned-commons
+@opindex mpe-aligned-commons
+This option is available for Cygwin and MinGW targets. It
+specifies that the GNU extension to the PE file format that
+permits the correct alignment of COMMON variables should be
+used when generating code. It will be enabled by default if
+GCC detects that the target assembler found during configuration
+supports the feature.
@end table
See also under @ref{i386 and x86-64 Options} for standard options.
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index b966c27a880..065529fdf03 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -2730,6 +2730,25 @@ Constants in the range @minus{}8 to 2
@end table
+@item Moxie---@file{config/moxie/constraints.md}
+@table @code
+@item A
+An absolute address
+
+@item B
+An offset address
+
+@item W
+A register indirect memory operand
+
+@item I
+A constant in the range of 0 to 255.
+
+@item N
+A constant in the range of 0 to -255.
+
+@end table
+
@need 1000
@item SPARC---@file{config/sparc/sparc.h}
@table @code
@@ -4236,30 +4255,6 @@ the operand to that mode before generating the instruction.
@item @samp{one_cmpl@var{m}2}
Store the bitwise-complement of operand 1 into operand 0.
-@cindex @code{cmp@var{m}} instruction pattern
-@item @samp{cmp@var{m}}
-Compare operand 0 and operand 1, and set the condition codes.
-The RTL pattern should look like this:
-
-@smallexample
-(set (cc0) (compare (match_operand:@var{m} 0 @dots{})
- (match_operand:@var{m} 1 @dots{})))
-@end smallexample
-
-@cindex @code{tst@var{m}} instruction pattern
-@item @samp{tst@var{m}}
-Compare operand 0 against zero, and set the condition codes.
-The RTL pattern should look like this:
-
-@smallexample
-(set (cc0) (match_operand:@var{m} 0 @dots{}))
-@end smallexample
-
-@samp{tst@var{m}} patterns should not be defined for machines that do
-not use @code{(cc0)}. Doing so would confuse the optimizer since it
-would no longer be clear which @code{set} operations were comparisons.
-The @samp{cmp@var{m}} patterns should be used instead.
-
@cindex @code{movmem@var{m}} instruction pattern
@item @samp{movmem@var{m}}
Block move instruction. The destination and source blocks of memory
@@ -4522,16 +4517,14 @@ move operand 2 or (operands 2 + operand 3) into operand 0 according to the
comparison in operand 1. If the comparison is true, operand 2 is moved into
operand 0, otherwise (operand 2 + operand 3) is moved.
-@cindex @code{s@var{cond}} instruction pattern
-@item @samp{s@var{cond}}
-Store zero or nonzero in the operand according to the condition codes.
-Value stored is nonzero iff the condition @var{cond} is true.
-@var{cond} is the name of a comparison operation expression code, such
-as @code{eq}, @code{lt} or @code{leu}.
-
-You specify the mode that the operand must have when you write the
-@code{match_operand} expression. The compiler automatically sees
-which mode you have used and supplies an operand of that mode.
+@cindex @code{cstore@var{mode}4} instruction pattern
+@item @samp{cstore@var{mode}4}
+Store zero or nonzero in operand 0 according to whether a comparison
+is true. Operand 1 is a comparison operator. Operand 2 and operand 3
+are the first and second operand of the comparison, respectively.
+You specify the mode that operand 0 must have when you write the
+@code{match_operand} expression. The compiler automatically sees which
+mode you have used and supplies an operand of that mode.
The value stored for a true condition must have 1 as its low bit, or
else must be negative. Otherwise the instruction is not suitable and
@@ -4548,33 +4541,11 @@ integer comparisons, it is best to omit these patterns.
If these operations are omitted, the compiler will usually generate code
that copies the constant one to the target and branches around an
assignment of zero to the target. If this code is more efficient than
-the potential instructions used for the @samp{s@var{cond}} pattern
+the potential instructions used for the @samp{cstore@var{mode}4} pattern
followed by those required to convert the result into a 1 or a zero in
-@code{SImode}, you should omit the @samp{s@var{cond}} operations from
+@code{SImode}, you should omit the @samp{cstore@var{mode}4} operations from
the machine description.
-@cindex @code{b@var{cond}} instruction pattern
-@item @samp{b@var{cond}}
-Conditional branch instruction. Operand 0 is a @code{label_ref} that
-refers to the label to jump to. Jump if the condition codes meet
-condition @var{cond}.
-
-Some machines do not follow the model assumed here where a comparison
-instruction is followed by a conditional branch instruction. In that
-case, the @samp{cmp@var{m}} (and @samp{tst@var{m}}) patterns should
-simply store the operands away and generate all the required insns in a
-@code{define_expand} (@pxref{Expander Definitions}) for the conditional
-branch operations. All calls to expand @samp{b@var{cond}} patterns are
-immediately preceded by calls to expand either a @samp{cmp@var{m}}
-pattern or a @samp{tst@var{m}} pattern.
-
-Machines that use a pseudo register for the condition code value, or
-where the mode used for the comparison depends on the condition being
-tested, should also use the above mechanism. @xref{Jump Patterns}.
-
-The above discussion also applies to the @samp{mov@var{mode}cc} and
-@samp{s@var{cond}} patterns.
-
@cindex @code{cbranch@var{mode}4} instruction pattern
@item @samp{cbranch@var{mode}4}
Conditional branch instruction combined with a compare instruction.
@@ -5025,18 +4996,20 @@ This pattern, if defined, signals an error, typically by causing some
kind of signal to be raised. Among other places, it is used by the Java
front end to signal `invalid array index' exceptions.
-@cindex @code{conditional_trap} instruction pattern
-@item @samp{conditional_trap}
+@cindex @code{ctrap@var{MM}4} instruction pattern
+@item @samp{ctrap@var{MM}4}
Conditional trap instruction. Operand 0 is a piece of RTL which
-performs a comparison. Operand 1 is the trap code, an integer.
+performs a comparison, and operands 1 and 2 are the arms of the
+comparison. Operand 3 is the trap code, an integer.
-A typical @code{conditional_trap} pattern looks like
+A typical @code{ctrap} pattern looks like
@smallexample
-(define_insn "conditional_trap"
+(define_insn "ctrapsi4"
[(trap_if (match_operator 0 "trap_operator"
- [(cc0) (const_int 0)])
- (match_operand 1 "const_int_operand" "i"))]
+ [(match_operand 1 "register_operand")
+ (match_operand 2 "immediate_operand")])
+ (match_operand 3 "const_int_operand" "i"))]
""
"@dots{}")
@end smallexample
@@ -5092,14 +5065,16 @@ operation and all memory operations after the atomic operation occur
after the atomic operation.
For targets where the success or failure of the compare-and-swap
-operation is available via the status flags, it is possible
-to avoid a separate compare operation and issue the subsequent
-setcc or branch immediately after the compare-and-swap. To this
-end, GCC will look for a @code{MODE_CC} set in the output of
-@code{sync_compare_and_swap@var{mode}}; if the machine description
-includes such a set, the target should also define a special @code{cmpcc}
-instruction. GCC will then be able to take the destination of the
-@code{MODE_CC} set and use it as the first operand of @code{cmpcc}.
+operation is available via the status flags, it is possible to
+avoid a separate compare operation and issue the subsequent
+branch or store-flag operation immediately after the compare-and-swap.
+To this end, GCC will look for a @code{MODE_CC} set in the
+output of @code{sync_compare_and_swap@var{mode}}; if the machine
+description includes such a set, the target should also define special
+@code{cbranchcc4} and/or @code{cstorecc4} instructions. GCC will then
+be able to take the destination of the @code{MODE_CC} set and pass it
+to the @code{cbranchcc4} or @code{cstorecc4} pattern as the first
+operand of the comparison (the second will be @code{(const_int 0)}).
@cindex @code{sync_add@var{mode}} instruction pattern
@cindex @code{sync_sub@var{mode}} instruction pattern
@@ -5275,48 +5250,6 @@ constant value.
@cindex Dependent Patterns
@cindex Interdependence of Patterns
-Every machine description must have a named pattern for each of the
-conditional branch names @samp{b@var{cond}}. The recognition template
-must always have the form
-
-@smallexample
-(set (pc)
- (if_then_else (@var{cond} (cc0) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))
-@end smallexample
-
-@noindent
-In addition, every machine description must have an anonymous pattern
-for each of the possible reverse-conditional branches. Their templates
-look like
-
-@smallexample
-(set (pc)
- (if_then_else (@var{cond} (cc0) (const_int 0))
- (pc)
- (label_ref (match_operand 0 "" ""))))
-@end smallexample
-
-@noindent
-They are necessary because jump optimization can turn direct-conditional
-branches into reverse-conditional branches.
-
-It is often convenient to use the @code{match_operator} construct to
-reduce the number of patterns that must be specified for branches. For
-example,
-
-@smallexample
-(define_insn ""
- [(set (pc)
- (if_then_else (match_operator 0 "comparison_operator"
- [(cc0) (const_int 0)])
- (pc)
- (label_ref (match_operand 1 "" ""))))]
- "@var{condition}"
- "@dots{}")
-@end smallexample
-
In some cases machines support instructions identical except for the
machine mode of one or more operands. For example, there may be
``sign-extend halfword'' and ``sign-extend byte'' instructions whose
@@ -5357,113 +5290,38 @@ generating the appropriate machine instruction.
@cindex jump instruction patterns
@cindex defining jump instruction patterns
-For most machines, GCC assumes that the machine has a condition code.
-A comparison insn sets the condition code, recording the results of both
-signed and unsigned comparison of the given operands. A separate branch
-insn tests the condition code and branches or not according its value.
-The branch insns come in distinct signed and unsigned flavors. Many
-common machines, such as the VAX, the 68000 and the 32000, work this
-way.
-
-Some machines have distinct signed and unsigned compare instructions, and
-only one set of conditional branch instructions. The easiest way to handle
-these machines is to treat them just like the others until the final stage
-where assembly code is written. At this time, when outputting code for the
-compare instruction, peek ahead at the following branch using
-@code{next_cc0_user (insn)}. (The variable @code{insn} refers to the insn
-being output, in the output-writing code in an instruction pattern.) If
-the RTL says that is an unsigned branch, output an unsigned compare;
-otherwise output a signed compare. When the branch itself is output, you
-can treat signed and unsigned branches identically.
-
-The reason you can do this is that GCC always generates a pair of
-consecutive RTL insns, possibly separated by @code{note} insns, one to
-set the condition code and one to test it, and keeps the pair inviolate
-until the end.
-
-To go with this technique, you must define the machine-description macro
-@code{NOTICE_UPDATE_CC} to do @code{CC_STATUS_INIT}; in other words, no
-compare instruction is superfluous.
-
-Some machines have compare-and-branch instructions and no condition code.
-A similar technique works for them. When it is time to ``output'' a
-compare instruction, record its operands in two static variables. When
-outputting the branch-on-condition-code instruction that follows, actually
-output a compare-and-branch instruction that uses the remembered operands.
-
-It also works to define patterns for compare-and-branch instructions.
-In optimizing compilation, the pair of compare and branch instructions
-will be combined according to these patterns. But this does not happen
-if optimization is not requested. So you must use one of the solutions
-above in addition to any special patterns you define.
-
-In many RISC machines, most instructions do not affect the condition
-code and there may not even be a separate condition code register. On
-these machines, the restriction that the definition and use of the
-condition code be adjacent insns is not necessary and can prevent
-important optimizations. For example, on the IBM RS/6000, there is a
-delay for taken branches unless the condition code register is set three
-instructions earlier than the conditional branch. The instruction
-scheduler cannot perform this optimization if it is not permitted to
-separate the definition and use of the condition code register.
-
-On these machines, do not use @code{(cc0)}, but instead use a register
-to represent the condition code. If there is a specific condition code
-register in the machine, use a hard register. If the condition code or
-comparison result can be placed in any general register, or if there are
-multiple condition registers, use a pseudo register.
-
-@findex prev_cc0_setter
-@findex next_cc0_user
-On some machines, the type of branch instruction generated may depend on
-the way the condition code was produced; for example, on the 68k and
-SPARC, setting the condition code directly from an add or subtract
-instruction does not clear the overflow bit the way that a test
-instruction does, so a different branch instruction must be used for
-some conditional branches. For machines that use @code{(cc0)}, the set
-and use of the condition code must be adjacent (separated only by
-@code{note} insns) allowing flags in @code{cc_status} to be used.
-(@xref{Condition Code}.) Also, the comparison and branch insns can be
-located from each other by using the functions @code{prev_cc0_setter}
-and @code{next_cc0_user}.
-
-However, this is not true on machines that do not use @code{(cc0)}. On
-those machines, no assumptions can be made about the adjacency of the
-compare and branch insns and the above methods cannot be used. Instead,
-we use the machine mode of the condition code register to record
-different formats of the condition code register.
-
-Registers used to store the condition code value should have a mode that
-is in class @code{MODE_CC}. Normally, it will be @code{CCmode}. If
-additional modes are required (as for the add example mentioned above in
-the SPARC), define them in @file{@var{machine}-modes.def}
-(@pxref{Condition Code}). Also define @code{SELECT_CC_MODE} to choose
-a mode given an operand of a compare.
-
-If it is known during RTL generation that a different mode will be
-required (for example, if the machine has separate compare instructions
-for signed and unsigned quantities, like most IBM processors), they can
-be specified at that time.
-
-If the cases that require different modes would be made by instruction
-combination, the macro @code{SELECT_CC_MODE} determines which machine
-mode should be used for the comparison result. The patterns should be
-written using that mode. To support the case of the add on the SPARC
-discussed above, we have the pattern
-
-@smallexample
-(define_insn ""
- [(set (reg:CC_NOOV 0)
- (compare:CC_NOOV
- (plus:SI (match_operand:SI 0 "register_operand" "%r")
- (match_operand:SI 1 "arith_operand" "rI"))
- (const_int 0)))]
- ""
- "@dots{}")
-@end smallexample
-
-The @code{SELECT_CC_MODE} macro on the SPARC returns @code{CC_NOOVmode}
-for comparisons whose argument is a @code{plus}.
+GCC does not assume anything about how the machine realizes jumps.
+The machine description should define a single pattern, usually
+a @code{define_expand}, which expands to all the required insns.
+
+Usually, this would be a comparison insn to set the condition code
+and a separate branch insn testing the condition code and branching
+or not according to its value. For many machines, however,
+separating compares and branches is limiting, which is why the
+more flexible approach with one @code{define_expand} is used in GCC.
+The machine description becomes clearer for architectures that
+have compare-and-branch instructions but no condition code. It also
+works better when different sets of comparison operators are supported
+by different kinds of conditional branches (e.g. integer vs. floating-point),
+or by conditional branches with respect to conditional stores.
+
+Two separate insns are always used if the machine description represents
+a condition code register using the legacy RTL expression @code{(cc0)},
+and on most machines that use a separate condition code register
+(@pxref{Condition Code}). For machines that use @code{(cc0)}, in
+fact, the set and use of the condition code must be separate and
+adjacent@footnote{@code{note} insns can separate them, though.}, thus
+allowing flags in @code{cc_status} to be used (@pxref{Condition Code}) and
+so that the comparison and branch insns could be located from each other
+by using the functions @code{prev_cc0_setter} and @code{next_cc0_user}.
+
+Even in this case having a single entry point for conditional branches
+is advantageous, because it handles equally well the case where a single
+comparison instruction records the results of both signed and unsigned
+comparison of the given operands (with the branch insns coming in distinct
+signed and unsigned flavors) as in the x86 or SPARC, and the case where
+there are distinct signed and unsigned compare instructions and only
+one set of conditional branch instructions as in the PowerPC.
@end ifset
@ifset INTERNALS
@@ -5625,13 +5483,9 @@ the operations as far as possible. For instance,
@cindex @code{compare}, canonicalization of
@item
For the @code{compare} operator, a constant is always the second operand
-on machines where @code{cc0} is used (@pxref{Jump Patterns}). On other
-machines, there are rare cases where the compiler might want to construct
-a @code{compare} with a constant as the first operand. However, these
-cases are not common enough for it to be worthwhile to provide a pattern
-matching a constant as the first operand unless the machine actually has
-such an instruction.
+if the first argument is a condition code register or @code{(cc0)}.
+@item
An operand of @code{neg}, @code{not}, @code{mult}, @code{plus}, or
@code{minus} is made the first operand under the same conditions as
above.
@@ -5699,11 +5553,6 @@ the form
(plus:@var{m} (plus:@var{m} @var{x} @var{y}) @var{constant})
@end smallexample
-@item
-On machines that do not use @code{cc0},
-@code{(compare @var{x} (const_int 0))} will be converted to
-@var{x}.
-
@cindex @code{zero_extract}, canonicalization of
@cindex @code{sign_extract}, canonicalization of
@item
diff --git a/gcc/doc/passes.texi b/gcc/doc/passes.texi
index 3dcee398dd5..b28b87cb57a 100644
--- a/gcc/doc/passes.texi
+++ b/gcc/doc/passes.texi
@@ -21,7 +21,7 @@ where near complete.
* Parsing pass:: The language front end turns text into bits.
* Gimplification pass:: The bits are turned into something we can optimize.
* Pass manager:: Sequencing the optimization passes.
-* Tree-SSA passes:: Optimizations on a high-level representation.
+* Tree SSA passes:: Optimizations on a high-level representation.
* RTL passes:: Optimizations on a low-level representation.
@end menu
@@ -94,8 +94,8 @@ be passed to @code{rest_of_type_compilation}. Each function definition
should be passed to @code{cgraph_finalize_function}.
TODO: I know rest_of_compilation currently has all sorts of
-rtl-generation semantics. I plan to move all code generation
-bits (both tree and rtl) to compile_function. Should we hide
+RTL generation semantics. I plan to move all code generation
+bits (both Tree and RTL) to compile_function. Should we hide
cgraph from the front ends and move back to rest_of_compilation
as the official interface? Possibly we should rename all three
interfaces such that the names match in some meaningful way and
@@ -172,12 +172,12 @@ dump anything.
TODO: describe the global variables set up by the pass manager,
and a brief description of how a new pass should use it.
-I need to look at what info rtl passes use first@enddots{}
+I need to look at what info RTL passes use first@enddots{}
-@node Tree-SSA passes
-@section Tree-SSA passes
+@node Tree SSA passes
+@section Tree SSA passes
-The following briefly describes the tree optimization passes that are
+The following briefly describes the Tree optimization passes that are
run after gimplification and what source files they are located in.
@itemize @bullet
@@ -401,7 +401,7 @@ and described by @code{pass_loop}.
The optimizations performed by this pass are:
Loop invariant motion. This pass moves only invariants that
-would be hard to handle on rtl level (function calls, operations that expand to
+would be hard to handle on RTL level (function calls, operations that expand to
nontrivial sequences of insns). With @option{-funswitch-loops} it also moves
operands of conditions that are invariant out of the loop, so that we can use
just trivial invariantness analysis in loop unswitching. The pass also includes
@@ -422,8 +422,8 @@ Loop unswitching. This pass moves the conditional jumps that are invariant
out of the loops. To achieve this, a duplicate of the loop is created for
each possible outcome of conditional jump(s). The pass is implemented in
@file{tree-ssa-loop-unswitch.c}. This pass should eventually replace the
-rtl-level loop unswitching in @file{loop-unswitch.c}, but currently
-the rtl-level pass is not completely redundant yet due to deficiencies
+RTL level loop unswitching in @file{loop-unswitch.c}, but currently
+the RTL level pass is not completely redundant yet due to deficiencies
in tree level alias analysis.
The optimizations also use various utility functions contained in
@@ -438,11 +438,19 @@ conceptually unrolled by a factor @code{VF} (vectorization factor), which is
the number of elements operated upon in parallel in each iteration, and the
@code{VF} copies of each scalar operation are fused to form a vector operation.
Additional loop transformations such as peeling and versioning may take place
-to align the number of iterations, and to align the memory accesses in the loop.
-The pass is implemented in @file{tree-vectorizer.c} (the main driver and general
-utilities), @file{tree-vect-analyze.c} and @file{tree-vect-transform.c}.
+to align the number of iterations, and to align the memory accesses in the
+loop.
+The pass is implemented in @file{tree-vectorizer.c} (the main driver),
+@file{tree-vect-loop.c} and @file{tree-vect-loop-manip.c} (loop specific parts
+and general loop utilities), @file{tree-vect-slp} (loop-aware SLP
+functionality), @file{tree-vect-stmts.c} and @file{tree-vect-data-refs.c}.
Analysis of data references is in @file{tree-data-ref.c}.
+SLP Vectorization. This pass performs vectorization of straight-line code. The
+pass is implemented in @file{tree-vectorizer.c} (the main driver),
+@file{tree-vect-slp.c}, @file{tree-vect-stmts.c} and
+@file{tree-vect-data-refs.c}.
+
Autoparallelization. This pass splits the loop iteration space to run
into several threads. The pass is implemented in @file{tree-parloops.c}.
@@ -651,8 +659,8 @@ registers don't need to be saved. This pass is located in
@node RTL passes
@section RTL passes
-The following briefly describes the rtl generation and optimization
-passes that are run after tree optimization.
+The following briefly describes the RTL generation and optimization
+passes that are run after the Tree optimization passes.
@itemize @bullet
@item RTL generation
@@ -679,15 +687,15 @@ generated from the machine description by the programs @code{genflags}
and @code{gencodes}, tell this pass which standard names are available
for use and which patterns correspond to them.
-@item Generate exception handling landing pads
+@item Generation of exception landing pads
This pass generates the glue that handles communication between the
exception handling library routines and the exception handlers within
the function. Entry points in the function that are invoked by the
exception handling library are called @dfn{landing pads}. The code
-for this pass is located within @file{except.c}.
+for this pass is located in @file{except.c}.
-@item Cleanup control flow graph
+@item Control flow graph cleanup
This pass removes unreachable code, simplifies jumps to next, jumps to
jump, jumps across jumps, etc. The pass is run multiple times.
@@ -702,16 +710,16 @@ This pass attempts to remove redundant computation by substituting
variables that come from a single definition, and
seeing if the result can be simplified. It performs copy propagation
and addressing mode selection. The pass is run twice, with values
-being propagated into loops only on the second run. It is located in
-@file{fwprop.c}.
+being propagated into loops only on the second run. The code is
+located in @file{fwprop.c}.
@item Common subexpression elimination
This pass removes redundant computation within basic blocks, and
optimizes addressing modes based on cost. The pass is run twice.
-The source is located in @file{cse.c}.
+The code for this pass is located in @file{cse.c}.
-@item Global common subexpression elimination.
+@item Global common subexpression elimination
This pass performs two
different types of GCSE depending on whether you are optimizing for
@@ -755,22 +763,13 @@ This pass attempts to replace conditional branches and surrounding
assignments with arithmetic, boolean value producing comparison
instructions, and conditional move instructions. In the very last
invocation after reload, it will generate predicated instructions
-when supported by the target. The pass is located in @file{ifcvt.c}.
+when supported by the target. The code is located in @file{ifcvt.c}.
@item Web construction
This pass splits independent uses of each pseudo-register. This can
improve effect of the other transformation, such as CSE or register
-allocation. Its source files are @file{web.c}.
-
-@item Life analysis
-
-This pass computes which pseudo-registers are live at each point in
-the program, and makes the first instruction that uses a value point
-at the instruction that computed the value. It then deletes
-computations whose results are never used, and combines memory
-references with add or subtract instructions to make autoincrement or
-autodecrement addressing. The pass is located in @file{flow.c}.
+allocation. The code for this pass is located in @file{web.c}.
@item Instruction combination
@@ -778,23 +777,23 @@ This pass attempts to combine groups of two or three instructions that
are related by data flow into single instructions. It combines the
RTL expressions for the instructions by substitution, simplifies the
result using algebra, and then attempts to match the result against
-the machine description. The pass is located in @file{combine.c}.
+the machine description. The code is located in @file{combine.c}.
@item Register movement
This pass looks for cases where matching constraints would force an
instruction to need a reload, and this reload would be a
register-to-register move. It then attempts to change the registers
-used by the instruction to avoid the move instruction.
-The pass is located in @file{regmove.c}.
+used by the instruction to avoid the move instruction. The code is
+located in @file{regmove.c}.
-@item Optimize mode switching
+@item Mode switching optimization
This pass looks for instructions that require the processor to be in a
specific ``mode'' and minimizes the number of mode changes required to
satisfy all users. What these modes are, and what they apply to are
-completely target-specific.
-The source is located in @file{mode-switching.c}.
+completely target-specific. The code for this pass is located in
+@file{mode-switching.c}.
@cindex modulo scheduling
@cindex sms, swing, software pipelining
@@ -802,8 +801,8 @@ The source is located in @file{mode-switching.c}.
This pass looks at innermost loops and reorders their instructions
by overlapping different iterations. Modulo scheduling is performed
-immediately before instruction scheduling.
-The pass is located in (@file{modulo-sched.c}).
+immediately before instruction scheduling. The code for this pass is
+located in @file{modulo-sched.c}.
@item Instruction scheduling
@@ -813,7 +812,7 @@ floating point instructions often have this behavior on RISC machines.
It re-orders instructions within a basic block to try to separate the
definition and use of items that otherwise would cause pipeline
stalls. This pass is performed twice, before and after register
-allocation. The pass is located in @file{haifa-sched.c},
+allocation. The code for this pass is located in @file{haifa-sched.c},
@file{sched-deps.c}, @file{sched-ebb.c}, @file{sched-rgn.c} and
@file{sched-vis.c}.
@@ -884,13 +883,13 @@ This pass computes where the variables are stored at each
position in code and generates notes describing the variable locations
to RTL code. The location lists are then generated according to these
notes to debug information if the debugging information format supports
-location lists.
+location lists. The code is located in @file{var-tracking.c}.
@item Delayed branch scheduling
This optional pass attempts to find instructions that can go into the
-delay slots of other instructions, usually jumps and calls. The
-source file name is @file{reorg.c}.
+delay slots of other instructions, usually jumps and calls. The code
+for this pass is located in @file{reorg.c}.
@item Branch shortening
@@ -899,13 +898,14 @@ Thus, longer sequences of instructions must be used for long branches.
In this pass, the compiler figures out what how far each instruction
will be from each other instruction, and therefore whether the usual
instructions, or the longer sequences, must be used for each branch.
+The code for this pass is located in @file{final.c}.
@item Register-to-stack conversion
Conversion from usage of some hard registers to usage of a register
stack may be done at this point. Currently, this is supported only
-for the floating-point registers of the Intel 80387 coprocessor. The
-source file name is @file{reg-stack.c}.
+for the floating-point registers of the Intel 80387 coprocessor. The
+code for this pass is located in @file{reg-stack.c}.
@item Final
diff --git a/gcc/doc/plugins.texi b/gcc/doc/plugins.texi
index 7c3fbed354e..f02f931b102 100644
--- a/gcc/doc/plugins.texi
+++ b/gcc/doc/plugins.texi
@@ -9,7 +9,7 @@
@section Loading Plugins
-Plugins are supported on platforms that support @option{-ld
+Plugins are supported on platforms that support @option{-ldl
-rdynamic}. They are loaded by the compiler using @code{dlopen}
and invoked at pre-determined locations in the compilation
process.
@@ -30,6 +30,8 @@ Plugins are activated by the compiler at specific events as defined in
call @code{register_callback} specifying the name of the event and
address of the callback function that will handle that event.
+The header @file{gcc-plugin.h} must be the first gcc header to be included.
+
@subsection Plugin initialization
Every plugin should export a function called @code{plugin_init} that
@@ -41,14 +43,49 @@ This function is called from @code{compile_file} right before invoking
the parser. The arguments to @code{plugin_init} are:
@itemize @bullet
-@item @code{plugin_name}: Name of the plugin.
-@item @code{argc}: Number of arguments specified with @option{-fplugin-arg-...}.
-@item @code{argv}: Array of @code{argc} key-value pairs.
+@item @code{plugin_info}: Plugin invocation information.
+@item @code{version}: GCC version.
@end itemize
+The @code{plugin_info} struct is defined as follows:
+
+@smallexample
+struct plugin_name_args
+@{
+ char *base_name; /* Short name of the plugin
+ (filename without .so suffix). */
+ const char *full_name; /* Path to the plugin as specified with
+ -fplugin=. */
+ int argc; /* Number of arguments specified with
+ -fplugin-arg-.... */
+ struct plugin_argument *argv; /* Array of ARGC key-value pairs. */
+ const char *version; /* Version string provided by plugin. */
+ const char *help; /* Help string provided by plugin. */
+@}
+@end smallexample
+
If initialization fails, @code{plugin_init} must return a non-zero
value. Otherwise, it should return 0.
+The version of the GCC compiler loading the plugin is described by the
+following structure:
+
+@smallexample
+struct plugin_gcc_version
+@{
+ const char *basever;
+ const char *datestamp;
+ const char *devphase;
+ const char *revision;
+ const char *configuration_arguments;
+@};
+@end smallexample
+
+The function @code{plugin_default_version_check} takes two pointers to
+such structure and compare them field by field. It can be used by the
+plugin's @code{plugin_init} function.
+
+
@subsection Plugin callbacks
Callback functions have the following prototype:
@@ -71,12 +108,20 @@ enum plugin_event
PLUGIN_FINISH_UNIT, /* Useful for summary processing. */
PLUGIN_CXX_CP_PRE_GENERICIZE, /* Allows to see low level AST in C++ FE. */
PLUGIN_FINISH, /* Called before GCC exits. */
+ PLUGIN_INFO, /* Information about the plugin. */
+ PLUGIN_GGC_START, /* Called at start of GCC Garbage Collection. */
+ PLUGIN_GGC_MARKING, /* Extend the GGC marking. */
+ PLUGIN_GGC_END, /* Called at end of GGC. */
+ PLUGIN_REGISTER_GGC_ROOTS, /* Register an extra GGC root table. */
+ PLUGIN_ATTRIBUTES, /* Called during attribute registration */
PLUGIN_EVENT_LAST /* Dummy event used for indexing callback
array. */
@};
@end smallexample
-To register a callback, the plugin calls @code{register_callback} with the arguments:
+
+To register a callback, the plugin calls @code{register_callback} with
+the arguments:
@itemize
@item @code{char *name}: Plugin name.
@@ -85,6 +130,9 @@ To register a callback, the plugin calls @code{register_callback} with the argum
@item @code{void *user_data}: Pointer to plugin-specific data.
@end itemize
+For the PLUGIN_PASS_MANAGER_SETUP, PLUGIN_INFO, and
+PLUGIN_REGISTER_GGC_ROOTS pseudo-events the @code{callback} should be
+null, and the @code{user_data} is specific.
@section Interacting with the pass manager
@@ -119,7 +167,8 @@ struct plugin_pass
/* Sample plugin code that registers a new pass. */
int
-plugin_init (const char *plugin_name, int argc, struct plugin_argument *argv)
+plugin_init (struct plugin_name_args *plugin_info,
+ struct plugin_gcc_version *version)
@{
struct plugin_pass pass_info;
@@ -130,8 +179,86 @@ plugin_init (const char *plugin_name, int argc, struct plugin_argument *argv)
...
/* Register the new pass. */
- register_callback (plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &pass_info);
+ register_callback (plugin_info->base_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &pass_info);
...
@}
@end smallexample
+
+
+@section Interacting with the GCC Garbage Collector
+
+Some plugins may want to be informed when GGC (the GCC Garbage
+Collector) is running. They can register callbacks for the
+@code{PLUGIN_GGC_START} and @code{PLUGIN_GGC_END} events (for which
+the callback is called with a null @code{gcc_data}) to be notified of
+the start or end of the GCC garbage collection.
+
+Some plugins may need to have GGC mark additional data. This can be
+done by registering a callback (called with a null @code{gcc_data})
+for the @code{PLUGIN_GGC_MARKING} event. Such callbacks can call the
+@code{ggc_set_mark} routine, preferably thru the @code{ggc_mark} macro
+(and conversely, these routines should usually not be used in plugins
+outside of the @code{PLUGIN_GGC_MARKING} event).
+
+Some plugins may need to add extra GGC root tables, e.g. to handle
+their own @code{GTY}-ed data. This can be done with the
+@code{PLUGIN_REGISTER_GGC_ROOTS} pseudo-event with a null callback and
+the extra root table as @code{user_data}. Running the @code{gengtype
+-p @var{source-dir} @var{file-list} @var{plugin*.c} ...} utility
+generates this extra root table.
+
+You should understand the details of memory management inside GCC
+before using @code{PLUGIN_GGC_MARKING} or
+@code{PLUGIN_REGISTER_GGC_ROOTS}.
+
+
+@section Giving information about a plugin
+
+A plugin should give some information to the user about itself. This
+uses the following structure:
+
+@smallexample
+struct plugin_info
+@{
+ const char *version;
+ const char *help;
+@};
+@end smallexample
+
+Such a structure is passed as the @code{user_data} by the plugin's
+init routine using @code{register_callback} with the
+@code{PLUGIN_INFO} pseudo-event and a null callback.
+
+@section Registering custom attributes
+
+For analysis purposes it is useful to be able to add custom attributes.
+
+The @code{PLUGIN_ATTRIBUTES} callback is called during attribute
+registration. Use the @code{register_attribute} function to register
+custom attributes.
+
+@smallexample
+/* Attribute handler callback */
+static tree
+handle_user_attribute (tree *node, tree name, tree args,
+ int flags, bool *no_add_attrs)
+@{
+ return NULL_TREE;
+@}
+
+/* Attribute definition */
+static struct attribute_spec user_attr =
+ @{ "user", 1, 1, false, false, false, handle_user_attribute @};
+
+/* Plugin callback called during attribute registration.
+Registered with register_callback (plugin_name, PLUGIN_ATTRIBUTES, register_attributes, NULL)
+*/
+static void
+register_attributes (void *event_data, void *data)
+@{
+ warning (0, G_("Callback to register attributes"));
+ register_attribute (&user_attr);
+@}
+
+@end smallexample
diff --git a/gcc/doc/rtl.texi b/gcc/doc/rtl.texi
index 2567f10f4b0..79baa10e25d 100644
--- a/gcc/doc/rtl.texi
+++ b/gcc/doc/rtl.texi
@@ -10,10 +10,10 @@
@cindex representation of RTL
@cindex Register Transfer Language (RTL)
-Most of the work of the compiler is done on an intermediate representation
-called register transfer language. In this language, the instructions to be
-output are described, pretty much one by one, in an algebraic form that
-describes what the instruction does.
+The last part of the compiler work is done on a low-level intermediate
+representation called Register Transfer Language. In this language, the
+instructions to be output are described, pretty much one by one, in an
+algebraic form that describes what the instruction does.
RTL is inspired by Lisp lists. It has both an internal form, made up of
structures that point at other structures, and a textual form that is used
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 4c9b16279b5..bc15583bfb0 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -2504,8 +2504,8 @@ added to another register (as well as added to a displacement).
@defmac REGNO_OK_FOR_BASE_P (@var{num})
A C expression which is nonzero if register number @var{num} is
suitable for use as a base register in operand addresses.
-Like @code{GO_IF_LEGITIMATE_ADDRESS}, this macro should also
-exist in strict or non-strict variants. Both variants behave
+Like @code{TARGET_LEGITIMATE_ADDRESS_P}, this macro should also
+define a strict and a non-strict variant. Both variants behave
the same for hard register; for pseudos, the strict variant will
pass only those that have been allocated to a valid hard registers,
while the non-strict variant will pass all pseudos.
@@ -5361,42 +5361,31 @@ expressions and @code{const} arithmetic expressions, in addition to
@defmac MAX_REGS_PER_ADDRESS
A number, the maximum number of registers that can appear in a valid
memory address. Note that it is up to you to specify a value equal to
-the maximum number that @code{GO_IF_LEGITIMATE_ADDRESS} would ever
+the maximum number that @code{TARGET_LEGITIMATE_ADDRESS_P} would ever
accept.
@end defmac
-@defmac GO_IF_LEGITIMATE_ADDRESS (@var{mode}, @var{x}, @var{label})
-A C compound statement with a conditional @code{goto @var{label};}
-executed if @var{x} (an RTX) is a legitimate memory address on the
-target machine for a memory operand of mode @var{mode}.
+@deftypefn {Target Hook} TARGET_LEGITIMATE_ADDRESS_P (enum machine_mode @var{mode}, rtx @var{x}, bool @var{strict})
+A function that returns whether @var{x} (an RTX) is a legitimate memory
+address on the target machine for a memory operand of mode @var{mode}.
-It usually pays to define several simpler macros to serve as
-subroutines for this one. Otherwise it may be too complicated to
-understand.
+Legitimate addresses are defined in two variants: a strict variant and a
+non-strict one. The @code{strict} parameter chooses which variant is
+desired by the caller.
-This macro must exist in two variants: a strict variant and a
-non-strict one. The strict variant is used in the reload pass. It
-must be defined so that any pseudo-register that has not been
-allocated a hard register is considered a memory reference. In
-contexts where some kind of register is required, a pseudo-register
-with no hard register must be rejected.
+The strict variant is used in the reload pass. It must be defined so
+that any pseudo-register that has not been allocated a hard register is
+considered a memory reference. This is because in contexts where some
+kind of register is required, a pseudo-register with no hard register
+must be rejected. For non-hard registers, the strict variant should look
+up the @code{reg_renumber} array; it should then proceed using the hard
+register number in the array, or treat the pseudo as a memory reference
+if the array holds @code{-1}.
The non-strict variant is used in other passes. It must be defined to
accept all pseudo-registers in every context where some kind of
register is required.
-@findex REG_OK_STRICT
-Compiler source files that want to use the strict variant of this
-macro define the macro @code{REG_OK_STRICT}. You should use an
-@code{#ifdef REG_OK_STRICT} conditional to define the strict variant
-in that case and the non-strict variant otherwise.
-
-Subroutines to check for acceptable registers for various purposes (one
-for base registers, one for index registers, and so on) are typically
-among the subroutines used to define @code{GO_IF_LEGITIMATE_ADDRESS}.
-Then only these subroutine macros need have two variants; the higher
-levels of macros may be the same whether strict or not.
-
Normally, constant addresses which are the sum of a @code{symbol_ref}
and an integer are stored inside a @code{const} RTX to mark them as
constant. Therefore, there is no need to recognize such sums
@@ -5417,13 +5406,30 @@ into the @code{symbol_ref}, and then check for it here. When you see a
@code{const}, you will have to look inside it to find the
@code{symbol_ref} in order to determine the section. @xref{Assembler
Format}.
-@end defmac
+
+@cindex @code{GO_IF_LEGITIMATE_ADDRESS}
+Some ports are still using a deprecated legacy substitute for
+this hook, the @code{GO_IF_LEGITIMATE_ADDRESS} macro. This macro
+has this syntax:
+
+@example
+#define GO_IF_LEGITIMATE_ADDRESS (@var{mode}, @var{x}, @var{label})
+@end example
+
+@noindent
+and should @code{goto @var{label}} if the address @var{x} is a valid
+address on the target machine for a memory operand of mode @var{mode}.
+Whether the strict or non-strict variants are desired is defined by
+the @code{REG_OK_STRICT} macro introduced earlier in this section.
+Using the hook is usually simpler because it limits the number of
+files that are recompiled when changes are made.
+@end deftypefn
@defmac TARGET_MEM_CONSTRAINT
A single character to be used instead of the default @code{'m'}
character for general memory addresses. This defines the constraint
letter which matches the memory addresses accepted by
-@code{GO_IF_LEGITIMATE_ADDRESS_P}. Define this macro if you want to
+@code{TARGET_LEGITIMATE_ADDRESS_P}. Define this macro if you want to
support new address formats in your back end without changing the
semantics of the @code{'m'} constraint. This is necessary in order to
preserve functionality of inline assembly constructs using the
@@ -5724,8 +5730,47 @@ or target-specific sections.
@section Condition Code Status
@cindex condition code status
-@c prevent bad page break with this line
-This describes the condition code status.
+The macros in this section can be split in two families, according to the
+two ways of representing condition codes in GCC.
+
+The first representation is the so called @code{(cc0)} representation
+(@pxref{Jump Patterns}), where all instructions can have an implicit
+clobber of the condition codes. The second is the condition code
+register representation, which provides better schedulability for
+architectures that do have a condition code register, but on which
+most instructions do not affect it. The latter category includes
+most RISC machines.
+
+The implicit clobbering poses a strong restriction on the placement of
+the definition and use of the condition code, which need to be in adjacent
+insns for machines using @code{(cc0)}. This can prevent important
+optimizations on some machines. For example, on the IBM RS/6000, there
+is a delay for taken branches unless the condition code register is set
+three instructions earlier than the conditional branch. The instruction
+scheduler cannot perform this optimization if it is not permitted to
+separate the definition and use of the condition code register.
+
+For this reason, it is possible and suggested to use a register to
+represent the condition code for new ports. If there is a specific
+condition code register in the machine, use a hard register. If the
+condition code or comparison result can be placed in any general register,
+or if there are multiple condition registers, use a pseudo register.
+Registers used to store the condition code value will usually have a mode
+that is in class @code{MODE_CC}.
+
+Alternatively, you can use @code{BImode} if the comparison operator is
+specified already in the compare instruction. In this case, you are not
+interested in most macros in this section.
+
+@menu
+* CC0 Condition Codes:: Old style representation of condition codes.
+* MODE_CC Condition Codes:: Modern representation of condition codes.
+* Cond. Exec. Macros:: Macros to control conditional execution.
+@end menu
+
+@node CC0 Condition Codes
+@subsection Representation of condition codes using @code{(cc0)}
+@findex cc0
@findex cc_status
The file @file{conditions.h} defines a variable @code{cc_status} to
@@ -5791,12 +5836,45 @@ that looks at an attribute (@pxref{Insn Attributes}) named, for example,
two places, the @file{md} file and in @code{NOTICE_UPDATE_CC}.
@end defmac
+@node MODE_CC Condition Codes
+@subsection Representation of condition codes using registers
+@findex CCmode
+@findex MODE_CC
+
@defmac SELECT_CC_MODE (@var{op}, @var{x}, @var{y})
-Returns a mode from class @code{MODE_CC} to be used when comparison
-operation code @var{op} is applied to rtx @var{x} and @var{y}. For
-example, on the SPARC, @code{SELECT_CC_MODE} is defined as (see
-@pxref{Jump Patterns} for a description of the reason for this
-definition)
+On many machines, the condition code may be produced by other instructions
+than compares, for example the branch can use directly the condition
+code set by a subtract instruction. However, on some machines
+when the condition code is set this way some bits (such as the overflow
+bit) are not set in the same way as a test instruction, so that a different
+branch instruction must be used for some conditional branches. When
+this happens, use the machine mode of the condition code register to
+record different formats of the condition code register. Modes can
+also be used to record which compare instruction (e.g. a signed or an
+unsigned comparison) produced the condition codes.
+
+If other modes than @code{CCmode} are required, add them to
+@file{@var{machine}-modes.def} and define @code{SELECT_CC_MODE} to choose
+a mode given an operand of a compare. This is needed because the modes
+have to be chosen not only during RTL generation but also, for example,
+by instruction combination. The result of @code{SELECT_CC_MODE} should
+be consistent with the mode used in the patterns; for example to support
+the case of the add on the SPARC discussed above, we have the pattern
+
+@smallexample
+(define_insn ""
+ [(set (reg:CC_NOOV 0)
+ (compare:CC_NOOV
+ (plus:SI (match_operand:SI 0 "register_operand" "%r")
+ (match_operand:SI 1 "arith_operand" "rI"))
+ (const_int 0)))]
+ ""
+ "@dots{}")
+@end smallexample
+
+@noindent
+together with a @code{SELECT_CC_MODE} that returns @code{CC_NOOVmode}
+for comparisons whose argument is a @code{plus}:
@smallexample
#define SELECT_CC_MODE(OP,X,Y) \
@@ -5807,6 +5885,10 @@ definition)
? CC_NOOVmode : CCmode))
@end smallexample
+Another reason to use modes is to retain information on which operands
+were used by the comparison; see @code{REVERSIBLE_CC_MODE} later in
+this section.
+
You should define this macro if and only if you define extra CC modes
in @file{@var{machine}-modes.def}.
@end defmac
@@ -5863,20 +5945,6 @@ like:
@end smallexample
@end defmac
-@defmac REVERSE_CONDEXEC_PREDICATES_P (@var{op1}, @var{op2})
-A C expression that returns true if the conditional execution predicate
-@var{op1}, a comparison operation, is the inverse of @var{op2} and vice
-versa. Define this to return 0 if the target has conditional execution
-predicates that cannot be reversed safely. There is no need to validate
-that the arguments of op1 and op2 are the same, this is done separately.
-If no expansion is specified, this macro is defined as follows:
-
-@smallexample
-#define REVERSE_CONDEXEC_PREDICATES_P (x, y) \
- (GET_CODE ((x)) == reversed_comparison_code ((y), NULL))
-@end smallexample
-@end defmac
-
@deftypefn {Target Hook} bool TARGET_FIXED_CONDITION_CODE_REGS (unsigned int *, unsigned int *)
On targets which do not use @code{(cc0)}, and which use a hard
register rather than a pseudo-register to hold condition codes, the
@@ -5905,6 +5973,29 @@ same. If they are, it returns that mode. If they are different, it
returns @code{VOIDmode}.
@end deftypefn
+@node Cond. Exec. Macros
+@subsection Macros to control conditional execution
+@findex conditional execution
+@findex predication
+
+There is one macro that may need to be defined for targets
+supporting conditional execution, independent of how they
+represent conditional branches.
+
+@defmac REVERSE_CONDEXEC_PREDICATES_P (@var{op1}, @var{op2})
+A C expression that returns true if the conditional execution predicate
+@var{op1}, a comparison operation, is the inverse of @var{op2} and vice
+versa. Define this to return 0 if the target has conditional execution
+predicates that cannot be reversed safely. There is no need to validate
+that the arguments of op1 and op2 are the same, this is done separately.
+If no expansion is specified, this macro is defined as follows:
+
+@smallexample
+#define REVERSE_CONDEXEC_PREDICATES_P (x, y) \
+ (GET_CODE ((x)) == reversed_comparison_code ((y), NULL))
+@end smallexample
+@end defmac
+
@node Costs
@section Describing Relative Costs of Operations
@cindex costs of instructions
@@ -6872,13 +6963,14 @@ The default value is false.
This section describes macros that help implement generation of position
independent code. Simply defining these macros is not enough to
-generate valid PIC; you must also add support to the macros
-@code{GO_IF_LEGITIMATE_ADDRESS} and @code{PRINT_OPERAND_ADDRESS}, as
-well as @code{LEGITIMIZE_ADDRESS}. You must modify the definition of
-@samp{movsi} to do something appropriate when the source operand
-contains a symbolic address. You may also need to alter the handling of
-switch statements so that they use relative addresses.
-@c i rearranged the order of the macros above to try to force one of
+generate valid PIC; you must also add support to the hook
+@code{TARGET_LEGITIMATE_ADDRESS_P} and to the macro
+@code{PRINT_OPERAND_ADDRESS}, as well as @code{LEGITIMIZE_ADDRESS}. You
+must modify the definition of @samp{movsi} to do something appropriate
+when the source operand contains a symbolic address. You may also
+need to alter the handling of switch statements so that they use
+relative addresses.
+@c i rearranged the order of the macros above to try to force one of
@c them to the next line, to eliminate an overfull hbox. --mew 10feb93
@defmac PIC_OFFSET_TABLE_REGNUM
@@ -7292,7 +7384,14 @@ outputting a single uninitialized variable.
A C statement (sans semicolon) to output to the stdio stream
@var{stream} the assembler definition of a common-label named
@var{name} whose size is @var{size} bytes. The variable @var{rounded}
-is the size rounded up to whatever alignment the caller wants.
+is the size rounded up to whatever alignment the caller wants. It is
+possible that @var{size} may be zero, for instance if a struct with no
+other member than a zero-length array is defined. In this case, the
+backend must output a symbol definition that allocates at least one
+byte, both so that the address of the resulting object does not compare
+equal to any other, and because some object formats cannot even express
+the concept of a zero-sized common symbol, as that is how they represent
+an ordinary undefined external.
Use the expression @code{assemble_name (@var{stream}, @var{name})} to
output the name itself; before and after that, output the additional
@@ -10689,6 +10788,38 @@ and @var{type2}, or @code{NULL} if validity should be determined by
the front end.
@end deftypefn
+@deftypefn {Target Hook} {const char *} TARGET_INVALID_PARAMETER_TYPE (tree @var{type})
+If defined, this macro returns the diagnostic message when it is
+invalid for functions to include parameters of type @var{type},
+or @code{NULL} if validity should be determined by
+the front end. This is currently used only by the C and C++ front ends.
+@end deftypefn
+
+@deftypefn {Target Hook} {const char *} TARGET_INVALID_RETURN_TYPE (tree @var{type})
+If defined, this macro returns the diagnostic message when it is
+invalid for functions to have return type @var{type},
+or @code{NULL} if validity should be determined by
+the front end. This is currently used only by the C and C++ front ends.
+@end deftypefn
+
+@deftypefn {Target Hook} {tree} TARGET_PROMOTED_TYPE (tree @var{type})
+If defined, this target hook returns the type to which values of
+@var{type} should be promoted when they appear in expressions,
+analogous to the integer promotions, or @code{NULL_TREE} to use the
+front end's normal promotion rules. This hook is useful when there are
+target-specific types with special promotion rules.
+This is currently used only by the C and C++ front ends.
+@end deftypefn
+
+@deftypefn {Target Hook} {tree} TARGET_CONVERT_TO_TYPE (tree @var{type}, tree @var{expr})
+If defined, this hook returns the result of converting @var{expr} to
+@var{type}. It should return the converted expression,
+or @code{NULL_TREE} to apply the front end's normal conversion rules.
+This hook is useful when there are target-specific types with special
+conversion rules.
+This is currently used only by the C and C++ front ends.
+@end deftypefn
+
@defmac TARGET_USE_JCR_SECTION
This macro determines whether to use the JCR section to register Java
classes. By default, TARGET_USE_JCR_SECTION is defined to 1 if both
@@ -10728,3 +10859,21 @@ cannot safely move arguments from the registers in which they are passed
to the stack. Therefore, this hook should return true in general, but
false for naked functions. The default implementation always returns true.
@end deftypefn
+
+
+@deftypevr {Target Hook} {unsigned HOST_WIDE_INT} TARGET_CONST_ANCHOR
+On some architectures it can take multiple instructions to synthesize
+a constant. If there is another constant already in a register that
+is close enough in value then it is preferable that the new constant
+is computed from this register using immediate addition or
+substraction. We accomplish this through CSE. Besides the value of
+the constant we also add a lower and an upper constant anchor to the
+available expressions. These are then queried when encountering new
+constants. The anchors are computed by rounding the constant up and
+down to a multiple of the value of @code{TARGET_CONST_ANCHOR}.
+@code{TARGET_CONST_ANCHOR} should be the maximum positive value
+accepted by immediate-add plus one. We currently assume that the
+value of @code{TARGET_CONST_ANCHOR} is a power of 2. For example, on
+MIPS, where add-immediate takes a 16-bit signed value,
+@code{TARGET_CONST_ANCHOR} is set to @samp{0x8000}. The default value
+is zero, which disables this optimization. @end deftypevr
diff --git a/gcc/doc/tree-ssa.texi b/gcc/doc/tree-ssa.texi
index 659431b0274..ebb85a05769 100644
--- a/gcc/doc/tree-ssa.texi
+++ b/gcc/doc/tree-ssa.texi
@@ -41,6 +41,7 @@ passes for GIMPLE@.
* SSA Operands:: SSA names referenced by GIMPLE statements.
* SSA:: Static Single Assignment representation.
* Alias analysis:: Representing aliased loads and stores.
+* Memory model:: Memory model used by the middle-end.
@end menu
@node Annotations
@@ -108,9 +109,9 @@ full object that they represent. For instance, given
Since @code{a} and @code{b} are non-aliased locals, the statement
@code{a = b} will have one real definition and one real use because
-variable @code{b} is completely modified with the contents of
-variable @code{a}. Real definition are also known as @dfn{killing
-definitions}. Similarly, the use of @code{a} reads all its bits.
+variable @code{a} is completely modified with the contents of
+variable @code{b}. Real definition are also known as @dfn{killing
+definitions}. Similarly, the use of @code{b} reads all its bits.
In contrast, virtual operands are used with variables that can have
a partial or ambiguous reference. This includes structures, arrays,
@@ -892,3 +893,31 @@ providing its aliasing VDEF. The walk stops if asked to.
@end enumerate
+
+@node Memory model
+@section Memory model
+@cindex memory model
+
+The memory model used by the middle-end models that of the C/C++
+languages. The middle-end has the notion of an effective type
+of a memory region which is used for type-based alias analysis.
+
+The following is a refinement of ISO C99 6.5/6, clarifying the block copy case
+to follow common sense and extending the concept of a dynamic effective
+type to objects with a declared type as required for C++.
+
+@smallexample
+The effective type of an object for an access to its stored value is
+the declared type of the object or the effective type determined by
+a previous store to it. If a value is stored into an object through
+an lvalue having a type that is not a character type, then the
+type of the lvalue becomes the effective type of the object for that
+access and for subsequent accesses that do not modify the stored value.
+If a value is copied into an object using @code{memcpy} or @code{memmove},
+or is copied as an array of character type, then the effective type
+of the modified object for that access and for subsequent accesses that
+do not modify the value is undetermined. For all other accesses to an
+object, the effective type of the object is simply the type of the
+lvalue used for the access.
+@end smallexample
+
diff --git a/gcc/dojump.c b/gcc/dojump.c
index 36430851393..76f62c62eba 100644
--- a/gcc/dojump.c
+++ b/gcc/dojump.c
@@ -756,64 +756,6 @@ do_jump_by_parts_equality (tree exp, rtx if_false_label, rtx if_true_label)
if_true_label);
}
-/* Generate code for a comparison of OP0 and OP1 with rtx code CODE.
- MODE is the machine mode of the comparison, not of the result.
- (including code to compute the values to be compared) and set CC0
- according to the result. The decision as to signed or unsigned
- comparison must be made by the caller.
-
- We force a stack adjustment unless there are currently
- things pushed on the stack that aren't yet used.
-
- If MODE is BLKmode, SIZE is an RTX giving the size of the objects being
- compared. */
-
-rtx
-compare_from_rtx (rtx op0, rtx op1, enum rtx_code code, int unsignedp,
- enum machine_mode mode, rtx size)
-{
- rtx tem;
-
- /* If one operand is constant, make it the second one. Only do this
- if the other operand is not constant as well. */
-
- if (swap_commutative_operands_p (op0, op1))
- {
- tem = op0;
- op0 = op1;
- op1 = tem;
- code = swap_condition (code);
- }
-
- do_pending_stack_adjust ();
-
- code = unsignedp ? unsigned_condition (code) : code;
- tem = simplify_relational_operation (code, VOIDmode, mode, op0, op1);
- if (tem)
- {
- if (CONSTANT_P (tem))
- return tem;
-
- if (COMPARISON_P (tem))
- {
- code = GET_CODE (tem);
- op0 = XEXP (tem, 0);
- op1 = XEXP (tem, 1);
- mode = GET_MODE (op0);
- unsignedp = (code == GTU || code == LTU
- || code == GEU || code == LEU);
- }
- }
-
- emit_cmp_insn (op0, op1, code, size, mode, unsignedp);
-
-#if HAVE_cc0
- return gen_rtx_fmt_ee (code, VOIDmode, cc0_rtx, const0_rtx);
-#else
- return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
-#endif
-}
-
/* Like do_compare_and_jump but expects the values to compare as two rtx's.
The decision as to signed or unsigned comparison must be made by the caller.
diff --git a/gcc/dse.c b/gcc/dse.c
index ce2b7151c9f..3284ad4f5b6 100644
--- a/gcc/dse.c
+++ b/gcc/dse.c
@@ -2245,6 +2245,7 @@ check_mem_read_rtx (rtx *loc, void *data)
if (store_info->rhs
&& store_info->group_id == -1
&& store_info->cse_base == base
+ && width != -1
&& offset >= store_info->begin
&& offset + width <= store_info->end
&& all_positions_needed_p (store_info,
diff --git a/gcc/dummy-checksum.c b/gcc/dummy-checksum.c
index 81190a6ca15..c90f1ca9340 100644
--- a/gcc/dummy-checksum.c
+++ b/gcc/dummy-checksum.c
@@ -1 +1,3 @@
-const unsigned char executable_checksum[16] = { 0 };
+#include "config.h"
+#include "system.h"
+EXPORTED_CONST unsigned char executable_checksum[16] = { 0 };
diff --git a/gcc/dwarf2.h b/gcc/dwarf2.h
index a60064b93ba..96d989ed2f9 100644
--- a/gcc/dwarf2.h
+++ b/gcc/dwarf2.h
@@ -565,7 +565,13 @@ enum dwarf_location_atom
DW_OP_HP_fltconst8 = 0xe3,
DW_OP_HP_mod_range = 0xe4,
DW_OP_HP_unmod_range = 0xe5,
- DW_OP_HP_tls = 0xe6
+ DW_OP_HP_tls = 0xe6,
+
+ /* Used internally in dwarf2out.c to distinguish DW_OP_addr with a
+ direct symbol relocation from DW_OP_addr with a dtp-relative
+ symbol relocation. */
+ INTERNAL_DW_OP_tls_addr = 0x103
+
};
/* Type encodings. */
@@ -779,7 +785,6 @@ enum dwarf_call_frame_info
#define DW_CIE_ID 0xffffffff
#define DW64_CIE_ID 0xffffffffffffffffULL
-#define DW_CIE_VERSION 1
#define DW_CFA_extended 0
diff --git a/gcc/dwarf2asm.c b/gcc/dwarf2asm.c
index 7e3fc82c9de..7b0fa7b6262 100644
--- a/gcc/dwarf2asm.c
+++ b/gcc/dwarf2asm.c
@@ -871,7 +871,7 @@ dw2_output_indirect_constant_1 (splay_tree_node node,
sym = (const char *) node->key;
id = (tree) node->value;
- decl = build_decl (VAR_DECL, id, ptr_type_node);
+ decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, id, ptr_type_node);
DECL_ARTIFICIAL (decl) = 1;
DECL_IGNORED_P (decl) = 1;
DECL_INITIAL (decl) = decl;
@@ -879,7 +879,7 @@ dw2_output_indirect_constant_1 (splay_tree_node node,
if (TREE_PUBLIC (id))
{
TREE_PUBLIC (decl) = 1;
- make_decl_one_only (decl);
+ make_decl_one_only (decl, DECL_ASSEMBLER_NAME (decl));
}
else
TREE_STATIC (decl) = 1;
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index c387c57170c..fa1484d5906 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -91,7 +91,9 @@ along with GCC; see the file COPYING3. If not see
#include "input.h"
#ifdef DWARF2_DEBUGGING_INFO
-static void dwarf2out_source_line (unsigned int, const char *);
+static void dwarf2out_source_line (unsigned int, const char *, int);
+
+static rtx last_var_location_insn;
static rtx last_var_location_insn;
#endif
@@ -249,7 +251,8 @@ typedef struct GTY(()) cfa_loc {
HOST_WIDE_INT offset;
HOST_WIDE_INT base_offset;
unsigned int reg;
- int indirect; /* 1 if CFA is accessed via a dereference. */
+ BOOL_BITFIELD indirect : 1; /* 1 if CFA is accessed via a dereference. */
+ BOOL_BITFIELD in_use : 1; /* 1 if a saved cfa is stored here. */
} dw_cfa_location;
/* All call frame descriptions (FDE's) in the GCC generated DWARF
@@ -318,8 +321,6 @@ dw_fde_node;
#define DWARF_INITIAL_LENGTH_SIZE (DWARF_OFFSET_SIZE == 4 ? 4 : 12)
#endif
-#define DWARF_VERSION 2
-
/* Round SIZE up to the nearest BOUNDARY. */
#define DWARF_ROUND(SIZE,BOUNDARY) \
((((SIZE) + (BOUNDARY) - 1) / (BOUNDARY)) * (BOUNDARY))
@@ -410,7 +411,7 @@ static const char *dwarf_cfi_name (unsigned);
static dw_cfi_ref new_cfi (void);
static void add_cfi (dw_cfi_ref *, dw_cfi_ref);
static void add_fde_cfi (const char *, dw_cfi_ref);
-static void lookup_cfa_1 (dw_cfi_ref, dw_cfa_location *);
+static void lookup_cfa_1 (dw_cfi_ref, dw_cfa_location *, dw_cfa_location *);
static void lookup_cfa (dw_cfa_location *);
static void reg_save (const char *, unsigned, unsigned, HOST_WIDE_INT);
#ifdef DWARF2_UNWIND_INFO
@@ -529,6 +530,25 @@ init_return_column_size (enum machine_mode mode, rtx mem, unsigned int c)
emit_move_insn (adjust_address (mem, mode, offset), GEN_INT (size));
}
+/* Divide OFF by DWARF_CIE_DATA_ALIGNMENT, asserting no remainder. */
+
+static inline HOST_WIDE_INT
+div_data_align (HOST_WIDE_INT off)
+{
+ HOST_WIDE_INT r = off / DWARF_CIE_DATA_ALIGNMENT;
+ gcc_assert (r * DWARF_CIE_DATA_ALIGNMENT == off);
+ return r;
+}
+
+/* Return true if we need a signed version of a given opcode
+ (e.g. DW_CFA_offset_extended_sf vs DW_CFA_offset_extended). */
+
+static inline bool
+need_data_align_sf_opcode (HOST_WIDE_INT off)
+{
+ return DWARF_CIE_DATA_ALIGNMENT < 0 ? off > 0 : off < 0;
+}
+
/* Generate code to initialize the register size table. */
void
@@ -674,7 +694,10 @@ add_cfi (dw_cfi_ref *list_head, dw_cfi_ref cfi)
/* When DRAP is used, CFA is defined with an expression. Redefine
CFA may lead to a different CFA value. */
- if (fde && fde->drap_reg != INVALID_REGNUM)
+ /* ??? Of course, this heuristic fails when we're annotating epilogues,
+ because of course we'll always want to redefine the CFA back to the
+ stack pointer on the way out. Where should we move this check? */
+ if (0 && fde && fde->drap_reg != INVALID_REGNUM)
switch (cfi->dw_cfi_opc)
{
case DW_CFA_def_cfa_register:
@@ -695,14 +718,15 @@ add_cfi (dw_cfi_ref *list_head, dw_cfi_ref cfi)
*p = cfi;
}
-/* Generate a new label for the CFI info to refer to. */
+/* Generate a new label for the CFI info to refer to. FORCE is true
+ if a label needs to be output even when using .cfi_* directives. */
char *
-dwarf2out_cfi_label (void)
+dwarf2out_cfi_label (bool force)
{
static char label[20];
- if (dwarf2out_do_cfi_asm ())
+ if (!force && dwarf2out_do_cfi_asm ())
{
/* In this case, we will be emitting the asm directive instead of
the label, so just return a placeholder to keep the rest of the
@@ -718,23 +742,88 @@ dwarf2out_cfi_label (void)
return label;
}
+/* True if remember_state should be emitted before following CFI directive. */
+static bool emit_cfa_remember;
+
/* Add CFI to the current fde at the PC value indicated by LABEL if specified,
or to the CIE if LABEL is NULL. */
static void
add_fde_cfi (const char *label, dw_cfi_ref cfi)
{
- dw_cfi_ref *list_head = &cie_cfi_head;
+ dw_cfi_ref *list_head;
+
+ if (emit_cfa_remember)
+ {
+ dw_cfi_ref cfi_remember;
+
+ /* Emit the state save. */
+ emit_cfa_remember = false;
+ cfi_remember = new_cfi ();
+ cfi_remember->dw_cfi_opc = DW_CFA_remember_state;
+ add_fde_cfi (label, cfi_remember);
+ }
+
+ list_head = &cie_cfi_head;
if (dwarf2out_do_cfi_asm ())
{
if (label)
{
+ dw_fde_ref fde = current_fde ();
+
+ gcc_assert (fde != NULL);
+
+ /* We still have to add the cfi to the list so that lookup_cfa
+ works later on. When -g2 and above we even need to force
+ emitting of CFI labels and add to list a DW_CFA_set_loc for
+ convert_cfa_to_fb_loc_list purposes. If we're generating
+ DWARF3 output we use DW_OP_call_frame_cfa and so don't use
+ convert_cfa_to_fb_loc_list. */
+ if (dwarf_version == 2
+ && debug_info_level > DINFO_LEVEL_TERSE
+ && (write_symbols == DWARF2_DEBUG
+ || write_symbols == VMS_AND_DWARF2_DEBUG))
+ {
+ switch (cfi->dw_cfi_opc)
+ {
+ case DW_CFA_def_cfa_offset:
+ case DW_CFA_def_cfa_offset_sf:
+ case DW_CFA_def_cfa_register:
+ case DW_CFA_def_cfa:
+ case DW_CFA_def_cfa_sf:
+ case DW_CFA_def_cfa_expression:
+ case DW_CFA_restore_state:
+ if (*label == 0 || strcmp (label, "<do not output>") == 0)
+ label = dwarf2out_cfi_label (true);
+
+ if (fde->dw_fde_current_label == NULL
+ || strcmp (label, fde->dw_fde_current_label) != 0)
+ {
+ dw_cfi_ref xcfi;
+
+ label = xstrdup (label);
+
+ /* Set the location counter to the new label. */
+ xcfi = new_cfi ();
+ /* It doesn't metter whether DW_CFA_set_loc
+ or DW_CFA_advance_loc4 is added here, those aren't
+ emitted into assembly, only looked up by
+ convert_cfa_to_fb_loc_list. */
+ xcfi->dw_cfi_opc = DW_CFA_set_loc;
+ xcfi->dw_cfi_oprnd1.dw_cfi_addr = label;
+ add_cfi (&fde->dw_fde_cfi, xcfi);
+ fde->dw_fde_current_label = label;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
output_cfi_directive (cfi);
- /* We still have to add the cfi to the list so that
- lookup_cfa works later on. */
- list_head = &current_fde ()->dw_fde_cfi;
+ list_head = &fde->dw_fde_cfi;
}
/* ??? If this is a CFI for the CIE, we don't emit. This
assumes that the standard CIE contents that the assembler
@@ -749,7 +838,7 @@ add_fde_cfi (const char *label, dw_cfi_ref cfi)
gcc_assert (fde != NULL);
if (*label == 0)
- label = dwarf2out_cfi_label ();
+ label = dwarf2out_cfi_label (false);
if (fde->dw_fde_current_label == NULL
|| strcmp (label, fde->dw_fde_current_label) != 0)
@@ -780,7 +869,7 @@ add_fde_cfi (const char *label, dw_cfi_ref cfi)
/* Subroutine of lookup_cfa. */
static void
-lookup_cfa_1 (dw_cfi_ref cfi, dw_cfa_location *loc)
+lookup_cfa_1 (dw_cfi_ref cfi, dw_cfa_location *loc, dw_cfa_location *remember)
{
switch (cfi->dw_cfi_opc)
{
@@ -799,6 +888,18 @@ lookup_cfa_1 (dw_cfi_ref cfi, dw_cfa_location *loc)
case DW_CFA_def_cfa_expression:
get_cfa_from_loc_descr (loc, cfi->dw_cfi_oprnd1.dw_cfi_loc);
break;
+
+ case DW_CFA_remember_state:
+ gcc_assert (!remember->in_use);
+ *remember = *loc;
+ remember->in_use = 1;
+ break;
+ case DW_CFA_restore_state:
+ gcc_assert (remember->in_use);
+ *loc = *remember;
+ remember->in_use = 0;
+ break;
+
default:
break;
}
@@ -811,19 +912,19 @@ lookup_cfa (dw_cfa_location *loc)
{
dw_cfi_ref cfi;
dw_fde_ref fde;
+ dw_cfa_location remember;
+ memset (loc, 0, sizeof (*loc));
loc->reg = INVALID_REGNUM;
- loc->offset = 0;
- loc->indirect = 0;
- loc->base_offset = 0;
+ remember = *loc;
for (cfi = cie_cfi_head; cfi; cfi = cfi->dw_cfi_next)
- lookup_cfa_1 (cfi, loc);
+ lookup_cfa_1 (cfi, loc, &remember);
fde = current_fde ();
if (fde)
for (cfi = fde->dw_fde_cfi; cfi; cfi = cfi->dw_cfi_next)
- lookup_cfa_1 (cfi, loc);
+ lookup_cfa_1 (cfi, loc, &remember);
}
/* The current rule for calculating the DWARF2 canonical frame address. */
@@ -833,6 +934,9 @@ static dw_cfa_location cfa;
from the CFA. */
static dw_cfa_location cfa_store;
+/* The current save location around an epilogue. */
+static dw_cfa_location cfa_remember;
+
/* The running total of the size of arguments pushed onto the stack. */
static HOST_WIDE_INT args_size;
@@ -896,7 +1000,7 @@ def_cfa_1 (const char *label, dw_cfa_location *loc_p)
the CFA register did not change but the offset did. The data
factoring for DW_CFA_def_cfa_offset_sf happens in output_cfi, or
in the assembler via the .cfi_def_cfa_offset directive. */
- if (loc.offset < 0)
+ if (need_data_align_sf_opcode (loc.offset))
cfi->dw_cfi_opc = DW_CFA_def_cfa_offset_sf;
else
cfi->dw_cfi_opc = DW_CFA_def_cfa_offset;
@@ -923,7 +1027,7 @@ def_cfa_1 (const char *label, dw_cfa_location *loc_p)
the specified offset. The data factoring for DW_CFA_def_cfa_sf
happens in output_cfi, or in the assembler via the .cfi_def_cfa
directive. */
- if (loc.offset < 0)
+ if (need_data_align_sf_opcode (loc.offset))
cfi->dw_cfi_opc = DW_CFA_def_cfa_sf;
else
cfi->dw_cfi_opc = DW_CFA_def_cfa;
@@ -971,7 +1075,7 @@ reg_save (const char *label, unsigned int reg, unsigned int sreg, HOST_WIDE_INT
}
else if (sreg == INVALID_REGNUM)
{
- if (offset < 0)
+ if (need_data_align_sf_opcode (offset))
cfi->dw_cfi_opc = DW_CFA_offset_extended_sf;
else if (reg & ~0x3f)
cfi->dw_cfi_opc = DW_CFA_offset_extended;
@@ -1218,8 +1322,7 @@ compute_barrier_args_size_1 (rtx insn, HOST_WIDE_INT cur_args_size,
if (! RTX_FRAME_RELATED_P (insn))
{
- if (prologue_epilogue_contains (insn)
- || sibcall_epilogue_contains (insn))
+ if (prologue_epilogue_contains (insn))
/* Nothing */;
else if (GET_CODE (PATTERN (insn)) == SET)
offset = stack_adjust_offset (PATTERN (insn), cur_args_size, 0);
@@ -1392,7 +1495,7 @@ dwarf2out_stack_adjust (rtx insn, bool after_p)
with this function. Proper support would require all frame-related
insns to be marked, and to be able to handle saving state around
epilogues textually in the middle of the function. */
- if (prologue_epilogue_contains (insn) || sibcall_epilogue_contains (insn))
+ if (prologue_epilogue_contains (insn))
return;
/* If INSN is an instruction from target of an annulled branch, the
@@ -1465,7 +1568,7 @@ dwarf2out_stack_adjust (rtx insn, bool after_p)
if (offset == 0)
return;
- label = dwarf2out_cfi_label ();
+ label = dwarf2out_cfi_label (false);
dwarf2out_args_size_adjust (offset, label);
}
@@ -1666,6 +1769,156 @@ reg_saved_in (rtx reg)
value, not an offset. */
static dw_cfa_location cfa_temp;
+/* A subroutine of dwarf2out_frame_debug, process a REG_DEF_CFA note. */
+
+static void
+dwarf2out_frame_debug_def_cfa (rtx pat, const char *label)
+{
+ memset (&cfa, 0, sizeof (cfa));
+
+ switch (GET_CODE (pat))
+ {
+ case PLUS:
+ cfa.reg = REGNO (XEXP (pat, 0));
+ cfa.offset = INTVAL (XEXP (pat, 1));
+ break;
+
+ case REG:
+ cfa.reg = REGNO (pat);
+ break;
+
+ default:
+ /* Recurse and define an expression. */
+ gcc_unreachable ();
+ }
+
+ def_cfa_1 (label, &cfa);
+}
+
+/* A subroutine of dwarf2out_frame_debug, process a REG_ADJUST_CFA note. */
+
+static void
+dwarf2out_frame_debug_adjust_cfa (rtx pat, const char *label)
+{
+ rtx src, dest;
+
+ gcc_assert (GET_CODE (pat) == SET);
+ dest = XEXP (pat, 0);
+ src = XEXP (pat, 1);
+
+ switch (GET_CODE (src))
+ {
+ case PLUS:
+ gcc_assert (REGNO (XEXP (src, 0)) == cfa.reg);
+ cfa.offset -= INTVAL (XEXP (src, 1));
+ break;
+
+ case REG:
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+
+ cfa.reg = REGNO (dest);
+ gcc_assert (cfa.indirect == 0);
+
+ def_cfa_1 (label, &cfa);
+}
+
+/* A subroutine of dwarf2out_frame_debug, process a REG_CFA_OFFSET note. */
+
+static void
+dwarf2out_frame_debug_cfa_offset (rtx set, const char *label)
+{
+ HOST_WIDE_INT offset;
+ rtx src, addr, span;
+
+ src = XEXP (set, 1);
+ addr = XEXP (set, 0);
+ gcc_assert (MEM_P (addr));
+ addr = XEXP (addr, 0);
+
+ /* As documented, only consider extremely simple addresses. */
+ switch (GET_CODE (addr))
+ {
+ case REG:
+ gcc_assert (REGNO (addr) == cfa.reg);
+ offset = -cfa.offset;
+ break;
+ case PLUS:
+ gcc_assert (REGNO (XEXP (addr, 0)) == cfa.reg);
+ offset = INTVAL (XEXP (addr, 1)) - cfa.offset;
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
+ span = targetm.dwarf_register_span (src);
+
+ /* ??? We'd like to use queue_reg_save, but we need to come up with
+ a different flushing heuristic for epilogues. */
+ if (!span)
+ reg_save (label, DWARF_FRAME_REGNUM (REGNO (src)), INVALID_REGNUM, offset);
+ else
+ {
+ /* We have a PARALLEL describing where the contents of SRC live.
+ Queue register saves for each piece of the PARALLEL. */
+ int par_index;
+ int limit;
+ HOST_WIDE_INT span_offset = offset;
+
+ gcc_assert (GET_CODE (span) == PARALLEL);
+
+ limit = XVECLEN (span, 0);
+ for (par_index = 0; par_index < limit; par_index++)
+ {
+ rtx elem = XVECEXP (span, 0, par_index);
+
+ reg_save (label, DWARF_FRAME_REGNUM (REGNO (elem)),
+ INVALID_REGNUM, span_offset);
+ span_offset += GET_MODE_SIZE (GET_MODE (elem));
+ }
+ }
+}
+
+/* A subroutine of dwarf2out_frame_debug, process a REG_CFA_REGISTER note. */
+
+static void
+dwarf2out_frame_debug_cfa_register (rtx set, const char *label)
+{
+ rtx src, dest;
+ unsigned sregno, dregno;
+
+ src = XEXP (set, 1);
+ dest = XEXP (set, 0);
+
+ if (src == pc_rtx)
+ sregno = DWARF_FRAME_RETURN_COLUMN;
+ else
+ sregno = DWARF_FRAME_REGNUM (REGNO (src));
+
+ dregno = DWARF_FRAME_REGNUM (REGNO (dest));
+
+ /* ??? We'd like to use queue_reg_save, but we need to come up with
+ a different flushing heuristic for epilogues. */
+ reg_save (label, sregno, dregno, 0);
+}
+
+/* A subroutine of dwarf2out_frame_debug, process a REG_CFA_RESTORE note. */
+
+static void
+dwarf2out_frame_debug_cfa_restore (rtx reg, const char *label)
+{
+ dw_cfi_ref cfi = new_cfi ();
+ unsigned int regno = DWARF_FRAME_REGNUM (REGNO (reg));
+
+ cfi->dw_cfi_opc = (regno & ~0x3f ? DW_CFA_restore_extended : DW_CFA_restore);
+ cfi->dw_cfi_oprnd1.dw_cfi_reg_num = regno;
+
+ add_fde_cfi (label, cfi);
+}
+
/* Record call frame debugging information for an expression EXPR,
which either sets SP or FP (adjusting how we calculate the frame
address) or saves a register to the stack or another register.
@@ -2373,7 +2626,8 @@ void
dwarf2out_frame_debug (rtx insn, bool after_p)
{
const char *label;
- rtx src;
+ rtx note, n;
+ bool handled_one = false;
if (insn == NULL_RTX)
{
@@ -2417,16 +2671,155 @@ dwarf2out_frame_debug (rtx insn, bool after_p)
return;
}
- label = dwarf2out_cfi_label ();
- src = find_reg_note (insn, REG_FRAME_RELATED_EXPR, NULL_RTX);
- if (src)
- insn = XEXP (src, 0);
- else
- insn = PATTERN (insn);
+ label = dwarf2out_cfi_label (false);
+
+ for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
+ switch (REG_NOTE_KIND (note))
+ {
+ case REG_FRAME_RELATED_EXPR:
+ insn = XEXP (note, 0);
+ goto found;
+
+ case REG_CFA_DEF_CFA:
+ dwarf2out_frame_debug_def_cfa (XEXP (note, 0), label);
+ handled_one = true;
+ break;
+
+ case REG_CFA_ADJUST_CFA:
+ n = XEXP (note, 0);
+ if (n == NULL)
+ {
+ n = PATTERN (insn);
+ if (GET_CODE (n) == PARALLEL)
+ n = XVECEXP (n, 0, 0);
+ }
+ dwarf2out_frame_debug_adjust_cfa (n, label);
+ handled_one = true;
+ break;
+
+ case REG_CFA_OFFSET:
+ n = XEXP (note, 0);
+ if (n == NULL)
+ n = single_set (insn);
+ dwarf2out_frame_debug_cfa_offset (n, label);
+ handled_one = true;
+ break;
+
+ case REG_CFA_REGISTER:
+ n = XEXP (note, 0);
+ if (n == NULL)
+ {
+ n = PATTERN (insn);
+ if (GET_CODE (n) == PARALLEL)
+ n = XVECEXP (n, 0, 0);
+ }
+ dwarf2out_frame_debug_cfa_register (n, label);
+ handled_one = true;
+ break;
+
+ case REG_CFA_RESTORE:
+ n = XEXP (note, 0);
+ if (n == NULL)
+ {
+ n = PATTERN (insn);
+ if (GET_CODE (n) == PARALLEL)
+ n = XVECEXP (n, 0, 0);
+ n = XEXP (n, 0);
+ }
+ dwarf2out_frame_debug_cfa_restore (n, label);
+ handled_one = true;
+ break;
+
+ default:
+ break;
+ }
+ if (handled_one)
+ return;
+ insn = PATTERN (insn);
+ found:
dwarf2out_frame_debug_expr (insn, label);
}
+/* Determine if we need to save and restore CFI information around this
+ epilogue. If SIBCALL is true, then this is a sibcall epilogue. If
+ we do need to save/restore, then emit the save now, and insert a
+ NOTE_INSN_CFA_RESTORE_STATE at the appropriate place in the stream. */
+
+void
+dwarf2out_begin_epilogue (rtx insn)
+{
+ bool saw_frp = false;
+ rtx i;
+
+ /* Scan forward to the return insn, noticing if there are possible
+ frame related insns. */
+ for (i = NEXT_INSN (insn); i ; i = NEXT_INSN (i))
+ {
+ if (!INSN_P (i))
+ continue;
+
+ /* Look for both regular and sibcalls to end the block. */
+ if (returnjump_p (i))
+ break;
+ if (CALL_P (i) && SIBLING_CALL_P (i))
+ break;
+
+ if (RTX_FRAME_RELATED_P (i))
+ saw_frp = true;
+ }
+
+ /* If the port doesn't emit epilogue unwind info, we don't need a
+ save/restore pair. */
+ if (!saw_frp)
+ return;
+
+ /* Otherwise, search forward to see if the return insn was the last
+ basic block of the function. If so, we don't need save/restore. */
+ gcc_assert (i != NULL);
+ i = next_real_insn (i);
+ if (i == NULL)
+ return;
+
+ /* Insert the restore before that next real insn in the stream, and before
+ a potential NOTE_INSN_EPILOGUE_BEG -- we do need these notes to be
+ properly nested. This should be after any label or alignment. This
+ will be pushed into the CFI stream by the function below. */
+ while (1)
+ {
+ rtx p = PREV_INSN (i);
+ if (!NOTE_P (p))
+ break;
+ if (NOTE_KIND (p) == NOTE_INSN_BASIC_BLOCK)
+ break;
+ i = p;
+ }
+ emit_note_before (NOTE_INSN_CFA_RESTORE_STATE, i);
+
+ emit_cfa_remember = true;
+
+ /* And emulate the state save. */
+ gcc_assert (!cfa_remember.in_use);
+ cfa_remember = cfa;
+ cfa_remember.in_use = 1;
+}
+
+/* A "subroutine" of dwarf2out_begin_epilogue. Emit the restore required. */
+
+void
+dwarf2out_frame_debug_restore_state (void)
+{
+ dw_cfi_ref cfi = new_cfi ();
+ const char *label = dwarf2out_cfi_label (false);
+
+ cfi->dw_cfi_opc = DW_CFA_restore_state;
+ add_fde_cfi (label, cfi);
+
+ gcc_assert (cfa_remember.in_use);
+ cfa = cfa_remember;
+ cfa_remember.in_use = 0;
+}
+
#endif
/* Describe for the GTY machinery what parts of dw_cfi_oprnd1 are used. */
@@ -2440,6 +2833,8 @@ dw_cfi_oprnd1_desc (enum dwarf_call_frame_info cfi)
{
case DW_CFA_nop:
case DW_CFA_GNU_window_save:
+ case DW_CFA_remember_state:
+ case DW_CFA_restore_state:
return dw_cfi_oprnd_unused;
case DW_CFA_set_loc:
@@ -2454,6 +2849,7 @@ dw_cfi_oprnd1_desc (enum dwarf_call_frame_info cfi)
case DW_CFA_def_cfa:
case DW_CFA_offset_extended_sf:
case DW_CFA_def_cfa_sf:
+ case DW_CFA_restore:
case DW_CFA_restore_extended:
case DW_CFA_undefined:
case DW_CFA_same_value:
@@ -2557,16 +2953,6 @@ switch_to_eh_frame_section (void)
}
}
-/* Divide OFF by DWARF_CIE_DATA_ALIGNMENT, asserting no remainder. */
-
-static HOST_WIDE_INT
-div_data_align (HOST_WIDE_INT off)
-{
- HOST_WIDE_INT r = off / DWARF_CIE_DATA_ALIGNMENT;
- gcc_assert (r * DWARF_CIE_DATA_ALIGNMENT == off);
- return r;
-}
-
/* Output a Call Frame Information opcode and its operand(s). */
static void
@@ -2731,42 +3117,42 @@ output_cfi_directive (dw_cfi_ref cfi)
case DW_CFA_offset:
case DW_CFA_offset_extended:
case DW_CFA_offset_extended_sf:
- r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, 0);
+ r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, 1);
fprintf (asm_out_file, "\t.cfi_offset %lu, "HOST_WIDE_INT_PRINT_DEC"\n",
r, cfi->dw_cfi_oprnd2.dw_cfi_offset);
break;
case DW_CFA_restore:
case DW_CFA_restore_extended:
- r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, 0);
+ r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, 1);
fprintf (asm_out_file, "\t.cfi_restore %lu\n", r);
break;
case DW_CFA_undefined:
- r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, 0);
+ r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, 1);
fprintf (asm_out_file, "\t.cfi_undefined %lu\n", r);
break;
case DW_CFA_same_value:
- r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, 0);
+ r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, 1);
fprintf (asm_out_file, "\t.cfi_same_value %lu\n", r);
break;
case DW_CFA_def_cfa:
case DW_CFA_def_cfa_sf:
- r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, 0);
+ r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, 1);
fprintf (asm_out_file, "\t.cfi_def_cfa %lu, "HOST_WIDE_INT_PRINT_DEC"\n",
r, cfi->dw_cfi_oprnd2.dw_cfi_offset);
break;
case DW_CFA_def_cfa_register:
- r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, 0);
+ r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, 1);
fprintf (asm_out_file, "\t.cfi_def_cfa_register %lu\n", r);
break;
case DW_CFA_register:
- r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, 0);
- r2 = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd2.dw_cfi_reg_num, 0);
+ r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, 1);
+ r2 = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd2.dw_cfi_reg_num, 1);
fprintf (asm_out_file, "\t.cfi_register %lu, %lu\n", r, r2);
break;
@@ -2777,6 +3163,13 @@ output_cfi_directive (dw_cfi_ref cfi)
cfi->dw_cfi_oprnd1.dw_cfi_offset);
break;
+ case DW_CFA_remember_state:
+ fprintf (asm_out_file, "\t.cfi_remember_state\n");
+ break;
+ case DW_CFA_restore_state:
+ fprintf (asm_out_file, "\t.cfi_restore_state\n");
+ break;
+
case DW_CFA_GNU_args_size:
fprintf (asm_out_file, "\t.cfi_escape 0x%x,", DW_CFA_GNU_args_size);
dw2_asm_output_data_uleb128_raw (cfi->dw_cfi_oprnd1.dw_cfi_offset);
@@ -2820,6 +3213,7 @@ output_call_frame_info (int for_eh)
int per_encoding = DW_EH_PE_absptr;
int lsda_encoding = DW_EH_PE_absptr;
int return_reg;
+ int dw_cie_version;
/* Don't emit a CIE if there won't be any FDEs. */
if (fde_table_in_use == 0)
@@ -2900,7 +3294,14 @@ output_call_frame_info (int for_eh)
(for_eh ? 0 : DWARF_CIE_ID),
"CIE Identifier Tag");
- dw2_asm_output_data (1, DW_CIE_VERSION, "CIE Version");
+ /* Use the CIE version 3 for DWARF3; allow DWARF2 to continue to
+ use CIE version 1, unless that would produce incorrect results
+ due to overflowing the return register column. */
+ return_reg = DWARF2_FRAME_REG_OUT (DWARF_FRAME_RETURN_COLUMN, for_eh);
+ dw_cie_version = 1;
+ if (return_reg >= 256 || dwarf_version > 2)
+ dw_cie_version = 3;
+ dw2_asm_output_data (1, dw_cie_version, "CIE Version");
augmentation[0] = 0;
augmentation_size = 0;
@@ -2972,8 +3373,7 @@ output_call_frame_info (int for_eh)
dw2_asm_output_data_sleb128 (DWARF_CIE_DATA_ALIGNMENT,
"CIE Data Alignment Factor");
- return_reg = DWARF2_FRAME_REG_OUT (DWARF_FRAME_RETURN_COLUMN, for_eh);
- if (DW_CIE_VERSION == 1)
+ if (dw_cie_version == 1)
dw2_asm_output_data (1, return_reg, "CIE RA Column");
else
dw2_asm_output_data_uleb128 (return_reg, "CIE RA Column");
@@ -3243,7 +3643,7 @@ dwarf2out_begin_prologue (unsigned int line ATTRIBUTE_UNUSED,
prologue case, not the eh frame case. */
#ifdef DWARF2_DEBUGGING_INFO
if (file)
- dwarf2out_source_line (line, file);
+ dwarf2out_source_line (line, file, 0);
#endif
if (dwarf2out_do_cfi_asm ())
@@ -3397,12 +3797,6 @@ struct GTY(()) dwarf_file_data {
int emitted_number;
};
-/* We need some way to distinguish DW_OP_addr with a direct symbol
- relocation from DW_OP_addr with a dtp-relative symbol relocation. */
-#define INTERNAL_DW_OP_tls_addr \
- ((enum dwarf_location_atom)(0x100 + DW_OP_addr))
-
-
typedef struct dw_val_struct *dw_val_ref;
typedef struct die_struct *dw_die_ref;
typedef const struct die_struct *const_dw_die_ref;
@@ -3820,6 +4214,7 @@ dwarf_stack_op_name (unsigned int op)
return "DW_OP_xderef_size";
case DW_OP_nop:
return "DW_OP_nop";
+
case DW_OP_push_object_address:
return "DW_OP_push_object_address";
case DW_OP_call2:
@@ -3832,10 +4227,20 @@ dwarf_stack_op_name (unsigned int op)
return "DW_OP_implicit_value";
case DW_OP_stack_value:
return "DW_OP_stack_value";
+ case DW_OP_form_tls_address:
+ return "DW_OP_form_tls_address";
+ case DW_OP_call_frame_cfa:
+ return "DW_OP_call_frame_cfa";
+ case DW_OP_bit_piece:
+ return "DW_OP_bit_piece";
+
case DW_OP_GNU_push_tls_address:
return "DW_OP_GNU_push_tls_address";
case DW_OP_GNU_uninit:
return "DW_OP_GNU_uninit";
+ case DW_OP_GNU_encoded_addr:
+ return "DW_OP_GNU_encoded_addr";
+
default:
return "OP_<unknown>";
}
@@ -5179,8 +5584,7 @@ static void output_line_info (void);
static void output_file_names (void);
static dw_die_ref base_type_die (tree);
static int is_base_type (tree);
-static bool is_subrange_type (const_tree);
-static dw_die_ref subrange_type_die (tree, dw_die_ref);
+static dw_die_ref subrange_type_die (tree, tree, tree, dw_die_ref);
static dw_die_ref modified_type_die (tree, int, int, dw_die_ref);
static int type_is_enum (const_tree);
static unsigned int dbx_reg_number (const_rtx);
@@ -5319,6 +5723,9 @@ static int maybe_emit_file (struct dwarf_file_data *fd);
#ifndef DEBUG_PUBNAMES_SECTION
#define DEBUG_PUBNAMES_SECTION ".debug_pubnames"
#endif
+#ifndef DEBUG_PUBTYPES_SECTION
+#define DEBUG_PUBTYPES_SECTION ".debug_pubtypes"
+#endif
#ifndef DEBUG_STR_SECTION
#define DEBUG_STR_SECTION ".debug_str"
#endif
@@ -7600,7 +8007,6 @@ build_abbrev_table (dw_die_ref die)
&& AT_ref (a)->die_mark == 0)
{
gcc_assert (AT_ref (a)->die_symbol);
-
set_AT_ref_external (a, 1);
}
@@ -7728,7 +8134,9 @@ size_of_die (dw_die_ref die)
size += 1;
break;
case dw_val_class_die_ref:
- if (AT_ref_external (a))
+ /* In DWARF2, DW_FORM_ref_addr is sized by target address length,
+ whereas in DWARF3 it's always sized as an offset. */
+ if (AT_ref_external (a) && dwarf_version == 2)
size += DWARF2_ADDR_SIZE;
else
size += DWARF_OFFSET_SIZE;
@@ -8257,10 +8665,17 @@ output_die (dw_die_ref die)
if (AT_ref_external (a))
{
char *sym = AT_ref (a)->die_symbol;
+ int size;
gcc_assert (sym);
- dw2_asm_output_offset (DWARF2_ADDR_SIZE, sym, debug_info_section,
- "%s", name);
+
+ /* In DWARF2, DW_FORM_ref_addr is sized by target address
+ length, whereas in DWARF3 it's always sized as an offset. */
+ if (dwarf_version == 2)
+ size = DWARF2_ADDR_SIZE;
+ else
+ size = DWARF_OFFSET_SIZE;
+ dw2_asm_output_offset (size, sym, debug_info_section, "%s", name);
}
else
{
@@ -8339,7 +8754,7 @@ output_compilation_unit_header (void)
dw2_asm_output_data (DWARF_OFFSET_SIZE,
next_die_offset - DWARF_INITIAL_LENGTH_SIZE,
"Length of Compilation Unit Info");
- dw2_asm_output_data (2, DWARF_VERSION, "DWARF version number");
+ dw2_asm_output_data (2, dwarf_version, "DWARF version number");
dw2_asm_output_offset (DWARF_OFFSET_SIZE, abbrev_section_label,
debug_abbrev_section,
"Offset Into Abbrev. Section");
@@ -8420,7 +8835,6 @@ add_pubname_string (const char *str, dw_die_ref die)
static void
add_pubname (tree decl, dw_die_ref die)
{
-
if (TREE_PUBLIC (decl))
add_pubname_string (dwarf2_name (decl, 1), die);
}
@@ -8480,7 +8894,8 @@ output_pubnames (VEC (pubname_entry, gc) * names)
else
dw2_asm_output_data (DWARF_OFFSET_SIZE, pubnames_length,
"Length of Public Type Names Info");
- dw2_asm_output_data (2, DWARF_VERSION, "DWARF Version");
+ /* Version number for pubnames/pubtypes is still 2, even in DWARF3. */
+ dw2_asm_output_data (2, 2, "DWARF Version");
dw2_asm_output_offset (DWARF_OFFSET_SIZE, debug_info_section_label,
debug_info_section,
"Offset of Compilation Unit Info");
@@ -8542,7 +8957,8 @@ output_aranges (void)
"Initial length escape value indicating 64-bit DWARF extension");
dw2_asm_output_data (DWARF_OFFSET_SIZE, aranges_length,
"Length of Address Ranges Info");
- dw2_asm_output_data (2, DWARF_VERSION, "DWARF Version");
+ /* Version number for aranges is still 2, even in DWARF3. */
+ dw2_asm_output_data (2, 2, "DWARF Version");
dw2_asm_output_offset (DWARF_OFFSET_SIZE, debug_info_section_label,
debug_info_section,
"Offset of Compilation Unit Info");
@@ -9087,7 +9503,7 @@ output_line_info (void)
"Length of Source Line Info");
ASM_OUTPUT_LABEL (asm_out_file, l1);
- dw2_asm_output_data (2, DWARF_VERSION, "DWARF Version");
+ dw2_asm_output_data (2, dwarf_version, "DWARF Version");
dw2_asm_output_delta (DWARF_OFFSET_SIZE, p2, p1, "Prolog Length");
ASM_OUTPUT_LABEL (asm_out_file, p1);
@@ -9386,6 +9802,11 @@ base_type_die (tree type)
if (TREE_CODE (type) == ERROR_MARK || TREE_CODE (type) == VOID_TYPE)
return 0;
+ /* If this is a subtype that should not be emitted as a subrange type,
+ use the base type. See subrange_type_for_debug_p. */
+ if (TREE_CODE (type) == INTEGER_TYPE && TREE_TYPE (type) != NULL_TREE)
+ type = TREE_TYPE (type);
+
switch (TREE_CODE (type))
{
case INTEGER_TYPE:
@@ -9505,67 +9926,11 @@ simple_type_size_in_bits (const_tree type)
return TYPE_ALIGN (type);
}
-/* Return true if the debug information for the given type should be
- emitted as a subrange type. */
-
-static inline bool
-is_subrange_type (const_tree type)
-{
- tree subtype = TREE_TYPE (type);
-
- /* Subrange types are identified by the fact that they are integer
- types, and that they have a subtype which is either an integer type
- or an enumeral type. */
-
- if (TREE_CODE (type) != INTEGER_TYPE
- || subtype == NULL_TREE)
- return false;
-
- if (TREE_CODE (subtype) != INTEGER_TYPE
- && TREE_CODE (subtype) != ENUMERAL_TYPE
- && TREE_CODE (subtype) != BOOLEAN_TYPE)
- return false;
-
- if (TREE_CODE (type) == TREE_CODE (subtype)
- && int_size_in_bytes (type) == int_size_in_bytes (subtype)
- && TYPE_MIN_VALUE (type) != NULL
- && TYPE_MIN_VALUE (subtype) != NULL
- && tree_int_cst_equal (TYPE_MIN_VALUE (type), TYPE_MIN_VALUE (subtype))
- && TYPE_MAX_VALUE (type) != NULL
- && TYPE_MAX_VALUE (subtype) != NULL
- && tree_int_cst_equal (TYPE_MAX_VALUE (type), TYPE_MAX_VALUE (subtype)))
- {
- /* The type and its subtype have the same representation. If in
- addition the two types also have the same name, then the given
- type is not a subrange type, but rather a plain base type. */
- /* FIXME: brobecker/2004-03-22:
- Sizetype INTEGER_CSTs nodes are canonicalized. It should
- therefore be sufficient to check the TYPE_SIZE node pointers
- rather than checking the actual size. Unfortunately, we have
- found some cases, such as in the Ada "integer" type, where
- this is not the case. Until this problem is solved, we need to
- keep checking the actual size. */
- tree type_name = TYPE_NAME (type);
- tree subtype_name = TYPE_NAME (subtype);
-
- if (type_name != NULL && TREE_CODE (type_name) == TYPE_DECL)
- type_name = DECL_NAME (type_name);
-
- if (subtype_name != NULL && TREE_CODE (subtype_name) == TYPE_DECL)
- subtype_name = DECL_NAME (subtype_name);
-
- if (type_name == subtype_name)
- return false;
- }
-
- return true;
-}
-
/* Given a pointer to a tree node for a subrange type, return a pointer
to a DIE that describes the given type. */
static dw_die_ref
-subrange_type_die (tree type, dw_die_ref context_die)
+subrange_type_die (tree type, tree low, tree high, dw_die_ref context_die)
{
dw_die_ref subrange_die;
const HOST_WIDE_INT size_in_bytes = int_size_in_bytes (type);
@@ -9582,12 +9947,10 @@ subrange_type_die (tree type, dw_die_ref context_die)
add_AT_unsigned (subrange_die, DW_AT_byte_size, size_in_bytes);
}
- if (TYPE_MIN_VALUE (type) != NULL)
- add_bound_info (subrange_die, DW_AT_lower_bound,
- TYPE_MIN_VALUE (type));
- if (TYPE_MAX_VALUE (type) != NULL)
- add_bound_info (subrange_die, DW_AT_upper_bound,
- TYPE_MAX_VALUE (type));
+ if (low)
+ add_bound_info (subrange_die, DW_AT_lower_bound, low);
+ if (high)
+ add_bound_info (subrange_die, DW_AT_upper_bound, high);
return subrange_die;
}
@@ -9604,7 +9967,7 @@ modified_type_die (tree type, int is_const_type, int is_volatile_type,
dw_die_ref sub_die = NULL;
tree item_type = NULL;
tree qualified_type;
- tree name;
+ tree name, low, high;
if (code == ERROR_MARK)
return NULL;
@@ -9674,9 +10037,11 @@ modified_type_die (tree type, int is_const_type, int is_volatile_type,
simple_type_size_in_bits (type) / BITS_PER_UNIT);
item_type = TREE_TYPE (type);
}
- else if (is_subrange_type (type))
+ else if (code == INTEGER_TYPE
+ && TREE_TYPE (type) != NULL_TREE
+ && subrange_type_for_debug_p (type, &low, &high))
{
- mod_type_die = subrange_type_die (type, context_die);
+ mod_type_die = subrange_type_die (type, low, high, context_die);
item_type = TREE_TYPE (type);
}
else if (is_base_type (type))
@@ -12576,6 +12941,7 @@ convert_cfa_to_fb_loc_list (HOST_WIDE_INT offset)
dw_cfi_ref cfi;
dw_cfa_location last_cfa, next_cfa;
const char *start_label, *last_label, *section;
+ dw_cfa_location remember;
fde = current_fde ();
gcc_assert (fde != NULL);
@@ -12584,17 +12950,16 @@ convert_cfa_to_fb_loc_list (HOST_WIDE_INT offset)
list_tail = &list;
list = NULL;
+ memset (&next_cfa, 0, sizeof (next_cfa));
next_cfa.reg = INVALID_REGNUM;
- next_cfa.offset = 0;
- next_cfa.indirect = 0;
- next_cfa.base_offset = 0;
+ remember = next_cfa;
start_label = fde->dw_fde_begin;
/* ??? Bald assumption that the CIE opcode list does not contain
advance opcodes. */
for (cfi = cie_cfi_head; cfi; cfi = cfi->dw_cfi_next)
- lookup_cfa_1 (cfi, &next_cfa);
+ lookup_cfa_1 (cfi, &next_cfa, &remember);
last_cfa = next_cfa;
last_label = start_label;
@@ -12621,14 +12986,10 @@ convert_cfa_to_fb_loc_list (HOST_WIDE_INT offset)
case DW_CFA_advance_loc:
/* The encoding is complex enough that we should never emit this. */
- case DW_CFA_remember_state:
- case DW_CFA_restore_state:
- /* We don't handle these two in this function. It would be possible
- if it were to be required. */
gcc_unreachable ();
default:
- lookup_cfa_1 (cfi, &next_cfa);
+ lookup_cfa_1 (cfi, &next_cfa, &remember);
break;
}
@@ -13945,6 +14306,7 @@ dwarf2out_abstract_function (tree decl)
/* Make sure we have the actual abstract inline, not a clone. */
decl = DECL_ORIGIN (decl);
+ htab_empty (decl_loc_table);
old_die = lookup_decl_die (decl);
if (old_die && get_AT (old_die, DW_AT_inline))
@@ -14219,17 +14581,19 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
(3) We can at least reuse the code inspection and interpretation
code that determines the CFA position at various points in the
function. */
- /* ??? Use some command-line or configury switch to enable the use
- of dwarf3 DW_OP_call_frame_cfa. At present there are no dwarf
- consumers that understand it; fall back to "pure" dwarf2 and
- convert the CFA data into a location list. */
- {
- dw_loc_list_ref list = convert_cfa_to_fb_loc_list (cfa_fb_offset);
- if (list->dw_loc_next)
- add_AT_loc_list (subr_die, DW_AT_frame_base, list);
- else
- add_AT_loc (subr_die, DW_AT_frame_base, list->expr);
- }
+ if (dwarf_version >= 3)
+ {
+ dw_loc_descr_ref op = new_loc_descr (DW_OP_call_frame_cfa, 0, 0);
+ add_AT_loc (subr_die, DW_AT_frame_base, op);
+ }
+ else
+ {
+ dw_loc_list_ref list = convert_cfa_to_fb_loc_list (cfa_fb_offset);
+ if (list->dw_loc_next)
+ add_AT_loc_list (subr_die, DW_AT_frame_base, list);
+ else
+ add_AT_loc (subr_die, DW_AT_frame_base, list->expr);
+ }
/* Compute a displacement from the "steady-state frame pointer" to
the CFA. The former is what all stack slots and argument slots
@@ -15175,6 +15539,12 @@ gen_type_die_with_usage (tree type, dw_die_ref context_die,
/* Prevent broken recursion; we can't hand off to the same type. */
gcc_assert (DECL_ORIGINAL_TYPE (TYPE_NAME (type)) != type);
+ /* Use the DIE of the containing namespace as the parent DIE of
+ the type description DIE we want to generate. */
+ if (DECL_CONTEXT (TYPE_NAME (type))
+ && TREE_CODE (DECL_CONTEXT (TYPE_NAME (type))) == NAMESPACE_DECL)
+ context_die = lookup_decl_die (DECL_CONTEXT (TYPE_NAME (type)));
+
TREE_ASM_WRITTEN (type) = 1;
gen_decl_die (TYPE_NAME (type), NULL, context_die);
return;
@@ -16382,7 +16752,8 @@ dwarf2out_begin_function (tree fun)
'line_info_table' for later output of the .debug_line section. */
static void
-dwarf2out_source_line (unsigned int line, const char *filename)
+dwarf2out_source_line (unsigned int line, const char *filename,
+ int discriminator ATTRIBUTE_UNUSED)
{
if (debug_info_level >= DINFO_LEVEL_NORMAL
&& line != 0)
@@ -16399,7 +16770,12 @@ dwarf2out_source_line (unsigned int line, const char *filename)
if (DWARF2_ASM_LINE_DEBUG_INFO)
{
/* Emit the .loc directive understood by GNU as. */
- fprintf (asm_out_file, "\t.loc %d %d 0\n", file_num, line);
+ fprintf (asm_out_file, "\t.loc %d %d 0", file_num, line);
+#ifdef HAVE_GAS_DISCRIMINATOR
+ if (discriminator != 0)
+ fprintf (asm_out_file, " discriminator %d", discriminator);
+#endif /* HAVE_GAS_DISCRIMINATOR */
+ fputc ('\n', asm_out_file);
/* Indicate that line number info exists. */
line_info_table_in_use++;
@@ -16600,10 +16976,8 @@ dwarf2out_init (const char *filename ATTRIBUTE_UNUSED)
SECTION_DEBUG, NULL);
debug_pubnames_section = get_section (DEBUG_PUBNAMES_SECTION,
SECTION_DEBUG, NULL);
-#ifdef DEBUG_PUBTYPES_SECTION
debug_pubtypes_section = get_section (DEBUG_PUBTYPES_SECTION,
SECTION_DEBUG, NULL);
-#endif
debug_str_section = get_section (DEBUG_STR_SECTION,
DEBUG_STR_SECTION_FLAGS, NULL);
debug_ranges_section = get_section (DEBUG_RANGES_SECTION,
@@ -17020,25 +17394,23 @@ static inline void
move_linkage_attr (dw_die_ref die)
{
unsigned ix = VEC_length (dw_attr_node, die->die_attr);
- dw_attr_node linkage = *VEC_last (dw_attr_node, die->die_attr);
- dw_attr_ref prev;
+ dw_attr_node linkage = *VEC_index (dw_attr_node, die->die_attr, ix - 1);
gcc_assert (linkage.dw_attr == DW_AT_MIPS_linkage_name);
- while (--ix)
+ while (--ix > 0)
{
- prev = VEC_index (dw_attr_node, die->die_attr, ix - 1);
+ dw_attr_node *prev = VEC_index (dw_attr_node, die->die_attr, ix - 1);
if (prev->dw_attr == DW_AT_decl_line || prev->dw_attr == DW_AT_name)
- {
- VEC_replace (dw_attr_node, die->die_attr, ix, &linkage);
- return;
- }
- else
- VEC_replace (dw_attr_node, die->die_attr, ix, prev);
+ break;
}
- gcc_unreachable ();
+ if (ix != VEC_length (dw_attr_node, die->die_attr) - 1)
+ {
+ VEC_pop (dw_attr_node, die->die_attr);
+ VEC_quick_insert (dw_attr_node, die->die_attr, ix, &linkage);
+ }
}
/* Output stuff that dwarf requires at the end of every file,
@@ -17253,14 +17625,15 @@ dwarf2out_finish (const char *filename)
output_pubnames (pubname_table);
}
-#ifdef DEBUG_PUBTYPES_SECTION
/* Output public types table if necessary. */
+ /* ??? Only defined by DWARF3, but emitted by Darwin for DWARF2.
+ It shouldn't hurt to emit it always, since pure DWARF2 consumers
+ simply won't look for the section. */
if (!VEC_empty (pubname_entry, pubtype_table))
{
switch_to_section (debug_pubtypes_section);
output_pubnames (pubtype_table);
}
-#endif
/* Output the address range information. We only put functions in the arange
table, so don't write it out if we don't have any. */
diff --git a/gcc/dwarf2out.h b/gcc/dwarf2out.h
index 154bb143dbb..85c320dfbd5 100644
--- a/gcc/dwarf2out.h
+++ b/gcc/dwarf2out.h
@@ -20,6 +20,8 @@ along with GCC; see the file COPYING3. If not see
extern void dwarf2out_decl (tree);
extern void dwarf2out_frame_debug (rtx, bool);
+extern void dwarf2out_begin_epilogue (rtx);
+extern void dwarf2out_frame_debug_restore_state (void);
extern void debug_dwarf (void);
struct die_struct;
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index 6fe38537d58..184f69aa2c5 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -2244,7 +2244,8 @@ get_spill_slot_decl (bool force_build_p)
if (d || !force_build_p)
return d;
- d = build_decl (VAR_DECL, get_identifier ("%sfp"), void_type_node);
+ d = build_decl (DECL_SOURCE_LOCATION (current_function_decl),
+ VAR_DECL, get_identifier ("%sfp"), void_type_node);
DECL_ARTIFICIAL (d) = 1;
DECL_IGNORED_P (d) = 1;
TREE_USED (d) = 1;
@@ -3416,6 +3417,10 @@ try_split (rtx pat, rtx trial, int last)
rtx insn_last, insn;
int njumps = 0;
+ /* We're not good at redistributing frame information. */
+ if (RTX_FRAME_RELATED_P (trial))
+ return trial;
+
if (any_condjump_p (trial)
&& (note = find_reg_note (trial, REG_BR_PROB, 0)))
split_branch_probability = INTVAL (XEXP (note, 0));
@@ -5384,6 +5389,9 @@ copy_insn_1 (rtx orig)
RTX_CODE code;
const char *format_ptr;
+ if (orig == NULL)
+ return NULL;
+
code = GET_CODE (orig);
switch (code)
diff --git a/gcc/emutls.c b/gcc/emutls.c
index a9c7cf6954c..b7ee3bdfa7c 100644
--- a/gcc/emutls.c
+++ b/gcc/emutls.c
@@ -155,23 +155,23 @@ __emutls_get_address (struct __emutls_object *obj)
if (__builtin_expect (arr == NULL, 0))
{
pointer size = offset + 32;
- arr = calloc (size, sizeof (void *));
+ arr = calloc (size + 1, sizeof (void *));
if (arr == NULL)
abort ();
arr->size = size;
__gthread_setspecific (emutls_key, (void *) arr);
}
- else if (__builtin_expect (offset >= arr->size, 0))
+ else if (__builtin_expect (offset > arr->size, 0))
{
pointer orig_size = arr->size;
pointer size = orig_size * 2;
- if (offset >= size)
+ if (offset > size)
size = offset + 32;
- arr = realloc (arr, size * sizeof (void *));
+ arr = realloc (arr, (size + 1) * sizeof (void *));
if (arr == NULL)
abort ();
arr->size = size;
- memset (arr->data + orig_size - 1, 0,
+ memset (arr->data + orig_size, 0,
(size - orig_size) * sizeof (void *));
__gthread_setspecific (emutls_key, (void *) arr);
}
diff --git a/gcc/errors.c b/gcc/errors.c
index d89e14d94d6..c75b361fb02 100644
--- a/gcc/errors.c
+++ b/gcc/errors.c
@@ -104,7 +104,8 @@ internal_error (const char *format, ...)
shares no directory elements with the pathname of __FILE__. This
is used by fancy_abort() to print `Internal compiler error in expr.c'
instead of `Internal compiler error in ../../GCC/gcc/expr.c'. This
- version if for the gen* programs and so needn't handle subdirectories. */
+ version is ment to be used for the gen* programs and therefor need not
+ handle subdirectories. */
const char *
trim_filename (const char *name)
diff --git a/gcc/except.c b/gcc/except.c
index a33f3096fbf..0e207d53509 100644
--- a/gcc/except.c
+++ b/gcc/except.c
@@ -99,7 +99,7 @@ tree (*lang_eh_runtime_type) (tree);
struct GTY(()) ehl_map_entry {
rtx label;
- struct eh_region *region;
+ struct eh_region_d *region;
};
static GTY(()) int call_site_base;
@@ -115,7 +115,7 @@ static int sjlj_fc_lsda_ofs;
static int sjlj_fc_jbuf_ofs;
-struct GTY(()) call_site_record
+struct GTY(()) call_site_record_d
{
rtx landing_pad;
int action;
@@ -144,9 +144,9 @@ static void sjlj_emit_function_exit (void);
static void sjlj_emit_dispatch_table (rtx, struct sjlj_lp_info *);
static void sjlj_build_landing_pads (void);
-static void remove_eh_handler (struct eh_region *);
-static void remove_eh_handler_and_replace (struct eh_region *,
- struct eh_region *, bool);
+static void remove_eh_handler (struct eh_region_d *);
+static void remove_eh_handler_and_replace (struct eh_region_d *,
+ struct eh_region_d *, bool);
/* The return value of reachable_next_level. */
enum reachable_code
@@ -162,13 +162,13 @@ enum reachable_code
};
struct reachable_info;
-static enum reachable_code reachable_next_level (struct eh_region *, tree,
+static enum reachable_code reachable_next_level (struct eh_region_d *, tree,
struct reachable_info *, bool);
static int action_record_eq (const void *, const void *);
static hashval_t action_record_hash (const void *);
static int add_action_record (htab_t, int, int);
-static int collect_one_action_chain (htab_t, struct eh_region *);
+static int collect_one_action_chain (htab_t, struct eh_region_d *);
static int add_call_site (rtx, int);
static void push_uleb128 (varray_type *, unsigned int);
@@ -221,11 +221,13 @@ init_eh (void)
sjlj_fc_type_node = lang_hooks.types.make_type (RECORD_TYPE);
- f_prev = build_decl (FIELD_DECL, get_identifier ("__prev"),
+ f_prev = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, get_identifier ("__prev"),
build_pointer_type (sjlj_fc_type_node));
DECL_FIELD_CONTEXT (f_prev) = sjlj_fc_type_node;
- f_cs = build_decl (FIELD_DECL, get_identifier ("__call_site"),
+ f_cs = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, get_identifier ("__call_site"),
integer_type_node);
DECL_FIELD_CONTEXT (f_cs) = sjlj_fc_type_node;
@@ -233,14 +235,17 @@ init_eh (void)
tmp = build_array_type (lang_hooks.types.type_for_mode
(targetm.unwind_word_mode (), 1),
tmp);
- f_data = build_decl (FIELD_DECL, get_identifier ("__data"), tmp);
+ f_data = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, get_identifier ("__data"), tmp);
DECL_FIELD_CONTEXT (f_data) = sjlj_fc_type_node;
- f_per = build_decl (FIELD_DECL, get_identifier ("__personality"),
+ f_per = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, get_identifier ("__personality"),
ptr_type_node);
DECL_FIELD_CONTEXT (f_per) = sjlj_fc_type_node;
- f_lsda = build_decl (FIELD_DECL, get_identifier ("__lsda"),
+ f_lsda = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, get_identifier ("__lsda"),
ptr_type_node);
DECL_FIELD_CONTEXT (f_lsda) = sjlj_fc_type_node;
@@ -260,7 +265,8 @@ init_eh (void)
#endif
tmp = build_index_type (tmp);
tmp = build_array_type (ptr_type_node, tmp);
- f_jbuf = build_decl (FIELD_DECL, get_identifier ("__jbuf"), tmp);
+ f_jbuf = build_decl (BUILTINS_LOCATION,
+ FIELD_DECL, get_identifier ("__jbuf"), tmp);
#ifdef DONT_USE_BUILTIN_SETJMP
/* We don't know what the alignment requirements of the
runtime's jmp_buf has. Overestimate. */
@@ -308,17 +314,17 @@ init_eh_for_function (void)
These are used from tree-eh.c when processing exception related
nodes during tree optimization. */
-static struct eh_region *
-gen_eh_region (enum eh_region_type type, struct eh_region *outer)
+static struct eh_region_d *
+gen_eh_region (enum eh_region_type type, struct eh_region_d *outer)
{
- struct eh_region *new_eh;
+ struct eh_region_d *new_eh;
#ifdef ENABLE_CHECKING
gcc_assert (doing_eh (0));
#endif
/* Insert a new blank region as a leaf in the tree. */
- new_eh = GGC_CNEW (struct eh_region);
+ new_eh = GGC_CNEW (struct eh_region_d);
new_eh->type = type;
new_eh->outer = outer;
if (outer)
@@ -337,23 +343,23 @@ gen_eh_region (enum eh_region_type type, struct eh_region *outer)
return new_eh;
}
-struct eh_region *
-gen_eh_region_cleanup (struct eh_region *outer)
+struct eh_region_d *
+gen_eh_region_cleanup (struct eh_region_d *outer)
{
- struct eh_region *cleanup = gen_eh_region (ERT_CLEANUP, outer);
+ struct eh_region_d *cleanup = gen_eh_region (ERT_CLEANUP, outer);
return cleanup;
}
-struct eh_region *
-gen_eh_region_try (struct eh_region *outer)
+struct eh_region_d *
+gen_eh_region_try (struct eh_region_d *outer)
{
return gen_eh_region (ERT_TRY, outer);
}
-struct eh_region *
-gen_eh_region_catch (struct eh_region *t, tree type_or_list)
+struct eh_region_d *
+gen_eh_region_catch (struct eh_region_d *t, tree type_or_list)
{
- struct eh_region *c, *l;
+ struct eh_region_d *c, *l;
tree type_list, type_node;
/* Ensure to always end up with a type list to normalize further
@@ -382,10 +388,10 @@ gen_eh_region_catch (struct eh_region *t, tree type_or_list)
return c;
}
-struct eh_region *
-gen_eh_region_allowed (struct eh_region *outer, tree allowed)
+struct eh_region_d *
+gen_eh_region_allowed (struct eh_region_d *outer, tree allowed)
{
- struct eh_region *region = gen_eh_region (ERT_ALLOWED_EXCEPTIONS, outer);
+ struct eh_region_d *region = gen_eh_region (ERT_ALLOWED_EXCEPTIONS, outer);
region->u.allowed.type_list = allowed;
for (; allowed ; allowed = TREE_CHAIN (allowed))
@@ -394,26 +400,26 @@ gen_eh_region_allowed (struct eh_region *outer, tree allowed)
return region;
}
-struct eh_region *
-gen_eh_region_must_not_throw (struct eh_region *outer)
+struct eh_region_d *
+gen_eh_region_must_not_throw (struct eh_region_d *outer)
{
return gen_eh_region (ERT_MUST_NOT_THROW, outer);
}
int
-get_eh_region_number (struct eh_region *region)
+get_eh_region_number (struct eh_region_d *region)
{
return region->region_number;
}
bool
-get_eh_region_may_contain_throw (struct eh_region *region)
+get_eh_region_may_contain_throw (struct eh_region_d *region)
{
return region->may_contain_throw;
}
tree
-get_eh_region_tree_label (struct eh_region *region)
+get_eh_region_tree_label (struct eh_region_d *region)
{
return region->tree_label;
}
@@ -425,7 +431,7 @@ get_eh_region_no_tree_label (int region)
}
void
-set_eh_region_tree_label (struct eh_region *region, tree lab)
+set_eh_region_tree_label (struct eh_region_d *region, tree lab)
{
region->tree_label = lab;
}
@@ -434,8 +440,8 @@ void
expand_resx_expr (tree exp)
{
int region_nr = TREE_INT_CST_LOW (TREE_OPERAND (exp, 0));
- struct eh_region *reg = VEC_index (eh_region,
- cfun->eh->region_array, region_nr);
+ struct eh_region_d *reg = VEC_index (eh_region,
+ cfun->eh->region_array, region_nr);
gcc_assert (!reg->resume);
do_pending_stack_adjust ();
@@ -447,7 +453,7 @@ expand_resx_expr (tree exp)
call to a function which itself may contain a throw. */
void
-note_eh_region_may_contain_throw (struct eh_region *region)
+note_eh_region_may_contain_throw (struct eh_region_d *region)
{
while (region && !region->may_contain_throw)
{
@@ -486,7 +492,7 @@ get_exception_filter (void)
void
collect_eh_region_array (void)
{
- struct eh_region *i;
+ struct eh_region_d *i;
i = cfun->eh->region_tree;
if (! i)
@@ -538,9 +544,9 @@ collect_eh_region_array (void)
a problem. */
static bool
-can_be_reached_by_runtime (sbitmap contains_stmt, struct eh_region *r)
+can_be_reached_by_runtime (sbitmap contains_stmt, struct eh_region_d *r)
{
- struct eh_region *i = r->inner;
+ struct eh_region_d *i = r->inner;
unsigned n;
bitmap_iterator bi;
@@ -574,7 +580,7 @@ can_be_reached_by_runtime (sbitmap contains_stmt, struct eh_region *r)
firest place. */
if (found)
{
- struct eh_region *i1 = i;
+ struct eh_region_d *i1 = i;
tree type_thrown = NULL_TREE;
if (i1->type == ERT_THROW)
@@ -614,10 +620,10 @@ can_be_reached_by_runtime (sbitmap contains_stmt, struct eh_region *r)
/* Bring region R to the root of tree. */
static void
-bring_to_root (struct eh_region *r)
+bring_to_root (struct eh_region_d *r)
{
- struct eh_region **pp;
- struct eh_region *outer = r->outer;
+ struct eh_region_d **pp;
+ struct eh_region_d *outer = r->outer;
if (!r->outer)
return;
for (pp = &outer->inner; *pp != r; pp = &(*pp)->next_peer)
@@ -631,8 +637,8 @@ bring_to_root (struct eh_region *r)
/* Return true if region R2 can be replaced by R1. */
static bool
-eh_region_replaceable_by_p (const struct eh_region *r1,
- const struct eh_region *r2)
+eh_region_replaceable_by_p (const struct eh_region_d *r1,
+ const struct eh_region_d *r2)
{
/* Regions are semantically same if they are of same type,
have same label and type. */
@@ -649,7 +655,7 @@ eh_region_replaceable_by_p (const struct eh_region *r1,
break;
case ERT_TRY:
{
- struct eh_region *c1, *c2;
+ struct eh_region_d *c1, *c2;
for (c1 = r1->u.eh_try.eh_catch,
c2 = r2->u.eh_try.eh_catch;
c1 && c2;
@@ -690,10 +696,10 @@ eh_region_replaceable_by_p (const struct eh_region *r1,
/* Replace region R2 by R1. */
static void
-replace_region (struct eh_region *r1, struct eh_region *r2)
+replace_region (struct eh_region_d *r1, struct eh_region_d *r2)
{
- struct eh_region *next1 = r1->u.eh_try.eh_catch;
- struct eh_region *next2 = r2->u.eh_try.eh_catch;
+ struct eh_region_d *next1 = r1->u.eh_try.eh_catch;
+ struct eh_region_d *next2 = r2->u.eh_try.eh_catch;
bool is_try = r1->type == ERT_TRY;
gcc_assert (r1->type != ERT_CATCH);
@@ -729,7 +735,7 @@ hash_type_list (tree t)
static hashval_t
hash_eh_region (const void *r)
{
- const struct eh_region *region = (const struct eh_region *)r;
+ const struct eh_region_d *region = (const struct eh_region_d *) r;
hashval_t val = region->type;
if (region->tree_label)
@@ -741,7 +747,7 @@ hash_eh_region (const void *r)
break;
case ERT_TRY:
{
- struct eh_region *c;
+ struct eh_region_d *c;
for (c = region->u.eh_try.eh_catch;
c; c = c->u.eh_catch.next_catch)
val = iterative_hash_hashval_t (hash_eh_region (c), val);
@@ -770,8 +776,8 @@ hash_eh_region (const void *r)
static int
eh_regions_equal_p (const void *r1, const void *r2)
{
- return eh_region_replaceable_by_p ((const struct eh_region *)r1,
- (const struct eh_region *)r2);
+ return eh_region_replaceable_by_p ((const struct eh_region_d *) r1,
+ (const struct eh_region_d *) r2);
}
/* Walk all peers of REGION and try to merge those regions
@@ -779,9 +785,9 @@ eh_regions_equal_p (const void *r1, const void *r2)
recursively too. */
static bool
-merge_peers (struct eh_region *region)
+merge_peers (struct eh_region_d *region)
{
- struct eh_region *r1, *r2, *outer = NULL, *next;
+ struct eh_region_d *r1, *r2, *outer = NULL, *next;
bool merged = false;
int num_regions = 0;
if (region)
@@ -851,7 +857,7 @@ merge_peers (struct eh_region *region)
if (!*slot)
*slot = r1;
else
- replace_region ((struct eh_region *)*slot, r1);
+ replace_region ((struct eh_region_d *) *slot, r1);
}
htab_delete (hash);
}
@@ -868,10 +874,10 @@ void
remove_unreachable_regions (sbitmap reachable, sbitmap contains_stmt)
{
int i;
- struct eh_region *r;
+ struct eh_region_d *r;
VEC(eh_region,heap) *must_not_throws = VEC_alloc (eh_region, heap, 16);
- struct eh_region *local_must_not_throw = NULL;
- struct eh_region *first_must_not_throw = NULL;
+ struct eh_region_d *local_must_not_throw = NULL;
+ struct eh_region_d *first_must_not_throw = NULL;
for (i = cfun->eh->last_region_number; i > 0; --i)
{
@@ -907,7 +913,7 @@ remove_unreachable_regions (sbitmap reachable, sbitmap contains_stmt)
{
/* TRY regions are reachable if any of its CATCH regions
are reachable. */
- struct eh_region *c;
+ struct eh_region_d *c;
for (c = r->u.eh_try.eh_catch; c;
c = c->u.eh_catch.next_catch)
if (TEST_BIT (reachable, c->region_number))
@@ -1001,7 +1007,7 @@ label_to_region_map (void)
cfun->cfg->last_label_uid + 1);
for (i = cfun->eh->last_region_number; i > 0; --i)
{
- struct eh_region *r = VEC_index (eh_region, cfun->eh->region_array, i);
+ struct eh_region_d *r = VEC_index (eh_region, cfun->eh->region_array, i);
if (r && r->region_number == i
&& r->tree_label && LABEL_DECL_UID (r->tree_label) >= 0)
{
@@ -1030,7 +1036,7 @@ num_eh_regions (void)
int
get_next_region_sharing_label (int region)
{
- struct eh_region *r;
+ struct eh_region_d *r;
if (!region)
return 0;
r = VEC_index (eh_region, cfun->eh->region_array, region);
@@ -1039,6 +1045,43 @@ get_next_region_sharing_label (int region)
return r->next_region_sharing_label->region_number;
}
+/* Return bitmap of all labels that are handlers of must not throw regions. */
+
+bitmap
+must_not_throw_labels (void)
+{
+ struct eh_region_d *i;
+ bitmap labels = BITMAP_ALLOC (NULL);
+
+ i = cfun->eh->region_tree;
+ if (! i)
+ return labels;
+
+ while (1)
+ {
+ if (i->type == ERT_MUST_NOT_THROW && i->tree_label
+ && LABEL_DECL_UID (i->tree_label) >= 0)
+ bitmap_set_bit (labels, LABEL_DECL_UID (i->tree_label));
+
+ /* If there are sub-regions, process them. */
+ if (i->inner)
+ i = i->inner;
+ /* If there are peers, process them. */
+ else if (i->next_peer)
+ i = i->next_peer;
+ /* Otherwise, step back up the tree to the next peer. */
+ else
+ {
+ do {
+ i = i->outer;
+ if (i == NULL)
+ return labels;
+ } while (i->next_peer == NULL);
+ i = i->next_peer;
+ }
+ }
+}
+
/* Set up EH labels for RTL. */
void
@@ -1052,7 +1095,7 @@ convert_from_eh_region_ranges (void)
we allocated earlier. */
for (i = 1; i <= n; ++i)
{
- struct eh_region *region;
+ struct eh_region_d *region;
region = VEC_index (eh_region, cfun->eh->region_array, i);
if (region && region->tree_label)
@@ -1070,7 +1113,7 @@ find_exception_handler_labels (void)
for (i = cfun->eh->last_region_number; i > 0; --i)
{
- struct eh_region *region;
+ struct eh_region_d *region;
rtx lab;
region = VEC_index (eh_region, cfun->eh->region_array, i);
@@ -1092,7 +1135,7 @@ current_function_has_exception_handlers (void)
for (i = cfun->eh->last_region_number; i > 0; --i)
{
- struct eh_region *region;
+ struct eh_region_d *region;
region = VEC_index (eh_region, cfun->eh->region_array, i);
if (region
@@ -1147,7 +1190,7 @@ duplicate_eh_regions_1 (eh_region old, eh_region outer, int eh_offset)
{
eh_region ret, n;
- ret = n = GGC_NEW (struct eh_region);
+ ret = n = GGC_NEW (struct eh_region_d);
*n = *old;
n->outer = outer;
@@ -1185,8 +1228,8 @@ duplicate_eh_regions_1 (eh_region old, eh_region outer, int eh_offset)
/* Look for first outer region of R (or R itself) that is
TRY region. Return NULL if none. */
-static struct eh_region *
-find_prev_try (struct eh_region * r)
+static struct eh_region_d *
+find_prev_try (struct eh_region_d * r)
{
for (; r && r->type != ERT_TRY; r = r->outer)
if (r->type == ERT_MUST_NOT_THROW
@@ -1361,10 +1404,10 @@ duplicate_eh_regions (struct function *ifun, duplicate_eh_regions_map map,
/* Return new copy of eh region OLD inside region NEW_OUTER.
Do not care about updating the tree otherwise. */
-static struct eh_region *
-copy_eh_region_1 (struct eh_region *old, struct eh_region *new_outer)
+static struct eh_region_d *
+copy_eh_region_1 (struct eh_region_d *old, struct eh_region_d *new_outer)
{
- struct eh_region *new_eh = gen_eh_region (old->type, new_outer);
+ struct eh_region_d *new_eh = gen_eh_region (old->type, new_outer);
new_eh->u = old->u;
new_eh->tree_label = old->tree_label;
new_eh->may_contain_throw = old->may_contain_throw;
@@ -1380,10 +1423,10 @@ copy_eh_region_1 (struct eh_region *old, struct eh_region *new_outer)
Copy whole catch-try chain if neccesary. */
-static struct eh_region *
-copy_eh_region (struct eh_region *old, struct eh_region *new_outer)
+static struct eh_region_d *
+copy_eh_region (struct eh_region_d *old, struct eh_region_d *new_outer)
{
- struct eh_region *r, *n, *old_try, *new_try, *ret = NULL;
+ struct eh_region_d *r, *n, *old_try, *new_try, *ret = NULL;
VEC(eh_region,heap) *catch_list = NULL;
if (old->type != ERT_CATCH)
@@ -1438,7 +1481,7 @@ copy_eh_region (struct eh_region *old, struct eh_region *new_outer)
/* Callback for forach_reachable_handler that push REGION into single VECtor DATA. */
static void
-push_reachable_handler (struct eh_region *region, void *data)
+push_reachable_handler (struct eh_region_d *region, void *data)
{
VEC(eh_region,heap) **trace = (VEC(eh_region,heap) **) data;
VEC_safe_push (eh_region, heap, *trace, region);
@@ -1448,17 +1491,17 @@ push_reachable_handler (struct eh_region *region, void *data)
IS_RESX, INLINABLE_CALL and REGION_NMUBER match the parameter of
foreach_reachable_handler. */
-struct eh_region *
+struct eh_region_d *
redirect_eh_edge_to_label (edge e, tree new_dest_label, bool is_resx,
bool inlinable_call, int region_number)
{
- struct eh_region *outer;
- struct eh_region *region;
+ struct eh_region_d *outer;
+ struct eh_region_d *region;
VEC (eh_region, heap) * trace = NULL;
int i;
int start_here = -1;
basic_block old_bb = e->dest;
- struct eh_region *old, *r = NULL;
+ struct eh_region_d *old, *r = NULL;
bool update_inplace = true;
edge_iterator ei;
edge e2;
@@ -1584,7 +1627,7 @@ redirect_eh_edge_to_label (edge e, tree new_dest_label, bool is_resx,
int
eh_region_outermost (struct function *ifun, int region_a, int region_b)
{
- struct eh_region *rp_a, *rp_b;
+ struct eh_region_d *rp_a, *rp_b;
sbitmap b_outer;
gcc_assert (ifun->eh->last_region_number > 0);
@@ -1810,7 +1853,7 @@ assign_filter_values (void)
for (i = cfun->eh->last_region_number; i > 0; --i)
{
- struct eh_region *r;
+ struct eh_region_d *r;
r = VEC_index (eh_region, cfun->eh->region_array, i);
@@ -1905,7 +1948,7 @@ build_post_landing_pads (void)
for (i = cfun->eh->last_region_number; i > 0; --i)
{
- struct eh_region *region;
+ struct eh_region_d *region;
rtx seq;
region = VEC_index (eh_region, cfun->eh->region_array, i);
@@ -1938,7 +1981,7 @@ build_post_landing_pads (void)
switch statement generation code in expand_end_case.
Rapid prototyping sez a sequence of ifs. */
{
- struct eh_region *c;
+ struct eh_region_d *c;
for (c = region->u.eh_try.eh_catch; c ; c = c->u.eh_catch.next_catch)
{
if (c->u.eh_catch.type_list == NULL)
@@ -2033,8 +2076,8 @@ connect_post_landing_pads (void)
for (i = cfun->eh->last_region_number; i > 0; --i)
{
- struct eh_region *region;
- struct eh_region *outer;
+ struct eh_region_d *region;
+ struct eh_region_d *outer;
rtx seq;
rtx barrier;
@@ -2110,7 +2153,7 @@ dw2_build_landing_pads (void)
for (i = cfun->eh->last_region_number; i > 0; --i)
{
- struct eh_region *region;
+ struct eh_region_d *region;
rtx seq;
basic_block bb;
edge e;
@@ -2178,7 +2221,7 @@ sjlj_find_directly_reachable_regions (struct sjlj_lp_info *lp_info)
for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
{
- struct eh_region *region;
+ struct eh_region_d *region;
enum reachable_code rc;
tree type_thrown;
rtx note;
@@ -2234,7 +2277,8 @@ sjlj_assign_call_site_values (rtx dispatch_label, struct sjlj_lp_info *lp_info)
for (i = cfun->eh->last_region_number; i > 0; --i)
if (lp_info[i].directly_reachable)
{
- struct eh_region *r = VEC_index (eh_region, cfun->eh->region_array, i);
+ struct eh_region_d *r =
+ VEC_index (eh_region, cfun->eh->region_array, i);
r->landing_pad = dispatch_label;
lp_info[i].action_index = collect_one_action_chain (ar_hash, r);
@@ -2291,7 +2335,7 @@ sjlj_mark_call_sites (struct sjlj_lp_info *lp_info)
for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
{
- struct eh_region *region;
+ struct eh_region_d *region;
int this_call_site;
rtx note, before, p;
@@ -2518,14 +2562,17 @@ sjlj_emit_dispatch_table (rtx dispatch_label, struct sjlj_lp_info *lp_info)
emit_cmp_and_jump_insns (dispatch, GEN_INT (lp_info[i].dispatch_index),
EQ, NULL_RTX, TYPE_MODE (integer_type_node), 0,
- ((struct eh_region *)VEC_index (eh_region, cfun->eh->region_array, i))
- ->post_landing_pad);
+ (((struct eh_region_d *)
+ VEC_index (eh_region,
+ cfun->eh->region_array, i))
+ ->post_landing_pad));
}
seq = get_insns ();
end_sequence ();
- before = (((struct eh_region *)VEC_index (eh_region, cfun->eh->region_array, first_reachable))
+ before = (((struct eh_region_d *)
+ VEC_index (eh_region, cfun->eh->region_array, first_reachable))
->post_landing_pad);
bb = emit_to_new_bb_before (seq, before);
@@ -2636,11 +2683,11 @@ finish_eh_generation (void)
region.*/
static void
-remove_eh_handler_and_replace (struct eh_region *region,
- struct eh_region *replace,
+remove_eh_handler_and_replace (struct eh_region_d *region,
+ struct eh_region_d *replace,
bool update_catch_try)
{
- struct eh_region **pp, **pp_start, *p, *outer, *inner;
+ struct eh_region_d **pp, **pp_start, *p, *outer, *inner;
rtx lab;
outer = region->outer;
@@ -2703,7 +2750,7 @@ remove_eh_handler_and_replace (struct eh_region *region,
if (region->type == ERT_CATCH
&& update_catch_try)
{
- struct eh_region *eh_try, *next, *prev;
+ struct eh_region_d *eh_try, *next, *prev;
for (eh_try = region->next_peer;
eh_try->type == ERT_CATCH;
@@ -2733,7 +2780,7 @@ remove_eh_handler_and_replace (struct eh_region *region,
etc. */
static void
-remove_eh_handler (struct eh_region *region)
+remove_eh_handler (struct eh_region_d *region)
{
remove_eh_handler_and_replace (region, region->outer, true);
}
@@ -2743,7 +2790,7 @@ remove_eh_handler (struct eh_region *region)
void
remove_eh_region (int r)
{
- struct eh_region *region;
+ struct eh_region_d *region;
region = VEC_index (eh_region, cfun->eh->region_array, r);
remove_eh_handler (region);
@@ -2755,7 +2802,7 @@ remove_eh_region (int r)
void
remove_eh_region_and_replace_by_outer_of (int r, int r2)
{
- struct eh_region *region, *region2;
+ struct eh_region_d *region, *region2;
region = VEC_index (eh_region, cfun->eh->region_array, r);
region2 = VEC_index (eh_region, cfun->eh->region_array, r2);
@@ -2771,7 +2818,7 @@ for_each_eh_label (void (*callback) (rtx))
int i;
for (i = 0; i < cfun->eh->last_region_number; i++)
{
- struct eh_region *r = VEC_index (eh_region, cfun->eh->region_array, i);
+ struct eh_region_d *r = VEC_index (eh_region, cfun->eh->region_array, i);
if (r && r->region_number == i && r->label
&& GET_CODE (r->label) == CODE_LABEL)
(*callback) (r->label);
@@ -2781,12 +2828,12 @@ for_each_eh_label (void (*callback) (rtx))
/* Invoke CALLBACK for every exception region in the current function. */
void
-for_each_eh_region (void (*callback) (struct eh_region *))
+for_each_eh_region (void (*callback) (struct eh_region_d *))
{
int i, n = cfun->eh->last_region_number;
for (i = 1; i <= n; ++i)
{
- struct eh_region *region;
+ struct eh_region_d *region;
region = VEC_index (eh_region, cfun->eh->region_array, i);
if (region)
@@ -2801,7 +2848,7 @@ struct reachable_info
{
tree types_caught;
tree types_allowed;
- void (*callback) (struct eh_region *, void *);
+ void (*callback) (struct eh_region_d *, void *);
void *callback_data;
};
@@ -2840,7 +2887,8 @@ check_handled (tree handled, tree type)
static void
add_reachable_handler (struct reachable_info *info,
- struct eh_region *lp_region, struct eh_region *region)
+ struct eh_region_d *lp_region,
+ struct eh_region_d *region)
{
if (! info)
return;
@@ -2857,7 +2905,7 @@ add_reachable_handler (struct reachable_info *info,
and caught/allowed type information between invocations. */
static enum reachable_code
-reachable_next_level (struct eh_region *region, tree type_thrown,
+reachable_next_level (struct eh_region_d *region, tree type_thrown,
struct reachable_info *info,
bool maybe_resx)
{
@@ -2872,7 +2920,7 @@ reachable_next_level (struct eh_region *region, tree type_thrown,
case ERT_TRY:
{
- struct eh_region *c;
+ struct eh_region_d *c;
enum reachable_code ret = RNL_NOT_CAUGHT;
for (c = region->u.eh_try.eh_catch; c ; c = c->u.eh_catch.next_catch)
@@ -3026,11 +3074,11 @@ reachable_next_level (struct eh_region *region, tree type_thrown,
void
foreach_reachable_handler (int region_number, bool is_resx, bool inlinable_call,
- void (*callback) (struct eh_region *, void *),
+ void (*callback) (struct eh_region_d *, void *),
void *callback_data)
{
struct reachable_info info;
- struct eh_region *region;
+ struct eh_region_d *region;
tree type_thrown;
memset (&info, 0, sizeof (info));
@@ -3088,7 +3136,7 @@ foreach_reachable_handler (int region_number, bool is_resx, bool inlinable_call,
reached by a given insn. */
static void
-arh_to_landing_pad (struct eh_region *region, void *data)
+arh_to_landing_pad (struct eh_region_d *region, void *data)
{
rtx *p_handlers = (rtx *) data;
if (! *p_handlers)
@@ -3096,7 +3144,7 @@ arh_to_landing_pad (struct eh_region *region, void *data)
}
static void
-arh_to_label (struct eh_region *region, void *data)
+arh_to_label (struct eh_region_d *region, void *data)
{
rtx *p_handlers = (rtx *) data;
*p_handlers = alloc_INSN_LIST (region->label, *p_handlers);
@@ -3138,7 +3186,7 @@ reachable_handlers (rtx insn)
bool
can_throw_internal_1 (int region_number, bool is_resx, bool inlinable_call)
{
- struct eh_region *region;
+ struct eh_region_d *region;
tree type_thrown;
region = VEC_index (eh_region, cfun->eh->region_array, region_number);
@@ -3201,7 +3249,7 @@ can_throw_internal (const_rtx insn)
bool
can_throw_external_1 (int region_number, bool is_resx, bool inlinable_call)
{
- struct eh_region *region;
+ struct eh_region_d *region;
tree type_thrown;
region = VEC_index (eh_region, cfun->eh->region_array, region_number);
@@ -3609,9 +3657,9 @@ add_action_record (htab_t ar_hash, int filter, int next)
}
static int
-collect_one_action_chain (htab_t ar_hash, struct eh_region *region)
+collect_one_action_chain (htab_t ar_hash, struct eh_region_d *region)
{
- struct eh_region *c;
+ struct eh_region_d *c;
int next;
/* If we've reached the top of the region chain, then we have
@@ -3724,7 +3772,7 @@ add_call_site (rtx landing_pad, int action)
{
call_site_record record;
- record = GGC_NEW (struct call_site_record);
+ record = GGC_NEW (struct call_site_record_d);
record->landing_pad = landing_pad;
record->action = action;
@@ -3758,7 +3806,7 @@ convert_to_eh_region_ranges (void)
for (iter = get_insns (); iter ; iter = NEXT_INSN (iter))
if (INSN_P (iter))
{
- struct eh_region *region;
+ struct eh_region_d *region;
int this_action;
rtx this_landing_pad;
@@ -3802,7 +3850,7 @@ convert_to_eh_region_ranges (void)
landing pads. Collect the landing pad for this region. */
if (this_action >= 0)
{
- struct eh_region *o;
+ struct eh_region_d *o;
for (o = region; ! o->landing_pad ; o = o->outer)
continue;
this_landing_pad = o->landing_pad;
@@ -3925,7 +3973,8 @@ dw2_size_of_call_site_table (void)
for (i = 0; i < n; ++i)
{
- struct call_site_record *cs = VEC_index (call_site_record, crtl->eh.call_site_record, i);
+ struct call_site_record_d *cs =
+ VEC_index (call_site_record, crtl->eh.call_site_record, i);
size += size_of_uleb128 (cs->action);
}
@@ -3941,7 +3990,8 @@ sjlj_size_of_call_site_table (void)
for (i = 0; i < n; ++i)
{
- struct call_site_record *cs = VEC_index (call_site_record, crtl->eh.call_site_record, i);
+ struct call_site_record_d *cs =
+ VEC_index (call_site_record, crtl->eh.call_site_record, i);
size += size_of_uleb128 (INTVAL (cs->landing_pad));
size += size_of_uleb128 (cs->action);
}
@@ -3958,7 +4008,8 @@ dw2_output_call_site_table (void)
for (i = 0; i < n; ++i)
{
- struct call_site_record *cs = VEC_index (call_site_record, crtl->eh.call_site_record, i);
+ struct call_site_record_d *cs =
+ VEC_index (call_site_record, crtl->eh.call_site_record, i);
char reg_start_lab[32];
char reg_end_lab[32];
char landing_pad_lab[32];
@@ -4012,7 +4063,8 @@ sjlj_output_call_site_table (void)
for (i = 0; i < n; ++i)
{
- struct call_site_record *cs = VEC_index (call_site_record, crtl->eh.call_site_record, i);
+ struct call_site_record_d *cs =
+ VEC_index (call_site_record, crtl->eh.call_site_record, i);
dw2_asm_output_data_uleb128 (INTVAL (cs->landing_pad),
"region %d landing pad", i);
@@ -4330,7 +4382,7 @@ get_eh_throw_stmt_table (struct function *fun)
void
dump_eh_tree (FILE * out, struct function *fun)
{
- struct eh_region *i;
+ struct eh_region_d *i;
int depth = 0;
static const char *const type_name[] = { "unknown", "cleanup", "try", "catch",
"allowed_exceptions", "must_not_throw",
@@ -4380,7 +4432,7 @@ dump_eh_tree (FILE * out, struct function *fun)
case ERT_TRY:
{
- struct eh_region *c;
+ struct eh_region_d *c;
fprintf (out, " catch regions:");
for (c = i->u.eh_try.eh_catch; c; c = c->u.eh_catch.next_catch)
fprintf (out, " %i", c->region_number);
@@ -4455,7 +4507,7 @@ debug_eh_tree (struct function *fn)
/* Verify EH region invariants. */
static bool
-verify_eh_region (struct eh_region *region)
+verify_eh_region (struct eh_region_d *region)
{
bool found = false;
if (!region)
@@ -4464,7 +4516,7 @@ verify_eh_region (struct eh_region *region)
{
case ERT_TRY:
{
- struct eh_region *c, *prev = NULL;
+ struct eh_region_d *c, *prev = NULL;
if (region->u.eh_try.eh_catch->u.eh_catch.prev_catch)
{
error ("Try region %i has wrong rh_catch pointer to %i",
@@ -4526,7 +4578,7 @@ verify_eh_region (struct eh_region *region)
void
verify_eh_tree (struct function *fun)
{
- struct eh_region *i, *outer = NULL;
+ struct eh_region_d *i, *outer = NULL;
bool err = false;
int nvisited = 0;
int count = 0;
diff --git a/gcc/except.h b/gcc/except.h
index 70506d3a8c5..58c596a17ba 100644
--- a/gcc/except.h
+++ b/gcc/except.h
@@ -37,17 +37,17 @@ enum eh_region_type
};
/* Describes one exception region. */
-struct GTY(()) eh_region
+struct GTY(()) eh_region_d
{
/* The immediately surrounding region. */
- struct eh_region *outer;
+ struct eh_region_d *outer;
/* The list of immediately contained regions. */
- struct eh_region *inner;
- struct eh_region *next_peer;
+ struct eh_region_d *inner;
+ struct eh_region_d *next_peer;
/* List of regions sharing label. */
- struct eh_region *next_region_sharing_label;
+ struct eh_region_d *next_region_sharing_label;
/* An identifier for this region. */
int region_number;
@@ -64,15 +64,15 @@ struct GTY(()) eh_region
/* A list of catch blocks, a surrounding try block,
and the label for continuing after a catch. */
struct eh_region_u_try {
- struct eh_region *eh_catch;
- struct eh_region *last_catch;
+ struct eh_region_d *eh_catch;
+ struct eh_region_d *last_catch;
} GTY ((tag ("ERT_TRY"))) eh_try;
/* The list through the catch handlers, the list of type objects
matched, and the list of associated filters. */
struct eh_region_u_catch {
- struct eh_region *next_catch;
- struct eh_region *prev_catch;
+ struct eh_region_d *next_catch;
+ struct eh_region_d *prev_catch;
tree type_list;
tree filter_list;
} GTY ((tag ("ERT_CATCH"))) eh_catch;
@@ -108,7 +108,7 @@ struct GTY(()) eh_region
unsigned may_contain_throw : 1;
};
-typedef struct eh_region *eh_region;
+typedef struct eh_region_d *eh_region;
DEF_VEC_P(eh_region);
DEF_VEC_ALLOC_P(eh_region, gc);
DEF_VEC_ALLOC_P(eh_region, heap);
@@ -118,7 +118,7 @@ DEF_VEC_ALLOC_P(eh_region, heap);
struct GTY(()) eh_status
{
/* The tree of all regions for this function. */
- struct eh_region *region_tree;
+ struct eh_region_d *region_tree;
/* The same information as an indexable array. */
VEC(eh_region,gc) *region_array;
@@ -133,14 +133,14 @@ extern int doing_eh (int);
/* Note that the current EH region (if any) may contain a throw, or a
call to a function which itself may contain a throw. */
-extern void note_eh_region_may_contain_throw (struct eh_region *);
+extern void note_eh_region_may_contain_throw (struct eh_region_d *);
/* Invokes CALLBACK for every exception handler label. Only used by old
loop hackery; should not be used by new code. */
extern void for_each_eh_label (void (*) (rtx));
/* Invokes CALLBACK for every exception region in the current function. */
-extern void for_each_eh_region (void (*) (struct eh_region *));
+extern void for_each_eh_region (void (*) (struct eh_region_d *));
/* Determine if the given INSN can throw an exception. */
extern bool can_throw_internal_1 (int, bool, bool);
@@ -182,19 +182,19 @@ extern int duplicate_eh_regions (struct function *, duplicate_eh_regions_map,
extern void sjlj_emit_function_exit_after (rtx);
extern void default_init_unwind_resume_libfunc (void);
-extern struct eh_region *gen_eh_region_cleanup (struct eh_region *);
-extern struct eh_region *gen_eh_region_try (struct eh_region *);
-extern struct eh_region *gen_eh_region_catch (struct eh_region *, tree);
-extern struct eh_region *gen_eh_region_allowed (struct eh_region *, tree);
-extern struct eh_region *gen_eh_region_must_not_throw (struct eh_region *);
-extern int get_eh_region_number (struct eh_region *);
-extern bool get_eh_region_may_contain_throw (struct eh_region *);
+extern struct eh_region_d *gen_eh_region_cleanup (struct eh_region_d *);
+extern struct eh_region_d *gen_eh_region_try (struct eh_region_d *);
+extern struct eh_region_d *gen_eh_region_catch (struct eh_region_d *, tree);
+extern struct eh_region_d *gen_eh_region_allowed (struct eh_region_d *, tree);
+extern struct eh_region_d *gen_eh_region_must_not_throw (struct eh_region_d *);
+extern int get_eh_region_number (struct eh_region_d *);
+extern bool get_eh_region_may_contain_throw (struct eh_region_d *);
extern tree get_eh_region_no_tree_label (int);
-extern tree get_eh_region_tree_label (struct eh_region *);
-extern void set_eh_region_tree_label (struct eh_region *, tree);
+extern tree get_eh_region_tree_label (struct eh_region_d *);
+extern void set_eh_region_tree_label (struct eh_region_d *, tree);
extern void foreach_reachable_handler (int, bool, bool,
- void (*) (struct eh_region *, void *),
+ void (*) (struct eh_region_d *, void *),
void *);
extern void collect_eh_region_array (void);
@@ -274,5 +274,6 @@ extern void set_eh_throw_stmt_table (struct function *, struct htab *);
extern void remove_unreachable_regions (sbitmap, sbitmap);
extern VEC(int,heap) * label_to_region_map (void);
extern int num_eh_regions (void);
-extern struct eh_region *redirect_eh_edge_to_label (struct edge_def *, tree, bool, bool, int);
+extern bitmap must_not_throw_labels (void);
+extern struct eh_region_d *redirect_eh_edge_to_label (struct edge_def *, tree, bool, bool, int);
extern int get_next_region_sharing_label (int);
diff --git a/gcc/expmed.c b/gcc/expmed.c
index d0c1621cc5e..321d5f6918d 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -5076,7 +5076,7 @@ make_tree (tree type, rtx x)
/* else fall through. */
default:
- t = build_decl (VAR_DECL, NULL_TREE, type);
+ t = build_decl (RTL_LOCATION (x), VAR_DECL, NULL_TREE, type);
/* If TYPE is a POINTER_TYPE, X might be Pmode with TYPE_MODE being
ptr_mode. So convert. */
@@ -5207,8 +5207,9 @@ emit_store_flag (rtx target, enum rtx_code code, rtx op0, rtx op1,
enum insn_code icode;
enum machine_mode compare_mode;
enum machine_mode target_mode = GET_MODE (target);
+ enum mode_class mclass;
rtx tem;
- rtx last = get_last_insn ();
+ rtx last;
rtx pattern, comparison;
if (unsignedp)
@@ -5342,117 +5343,41 @@ emit_store_flag (rtx target, enum rtx_code code, rtx op0, rtx op1,
return op0;
}
- icode = setcc_gen_code[(int) code];
-
- if (icode != CODE_FOR_nothing)
- {
- insn_operand_predicate_fn pred;
-
- /* We think we may be able to do this with a scc insn. Emit the
- comparison and then the scc insn. */
-
- do_pending_stack_adjust ();
- last = get_last_insn ();
-
- comparison
- = compare_from_rtx (op0, op1, code, unsignedp, mode, NULL_RTX);
- if (CONSTANT_P (comparison))
- {
- switch (GET_CODE (comparison))
- {
- case CONST_INT:
- if (comparison == const0_rtx)
- return const0_rtx;
- break;
-
-#ifdef FLOAT_STORE_FLAG_VALUE
- case CONST_DOUBLE:
- if (comparison == CONST0_RTX (GET_MODE (comparison)))
- return const0_rtx;
- break;
-#endif
- default:
- gcc_unreachable ();
- }
-
- if (normalizep == 1)
- return const1_rtx;
- if (normalizep == -1)
- return constm1_rtx;
- return const_true_rtx;
- }
-
- /* The code of COMPARISON may not match CODE if compare_from_rtx
- decided to swap its operands and reverse the original code.
-
- We know that compare_from_rtx returns either a CONST_INT or
- a new comparison code, so it is safe to just extract the
- code from COMPARISON. */
- code = GET_CODE (comparison);
-
- /* Get a reference to the target in the proper mode for this insn. */
- compare_mode = insn_data[(int) icode].operand[0].mode;
- subtarget = target;
- pred = insn_data[(int) icode].operand[0].predicate;
- if (optimize || ! (*pred) (subtarget, compare_mode))
- subtarget = gen_reg_rtx (compare_mode);
-
- pattern = GEN_FCN (icode) (subtarget);
- if (pattern)
- {
- emit_insn (pattern);
- return emit_store_flag_1 (target, subtarget, compare_mode,
- normalizep);
- }
- }
- else
+ mclass = GET_MODE_CLASS (mode);
+ for (compare_mode = mode; compare_mode != VOIDmode;
+ compare_mode = GET_MODE_WIDER_MODE (compare_mode))
{
- /* We don't have an scc insn, so try a cstore insn. */
-
- for (compare_mode = mode; compare_mode != VOIDmode;
- compare_mode = GET_MODE_WIDER_MODE (compare_mode))
- {
- icode = optab_handler (cstore_optab, compare_mode)->insn_code;
- if (icode != CODE_FOR_nothing)
- break;
- }
-
- if (icode != CODE_FOR_nothing)
+ enum machine_mode optab_mode = mclass == MODE_CC ? CCmode : compare_mode;
+ icode = optab_handler (cstore_optab, optab_mode)->insn_code;
+ if (icode != CODE_FOR_nothing)
{
+ rtx x, y;
enum machine_mode result_mode
= insn_data[(int) icode].operand[0].mode;
- rtx cstore_op0 = op0;
- rtx cstore_op1 = op1;
do_pending_stack_adjust ();
last = get_last_insn ();
- if (compare_mode != mode)
+ x = prepare_operand (icode, op0, 2, mode, compare_mode, unsignedp);
+ y = prepare_operand (icode, op1, 3, mode, compare_mode, unsignedp);
+ comparison = gen_rtx_fmt_ee (code, result_mode, x, y);
+ if (!x || !y
+ || !insn_data[icode].operand[2].predicate
+ (x, insn_data[icode].operand[2].mode)
+ || !insn_data[icode].operand[3].predicate
+ (y, insn_data[icode].operand[3].mode)
+ || !insn_data[icode].operand[1].predicate (comparison, VOIDmode))
{
- cstore_op0 = convert_modes (compare_mode, mode, cstore_op0,
- unsignedp);
- cstore_op1 = convert_modes (compare_mode, mode, cstore_op1,
- unsignedp);
+ delete_insns_since (last);
+ continue;
}
-
- if (!insn_data[(int) icode].operand[2].predicate (cstore_op0,
- compare_mode))
- cstore_op0 = copy_to_mode_reg (compare_mode, cstore_op0);
- if (!insn_data[(int) icode].operand[3].predicate (cstore_op1,
- compare_mode))
- cstore_op1 = copy_to_mode_reg (compare_mode, cstore_op1);
-
- comparison = gen_rtx_fmt_ee (code, result_mode, cstore_op0,
- cstore_op1);
subtarget = target;
-
if (optimize || !(insn_data[(int) icode].operand[0].predicate
(subtarget, result_mode)))
subtarget = gen_reg_rtx (result_mode);
- pattern = GEN_FCN (icode) (subtarget, comparison, cstore_op0,
- cstore_op1);
+ pattern = GEN_FCN (icode) (subtarget, comparison, x, y);
if (pattern)
{
@@ -5460,10 +5385,13 @@ emit_store_flag (rtx target, enum rtx_code code, rtx op0, rtx op1,
return emit_store_flag_1 (target, subtarget, result_mode,
normalizep);
}
+
+ delete_insns_since (last);
+ break;
}
}
- delete_insns_since (last);
+ last = get_last_insn ();
/* If optimizing, use different pseudo registers for each insn, instead
of reusing the same pseudo. This leads to better CSE, but slows
diff --git a/gcc/expr.c b/gcc/expr.c
index 7987baf55cd..6840dbc32b7 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -1424,7 +1424,7 @@ init_block_move_fn (const char *asmspec)
const_ptr_type_node, sizetype,
NULL_TREE);
- fn = build_decl (FUNCTION_DECL, fn, args);
+ fn = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL, fn, args);
DECL_EXTERNAL (fn) = 1;
TREE_PUBLIC (fn) = 1;
DECL_ARTIFICIAL (fn) = 1;
@@ -2714,7 +2714,7 @@ init_block_clear_fn (const char *asmspec)
integer_type_node, sizetype,
NULL_TREE);
- fn = build_decl (FUNCTION_DECL, fn, args);
+ fn = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL, fn, args);
DECL_EXTERNAL (fn) = 1;
TREE_PUBLIC (fn) = 1;
DECL_ARTIFICIAL (fn) = 1;
@@ -4296,6 +4296,36 @@ expand_assignment (tree to, tree from, bool nontemporal)
return;
}
+ else if (TREE_CODE (to) == MISALIGNED_INDIRECT_REF)
+ {
+ enum machine_mode mode, op_mode1;
+ enum insn_code icode;
+ rtx reg, addr, mem, insn;
+
+ reg = expand_expr (from, NULL_RTX, VOIDmode, EXPAND_NORMAL);
+ reg = force_not_mem (reg);
+
+ mode = TYPE_MODE (TREE_TYPE (to));
+ addr = expand_expr (TREE_OPERAND (to, 0), NULL_RTX, VOIDmode,
+ EXPAND_SUM);
+ addr = memory_address (mode, addr);
+ mem = gen_rtx_MEM (mode, addr);
+
+ set_mem_attributes (mem, to, 0);
+
+ icode = movmisalign_optab->handlers[mode].insn_code;
+ gcc_assert (icode != CODE_FOR_nothing);
+
+ op_mode1 = insn_data[icode].operand[1].mode;
+ if (! (*insn_data[icode].operand[1].predicate) (reg, op_mode1)
+ && op_mode1 != VOIDmode)
+ reg = copy_to_mode_reg (op_mode1, reg);
+
+ insn = GEN_FCN (icode) (mem, reg);
+ emit_insn (insn);
+ return;
+ }
+
/* If the rhs is a function call and its value is not an aggregate,
call the function before we start to compute the lhs.
This is needed for correct code for cases such as
@@ -5468,7 +5498,8 @@ store_constructor (tree exp, rtx target, int cleared, HOST_WIDE_INT size)
expand_normal (hi_index);
unsignedp = TYPE_UNSIGNED (domain);
- index = build_decl (VAR_DECL, NULL_TREE, domain);
+ index = build_decl (EXPR_LOCATION (exp),
+ VAR_DECL, NULL_TREE, domain);
index_r
= gen_reg_rtx (promote_mode (domain, DECL_MODE (index),
@@ -6225,6 +6256,45 @@ component_ref_field_offset (tree exp)
else
return SUBSTITUTE_PLACEHOLDER_IN_EXPR (DECL_FIELD_OFFSET (field), exp);
}
+
+/* Alignment in bits the TARGET of an assignment may be assumed to have. */
+
+static unsigned HOST_WIDE_INT
+target_align (const_tree target)
+{
+ /* We might have a chain of nested references with intermediate misaligning
+ bitfields components, so need to recurse to find out. */
+
+ unsigned HOST_WIDE_INT this_align, outer_align;
+
+ switch (TREE_CODE (target))
+ {
+ case BIT_FIELD_REF:
+ return 1;
+
+ case COMPONENT_REF:
+ this_align = DECL_ALIGN (TREE_OPERAND (target, 1));
+ outer_align = target_align (TREE_OPERAND (target, 0));
+ return MIN (this_align, outer_align);
+
+ case ARRAY_REF:
+ case ARRAY_RANGE_REF:
+ this_align = TYPE_ALIGN (TREE_TYPE (target));
+ outer_align = target_align (TREE_OPERAND (target, 0));
+ return MIN (this_align, outer_align);
+
+ CASE_CONVERT:
+ case NON_LVALUE_EXPR:
+ case VIEW_CONVERT_EXPR:
+ this_align = TYPE_ALIGN (TREE_TYPE (target));
+ outer_align = target_align (TREE_OPERAND (target, 0));
+ return MAX (this_align, outer_align);
+
+ default:
+ return TYPE_ALIGN (TREE_TYPE (target));
+ }
+}
+
/* Given an rtx VALUE that may contain additions and multiplications, return
an equivalent value that just refers to a register, memory, or constant.
@@ -6671,14 +6741,10 @@ highest_pow2_factor (const_tree exp)
static unsigned HOST_WIDE_INT
highest_pow2_factor_for_target (const_tree target, const_tree exp)
{
- unsigned HOST_WIDE_INT target_align, factor;
-
- factor = highest_pow2_factor (exp);
- if (TREE_CODE (target) == COMPONENT_REF)
- target_align = DECL_ALIGN_UNIT (TREE_OPERAND (target, 1));
- else
- target_align = TYPE_ALIGN_UNIT (TREE_TYPE (target));
- return MAX (factor, target_align);
+ unsigned HOST_WIDE_INT talign = target_align (target) / BITS_PER_UNIT;
+ unsigned HOST_WIDE_INT factor = highest_pow2_factor (exp);
+
+ return MAX (factor, talign);
}
/* Return &VAR expression for emulated thread local VAR. */
@@ -7473,7 +7539,8 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
with non-BLKmode values. */
gcc_assert (GET_MODE (ret) != BLKmode);
- val = build_decl (VAR_DECL, NULL, TREE_TYPE (exp));
+ val = build_decl (EXPR_LOCATION (exp),
+ VAR_DECL, NULL, TREE_TYPE (exp));
DECL_ARTIFICIAL (val) = 1;
DECL_IGNORED_P (val) = 1;
TREE_OPERAND (exp, 0) = val;
@@ -7541,9 +7608,6 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
/* Resolve the misalignment now, so that we don't have to remember
to resolve it later. Of course, this only works for reads. */
- /* ??? When we get around to supporting writes, we'll have to handle
- this in store_expr directly. The vectorizer isn't generating
- those yet, however. */
if (code == MISALIGNED_INDIRECT_REF)
{
int icode;
@@ -8249,7 +8313,8 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
}
if (!op0)
- op0 = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, mode, modifier);
+ op0 = expand_expr (TREE_OPERAND (exp, 0),
+ NULL_RTX, VOIDmode, modifier);
/* If the input and output modes are both the same, we are done. */
if (mode == GET_MODE (op0))
@@ -8257,7 +8322,8 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
/* If neither mode is BLKmode, and both modes are the same size
then we can use gen_lowpart. */
else if (mode != BLKmode && GET_MODE (op0) != BLKmode
- && GET_MODE_SIZE (mode) == GET_MODE_SIZE (GET_MODE (op0)))
+ && GET_MODE_SIZE (mode) == GET_MODE_SIZE (GET_MODE (op0))
+ && !COMPLEX_MODE_P (GET_MODE (op0)))
{
if (GET_CODE (op0) == SUBREG)
op0 = force_reg (GET_MODE (op0), op0);
@@ -9298,13 +9364,6 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
/* Lowered by gimplify.c. */
gcc_unreachable ();
- case CHANGE_DYNAMIC_TYPE_EXPR:
- /* This is ignored at the RTL level. The tree level set
- DECL_POINTER_ALIAS_SET of any variable to be 0, which is
- overkill for the RTL layer but is all that we can
- represent. */
- return const0_rtx;
-
case EXC_PTR_EXPR:
return get_exception_pointer ();
diff --git a/gcc/expr.h b/gcc/expr.h
index e3c38370bf2..64794834771 100644
--- a/gcc/expr.h
+++ b/gcc/expr.h
@@ -298,6 +298,9 @@ extern rtx expand_simple_unop (enum machine_mode, enum rtx_code, rtx, rtx,
perform the operation described by CODE and MODE. */
extern int have_insn_for (enum rtx_code, enum machine_mode);
+extern rtx prepare_operand (int, rtx, int, enum machine_mode, enum machine_mode,
+ int);
+
/* Emit code to make a call to a constant function or a library call. */
extern void emit_libcall_block (rtx, rtx, rtx, rtx);
@@ -573,9 +576,6 @@ extern void jumpif (tree, rtx);
the result is zero, or IF_TRUE_LABEL if the result is one. */
extern void do_jump (tree, rtx, rtx);
-/* Generate rtl to compare two rtx's, will call emit_cmp_insn. */
-extern rtx compare_from_rtx (rtx, rtx, enum rtx_code, int, enum machine_mode,
- rtx);
extern void do_compare_rtx_and_jump (rtx, rtx, enum rtx_code, int,
enum machine_mode, rtx, rtx, rtx);
diff --git a/gcc/final.c b/gcc/final.c
index c15b0966fc2..cd82542d636 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -130,6 +130,12 @@ rtx current_output_insn;
/* Line number of last NOTE. */
static int last_linenum;
+/* Last discriminator written to assembly. */
+static int last_discriminator;
+
+/* Discriminator of current block. */
+static int discriminator;
+
/* Highest line number in current block. */
static int high_block_linenum;
@@ -554,7 +560,17 @@ static int min_labelno, max_labelno;
int
label_to_alignment (rtx label)
{
- return LABEL_TO_ALIGNMENT (label);
+ if (CODE_LABEL_NUMBER (label) <= max_labelno)
+ return LABEL_TO_ALIGNMENT (label);
+ return 0;
+}
+
+int
+label_to_max_skip (rtx label)
+{
+ if (CODE_LABEL_NUMBER (label) <= max_labelno)
+ return LABEL_TO_MAX_SKIP (label);
+ return 0;
}
#ifdef HAVE_ATTR_length
@@ -892,6 +908,7 @@ shorten_branches (rtx first ATTRIBUTE_UNUSED)
if (LABEL_P (insn))
{
rtx next;
+ bool next_is_jumptable;
/* Merge in alignments computed by compute_alignments. */
log = LABEL_TO_ALIGNMENT (insn);
@@ -901,31 +918,30 @@ shorten_branches (rtx first ATTRIBUTE_UNUSED)
max_skip = LABEL_TO_MAX_SKIP (insn);
}
- log = LABEL_ALIGN (insn);
- if (max_log < log)
+ next = next_nonnote_insn (insn);
+ next_is_jumptable = next && JUMP_TABLE_DATA_P (next);
+ if (!next_is_jumptable)
{
- max_log = log;
- max_skip = LABEL_ALIGN_MAX_SKIP;
+ log = LABEL_ALIGN (insn);
+ if (max_log < log)
+ {
+ max_log = log;
+ max_skip = LABEL_ALIGN_MAX_SKIP;
+ }
}
- next = next_nonnote_insn (insn);
/* ADDR_VECs only take room if read-only data goes into the text
section. */
- if (JUMP_TABLES_IN_TEXT_SECTION
- || readonly_data_section == text_section)
- if (next && JUMP_P (next))
- {
- rtx nextbody = PATTERN (next);
- if (GET_CODE (nextbody) == ADDR_VEC
- || GET_CODE (nextbody) == ADDR_DIFF_VEC)
- {
- log = ADDR_VEC_ALIGN (next);
- if (max_log < log)
- {
- max_log = log;
- max_skip = LABEL_ALIGN_MAX_SKIP;
- }
- }
- }
+ if ((JUMP_TABLES_IN_TEXT_SECTION
+ || readonly_data_section == text_section)
+ && next_is_jumptable)
+ {
+ log = ADDR_VEC_ALIGN (next);
+ if (max_log < log)
+ {
+ max_log = log;
+ max_skip = LABEL_ALIGN_MAX_SKIP;
+ }
+ }
LABEL_TO_ALIGNMENT (insn) = max_log;
LABEL_TO_MAX_SKIP (insn) = max_skip;
max_log = 0;
@@ -1487,6 +1503,7 @@ final_start_function (rtx first ATTRIBUTE_UNUSED, FILE *file,
last_filename = locator_file (prologue_locator);
last_linenum = locator_line (prologue_locator);
+ last_discriminator = discriminator = 0;
high_block_linenum = high_function_linenum = last_linenum;
@@ -1843,6 +1860,8 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
else
*seen |= SEEN_BB;
+ discriminator = NOTE_BASIC_BLOCK (insn)->discriminator;
+
break;
case NOTE_INSN_EH_REGION_BEG:
@@ -1870,9 +1889,19 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
break;
case NOTE_INSN_EPILOGUE_BEG:
+#if defined (DWARF2_UNWIND_INFO) && defined (HAVE_epilogue)
+ if (dwarf2out_do_frame ())
+ dwarf2out_begin_epilogue (insn);
+#endif
targetm.asm_out.function_begin_epilogue (file);
break;
+ case NOTE_INSN_CFA_RESTORE_STATE:
+#if defined (DWARF2_UNWIND_INFO)
+ dwarf2out_frame_debug_restore_state ();
+#endif
+ break;
+
case NOTE_INSN_FUNCTION_BEG:
app_disable ();
(*debug_hooks->end_prologue) (last_linenum, last_filename);
@@ -2014,48 +2043,41 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
app_disable ();
next = next_nonnote_insn (insn);
- if (next != 0 && JUMP_P (next))
+ /* If this label is followed by a jump-table, make sure we put
+ the label in the read-only section. Also possibly write the
+ label and jump table together. */
+ if (next != 0 && JUMP_TABLE_DATA_P (next))
{
- rtx nextbody = PATTERN (next);
-
- /* If this label is followed by a jump-table,
- make sure we put the label in the read-only section. Also
- possibly write the label and jump table together. */
-
- if (GET_CODE (nextbody) == ADDR_VEC
- || GET_CODE (nextbody) == ADDR_DIFF_VEC)
- {
#if defined(ASM_OUTPUT_ADDR_VEC) || defined(ASM_OUTPUT_ADDR_DIFF_VEC)
- /* In this case, the case vector is being moved by the
- target, so don't output the label at all. Leave that
- to the back end macros. */
+ /* In this case, the case vector is being moved by the
+ target, so don't output the label at all. Leave that
+ to the back end macros. */
#else
- if (! JUMP_TABLES_IN_TEXT_SECTION)
- {
- int log_align;
+ if (! JUMP_TABLES_IN_TEXT_SECTION)
+ {
+ int log_align;
- switch_to_section (targetm.asm_out.function_rodata_section
- (current_function_decl));
+ switch_to_section (targetm.asm_out.function_rodata_section
+ (current_function_decl));
#ifdef ADDR_VEC_ALIGN
- log_align = ADDR_VEC_ALIGN (next);
+ log_align = ADDR_VEC_ALIGN (next);
#else
- log_align = exact_log2 (BIGGEST_ALIGNMENT / BITS_PER_UNIT);
+ log_align = exact_log2 (BIGGEST_ALIGNMENT / BITS_PER_UNIT);
#endif
- ASM_OUTPUT_ALIGN (file, log_align);
- }
- else
- switch_to_section (current_function_section ());
+ ASM_OUTPUT_ALIGN (file, log_align);
+ }
+ else
+ switch_to_section (current_function_section ());
#ifdef ASM_OUTPUT_CASE_LABEL
- ASM_OUTPUT_CASE_LABEL (file, "L", CODE_LABEL_NUMBER (insn),
- next);
+ ASM_OUTPUT_CASE_LABEL (file, "L", CODE_LABEL_NUMBER (insn),
+ next);
#else
- targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (insn));
+ targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (insn));
#endif
#endif
- break;
- }
+ break;
}
if (LABEL_ALT_ENTRY_P (insn))
output_alternate_entry_point (file, insn);
@@ -2171,7 +2193,9 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
note in a row. */
if (notice_source_line (insn))
{
- (*debug_hooks->source_line) (last_linenum, last_filename);
+ (*debug_hooks->source_line) (last_linenum,
+ last_filename,
+ last_discriminator);
}
if (GET_CODE (body) == ASM_INPUT)
@@ -2321,9 +2345,13 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
&& GET_CODE (SET_DEST (set)) == CC0
&& insn != last_ignored_compare)
{
+ rtx src1, src2;
if (GET_CODE (SET_SRC (set)) == SUBREG)
SET_SRC (set) = alter_subreg (&SET_SRC (set));
- else if (GET_CODE (SET_SRC (set)) == COMPARE)
+
+ src1 = SET_SRC (set);
+ src2 = NULL_RTX;
+ if (GET_CODE (SET_SRC (set)) == COMPARE)
{
if (GET_CODE (XEXP (SET_SRC (set), 0)) == SUBREG)
XEXP (SET_SRC (set), 0)
@@ -2331,11 +2359,18 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
if (GET_CODE (XEXP (SET_SRC (set), 1)) == SUBREG)
XEXP (SET_SRC (set), 1)
= alter_subreg (&XEXP (SET_SRC (set), 1));
+ if (XEXP (SET_SRC (set), 1)
+ == CONST0_RTX (GET_MODE (XEXP (SET_SRC (set), 0))))
+ src2 = XEXP (SET_SRC (set), 0);
}
if ((cc_status.value1 != 0
- && rtx_equal_p (SET_SRC (set), cc_status.value1))
+ && rtx_equal_p (src1, cc_status.value1))
|| (cc_status.value2 != 0
- && rtx_equal_p (SET_SRC (set), cc_status.value2)))
+ && rtx_equal_p (src1, cc_status.value2))
+ || (src2 != 0 && cc_status.value1 != 0
+ && rtx_equal_p (src2, cc_status.value1))
+ || (src2 != 0 && cc_status.value2 != 0
+ && rtx_equal_p (src2, cc_status.value2)))
{
/* Don't delete insn if it has an addressing side-effect. */
if (! FIND_REG_INC_NOTE (insn, NULL_RTX)
@@ -2349,9 +2384,7 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
}
}
}
-#endif
-#ifdef HAVE_cc0
/* If this is a conditional branch, maybe modify it
if the cc's are in a nonstandard state
so that it accomplishes the same thing that it would
@@ -2688,11 +2721,13 @@ notice_source_line (rtx insn)
if (filename
&& (force_source_line
|| filename != last_filename
- || last_linenum != linenum))
+ || last_linenum != linenum
+ || last_discriminator != discriminator))
{
force_source_line = false;
last_filename = filename;
last_linenum = linenum;
+ last_discriminator = discriminator;
high_block_linenum = MAX (last_linenum, high_block_linenum);
high_function_linenum = MAX (last_linenum, high_function_linenum);
return true;
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index fb590492fb4..433ec6085ab 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -119,10 +119,10 @@ static int simple_operand_p (const_tree);
static tree range_binop (enum tree_code, tree, tree, int, tree, int);
static tree range_predecessor (tree);
static tree range_successor (tree);
-static tree make_range (tree, int *, tree *, tree *, bool *);
-static tree build_range_check (tree, tree, int, tree, tree);
-static int merge_ranges (int *, tree *, tree *, int, tree, tree, int, tree,
- tree);
+extern tree make_range (tree, int *, tree *, tree *, bool *);
+extern tree build_range_check (tree, tree, int, tree, tree);
+extern bool merge_ranges (int *, tree *, tree *, int, tree, tree, int,
+ tree, tree);
static tree fold_range_test (enum tree_code, tree, tree, tree);
static tree fold_cond_expr_with_comparison (tree, tree, tree, tree);
static tree unextend (tree, int, int, tree);
@@ -2327,7 +2327,24 @@ fold_convert_const_real_from_real (tree type, const_tree arg1)
real_convert (&value, TYPE_MODE (type), &TREE_REAL_CST (arg1));
t = build_real (type, value);
- TREE_OVERFLOW (t) = TREE_OVERFLOW (arg1);
+ /* If converting an infinity or NAN to a representation that doesn't
+ have one, set the overflow bit so that we can produce some kind of
+ error message at the appropriate point if necessary. It's not the
+ most user-friendly message, but it's better than nothing. */
+ if (REAL_VALUE_ISINF (TREE_REAL_CST (arg1))
+ && !MODE_HAS_INFINITIES (TYPE_MODE (type)))
+ TREE_OVERFLOW (t) = 1;
+ else if (REAL_VALUE_ISNAN (TREE_REAL_CST (arg1))
+ && !MODE_HAS_NANS (TYPE_MODE (type)))
+ TREE_OVERFLOW (t) = 1;
+ /* Regular overflow, conversion produced an infinity in a mode that
+ can't represent them. */
+ else if (!MODE_HAS_INFINITIES (TYPE_MODE (type))
+ && REAL_VALUE_ISINF (value)
+ && !REAL_VALUE_ISINF (TREE_REAL_CST (arg1)))
+ TREE_OVERFLOW (t) = 1;
+ else
+ TREE_OVERFLOW (t) = TREE_OVERFLOW (arg1);
return t;
}
@@ -2626,9 +2643,10 @@ fold_convert (tree type, tree arg)
case POINTER_TYPE: case REFERENCE_TYPE:
case REAL_TYPE:
case FIXED_POINT_TYPE:
- return build2 (COMPLEX_EXPR, type,
- fold_convert (TREE_TYPE (type), arg),
- fold_convert (TREE_TYPE (type), integer_zero_node));
+ return fold_build2 (COMPLEX_EXPR, type,
+ fold_convert (TREE_TYPE (type), arg),
+ fold_convert (TREE_TYPE (type),
+ integer_zero_node));
case COMPLEX_TYPE:
{
tree rpart, ipart;
@@ -3741,7 +3759,7 @@ fold_truth_not_expr (tree arg)
case NON_LVALUE_EXPR:
return invert_truthvalue (TREE_OPERAND (arg, 0));
- case NOP_EXPR:
+ CASE_CONVERT:
if (TREE_CODE (TREE_TYPE (arg)) == BOOLEAN_TYPE)
{
t = build1 (TRUTH_NOT_EXPR, type, arg);
@@ -3750,7 +3768,6 @@ fold_truth_not_expr (tree arg)
/* ... fall through ... */
- case CONVERT_EXPR:
case FLOAT_EXPR:
t = build1 (TREE_CODE (arg), type,
invert_truthvalue (TREE_OPERAND (arg, 0)));
@@ -4398,7 +4415,7 @@ range_binop (enum tree_code code, tree type, tree arg0, int upper0_p,
because signed overflow is undefined; otherwise, do not change
*STRICT_OVERFLOW_P. */
-static tree
+tree
make_range (tree exp, int *pin_p, tree *plow, tree *phigh,
bool *strict_overflow_p)
{
@@ -4690,11 +4707,10 @@ make_range (tree exp, int *pin_p, tree *plow, tree *phigh,
type, TYPE, return an expression to test if EXP is in (or out of, depending
on IN_P) the range. Return 0 if the test couldn't be created. */
-static tree
+tree
build_range_check (tree type, tree exp, int in_p, tree low, tree high)
{
tree etype = TREE_TYPE (exp), value;
- enum tree_code code;
#ifdef HAVE_canonicalize_funcptr_for_compare
/* Disable this optimization for function pointer expressions
@@ -4777,35 +4793,14 @@ build_range_check (tree type, tree exp, int in_p, tree low, tree high)
}
/* Optimize (c>=low) && (c<=high) into (c-low>=0) && (c-low<=high-low).
- This requires wrap-around arithmetics for the type of the expression. */
- code = TREE_CODE (etype);
- switch (code)
- {
- case INTEGER_TYPE:
- case ENUMERAL_TYPE:
- case BOOLEAN_TYPE:
- /* There is no requirement that LOW be within the range of ETYPE
- if the latter is a subtype. It must, however, be within the base
- type of ETYPE. So be sure we do the subtraction in that type. */
- if (code == INTEGER_TYPE && TREE_TYPE (etype))
- {
- etype = TREE_TYPE (etype);
- /* But not in an enumeral or boolean type though. */
- code = TREE_CODE (etype);
- }
-
- if (code != INTEGER_TYPE)
- etype = lang_hooks.types.type_for_size (TYPE_PRECISION (etype),
- TYPE_UNSIGNED (etype));
- break;
+ This requires wrap-around arithmetics for the type of the expression.
+ First make sure that arithmetics in this type is valid, then make sure
+ that it wraps around. */
+ if (TREE_CODE (etype) == ENUMERAL_TYPE || TREE_CODE (etype) == BOOLEAN_TYPE)
+ etype = lang_hooks.types.type_for_size (TYPE_PRECISION (etype),
+ TYPE_UNSIGNED (etype));
- default:
- break;
- }
-
- /* If we don't have wrap-around arithmetics upfront, try to force it. */
- if (TREE_CODE (etype) == INTEGER_TYPE
- && !TYPE_OVERFLOW_WRAPS (etype))
+ if (TREE_CODE (etype) == INTEGER_TYPE && !TYPE_OVERFLOW_WRAPS (etype))
{
tree utype, minv, maxv;
@@ -4883,7 +4878,7 @@ range_successor (tree val)
/* Given two ranges, see if we can merge them into one. Return 1 if we
can, 0 if we can't. Set the output range into the specified parameters. */
-static int
+bool
merge_ranges (int *pin_p, tree *plow, tree *phigh, int in0_p, tree low0,
tree high0, int in1_p, tree low1, tree high1)
{
@@ -7229,11 +7224,6 @@ fold_sign_changed_comparison (enum tree_code code, tree type,
if (TYPE_PRECISION (inner_type) != TYPE_PRECISION (outer_type))
return NULL_TREE;
- /* If the conversion is from an integral subtype to its basetype
- leave it alone. */
- if (TREE_TYPE (inner_type) == outer_type)
- return NULL_TREE;
-
if (TREE_CODE (arg1) != INTEGER_CST
&& !(CONVERT_EXPR_P (arg1)
&& TREE_TYPE (TREE_OPERAND (arg1, 0)) == inner_type))
@@ -8010,6 +8000,13 @@ build_fold_addr_expr_with_type (tree t, tree ptrtype)
if (TREE_TYPE (t) != ptrtype)
t = build1 (NOP_EXPR, ptrtype, t);
}
+ else if (TREE_CODE (t) == VIEW_CONVERT_EXPR)
+ {
+ t = build_fold_addr_expr (TREE_OPERAND (t, 0));
+
+ if (TREE_TYPE (t) != ptrtype)
+ t = fold_convert (ptrtype, t);
+ }
else
t = build1 (ADDR_EXPR, ptrtype, t);
@@ -8291,17 +8288,16 @@ fold_unary (enum tree_code code, tree type, tree op0)
transformation effectively doesn't preserve non-maximal ranges. */
if (TREE_CODE (type) == INTEGER_TYPE
&& TREE_CODE (op0) == BIT_AND_EXPR
- && TREE_CODE (TREE_OPERAND (op0, 1)) == INTEGER_CST
- /* Not if the conversion is to the sub-type. */
- && TREE_TYPE (type) != TREE_TYPE (op0))
+ && TREE_CODE (TREE_OPERAND (op0, 1)) == INTEGER_CST)
{
- tree and = op0;
- tree and0 = TREE_OPERAND (and, 0), and1 = TREE_OPERAND (and, 1);
+ tree and_expr = op0;
+ tree and0 = TREE_OPERAND (and_expr, 0);
+ tree and1 = TREE_OPERAND (and_expr, 1);
int change = 0;
- if (TYPE_UNSIGNED (TREE_TYPE (and))
+ if (TYPE_UNSIGNED (TREE_TYPE (and_expr))
|| (TYPE_PRECISION (type)
- <= TYPE_PRECISION (TREE_TYPE (and))))
+ <= TYPE_PRECISION (TREE_TYPE (and_expr))))
change = 1;
else if (TYPE_PRECISION (TREE_TYPE (and1))
<= HOST_BITS_PER_WIDE_INT
@@ -8410,11 +8406,7 @@ fold_unary (enum tree_code code, tree type, tree op0)
|| POINTER_TYPE_P (type))
&& (INTEGRAL_TYPE_P (TREE_TYPE (op0))
|| POINTER_TYPE_P (TREE_TYPE (op0)))
- && TYPE_PRECISION (type) == TYPE_PRECISION (TREE_TYPE (op0))
- /* Do not muck with VIEW_CONVERT_EXPRs that convert from
- a sub-type to its base type as generated by the Ada FE. */
- && !(INTEGRAL_TYPE_P (TREE_TYPE (op0))
- && TREE_TYPE (TREE_TYPE (op0))))
+ && TYPE_PRECISION (type) == TYPE_PRECISION (TREE_TYPE (op0)))
return fold_convert (type, op0);
/* Strip inner integral conversions that do not change the precision. */
@@ -10185,8 +10177,12 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
&& TREE_INT_CST_HIGH (tree11) == 0
&& ((TREE_INT_CST_LOW (tree01) + TREE_INT_CST_LOW (tree11))
== TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg0, 0)))))
- return build2 (LROTATE_EXPR, type, TREE_OPERAND (arg0, 0),
- code0 == LSHIFT_EXPR ? tree01 : tree11);
+ return fold_convert (type,
+ build2 (LROTATE_EXPR,
+ TREE_TYPE (TREE_OPERAND (arg0, 0)),
+ TREE_OPERAND (arg0, 0),
+ code0 == LSHIFT_EXPR
+ ? tree01 : tree11));
else if (code11 == MINUS_EXPR)
{
tree tree110, tree111;
@@ -10200,10 +10196,12 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
(TREE_TYPE (TREE_OPERAND
(arg0, 0))))
&& operand_equal_p (tree01, tree111, 0))
- return build2 ((code0 == LSHIFT_EXPR
- ? LROTATE_EXPR
- : RROTATE_EXPR),
- type, TREE_OPERAND (arg0, 0), tree01);
+ return fold_convert (type,
+ build2 ((code0 == LSHIFT_EXPR
+ ? LROTATE_EXPR
+ : RROTATE_EXPR),
+ TREE_TYPE (TREE_OPERAND (arg0, 0)),
+ TREE_OPERAND (arg0, 0), tree01));
}
else if (code01 == MINUS_EXPR)
{
@@ -10218,10 +10216,12 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
(TREE_TYPE (TREE_OPERAND
(arg0, 0))))
&& operand_equal_p (tree11, tree011, 0))
- return build2 ((code0 != LSHIFT_EXPR
- ? LROTATE_EXPR
- : RROTATE_EXPR),
- type, TREE_OPERAND (arg0, 0), tree11);
+ return fold_convert (type,
+ build2 ((code0 != LSHIFT_EXPR
+ ? LROTATE_EXPR
+ : RROTATE_EXPR),
+ TREE_TYPE (TREE_OPERAND (arg0, 0)),
+ TREE_OPERAND (arg0, 0), tree11));
}
}
}
@@ -11392,6 +11392,8 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
if (prec < HOST_BITS_PER_WIDE_INT
|| newmask == ~(unsigned HOST_WIDE_INT) 0)
{
+ tree newmaskt;
+
if (shift_type != TREE_TYPE (arg0))
{
tem = fold_build2 (TREE_CODE (arg0), shift_type,
@@ -11402,9 +11404,9 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
}
else
tem = op0;
- return fold_build2 (BIT_AND_EXPR, type, tem,
- build_int_cst_type (TREE_TYPE (op1),
- newmask));
+ newmaskt = build_int_cst_type (TREE_TYPE (op1), newmask);
+ if (!tree_int_cst_equal (newmaskt, arg1))
+ return fold_build2 (BIT_AND_EXPR, type, tem, newmaskt);
}
}
}
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 7544345b356..12aa9dce0f5 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,601 @@
+2009-06-16 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/36947
+ PR fortran/40039
+ * expr.c (gfc_check_pointer_assign): Call 'gfc_compare_interfaces' with
+ error message.
+ * gfortran.h (gfc_compare_interfaces): Additional argument.
+ * interface.c (operator_correspondence): Removed.
+ (gfc_compare_interfaces): Additional argument to return error message.
+ Directly use the code from 'operator_correspondence' instead of calling
+ the function. Check for OPTIONAL. Some rearrangements.
+ (check_interface1): Call 'gfc_compare_interfaces' without error message.
+ (compare_parameter): Call 'gfc_compare_interfaces' with error message.
+ * resolve.c (check_generic_tbp_ambiguity): Call 'gfc_compare_interfaces'
+ without error message.
+
+2009-06-16 Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/40383
+ * trans-decl.c (create_function_arglist): Copy formal charlist to
+ have a proper passed_length for -fcheck=bounds.
+
+2009-06-12 Steven G. Kargl <kargls@comcast.net>
+
+ * arith.c (gfc_enum_initializer): Move function ...
+ * decl.c: ... here. Remove gfc_ prefix and make static.
+ (enumerator_decl): Update function call.
+ * gfortran.h: Remove gfc_enum_initializer prototype.
+
+2009-06-12 Aldy Hernandez <aldyh@redhat.com>
+
+ * trans-array.c (gfc_trans_allocate_array_storage): Pass
+ location on down.
+ (gfc_trans_array_constructor_value): Same.
+ (gfc_trans_scalarized_loop_end): Same.
+ (gfc_conv_ss_startstride): Same.
+ (gfc_trans_g77_array): Same.
+ (gfc_trans_dummy_array_bias): Same.
+ (gfc_conv_array_parameter): Same.
+ (structure_alloc_comps): Same.
+ * trans-expr.c (gfc_conv_function_call): Same.
+ (fill_with_spaces): Same.
+ (gfc_trans_string_copy): Same.
+ (gfc_trans_scalar_assign): Same.
+ * trans-stmt.c (gfc_trans_goto): Same.
+ (gfc_trans_if_1): Same.
+ (gfc_trans_simple_do): Same.
+ (gfc_trans_do): Same.
+ (gfc_trans_do_while): Same.
+ (gfc_trans_logical_select): Same.
+ (gfc_trans_select): Same.
+ (gfc_trans_forall_loop): Same.
+ (gfc_trans_nested_forall_loop): Same.
+ (generate_loop_for_temp_to_lhs): Same.
+ (generate_loop_for_rhs_to_temp): Same.
+ (gfc_trans_forall_1): Same.
+ (gfc_trans_where_assign): Same.
+ (gfc_trans_where_3): Same.
+ (gfc_trans_allocate): Same.
+ * trans.c (gfc_finish_block): Same.
+ (gfc_trans_runtime_check): Same.
+ (gfc_call_malloc): Same.
+ (gfc_allocate_with_status): Same.
+ (gfc_call_free): Same.
+ (gfc_deallocate_with_status): Same.
+ (gfc_call_realloc): Same.
+ (gfc_trans_code): Same.
+ * trans-decl.c (gfc_init_default_dt): Same.
+ (gfc_generate_constructors): Same.
+ * trans-io.c (gfc_trans_io_runtime_check): Same.
+ * trans-intrinsic.c (gfc_conv_intrinsic_ctime): Same.
+ (gfc_conv_intrinsic_fdate): Same.
+ (gfc_conv_intrinsic_ttynam): Same.
+ (gfc_conv_intrinsic_minmax): Same.
+ (gfc_conv_intrinsic_minmax_char): Same.
+ (gfc_conv_intrinsic_anyall): Same.
+ (gfc_conv_intrinsic_count): Same.
+ (gfc_conv_intrinsic_arith): Same.
+ (gfc_conv_intrinsic_minmaxloc): Same.
+ (gfc_conv_intrinsic_minmaxval): Same.
+ (gfc_conv_intrinsic_rrspacing): Same.
+ (gfc_conv_intrinsic_array_transfer): Same.
+ (gfc_conv_intrinsic_trim): Same.
+ (gfc_conv_intrinsic_repeat): Same.
+
+2009-06-12 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/40176
+ * resolve.c (resolve_symbol): Additional error check, preventing an
+ infinite loop.
+
+2009-06-11 Paul Thomas <pault@gcc.gnu.org>
+
+ PR fortran/40402
+ * resolve.c (next_data_value): It is an error if the value is
+ not constant.
+
+2009-06-11 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+
+ PR fortran/38718
+ * intrinsic.c (add_functions): Add simplifiers for ISNAN,
+ IS_IOSTAT_END and IS_IOSTAT_EOR.
+ * intrinsic.h (gfc_simplify_is_iostat_end, gfc_simplify_is_iostat_eor,
+ gfc_simplify_isnan): New prototypes.
+ * intrinsic.c (gfc_simplify_is_iostat_end, gfc_simplify_is_iostat_eor,
+ gfc_simplify_isnan): New functions.
+
+2009-06-11 Jakub Jelinek <jakub@redhat.com>
+
+ * interface.c (fold_unary): Rename to...
+ (fold_unary_intrinsic): ... this.
+ (gfc_extend_expr): Adjust caller.
+ (gfc_match_generic_spec): Likewise. Initialize *op to INTRINSIC_NONE
+ to avoid warnings.
+ * expr.c (gfc_simplify_expr): Initialize start and end before calling
+ gfc_extract_int.
+
+2009-06-10 Dave Korn <dave.korn.cygwin@gmail.com>
+
+ * trans-decl.c (create_main_function): Don't build main decl twice.
+
+2009-06-09 Tobias Burnus <burnus@net-b.de>
+
+ * trans-decl.c (gfc_generate_function_code): Use gfc_option.rtcheck
+ instead of flag_bounds_check.
+ * intrinsic.texi (ISO_FORTRAN_ENV): Document INT{8,16,32,64} and
+ REAL{32,64,128}.
+
+2009-06-08 Paul Thomas <pault@gcc.gnu.org>
+
+ * trans-array.h : Replace prototypes for
+ gfc_conv_descriptor_offset, gfc_conv_descriptor_stride,
+ gfc_conv_descriptor_lbound, gfc_conv_descriptor_ubound with new
+ prototypes of the same names with _get or _set appended.
+ * trans-array.c : Make the originals of the above static and
+ new functions for the _get and _set functions. Update all the
+ references to these descriptor access functions.
+ * trans-expr.c : Update references to the above descriptor
+ access functions.
+ * trans-intrinsic.c : The same.
+ * trans-openmp.c : The same.
+ * trans-stmt.c : The same.
+
+2009-06-08 Alexandre Oliva <aoliva@redhat.com>
+
+ * options.c (gfc_post_options): Disable dump_parse_tree
+ during -fcompare-debug-second.
+
+2009-06-07 Jerry DeLisle <jvdelisle@gcc.gnu.org>
+
+ PR fortran/40008
+ * gfortran.h (gfc_open): Add newunit expression to structure.
+ * io.c (io_tag): Add new unit tag and fix whitespace.
+ (match_open_element): Add matching for newunit.
+ (gfc_free_open): Free the newunit expression.
+ (gfc_resolve_open): Add newunit to resolution and check constraints.
+ (gfc_resolve_close): Add check for non-negative unit.
+ (gfc_resolve_filepos): Likewise.
+ (gfc_resolve_dt): Likewise.
+ * trans-io.c (set_parameter_value): Build runtime checks for unit
+ numbers within range of kind=4 integer. (gfc_trans_open) Set the
+ newunit parameter.
+ * ioparm.def (IOPARM): Define the newunit parameter as a pointer
+ to GFC_INTEGER_4, pint4.
+
+2009-06-07 Daniel Franke <franke.daniel@gmail.com>
+
+ PR fortran/25104
+ PR fortran/29962
+ * array.c (gfc_append_constructor): Added NULL-check.
+ * check.c (gfc_check_spread): Check DIM.
+ (gfc_check_unpack): Check that the ARRAY arguments provides enough
+ values for MASK.
+ * intrinsic.h (gfc_simplify_spread): New prototype.
+ (gfc_simplify_unpack): Likewise.
+ * intrinsic.c (add_functions): Added new simplifier callbacks.
+ * simplify.c (gfc_simplify_spread): New.
+ (gfc_simplify_unpack): New.
+ * expr.c (check_transformational): Allow additional transformational
+ intrinsics in initialization expression.
+
+2009-06-07 Daniel Franke <franke.daniel@gmail.com>
+
+ PR fortran/25104
+ PR fortran/29962
+ * check.c (gfc_check_all_any): Check rank of DIM.
+ (gfc_check_count): Likewise.
+ * intrinsic.h (gfc_simplify_all): New prototype.
+ (gfc_simplify_any): Likewise.
+ (gfc_simplify_count): Likewise.
+ (gfc_simplify_sum): Likewise.
+ (gfc_simplify_product): Likewise.
+ * intrinsic.c (add_functions): Added new simplifier callbacks.
+ * simplify.c (transformational_result): New.
+ (simplify_transformation_to_scalar): New.
+ (simplify_transformation_to_array): New.
+ (gfc_count): New.
+ (gfc_simplify_all): New.
+ (gfc_simplify_any): New.
+ (gfc_simplify_count): New.
+ (gfc_simplify_sum): New.
+ (gfc_simplify_product): New.
+ * expr.c (check_transformational): Allow additional transformational
+ intrinsics in initialization expression.
+
+2009-06-07 Daniel Franke <franke.daniel@gmail.com>
+
+ * check.c (dim_rank_check): Return SUCCESS if DIM=NULL.
+ (gfc_check_lbound): Removed (now) redundant check for DIM=NULL.
+ (gfc_check_minloc_maxloc): Likewise.
+ (check_reduction): Likewise.
+ (gfc_check_size): Likewise.
+ (gfc_check_ubound): Likewise.
+ (gfc_check_cshift): Added missing shape-conformance checks.
+ (gfc_check_eoshift): Likewise.
+ * gfortran.h (gfc_check_conformance): Modified prototype to printf-style.
+ * expr.c (gfc_check_conformance): Accept error-message chunks in
+ printf-style. Changed all callers.
+
+
+2009-06-07 Daniel Franke <franke.daniel@gmail.com>
+
+ PR fortran/25104
+ PR fortran/29962
+ * intrinsic.h (gfc_simplify_dot_product): New prototype.
+ (gfc_simplify_matmul): Likewise.
+ (gfc_simplify_transpose): Likewise.
+ * intrinsic.c (add_functions): Added new simplifier callbacks.
+ * simplify.c (init_result_expr): New.
+ (compute_dot_product): New.
+ (gfc_simplify_dot_product): New.
+ (gfc_simplify_matmul): New.
+ (gfc_simplify_transpose): New.
+ * expr.c (check_transformational): Allow transformational intrinsics
+ with simplifier in initialization expression.
+
+2009-06-06 Daniel Franke <franke.daniel@gmail.com>
+
+ PR fortran/37203
+ * simplify.c (gfc_simplify_reshape): Fixed reshaping of empty arrays
+ without padding.
+
+2009-06-06 Daniel Franke <franke.daniel@gmail.com>
+
+ PR fortran/32890
+ * intrinsic.h (gfc_simplify_pack): New prototype.
+ * intrinsic.c (add_functions): Added
+ simplifier-callback to PACK.
+ * simplify.c (is_constant_array_expr): Moved
+ to beginning of file.
+ (gfc_simplify_pack): New.
+ * check.c (gfc_check_pack): Check that VECTOR has enough elements.
+ Added safeguards for empty arrays.
+
+2009-06-05 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * simplify.c (call_mpc_func): Use mpc_realref/mpc_imagref
+ instead of MPC_RE/MPC_IM.
+
+2009-06-05 Alexandre Oliva <aoliva@redhat.com>
+
+ * trans-decl.c (gfc_build_qualified_array): Don't skip generation
+ of range types.
+ * trans.h (struct lang_type): Add base_decls.
+ (GFC_TYPE_ARRAY_BASE_DECL): New.
+ * trans-types.c (gfc_get_array_type_bounds): Initialize base decls
+ proactively and excessively.
+ (gfc_get_array_descr_info): Use existing base decls if available.
+
+2009-06-04 Daniel Franke <franke.daniel@gmail.com>
+
+ PR fortran/37203
+ * check.c (gfc_check_reshape): Additional checks for the
+ SHAPE and ORDER arguments.
+ * simplify.c (gfc_simplify_reshape): Converted argument checks
+ to asserts.
+
+2009-06-03 Tobias Burnus <burnus@net-b.de>
+
+ * gfortran.texi: Add mixed-language programming, mention
+ varying string lengths, some clean up of introduction parts.
+ * intrinsic.texi (instrinsic modules): Create @menu for subsections.
+ (ISO_C_BINDING): Support ISOCBINDING_INT_FAST128_T.
+ * libgfortran.h: Comment to rember to keep gfortran.texi in sync.
+ * iso-c-binding.def: Support ISOCBINDING_INT_FAST128_T.
+
+2009-06-03 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+ Tobias Burnus <burnus@net-b.de>
+
+ * iso-c-binding.def: Use INTMAX_TYPE instead of intmax_type_node.
+ * trans-types.c (init_c_interop_kinds): Remove intmax_type_node.
+
+2009-06-03 Alexandre Oliva <aoliva@redhat.com>
+
+ * module.c (mio_f2k_derived): Initialize cur.
+
+2009-06-01 Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/40309
+ * trans-decl.c (gfc_sym_identifier): Use "MAIN__" for PROGRAM "main".
+ (create_main_function): Set main_identifier_node.
+
+2009-05-29 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+
+ PR fortran/40019
+ * trans-types.c (gfc_build_uint_type): Make nonstatic.
+ * trans.h (gfor_fndecl_clz128, gfor_fndecl_ctz128): New prototypes.
+ * trans-types.h (gfc_build_uint_type): Add prototype.
+ * trans-decl.c (gfc_build_intrinsic_function_decls): Build
+ gfor_fndecl_clz128 and gfor_fndecl_ctz128.
+ * trans-intrinsic.c (gfc_conv_intrinsic_leadz,
+ gfc_conv_intrinsic_trailz): Call the right builtins or library
+ functions, and cast arguments to unsigned types first.
+ * simplify.c (gfc_simplify_leadz): Deal with negative arguments.
+
+2009-05-27 Ian Lance Taylor <iant@google.com>
+
+ * Make-lang.in (gfortran$(exeext)): Change $(COMPILER) to
+ $(LINKER).
+ (f951$(exeext)): Likewise.
+
+2009-05-27 Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/40270
+ * trans-decl.c (create_main_function): Mark MAIN__ and
+ argc/argv as TREE_USED and push/pop function_decl context
+ if needed.
+
+2009-05-26 Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/39178
+ * gfortranspec.c (lang_specific_driver): Stop linking
+ libgfortranbegin.
+ * trans-decl.c (gfc_build_builtin_function_decls): Stop
+ making MAIN__ publicly visible.
+ (gfc_build_builtin_function_decls): Add
+ gfor_fndecl_set_args.
+ (create_main_function) New function.
+ (gfc_generate_function_code): Use it.
+
+2009-05-26 Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/40246
+ * match.c (gfc_match_nullify): NULLify freed pointer.
+
+2009-05-26 Ian Lance Taylor <iant@google.com>
+
+ * Make-lang.in (gfortranspec.o): Use $(COMPILER).
+ (gfortran$(exeext), f951$(exeext), fortran/cpp.o): Likewise.
+
+2009-05-26 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * gfortran.h (GFC_MPC_RND_MODE): New.
+ * simplify.c (call_mpc_func): New helper function.
+ (gfc_simplify_cos, gfc_simplify_exp, gfc_simplify_log,
+ gfc_simplify_sin, gfc_simplify_sqrt): Add MPC support.
+
+2009-05-25 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/40176
+ * primary.c (gfc_match_varspec): Handle procedure pointer components
+ with array return value.
+ * resolve.c (resolve_expr_ppc): Ditto.
+ (resolve_symbol): Make sure the interface of a procedure pointer has
+ been resolved.
+ * trans-array.c (gfc_walk_function_expr): Handle procedure pointer
+ components with array return value.
+ * trans-expr.c (gfc_conv_component_ref,gfc_conv_procedure_call,
+ gfc_trans_arrayfunc_assign): Ditto.
+ (gfc_trans_pointer_assignment): Handle procedure pointer assignments,
+ where the rhs is a dummy argument.
+ * trans-types.c (gfc_get_ppc_type,gfc_get_derived_type): Handle
+ procedure pointer components with array return value.
+
+2009-05-24 Jerry DeLisle <jvdelisle@gcc.gnu.org>
+ Dominique Dhumieres
+
+ PR fortran/35732
+ PR fortran/39872
+ * trans-array.c (gfc_conv_ss_startstride): Add one to index.
+
+2009-05-22 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+
+ PR fortran/40195
+ * module.c (read_md5_from_module_file): Close file before returning.
+
+2009-05-18 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/40164
+ * primary.c (gfc_match_rvalue): Handle procedure pointer components in
+ arrays.
+ * resolve.c (resolve_ppc_call,resolve_expr_ppc): Resolve component and
+ array references.
+ (resolve_fl_derived): Procedure pointer components are not required to
+ have constant array bounds in their return value.
+
+2009-05-18 Janus Weil <janus@gcc.gnu.org>
+
+ * intrinsic.c (add_sym): Fix my last commit (r147655),
+ which broke bootstrap.
+
+2009-05-18 Richard Guenther <rguenther@suse.de>
+
+ PR fortran/40168
+ * trans-expr.c (gfc_trans_zero_assign): For local array
+ destinations use an assignment from an empty constructor.
+
+2009-05-18 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/36947
+ PR fortran/40039
+ * expr.c (gfc_check_pointer_assign): Check intents when comparing
+ interfaces.
+ * gfortran.h (typedef struct gfc_intrinsic_arg): Add 'intent' member.
+ (gfc_compare_interfaces): Additional argument.
+ * interface.c (operator_correspondence): Add check for equality of
+ intents, and new argument 'intent_check'.
+ (gfc_compare_interfaces): New argument 'intent_check', which is passed
+ on to operator_correspondence.
+ (check_interface1): Don't check intents when comparing interfaces.
+ (compare_parameter): Do check intents when comparing interfaces.
+ * intrinsic.c (add_sym): Add intents for arguments of intrinsic
+ procedures.
+ (add_sym_1,add_sym_1s,add_sym_1m,add_sym_2,add_sym_2s,add_sym_3,
+ add_sym_3ml,add_sym_3red,add_sym_3s,add_sym_4): Use INTENT_IN by
+ default.
+ (add_sym_1_intent,add_sym_1s_intent,add_sym_2s_intent,add_sym_3s_intent)
+ : New functions to add intrinsic symbols, specifying custom intents.
+ (add_sym_4s,add_sym_5s): Add new arguments to specify intents.
+ (add_functions,add_subroutines): Add intents for various intrinsics.
+ * resolve.c (check_generic_tbp_ambiguity): Don't check intents when
+ comparing interfaces.
+ * symbol.c (gfc_copy_formal_args_intr): Copy intent.
+
+2009-05-17 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+
+ * iso-fortran-env.def: Define INT8, INT16, INT32, INT64, REAL32,
+ REAL64 and REAL128.
+ * gfortran.h (gfc_get_int_kind_from_width_isofortranenv,
+ gfc_get_real_kind_from_width_isofortranenv): New prototypes.
+ * iso-c-binding.def: Update definitions for the INT*_T,
+ INT_LEAST*_T and INT_FAST*_T named parameters.
+ * trans-types.c (get_typenode_from_name, get_int_kind_from_name,
+ gfc_get_real_kind_from_width_isofortranenv): New functions.
+
+2009-05-17 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+
+ PR fortran/36260
+ * intrinsic.c (add_functions, add_subroutines): Fix argument
+ names and wrap long lines.
+ * intrinsic.texi: Fix documentation and argument names of
+ LOG_GAMMA, DATAN2, DBESJN, DTIME, ETIME, FSTAT, STAT, LSTAT,
+ GET_COMMAND, IDATE, LTIME, MOVE_ALLOC, NINT, OR, PRODUCT,
+ SUM, RAND, RANDOM_SEED, REAL, SELECTED_INT_KIND,
+ SELECTED_REAL_KIND and XOR.
+
+2009-05-16 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+
+ PR fortran/33197
+ * intrinsic.c (add_functions): Use ERFC_SCALED simplification.
+ * intrinsic.h (gfc_simplify_erfc_scaled): New prototype.
+ * simplify.c (fullprec_erfc_scaled, asympt_erfc_scaled,
+ gfc_simplify_erfc_scaled): New functions.
+
+2009-05-16 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+
+ PR fortran/31243
+ * resolve.c (resolve_substring): Don't allow too large substring
+ indexes.
+ (gfc_resolve_substring_charlen): Fix typo.
+ (gfc_resolve_character_operator): Fix typo.
+ (resolve_charlen): Catch unreasonably large string lengths.
+ * simplify.c (gfc_simplify_len): Don't error out on LEN
+ range checks.
+
+2009-05-16 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+
+ PR fortran/36031
+ * decl.c (set_enum_kind): Use global short-enums flag.
+ * gfortran.h (gfc_option_t): Remove short_enums flag.
+ * lang.opt (-fshort-enums): Refer to C documentation.
+ * options.c (gfc_init_options, gfc_handle_option): Use global
+ short-enums flag.
+
+2009-05-15 Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/39352
+ * f95-lang.c: Add gfc_maybe_initialize_eh.
+ * gfortran.h: Add gfc_maybe_initialize_eh prototype.
+ * Make-lang.in: Add new .h dendencies for f95-lang.c
+ * openmp.c (resolve_omp_do): Call gfc_maybe_initialize_eh.
+ * misc.c (gfc_free): Avoid #define trickery for free.
+
+2009-05-14 Steven G. Kargl <kargl@gcc.gnu.org>
+
+ * dump-parse-tree.c (show_code_node): Add ERRMSG to the dumping
+ of allocate and deallocate statements.
+
+2009-05-14 Ian Lance Taylor <iant@google.com>
+
+ * decl.c (match_attr_spec): Change d to unsigned int.
+ * dump-parse-tree.c (show_namespace): Change op to int. Add cast.
+ * interface.c (gfc_check_interfaces): Change i to int. Add casts.
+ * module.c (read_module): Change i to int. Add cast.
+ (write_module): Change i to int.
+ * symbol.c (gfc_get_namespace): Change in to int.
+ (gfc_free_namespace): Change i to int.
+ * trans-io.c (gfc_build_io_library_fndecls): Change ptype to
+ unsigned int. Add cast.
+ * trans-types.c (gfc_init_kinds): Change mode to unsigned int.
+ Add casts.
+
+2009-05-14 Daniel Kraft <d@domob.eu>
+
+ PR fortran/40045
+ * dump-parse-tree.c (show_typebound): Fix missing adaption to new
+ type-bound procedure storage structure.
+
+2009-05-14 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/39996
+ * decl.c (gfc_match_function_decl): Use gfc_add_type.
+ * symbol.c (gfc_add_type): Better checking for duplicate types in
+ function declarations. And: Always give an error for duplicte types,
+ not just a warning with -std=gnu.
+
+2009-05-14 Jakub Jelinek <jakub@redhat.com>
+
+ PR fortran/39865
+ * io.c (resolve_tag_format): CHARACTER array in FMT= argument
+ isn't an extension. Reject non-CHARACTER array element of
+ assumed shape or pointer or assumed size array.
+ * trans-array.c (array_parameter_size): New function.
+ (gfc_conv_array_parameter): Add size argument. Call
+ array_parameter_size if it is non-NULL.
+ * trans-array.h (gfc_conv_array_parameter): Adjust prototype.
+ * trans-expr.c (gfc_conv_function_call, gfc_trans_arrayfunc_assign):
+ Adjust callers.
+ * trans-intrinsic.c (gfc_conv_intrinsic_loc): Likewise.
+ * trans-io.c (gfc_convert_array_to_string): Rewritten.
+
+2009-05-13 Steven G. Kargl <kargl@gcc.gnu.org>
+
+ * gfortran.h (gfc_code): Rename struct member expr to expr1.
+ * openmp.c (resolve_omp_atomic): Update expr to expr1.
+ * interface.c (gfc_extend_assign): Ditto.
+ * trans-expr.c (gfc_conv_expr_reference, gfc_trans_assignment,
+ gfc_trans_init_assign): Ditto.
+ * dump-parse-tree.c (show_code_node): Ditto.
+ * trans-openmp.c (gfc_trans_omp_atomic): Ditto.
+ * trans-stmt.c ( gfc_trans_label_assign, gfc_trans_goto, gfc_trans_call,
+ gfc_trans_return, gfc_trans_pause, gfc_trans_stop, gfc_trans_if_1,
+ gfc_trans_arithmetic_if, gfc_trans_do_while, gfc_trans_integer_select,
+ gfc_trans_logical_select, gfc_trans_character_select
+ forall_make_variable_temp, check_forall_dependencies
+ gfc_trans_forall_1, gfc_trans_where_2, gfc_trans_where_3
+ gfc_trans_where, gfc_trans_allocate, gfc_trans_deallocate): Ditto.
+ * io.c (match_io_element, gfc_match_inquire): Ditto.
+ * resolve.c (resolve_typebound_call, resolve_ppc_call,
+ resolve_allocate_expr, resolve_allocate_deallocate, resolve_select,
+ resolve_transfer, resolve_where, gfc_resolve_assign_in_forall,
+ gfc_resolve_blocks, resolve_code, build_init_assign): Ditto.
+ * st.c (gfc_free_statement): Ditto.
+ * match.c (gfc_match_assignment, gfc_match_pointer_assignment,
+ match_arithmetic_if, gfc_match_if, gfc_match_elseif
+ gfc_match_stopcode, gfc_match_assign, gfc_match_goto,
+ gfc_match_nullify, match_typebound_call, gfc_match_call
+ gfc_match_select, match_simple_where, gfc_match_where
+ gfc_match_elsewhere, match_simple_forall, gfc_match_forall): Ditto.
+ * trans-io.c (gfc_trans_transfer): Ditto.
+ * parse.c (parse_where_block, parse_if_block): Ditto.
+
+2009-05-13 Steven G. Kargl <kargl@gcc.gnu.org>
+
+ * gfortran.h (gfc_code): Rename struct member label to label1.
+ * dump-parse-tree.c (show_code_node): Update symbol.
+ * trans-stmt.c (gfc_trans_label_assign, gfc_trans_goto,
+ gfc_trans_arithmetic_if): Ditto.
+ * resolve.c (gfc_resolve_blocks, resolve_code): Ditto.
+ * match.c (match_arithmetic_if, gfc_match_if, gfc_reference_st_label,
+ gfc_match_assign, gfc_match_goto): Ditto.
+ * parse.c (parse_do_block): Ditto.
+
+2009-05-13 Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/34153
+ * gfortran.h (gfc_exec_op): Add EXEC_END_PROCEDURE.
+ * dump-parse-tree.c (show_code_node): Use EXEC_END_PROCEDURE.
+ * trans.c (gfc_trans_code): Ditto.
+ * resolve.c (resolve_code): Ditto.
+ * st.c (gfc_free_statement): Ditto.
+ * parse.c (accept_statement): Ditto.
+
+2009-05-12 Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/40110
+ * decl.c (gfc_match_kind_spec): Turn C kind error into a warning.
+
2009-05-11 Steve Ellcey <sje@cup.hp.com>
* resolve.c (check_host_association): Initialize tail.
@@ -235,13 +833,13 @@
2009-04-24 Daniel Kraft <d@domob.eu>
* gfortran.h (gfc_get_typebound_proc): Removed as macro, now a function.
- (struct gfc_symtree): Moved `typebound' member inside union.
- (struct gfc_namespace): Add `tb_sym_root' as new symtree to sort out
+ (struct gfc_symtree): Moved "typebound" member inside union.
+ (struct gfc_namespace): Add "tb_sym_root" as new symtree to sort out
type-bound procedures there.
(gfc_get_tbp_symtree): New procedure.
* symbol.c (tentative_tbp_list): New global.
- (gfc_get_namespace): NULL new `tb_sym_root' member.
- (gfc_new_symtree): Removed initialization of `typebound' member.
+ (gfc_get_namespace): NULL new "tb_sym_root" member.
+ (gfc_new_symtree): Removed initialization of "typebound" member.
(gfc_undo_symbols): Process list of tentative tbp's.
(gfc_commit_symbols): Ditto.
(free_tb_tree): New method.
@@ -254,8 +852,8 @@
* primary.c (gfc_match_varspec): Ditto. Don't reference tbp-symbol
as it isn't a symbol any longer.
* module.c (mio_typebound_symtree): Adapt to changes.
- (mio_typebound_proc): Ditto, create symtrees using `gfc_get_tbp_symtree'
- rather than `gfc_get_sym_tree'.
+ (mio_typebound_proc): Ditto, create symtrees using "gfc_get_tbp_symtree"
+ rather than "gfc_get_sym_tree".
(mio_f2k_derived): Ditto.
* decl.c (match_procedure_in_type): Ditto.
(gfc_match_generic): Ditto. Don't reference tbp-symbol.
@@ -364,7 +962,7 @@
2009-04-11 Daniel Kraft <d@domob.eu>
PR fortran/37746
- * gfortran.h (struct gfc_charlen): New field `passed_length' to store
+ * gfortran.h (struct gfc_charlen): New field "passed_length" to store
the actual passed string length for dummy arguments.
* trans-decl.c (gfc_create_string_length): Formatting fixes and added
assertion, moved a local variable into the innermost block it is needed.
@@ -472,15 +1070,15 @@
2009-04-06 Janus Weil <janus@gcc.gnu.org>
- PR fortran/39414
- * decl.c (match_procedure_decl): Fix double declaration problems with
- PROCEDURE statements.
- * symbol.c (gfc_add_type): Ditto.
+ PR fortran/39414
+ * decl.c (match_procedure_decl): Fix double declaration problems with
+ PROCEDURE statements.
+ * symbol.c (gfc_add_type): Ditto.
2009-04-06 Paul Thomas <pault@gcc.gnu.org>
- PR fortran/36091
- * trans-array.c (gfc_conv_array_ref): If the symbol has the
+ PR fortran/36091
+ * trans-array.c (gfc_conv_array_ref): If the symbol has the
temporary attribute use the array_spec for the bounds.
* gfortran.h : Add the temporary field to the structure
'symbol_attribute'.
@@ -609,7 +1207,7 @@
2009-03-29 Daniel Kraft <d@domob.eu>
PR fortran/37423
- * gfortran.h (struct gfc_typebound_proc): Added new flag `deferred' and
+ * gfortran.h (struct gfc_typebound_proc): Added new flag "deferred" and
added a comment explaining DEFERRED binding handling.
* decl.c (match_binding_attributes): Really match DEFERRED attribute.
(match_procedure_in_type): Really match PROCEDURE(interface) syntax
@@ -621,7 +1219,7 @@
(resolve_typebound_procedure): Allow abstract interfaces as targets
for DEFERRED bindings.
(ensure_not_abstract_walker), (ensure_not_abstract): New methods.
- (resolve_fl_derived): Use new `ensure_not_abstract' method for
+ (resolve_fl_derived): Use new "ensure_not_abstract" method for
non-ABSTRACT types extending ABSTRACT ones to ensure each DEFERRED
binding is overridden.
(check_typebound_baseobject): New method.
@@ -630,7 +1228,7 @@
* gfc-internals.texi (Type-bound procedures): Document a little bit
about internal handling of DEFERRED bindings.
-2009-03-29 Tobias Schlüter <tobi@gcc.gnu.org>
+2009-03-29 Tobias Schlueter <tobi@gcc.gnu.org>
PR fortran/38507
* gfortran.h (gfc_st_label): Fix comment.
diff --git a/gcc/fortran/Make-lang.in b/gcc/fortran/Make-lang.in
index ba81b93b688..0ac9bb2262b 100644
--- a/gcc/fortran/Make-lang.in
+++ b/gcc/fortran/Make-lang.in
@@ -1,6 +1,6 @@
# -*- makefile -*-
# Top level makefile fragment for GNU gfortran, the GNU Fortran 95 compiler.
-# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software
+# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software
# Foundation, Inc.
# Contributed by Paul Brook <paul@nowt.org
# and Steven Bosscher <s.bosscher@student.tudelft.nl>
@@ -80,13 +80,13 @@ fortran: f951$(exeext)
gfortranspec.o: $(srcdir)/fortran/gfortranspec.c $(SYSTEM_H) $(TM_H) $(GCC_H) \
$(CONFIG_H) coretypes.h intl.h
(SHLIB_LINK='$(SHLIB_LINK)'; \
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(DRIVER_DEFINES) \
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(DRIVER_DEFINES) \
$(INCLUDES) $(srcdir)/fortran/gfortranspec.c)
# Create the compiler driver gfortran.
GFORTRAN_D_OBJS = $(GCC_OBJS) gfortranspec.o version.o prefix.o intl.o
gfortran$(exeext): $(GFORTRAN_D_OBJS) $(EXTRA_GCC_OBJS) $(LIBDEPS)
- $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ \
+ $(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
$(GFORTRAN_D_OBJS) $(EXTRA_GCC_OBJS) $(LIBS)
# Create a version of the gfortran driver which calls the cross-compiler.
@@ -97,7 +97,7 @@ gfortran-cross$(exeext): gfortran$(exeext)
# The compiler itself is called f951.
f951$(exeext): $(F95_OBJS) \
$(BACKEND) $(LIBDEPS) attribs.o
- $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ \
+ $(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
$(F95_OBJS) $(BACKEND) $(LIBS) attribs.o $(BACKENDLIBS)
gt-fortran-trans.h : s-gtype; @true
@@ -313,7 +313,8 @@ GFORTRAN_TRANS_DEPS = fortran/gfortran.h fortran/libgfortran.h \
fortran/f95-lang.o: $(GFORTRAN_TRANS_DEPS) fortran/mathbuiltins.def \
gt-fortran-f95-lang.h gtype-fortran.h $(CGRAPH_H) $(TARGET_H) fortran/cpp.h \
- $(BUILTINS_DEF) fortran/types.def
+ $(BUILTINS_DEF) fortran/types.def \
+ libfuncs.h expr.h except.h
fortran/scanner.o: toplev.h fortran/cpp.h
fortran/convert.o: $(GFORTRAN_TRANS_DEPS)
fortran/trans.o: $(GFORTRAN_TRANS_DEPS) tree-iterator.h
@@ -337,5 +338,5 @@ fortran/resolve.o: fortran/dependency.h fortran/data.h fortran/target-memory.h
fortran/data.o: fortran/data.h
fortran/options.o: $(PARAMS_H) $(TARGET_H) fortran/cpp.h
fortran/cpp.o: fortran/cpp.c $(BASEVER) incpath.h incpath.o
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) -DBASEVER=$(BASEVER_s) \
- $< $(OUTPUT_OPTION)
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) \
+ -DBASEVER=$(BASEVER_s) $< $(OUTPUT_OPTION)
diff --git a/gcc/fortran/arith.c b/gcc/fortran/arith.c
index 17f2221ef8c..9aaf1bc03a9 100644
--- a/gcc/fortran/arith.c
+++ b/gcc/fortran/arith.c
@@ -1561,7 +1561,7 @@ reduce_binary_aa (arith (*eval) (gfc_expr *, gfc_expr *, gfc_expr **),
rc = ARITH_OK;
d = op2->value.constructor;
- if (gfc_check_conformance ("elemental binary operation", op1, op2)
+ if (gfc_check_conformance (op1, op2, "elemental binary operation")
!= SUCCESS)
rc = ARITH_INCOMMENSURATE;
else
@@ -2627,48 +2627,3 @@ gfc_hollerith2logical (gfc_expr *src, int kind)
return result;
}
-
-
-/* Returns an initializer whose value is one higher than the value of the
- LAST_INITIALIZER argument. If the argument is NULL, the
- initializers value will be set to zero. The initializer's kind
- will be set to gfc_c_int_kind.
-
- If -fshort-enums is given, the appropriate kind will be selected
- later after all enumerators have been parsed. A warning is issued
- here if an initializer exceeds gfc_c_int_kind. */
-
-gfc_expr *
-gfc_enum_initializer (gfc_expr *last_initializer, locus where)
-{
- gfc_expr *result;
-
- result = gfc_get_expr ();
- result->expr_type = EXPR_CONSTANT;
- result->ts.type = BT_INTEGER;
- result->ts.kind = gfc_c_int_kind;
- result->where = where;
-
- mpz_init (result->value.integer);
-
- if (last_initializer != NULL)
- {
- mpz_add_ui (result->value.integer, last_initializer->value.integer, 1);
- result->where = last_initializer->where;
-
- if (gfc_check_integer_range (result->value.integer,
- gfc_c_int_kind) != ARITH_OK)
- {
- gfc_error ("Enumerator exceeds the C integer type at %C");
- return NULL;
- }
- }
- else
- {
- /* Control comes here, if it's the very first enumerator and no
- initializer has been given. It will be initialized to zero. */
- mpz_set_si (result->value.integer, 0);
- }
-
- return result;
-}
diff --git a/gcc/fortran/array.c b/gcc/fortran/array.c
index 46c7425b9c1..4d3345f3fd4 100644
--- a/gcc/fortran/array.c
+++ b/gcc/fortran/array.c
@@ -607,7 +607,8 @@ gfc_append_constructor (gfc_expr *base, gfc_expr *new_expr)
c->expr = new_expr;
- if (new_expr->ts.type != base->ts.type || new_expr->ts.kind != base->ts.kind)
+ if (new_expr
+ && (new_expr->ts.type != base->ts.type || new_expr->ts.kind != base->ts.kind))
gfc_internal_error ("gfc_append_constructor(): New node has wrong kind");
}
diff --git a/gcc/fortran/check.c b/gcc/fortran/check.c
index db29264e9a6..103c9417790 100644
--- a/gcc/fortran/check.c
+++ b/gcc/fortran/check.c
@@ -339,6 +339,9 @@ dim_rank_check (gfc_expr *dim, gfc_expr *array, int allow_assumed)
gfc_array_ref *ar;
int rank;
+ if (dim == NULL)
+ return SUCCESS;
+
if (dim->expr_type != EXPR_CONSTANT
|| (array->expr_type != EXPR_VARIABLE
&& array->expr_type != EXPR_ARRAY))
@@ -519,6 +522,9 @@ gfc_check_all_any (gfc_expr *mask, gfc_expr *dim)
if (dim_check (dim, 1, false) == FAILURE)
return FAILURE;
+ if (dim_rank_check (dim, mask, 0) == FAILURE)
+ return FAILURE;
+
return SUCCESS;
}
@@ -856,6 +862,8 @@ gfc_check_count (gfc_expr *mask, gfc_expr *dim, gfc_expr *kind)
return FAILURE;
if (dim_check (dim, 1, false) == FAILURE)
return FAILURE;
+ if (dim_rank_check (dim, mask, 0) == FAILURE)
+ return FAILURE;
if (kind_check (kind, 2, BT_INTEGER) == FAILURE)
return FAILURE;
if (kind && gfc_notify_std (GFC_STD_F2003, "Fortran 2003: '%s' intrinsic "
@@ -876,24 +884,56 @@ gfc_check_cshift (gfc_expr *array, gfc_expr *shift, gfc_expr *dim)
if (type_check (shift, 1, BT_INTEGER) == FAILURE)
return FAILURE;
- if (array->rank == 1)
+ if (dim_check (dim, 2, true) == FAILURE)
+ return FAILURE;
+
+ if (dim_rank_check (dim, array, false) == FAILURE)
+ return FAILURE;
+
+ if (array->rank == 1 || shift->rank == 0)
{
if (scalar_check (shift, 1) == FAILURE)
return FAILURE;
}
- else if (shift->rank != array->rank - 1 && shift->rank != 0)
+ else if (shift->rank == array->rank - 1)
{
- gfc_error ("SHIFT argument at %L of CSHIFT must have rank %d or be a "
- "scalar", &shift->where, array->rank - 1);
+ int d;
+ if (!dim)
+ d = 1;
+ else if (dim->expr_type == EXPR_CONSTANT)
+ gfc_extract_int (dim, &d);
+ else
+ d = -1;
+
+ if (d > 0)
+ {
+ int i, j;
+ for (i = 0, j = 0; i < array->rank; i++)
+ if (i != d - 1)
+ {
+ if (!identical_dimen_shape (array, i, shift, j))
+ {
+ gfc_error ("'%s' argument of '%s' intrinsic at %L has "
+ "invalid shape in dimension %d (%ld/%ld)",
+ gfc_current_intrinsic_arg[1],
+ gfc_current_intrinsic, &shift->where, i + 1,
+ mpz_get_si (array->shape[i]),
+ mpz_get_si (shift->shape[j]));
+ return FAILURE;
+ }
+
+ j += 1;
+ }
+ }
+ }
+ else
+ {
+ gfc_error ("'%s' argument of intrinsic '%s' at %L of must have rank "
+ "%d or be a scalar", gfc_current_intrinsic_arg[1],
+ gfc_current_intrinsic, &shift->where, array->rank - 1);
return FAILURE;
}
- /* TODO: Add shape conformance check between array (w/o dimension dim)
- and shift. */
-
- if (dim_check (dim, 2, true) == FAILURE)
- return FAILURE;
-
return SUCCESS;
}
@@ -1042,55 +1082,85 @@ gfc_check_eoshift (gfc_expr *array, gfc_expr *shift, gfc_expr *boundary,
if (type_check (shift, 1, BT_INTEGER) == FAILURE)
return FAILURE;
- if (array->rank == 1)
+ if (dim_check (dim, 3, true) == FAILURE)
+ return FAILURE;
+
+ if (dim_rank_check (dim, array, false) == FAILURE)
+ return FAILURE;
+
+ if (array->rank == 1 || shift->rank == 0)
{
- if (scalar_check (shift, 2) == FAILURE)
+ if (scalar_check (shift, 1) == FAILURE)
return FAILURE;
}
- else if (shift->rank != array->rank - 1 && shift->rank != 0)
+ else if (shift->rank == array->rank - 1)
{
- gfc_error ("SHIFT argument at %L of EOSHIFT must have rank %d or be a "
- "scalar", &shift->where, array->rank - 1);
+ int d;
+ if (!dim)
+ d = 1;
+ else if (dim->expr_type == EXPR_CONSTANT)
+ gfc_extract_int (dim, &d);
+ else
+ d = -1;
+
+ if (d > 0)
+ {
+ int i, j;
+ for (i = 0, j = 0; i < array->rank; i++)
+ if (i != d - 1)
+ {
+ if (!identical_dimen_shape (array, i, shift, j))
+ {
+ gfc_error ("'%s' argument of '%s' intrinsic at %L has "
+ "invalid shape in dimension %d (%ld/%ld)",
+ gfc_current_intrinsic_arg[1],
+ gfc_current_intrinsic, &shift->where, i + 1,
+ mpz_get_si (array->shape[i]),
+ mpz_get_si (shift->shape[j]));
+ return FAILURE;
+ }
+
+ j += 1;
+ }
+ }
+ }
+ else
+ {
+ gfc_error ("'%s' argument of intrinsic '%s' at %L of must have rank "
+ "%d or be a scalar", gfc_current_intrinsic_arg[1],
+ gfc_current_intrinsic, &shift->where, array->rank - 1);
return FAILURE;
}
- /* TODO: Add shape conformance check between array (w/o dimension dim)
- and shift. */
-
if (boundary != NULL)
{
if (same_type_check (array, 0, boundary, 2) == FAILURE)
return FAILURE;
- if (array->rank == 1)
+ if (array->rank == 1 || boundary->rank == 0)
{
if (scalar_check (boundary, 2) == FAILURE)
return FAILURE;
}
- else if (boundary->rank != array->rank - 1 && boundary->rank != 0)
+ else if (boundary->rank == array->rank - 1)
{
- gfc_error ("BOUNDARY argument at %L of EOSHIFT must have rank %d or be "
- "a scalar", &boundary->where, array->rank - 1);
- return FAILURE;
+ if (gfc_check_conformance (shift, boundary,
+ "arguments '%s' and '%s' for "
+ "intrinsic %s",
+ gfc_current_intrinsic_arg[1],
+ gfc_current_intrinsic_arg[2],
+ gfc_current_intrinsic ) == FAILURE)
+ return FAILURE;
}
-
- if (shift->rank == boundary->rank)
+ else
{
- int i;
- for (i = 0; i < shift->rank; i++)
- if (! identical_dimen_shape (shift, i, boundary, i))
- {
- gfc_error ("Different shape in dimension %d for SHIFT and "
- "BOUNDARY arguments of EOSHIFT at %L", shift->rank,
- &boundary->where);
- return FAILURE;
- }
+ gfc_error ("'%s' argument of intrinsic '%s' at %L of must have "
+ "rank %d or be a scalar", gfc_current_intrinsic_arg[1],
+ gfc_current_intrinsic, &shift->where, array->rank - 1);
+ return FAILURE;
}
}
- if (dim_check (dim, 4, true) == FAILURE)
- return FAILURE;
-
return SUCCESS;
}
@@ -1512,14 +1582,11 @@ gfc_check_lbound (gfc_expr *array, gfc_expr *dim, gfc_expr *kind)
if (array_check (array, 0) == FAILURE)
return FAILURE;
- if (dim != NULL)
- {
- if (dim_check (dim, 1, false) == FAILURE)
- return FAILURE;
+ if (dim_check (dim, 1, false) == FAILURE)
+ return FAILURE;
- if (dim_rank_check (dim, array, 1) == FAILURE)
- return FAILURE;
- }
+ if (dim_rank_check (dim, array, 1) == FAILURE)
+ return FAILURE;
if (kind_check (kind, 2, BT_INTEGER) == FAILURE)
return FAILURE;
@@ -1719,13 +1786,11 @@ check_rest (bt type, int kind, gfc_actual_arglist *arglist)
}
for (tmp = arglist, m=1; tmp != arg; tmp = tmp->next, m++)
- {
- char buffer[80];
- snprintf (buffer, 80, "arguments 'a%d' and 'a%d' for intrinsic '%s'",
- m, n, gfc_current_intrinsic);
- if (gfc_check_conformance (buffer, tmp->expr, x) == FAILURE)
+ if (gfc_check_conformance (tmp->expr, x,
+ "arguments 'a%d' and 'a%d' for "
+ "intrinsic '%s'", m, n,
+ gfc_current_intrinsic) == FAILURE)
return FAILURE;
- }
}
return SUCCESS;
@@ -1905,24 +1970,22 @@ gfc_check_minloc_maxloc (gfc_actual_arglist *ap)
ap->next->next->expr = m;
}
- if (d && dim_check (d, 1, false) == FAILURE)
+ if (dim_check (d, 1, false) == FAILURE)
return FAILURE;
- if (d && dim_rank_check (d, a, 0) == FAILURE)
+ if (dim_rank_check (d, a, 0) == FAILURE)
return FAILURE;
if (m != NULL && type_check (m, 2, BT_LOGICAL) == FAILURE)
return FAILURE;
- if (m != NULL)
- {
- char buffer[80];
- snprintf (buffer, 80, "arguments '%s' and '%s' for intrinsic %s",
- gfc_current_intrinsic_arg[0], gfc_current_intrinsic_arg[2],
- gfc_current_intrinsic);
- if (gfc_check_conformance (buffer, a, m) == FAILURE)
- return FAILURE;
- }
+ if (m != NULL
+ && gfc_check_conformance (a, m,
+ "arguments '%s' and '%s' for intrinsic %s",
+ gfc_current_intrinsic_arg[0],
+ gfc_current_intrinsic_arg[2],
+ gfc_current_intrinsic ) == FAILURE)
+ return FAILURE;
return SUCCESS;
}
@@ -1961,24 +2024,22 @@ check_reduction (gfc_actual_arglist *ap)
ap->next->next->expr = m;
}
- if (d && dim_check (d, 1, false) == FAILURE)
+ if (dim_check (d, 1, false) == FAILURE)
return FAILURE;
- if (d && dim_rank_check (d, a, 0) == FAILURE)
+ if (dim_rank_check (d, a, 0) == FAILURE)
return FAILURE;
if (m != NULL && type_check (m, 2, BT_LOGICAL) == FAILURE)
return FAILURE;
- if (m != NULL)
- {
- char buffer[80];
- snprintf (buffer, 80, "arguments '%s' and '%s' for intrinsic %s",
- gfc_current_intrinsic_arg[0], gfc_current_intrinsic_arg[2],
- gfc_current_intrinsic);
- if (gfc_check_conformance (buffer, a, m) == FAILURE)
- return FAILURE;
- }
+ if (m != NULL
+ && gfc_check_conformance (a, m,
+ "arguments '%s' and '%s' for intrinsic %s",
+ gfc_current_intrinsic_arg[0],
+ gfc_current_intrinsic_arg[2],
+ gfc_current_intrinsic) == FAILURE)
+ return FAILURE;
return SUCCESS;
}
@@ -2133,29 +2194,78 @@ gfc_check_null (gfc_expr *mold)
gfc_try
gfc_check_pack (gfc_expr *array, gfc_expr *mask, gfc_expr *vector)
{
- char buffer[80];
-
if (array_check (array, 0) == FAILURE)
return FAILURE;
if (type_check (mask, 1, BT_LOGICAL) == FAILURE)
return FAILURE;
- snprintf (buffer, 80, "arguments '%s' and '%s' for intrinsic '%s'",
- gfc_current_intrinsic_arg[0], gfc_current_intrinsic_arg[1],
- gfc_current_intrinsic);
- if (gfc_check_conformance (buffer, array, mask) == FAILURE)
+ if (gfc_check_conformance (array, mask,
+ "arguments '%s' and '%s' for intrinsic '%s'",
+ gfc_current_intrinsic_arg[0],
+ gfc_current_intrinsic_arg[1],
+ gfc_current_intrinsic) == FAILURE)
return FAILURE;
if (vector != NULL)
{
+ mpz_t array_size, vector_size;
+ bool have_array_size, have_vector_size;
+
if (same_type_check (array, 0, vector, 2) == FAILURE)
return FAILURE;
if (rank_check (vector, 2, 1) == FAILURE)
return FAILURE;
- /* TODO: More constraints here. */
+ /* VECTOR requires at least as many elements as MASK
+ has .TRUE. values. */
+ have_array_size = gfc_array_size (array, &array_size) == SUCCESS;
+ have_vector_size = gfc_array_size (vector, &vector_size) == SUCCESS;
+
+ if (have_vector_size
+ && (mask->expr_type == EXPR_ARRAY
+ || (mask->expr_type == EXPR_CONSTANT
+ && have_array_size)))
+ {
+ int mask_true_values = 0;
+
+ if (mask->expr_type == EXPR_ARRAY)
+ {
+ gfc_constructor *mask_ctor = mask->value.constructor;
+ while (mask_ctor)
+ {
+ if (mask_ctor->expr->expr_type != EXPR_CONSTANT)
+ {
+ mask_true_values = 0;
+ break;
+ }
+
+ if (mask_ctor->expr->value.logical)
+ mask_true_values++;
+
+ mask_ctor = mask_ctor->next;
+ }
+ }
+ else if (mask->expr_type == EXPR_CONSTANT && mask->value.logical)
+ mask_true_values = mpz_get_si (array_size);
+
+ if (mpz_get_si (vector_size) < mask_true_values)
+ {
+ gfc_error ("'%s' argument of '%s' intrinsic at %L must "
+ "provide at least as many elements as there "
+ "are .TRUE. values in '%s' (%ld/%d)",
+ gfc_current_intrinsic_arg[2],gfc_current_intrinsic,
+ &vector->where, gfc_current_intrinsic_arg[1],
+ mpz_get_si (vector_size), mask_true_values);
+ return FAILURE;
+ }
+ }
+
+ if (have_array_size)
+ mpz_clear (array_size);
+ if (have_vector_size)
+ mpz_clear (vector_size);
}
return SUCCESS;
@@ -2324,7 +2434,7 @@ gfc_check_reshape (gfc_expr *source, gfc_expr *shape,
{
mpz_t size;
mpz_t nelems;
- int m;
+ int shape_size;
if (array_check (source, 0) == FAILURE)
return FAILURE;
@@ -2342,26 +2452,121 @@ gfc_check_reshape (gfc_expr *source, gfc_expr *shape,
return FAILURE;
}
- m = mpz_cmp_ui (size, GFC_MAX_DIMENSIONS);
+ shape_size = mpz_get_ui (size);
mpz_clear (size);
- if (m > 0)
+ if (shape_size <= 0)
+ {
+ gfc_error ("'%s' argument of '%s' intrinsic at %L is empty",
+ gfc_current_intrinsic_arg[1], gfc_current_intrinsic,
+ &shape->where);
+ return FAILURE;
+ }
+ else if (shape_size > GFC_MAX_DIMENSIONS)
{
gfc_error ("'shape' argument of 'reshape' intrinsic at %L has more "
"than %d elements", &shape->where, GFC_MAX_DIMENSIONS);
return FAILURE;
}
+ else if (shape->expr_type == EXPR_ARRAY)
+ {
+ gfc_expr *e;
+ int i, extent;
+ for (i = 0; i < shape_size; ++i)
+ {
+ e = gfc_get_array_element (shape, i);
+ if (e->expr_type != EXPR_CONSTANT)
+ {
+ gfc_free_expr (e);
+ continue;
+ }
+
+ gfc_extract_int (e, &extent);
+ if (extent < 0)
+ {
+ gfc_error ("'%s' argument of '%s' intrinsic at %L has "
+ "negative element (%d)", gfc_current_intrinsic_arg[1],
+ gfc_current_intrinsic, &e->where, extent);
+ return FAILURE;
+ }
+
+ gfc_free_expr (e);
+ }
+ }
if (pad != NULL)
{
if (same_type_check (source, 0, pad, 2) == FAILURE)
return FAILURE;
+
if (array_check (pad, 2) == FAILURE)
return FAILURE;
}
- if (order != NULL && array_check (order, 3) == FAILURE)
- return FAILURE;
+ if (order != NULL)
+ {
+ if (array_check (order, 3) == FAILURE)
+ return FAILURE;
+
+ if (type_check (order, 3, BT_INTEGER) == FAILURE)
+ return FAILURE;
+
+ if (order->expr_type == EXPR_ARRAY)
+ {
+ int i, order_size, dim, perm[GFC_MAX_DIMENSIONS];
+ gfc_expr *e;
+
+ for (i = 0; i < GFC_MAX_DIMENSIONS; ++i)
+ perm[i] = 0;
+
+ gfc_array_size (order, &size);
+ order_size = mpz_get_ui (size);
+ mpz_clear (size);
+
+ if (order_size != shape_size)
+ {
+ gfc_error ("'%s' argument of '%s' intrinsic at %L "
+ "has wrong number of elements (%d/%d)",
+ gfc_current_intrinsic_arg[3],
+ gfc_current_intrinsic, &order->where,
+ order_size, shape_size);
+ return FAILURE;
+ }
+
+ for (i = 1; i <= order_size; ++i)
+ {
+ e = gfc_get_array_element (order, i-1);
+ if (e->expr_type != EXPR_CONSTANT)
+ {
+ gfc_free_expr (e);
+ continue;
+ }
+
+ gfc_extract_int (e, &dim);
+
+ if (dim < 1 || dim > order_size)
+ {
+ gfc_error ("'%s' argument of '%s' intrinsic at %L "
+ "has out-of-range dimension (%d)",
+ gfc_current_intrinsic_arg[3],
+ gfc_current_intrinsic, &e->where, dim);
+ return FAILURE;
+ }
+
+ if (perm[dim-1] != 0)
+ {
+ gfc_error ("'%s' argument of '%s' intrinsic at %L has "
+ "invalid permutation of dimensions (dimension "
+ "'%d' duplicated)", gfc_current_intrinsic_arg[3],
+ gfc_current_intrinsic, &e->where, dim);
+ return FAILURE;
+ }
+
+ perm[dim-1] = 1;
+ gfc_free_expr (e);
+ }
+ }
+ }
if (pad == NULL && shape->expr_type == EXPR_ARRAY
&& gfc_is_constant_expr (shape)
@@ -2555,14 +2760,11 @@ gfc_check_size (gfc_expr *array, gfc_expr *dim, gfc_expr *kind)
if (array_check (array, 0) == FAILURE)
return FAILURE;
- if (dim != NULL)
- {
- if (dim_check (dim, 1, true) == FAILURE)
- return FAILURE;
+ if (dim_check (dim, 1, true) == FAILURE)
+ return FAILURE;
- if (dim_rank_check (dim, array, 0) == FAILURE)
- return FAILURE;
- }
+ if (dim_rank_check (dim, array, 0) == FAILURE)
+ return FAILURE;
if (kind_check (kind, 2, BT_INTEGER) == FAILURE)
return FAILURE;
@@ -2614,6 +2816,18 @@ gfc_check_spread (gfc_expr *source, gfc_expr *dim, gfc_expr *ncopies)
if (dim_check (dim, 1, false) == FAILURE)
return FAILURE;
+ /* dim_rank_check() does not apply here. */
+ if (dim
+ && dim->expr_type == EXPR_CONSTANT
+ && (mpz_cmp_ui (dim->value.integer, 1) < 0
+ || mpz_cmp_ui (dim->value.integer, source->rank + 1) > 0))
+ {
+ gfc_error ("'%s' argument of '%s' intrinsic at %L is not a valid "
+ "dimension index", gfc_current_intrinsic_arg[1],
+ gfc_current_intrinsic, &dim->where);
+ return FAILURE;
+ }
+
if (type_check (ncopies, 2, BT_INTEGER) == FAILURE)
return FAILURE;
@@ -2898,14 +3112,11 @@ gfc_check_ubound (gfc_expr *array, gfc_expr *dim, gfc_expr *kind)
if (array_check (array, 0) == FAILURE)
return FAILURE;
- if (dim != NULL)
- {
- if (dim_check (dim, 1, false) == FAILURE)
- return FAILURE;
+ if (dim_check (dim, 1, false) == FAILURE)
+ return FAILURE;
- if (dim_rank_check (dim, array, 0) == FAILURE)
- return FAILURE;
- }
+ if (dim_rank_check (dim, array, 0) == FAILURE)
+ return FAILURE;
if (kind_check (kind, 2, BT_INTEGER) == FAILURE)
return FAILURE;
@@ -2921,6 +3132,8 @@ gfc_check_ubound (gfc_expr *array, gfc_expr *dim, gfc_expr *kind)
gfc_try
gfc_check_unpack (gfc_expr *vector, gfc_expr *mask, gfc_expr *field)
{
+ mpz_t vector_size;
+
if (rank_check (vector, 0, 1) == FAILURE)
return FAILURE;
@@ -2933,10 +3146,45 @@ gfc_check_unpack (gfc_expr *vector, gfc_expr *mask, gfc_expr *field)
if (same_type_check (vector, 0, field, 2) == FAILURE)
return FAILURE;
+ if (mask->expr_type == EXPR_ARRAY
+ && gfc_array_size (vector, &vector_size) == SUCCESS)
+ {
+ int mask_true_count = 0;
+ gfc_constructor *mask_ctor = mask->value.constructor;
+ while (mask_ctor)
+ {
+ if (mask_ctor->expr->expr_type != EXPR_CONSTANT)
+ {
+ mask_true_count = 0;
+ break;
+ }
+
+ if (mask_ctor->expr->value.logical)
+ mask_true_count++;
+
+ mask_ctor = mask_ctor->next;
+ }
+
+ if (mpz_get_si (vector_size) < mask_true_count)
+ {
+ gfc_error ("'%s' argument of '%s' intrinsic at %L must "
+ "provide at least as many elements as there "
+ "are .TRUE. values in '%s' (%ld/%d)",
+ gfc_current_intrinsic_arg[0], gfc_current_intrinsic,
+ &vector->where, gfc_current_intrinsic_arg[1],
+ mpz_get_si (vector_size), mask_true_count);
+ return FAILURE;
+ }
+
+ mpz_clear (vector_size);
+ }
+
if (mask->rank != field->rank && field->rank != 0)
{
- gfc_error ("FIELD argument at %L of UNPACK must have the same rank as "
- "MASK or be a scalar", &field->where);
+ gfc_error ("'%s' argument of '%s' intrinsic at %L must have "
+ "the same rank as '%s' or be a scalar",
+ gfc_current_intrinsic_arg[2], gfc_current_intrinsic,
+ &field->where, gfc_current_intrinsic_arg[1]);
return FAILURE;
}
@@ -2946,9 +3194,11 @@ gfc_check_unpack (gfc_expr *vector, gfc_expr *mask, gfc_expr *field)
for (i = 0; i < field->rank; i++)
if (! identical_dimen_shape (mask, i, field, i))
{
- gfc_error ("Different shape in dimension %d for MASK and FIELD "
- "arguments of UNPACK at %L", mask->rank, &field->where);
- return FAILURE;
+ gfc_error ("'%s' and '%s' arguments of '%s' intrinsic at %L "
+ "must have identical shape.",
+ gfc_current_intrinsic_arg[2],
+ gfc_current_intrinsic_arg[1], gfc_current_intrinsic,
+ &field->where);
}
}
diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c
index f3ff0e68380..1a4ca3616dc 100644
--- a/gcc/fortran/decl.c
+++ b/gcc/fortran/decl.c
@@ -24,6 +24,7 @@ along with GCC; see the file COPYING3. If not see
#include "gfortran.h"
#include "match.h"
#include "parse.h"
+#include "flags.h"
/* Macros to access allocate memory for gfc_data_variable,
@@ -2000,9 +2001,9 @@ kind_expr:
if (ts->f90_type != BT_UNKNOWN && ts->f90_type != ts->type
&& !((ts->f90_type == BT_REAL && ts->type == BT_COMPLEX)
|| (ts->f90_type == BT_COMPLEX && ts->type == BT_REAL)))
- gfc_error_now ("C kind type parameter is for type %s but type at %L "
- "is %s", gfc_basic_typename (ts->f90_type), &where,
- gfc_basic_typename (ts->type));
+ gfc_warning_now ("C kind type parameter is for type %s but type at %L "
+ "is %s", gfc_basic_typename (ts->f90_type), &where,
+ gfc_basic_typename (ts->type));
gfc_gobble_whitespace ();
if ((c = gfc_next_ascii_char ()) != ')'
@@ -2815,7 +2816,7 @@ match_attr_spec (void)
locus start, seen_at[NUM_DECL];
int seen[NUM_DECL];
- decl_types d;
+ unsigned int d;
const char *attr;
match m;
gfc_try t;
@@ -4708,14 +4709,6 @@ gfc_match_function_decl (void)
|| copy_prefix (&sym->attr, &sym->declared_at) == FAILURE)
goto cleanup;
- if (current_ts.type != BT_UNKNOWN && sym->ts.type != BT_UNKNOWN
- && !sym->attr.implicit_type)
- {
- gfc_error ("Function '%s' at %C already has a type of %s", name,
- gfc_basic_typename (sym->ts.type));
- goto cleanup;
- }
-
/* Delay matching the function characteristics until after the
specification block by signalling kind=-1. */
sym->declared_at = old_loc;
@@ -4726,12 +4719,17 @@ gfc_match_function_decl (void)
if (result == NULL)
{
- sym->ts = current_ts;
+ if (current_ts.type != BT_UNKNOWN
+ && gfc_add_type (sym, &current_ts, &gfc_current_locus) == FAILURE)
+ goto cleanup;
sym->result = sym;
}
else
{
- result->ts = current_ts;
+ if (current_ts.type != BT_UNKNOWN
+ && gfc_add_type (result, &current_ts, &gfc_current_locus)
+ == FAILURE)
+ goto cleanup;
sym->result = result;
}
@@ -5298,7 +5296,7 @@ set_enum_kind(void)
if (max_enum == NULL || enum_history == NULL)
return;
- if (!gfc_option.fshort_enums)
+ if (!flag_short_enums)
return;
i = 0;
@@ -6814,6 +6812,51 @@ gfc_match_enum (void)
}
+/* Returns an initializer whose value is one higher than the value of the
+ LAST_INITIALIZER argument. If the argument is NULL, the
+ initializers value will be set to zero. The initializer's kind
+ will be set to gfc_c_int_kind.
+
+ If -fshort-enums is given, the appropriate kind will be selected
+ later after all enumerators have been parsed. A warning is issued
+ here if an initializer exceeds gfc_c_int_kind. */
+
+static gfc_expr *
+enum_initializer (gfc_expr *last_initializer, locus where)
+{
+ gfc_expr *result;
+
+ result = gfc_get_expr ();
+ result->expr_type = EXPR_CONSTANT;
+ result->ts.type = BT_INTEGER;
+ result->ts.kind = gfc_c_int_kind;
+ result->where = where;
+
+ mpz_init (result->value.integer);
+
+ if (last_initializer != NULL)
+ {
+ mpz_add_ui (result->value.integer, last_initializer->value.integer, 1);
+ result->where = last_initializer->where;
+
+ if (gfc_check_integer_range (result->value.integer,
+ gfc_c_int_kind) != ARITH_OK)
+ {
+ gfc_error ("Enumerator exceeds the C integer type at %C");
+ return NULL;
+ }
+ }
+ else
+ {
+ /* Control comes here, if it's the very first enumerator and no
+ initializer has been given. It will be initialized to zero. */
+ mpz_set_si (result->value.integer, 0);
+ }
+
+ return result;
+}
+
+
/* Match a variable name with an optional initializer. When this
subroutine is called, a variable is expected to be parsed next.
Depending on what is happening at the moment, updates either the
@@ -6874,7 +6917,7 @@ enumerator_decl (void)
previous enumerator (stored in last_initializer) is incremented
by 1 and is used to initialize the current enumerator. */
if (initializer == NULL)
- initializer = gfc_enum_initializer (last_initializer, old_locus);
+ initializer = enum_initializer (last_initializer, old_locus);
if (initializer == NULL || initializer->ts.type != BT_INTEGER)
{
diff --git a/gcc/fortran/dump-parse-tree.c b/gcc/fortran/dump-parse-tree.c
index e007a54aea0..f6de8e824bc 100644
--- a/gcc/fortran/dump-parse-tree.c
+++ b/gcc/fortran/dump-parse-tree.c
@@ -1,5 +1,5 @@
/* Parse tree dumper
- Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008
+ Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009
Free Software Foundation, Inc.
Contributed by Steven Bosscher
@@ -680,9 +680,7 @@ show_components (gfc_symbol *sym)
static void
show_typebound (gfc_symtree* st)
{
- if (!st->n.tb)
- return;
-
+ gcc_assert (st->n.tb);
show_indent ();
if (st->n.tb->is_generic)
@@ -708,7 +706,7 @@ show_typebound (gfc_symtree* st)
else
fputs (", PRIVATE", dumpfile);
- fprintf (dumpfile, " :: %s => ", st->n.sym->name);
+ fprintf (dumpfile, " :: %s => ", st->name);
if (st->n.tb->is_generic)
{
@@ -739,7 +737,7 @@ show_f2k_derived (gfc_namespace* f2k)
}
/* Type-bound procedures. */
- gfc_traverse_symtree (f2k->sym_root, &show_typebound);
+ gfc_traverse_symtree (f2k->tb_sym_root, &show_typebound);
--show_level;
}
@@ -1148,6 +1146,9 @@ show_code_node (int level, gfc_code *c)
switch (c->op)
{
+ case EXEC_END_PROCEDURE:
+ break;
+
case EXEC_NOP:
fputs ("NOP", dumpfile);
break;
@@ -1163,38 +1164,38 @@ show_code_node (int level, gfc_code *c)
case EXEC_INIT_ASSIGN:
case EXEC_ASSIGN:
fputs ("ASSIGN ", dumpfile);
- show_expr (c->expr);
+ show_expr (c->expr1);
fputc (' ', dumpfile);
show_expr (c->expr2);
break;
case EXEC_LABEL_ASSIGN:
fputs ("LABEL ASSIGN ", dumpfile);
- show_expr (c->expr);
- fprintf (dumpfile, " %d", c->label->value);
+ show_expr (c->expr1);
+ fprintf (dumpfile, " %d", c->label1->value);
break;
case EXEC_POINTER_ASSIGN:
fputs ("POINTER ASSIGN ", dumpfile);
- show_expr (c->expr);
+ show_expr (c->expr1);
fputc (' ', dumpfile);
show_expr (c->expr2);
break;
case EXEC_GOTO:
fputs ("GOTO ", dumpfile);
- if (c->label)
- fprintf (dumpfile, "%d", c->label->value);
+ if (c->label1)
+ fprintf (dumpfile, "%d", c->label1->value);
else
{
- show_expr (c->expr);
+ show_expr (c->expr1);
d = c->block;
if (d != NULL)
{
fputs (", (", dumpfile);
for (; d; d = d ->block)
{
- code_indent (level, d->label);
+ code_indent (level, d->label1);
if (d->block != NULL)
fputc (',', dumpfile);
else
@@ -1218,26 +1219,26 @@ show_code_node (int level, gfc_code *c)
case EXEC_COMPCALL:
fputs ("CALL ", dumpfile);
- show_compcall (c->expr);
+ show_compcall (c->expr1);
break;
case EXEC_CALL_PPC:
fputs ("CALL ", dumpfile);
- show_expr (c->expr);
+ show_expr (c->expr1);
show_actual_arglist (c->ext.actual);
break;
case EXEC_RETURN:
fputs ("RETURN ", dumpfile);
- if (c->expr)
- show_expr (c->expr);
+ if (c->expr1)
+ show_expr (c->expr1);
break;
case EXEC_PAUSE:
fputs ("PAUSE ", dumpfile);
- if (c->expr != NULL)
- show_expr (c->expr);
+ if (c->expr1 != NULL)
+ show_expr (c->expr1);
else
fprintf (dumpfile, "%d", c->ext.stop_code);
@@ -1246,8 +1247,8 @@ show_code_node (int level, gfc_code *c)
case EXEC_STOP:
fputs ("STOP ", dumpfile);
- if (c->expr != NULL)
- show_expr (c->expr);
+ if (c->expr1 != NULL)
+ show_expr (c->expr1);
else
fprintf (dumpfile, "%d", c->ext.stop_code);
@@ -1255,15 +1256,15 @@ show_code_node (int level, gfc_code *c)
case EXEC_ARITHMETIC_IF:
fputs ("IF ", dumpfile);
- show_expr (c->expr);
+ show_expr (c->expr1);
fprintf (dumpfile, " %d, %d, %d",
- c->label->value, c->label2->value, c->label3->value);
+ c->label1->value, c->label2->value, c->label3->value);
break;
case EXEC_IF:
d = c->block;
fputs ("IF ", dumpfile);
- show_expr (d->expr);
+ show_expr (d->expr1);
fputc ('\n', dumpfile);
show_code (level + 1, d->next);
@@ -1272,19 +1273,19 @@ show_code_node (int level, gfc_code *c)
{
code_indent (level, 0);
- if (d->expr == NULL)
+ if (d->expr1 == NULL)
fputs ("ELSE\n", dumpfile);
else
{
fputs ("ELSE IF ", dumpfile);
- show_expr (d->expr);
+ show_expr (d->expr1);
fputc ('\n', dumpfile);
}
show_code (level + 1, d->next);
}
- code_indent (level, c->label);
+ code_indent (level, c->label1);
fputs ("ENDIF", dumpfile);
break;
@@ -1292,7 +1293,7 @@ show_code_node (int level, gfc_code *c)
case EXEC_SELECT:
d = c->block;
fputs ("SELECT CASE ", dumpfile);
- show_expr (c->expr);
+ show_expr (c->expr1);
fputc ('\n', dumpfile);
for (; d; d = d->block)
@@ -1314,7 +1315,7 @@ show_code_node (int level, gfc_code *c)
show_code (level + 1, d->next);
}
- code_indent (level, c->label);
+ code_indent (level, c->label1);
fputs ("END SELECT", dumpfile);
break;
@@ -1322,7 +1323,7 @@ show_code_node (int level, gfc_code *c)
fputs ("WHERE ", dumpfile);
d = c->block;
- show_expr (d->expr);
+ show_expr (d->expr1);
fputc ('\n', dumpfile);
show_code (level + 1, d->next);
@@ -1331,7 +1332,7 @@ show_code_node (int level, gfc_code *c)
{
code_indent (level, 0);
fputs ("ELSE WHERE ", dumpfile);
- show_expr (d->expr);
+ show_expr (d->expr1);
fputc ('\n', dumpfile);
show_code (level + 1, d->next);
}
@@ -1357,10 +1358,10 @@ show_code_node (int level, gfc_code *c)
fputc (',', dumpfile);
}
- if (c->expr != NULL)
+ if (c->expr1 != NULL)
{
fputc (',', dumpfile);
- show_expr (c->expr);
+ show_expr (c->expr1);
}
fputc ('\n', dumpfile);
@@ -1390,12 +1391,12 @@ show_code_node (int level, gfc_code *c)
case EXEC_DO_WHILE:
fputs ("DO WHILE ", dumpfile);
- show_expr (c->expr);
+ show_expr (c->expr1);
fputc ('\n', dumpfile);
show_code (level + 1, c->block->next);
- code_indent (level, c->label);
+ code_indent (level, c->label1);
fputs ("END DO", dumpfile);
break;
@@ -1413,10 +1414,16 @@ show_code_node (int level, gfc_code *c)
case EXEC_ALLOCATE:
fputs ("ALLOCATE ", dumpfile);
- if (c->expr)
+ if (c->expr1)
{
fputs (" STAT=", dumpfile);
- show_expr (c->expr);
+ show_expr (c->expr1);
+ }
+
+ if (c->expr2)
+ {
+ fputs (" ERRMSG=", dumpfile);
+ show_expr (c->expr2);
}
for (a = c->ext.alloc_list; a; a = a->next)
@@ -1429,10 +1436,16 @@ show_code_node (int level, gfc_code *c)
case EXEC_DEALLOCATE:
fputs ("DEALLOCATE ", dumpfile);
- if (c->expr)
+ if (c->expr1)
{
fputs (" STAT=", dumpfile);
- show_expr (c->expr);
+ show_expr (c->expr1);
+ }
+
+ if (c->expr2)
+ {
+ fputs (" ERRMSG=", dumpfile);
+ show_expr (c->expr2);
}
for (a = c->ext.alloc_list; a; a = a->next)
@@ -1795,7 +1808,7 @@ show_code_node (int level, gfc_code *c)
case EXEC_IOLENGTH:
fputs ("IOLENGTH ", dumpfile);
- show_expr (c->expr);
+ show_expr (c->expr1);
goto show_dt_code;
break;
@@ -1904,7 +1917,7 @@ show_code_node (int level, gfc_code *c)
case EXEC_TRANSFER:
fputs ("TRANSFER ", dumpfile);
- show_expr (c->expr);
+ show_expr (c->expr1);
break;
case EXEC_DT_END:
@@ -1970,7 +1983,7 @@ show_namespace (gfc_namespace *ns)
{
gfc_interface *intr;
gfc_namespace *save;
- gfc_intrinsic_op op;
+ int op;
gfc_equiv *eq;
int i;
@@ -2020,7 +2033,7 @@ show_namespace (gfc_namespace *ns)
show_indent ();
fprintf (dumpfile, "Operator interfaces for %s:",
- gfc_op2string (op));
+ gfc_op2string ((gfc_intrinsic_op) op));
for (; intr; intr = intr->next)
fprintf (dumpfile, " %s", intr->sym->name);
diff --git a/gcc/fortran/expr.c b/gcc/fortran/expr.c
index feaa6254840..13c6b636355 100644
--- a/gcc/fortran/expr.c
+++ b/gcc/fortran/expr.c
@@ -1654,18 +1654,16 @@ gfc_simplify_expr (gfc_expr *p, int type)
gfc_char_t *s;
int start, end;
+ start = 0;
if (p->ref && p->ref->u.ss.start)
{
gfc_extract_int (p->ref->u.ss.start, &start);
start--; /* Convert from one-based to zero-based. */
}
- else
- start = 0;
+ end = p->value.character.length;
if (p->ref && p->ref->u.ss.end)
gfc_extract_int (p->ref->u.ss.end, &end);
- else
- end = p->value.character.length;
s = gfc_get_wide_string (end - start + 2);
memcpy (s, p->value.character.string + start,
@@ -2127,8 +2125,16 @@ check_transformational (gfc_expr *e)
"selected_real_kind", "transfer", "trim", NULL
};
+ static const char * const trans_func_f2003[] = {
+ "all", "any", "count", "dot_product", "matmul", "null", "pack",
+ "product", "repeat", "reshape", "selected_char_kind", "selected_int_kind",
+ "selected_real_kind", "spread", "sum", "transfer", "transpose",
+ "trim", "unpack", NULL
+ };
+
int i;
const char *name;
+ const char *const *functions;
if (!e->value.function.isym
|| !e->value.function.isym->transformational)
@@ -2136,31 +2142,23 @@ check_transformational (gfc_expr *e)
name = e->symtree->n.sym->name;
+ functions = (gfc_option.allow_std & GFC_STD_F2003)
+ ? trans_func_f2003 : trans_func_f95;
+
/* NULL() is dealt with below. */
if (strcmp ("null", name) == 0)
return MATCH_NO;
- for (i = 0; trans_func_f95[i]; i++)
- if (strcmp (trans_func_f95[i], name) == 0)
- break;
+ for (i = 0; functions[i]; i++)
+ if (strcmp (functions[i], name) == 0)
+ break;
- /* FIXME, F2003: implement translation of initialization
- expressions before enabling this check. For F95, error
- out if the transformational function is not in the list. */
-#if 0
- if (trans_func_f95[i] == NULL
- && gfc_notify_std (GFC_STD_F2003,
- "transformational intrinsic '%s' at %L is not permitted "
- "in an initialization expression", name, &e->where) == FAILURE)
- return MATCH_ERROR;
-#else
- if (trans_func_f95[i] == NULL)
+ if (functions[i] == NULL)
{
gfc_error("transformational intrinsic '%s' at %L is not permitted "
"in an initialization expression", name, &e->where);
return MATCH_ERROR;
}
-#endif
return check_init_expr_arguments (e);
}
@@ -2777,18 +2775,25 @@ gfc_specification_expr (gfc_expr *e)
/* Given two expressions, make sure that the arrays are conformable. */
gfc_try
-gfc_check_conformance (const char *optype_msgid, gfc_expr *op1, gfc_expr *op2)
+gfc_check_conformance (gfc_expr *op1, gfc_expr *op2, const char *optype_msgid, ...)
{
int op1_flag, op2_flag, d;
mpz_t op1_size, op2_size;
gfc_try t;
+ va_list argp;
+ char buffer[240];
+
if (op1->rank == 0 || op2->rank == 0)
return SUCCESS;
+ va_start (argp, optype_msgid);
+ vsnprintf (buffer, 240, optype_msgid, argp);
+ va_end (argp);
+
if (op1->rank != op2->rank)
{
- gfc_error ("Incompatible ranks in %s (%d and %d) at %L", _(optype_msgid),
+ gfc_error ("Incompatible ranks in %s (%d and %d) at %L", _(buffer),
op1->rank, op2->rank, &op1->where);
return FAILURE;
}
@@ -2803,7 +2808,7 @@ gfc_check_conformance (const char *optype_msgid, gfc_expr *op1, gfc_expr *op2)
if (op1_flag && op2_flag && mpz_cmp (op1_size, op2_size) != 0)
{
gfc_error ("Different shape for %s at %L on dimension %d "
- "(%d and %d)", _(optype_msgid), &op1->where, d + 1,
+ "(%d and %d)", _(buffer), &op1->where, d + 1,
(int) mpz_get_si (op1_size),
(int) mpz_get_si (op2_size));
@@ -2951,7 +2956,7 @@ gfc_check_assign (gfc_expr *lvalue, gfc_expr *rvalue, int conform)
/* Check size of array assignments. */
if (lvalue->rank != 0 && rvalue->rank != 0
- && gfc_check_conformance ("array assignment", lvalue, rvalue) != SUCCESS)
+ && gfc_check_conformance (lvalue, rvalue, "array assignment") != SUCCESS)
return FAILURE;
if (rvalue->is_boz && lvalue->ts.type != BT_INTEGER
@@ -3137,6 +3142,7 @@ gfc_check_pointer_assign (gfc_expr *lvalue, gfc_expr *rvalue)
/* Checks on rvalue for procedure pointer assignments. */
if (proc_pointer)
{
+ char err[200];
attr = gfc_expr_attr (rvalue);
if (!((rvalue->expr_type == EXPR_NULL)
|| (rvalue->expr_type == EXPR_FUNCTION && attr.proc_pointer)
@@ -3176,10 +3182,11 @@ gfc_check_pointer_assign (gfc_expr *lvalue, gfc_expr *rvalue)
return SUCCESS;
if (rvalue->expr_type == EXPR_VARIABLE
&& !gfc_compare_interfaces (lvalue->symtree->n.sym,
- rvalue->symtree->n.sym, 0))
+ rvalue->symtree->n.sym, 0, 1, err,
+ sizeof(err)))
{
- gfc_error ("Interfaces don't match "
- "in procedure pointer assignment at %L", &rvalue->where);
+ gfc_error ("Interface mismatch in procedure pointer assignment "
+ "at %L: %s", &rvalue->where, err);
return FAILURE;
}
return SUCCESS;
diff --git a/gcc/fortran/f95-lang.c b/gcc/fortran/f95-lang.c
index 1aab3bf6cc3..97a071d06f9 100644
--- a/gcc/fortran/f95-lang.c
+++ b/gcc/fortran/f95-lang.c
@@ -43,6 +43,10 @@ along with GCC; see the file COPYING3. If not see
#include "diagnostic.h"
#include "tree-dump.h"
#include "cgraph.h"
+/* For gfc_maybe_initialize_eh. */
+#include "libfuncs.h"
+#include "expr.h"
+#include "except.h"
#include "gfortran.h"
#include "cpp.h"
@@ -165,6 +169,10 @@ static GTY(()) struct binding_level *free_binding_level;
It is indexed by a RID_... value. */
tree *ridpointers = NULL;
+/* True means we've initialized exception handling. */
+bool gfc_eh_initialized_p;
+
+
/* Prepare expr to be an argument of a TRUTH_NOT_EXPR,
or validate its data type for an `if' or `while' statement or ?..: exp.
@@ -1223,5 +1231,21 @@ gfc_init_ts (void)
tree_contains_struct[NAMESPACE_DECL][TS_DECL_MINIMAL] = 1;
}
+void
+gfc_maybe_initialize_eh (void)
+{
+ if (!flag_exceptions || gfc_eh_initialized_p)
+ return;
+
+ gfc_eh_initialized_p = true;
+ eh_personality_libfunc
+ = init_one_libfunc (USING_SJLJ_EXCEPTIONS
+ ? "__gcc_personality_sj0"
+ : "__gcc_personality_v0");
+ default_init_unwind_resume_libfunc ();
+ using_eh_for_cleanups ();
+}
+
+
#include "gt-fortran-f95-lang.h"
#include "gtype-fortran.h"
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index fad49c4e7cd..7b9c69753c9 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -1445,6 +1445,7 @@ typedef struct gfc_intrinsic_arg
gfc_typespec ts;
int optional;
+ ENUM_BITFIELD (sym_intent) intent:2;
gfc_actual_arglist *actual;
struct gfc_intrinsic_arg *next;
@@ -1555,6 +1556,7 @@ gfc_intrinsic_sym;
#include <gmp.h>
#include <mpfr.h>
#define GFC_RND_MODE GMP_RNDN
+#define GFC_MPC_RND_MODE MPC_RNDNN
typedef struct gfc_expr
{
@@ -1816,7 +1818,7 @@ typedef struct
{
gfc_expr *unit, *file, *status, *access, *form, *recl,
*blank, *position, *action, *delim, *pad, *iostat, *iomsg, *convert,
- *decimal, *encoding, *round, *sign, *asynchronous, *id;
+ *decimal, *encoding, *round, *sign, *asynchronous, *id, *newunit;
gfc_st_label *err;
}
gfc_open;
@@ -1893,7 +1895,7 @@ typedef enum
EXEC_ENTRY, EXEC_PAUSE, EXEC_STOP, EXEC_CONTINUE, EXEC_INIT_ASSIGN,
EXEC_IF, EXEC_ARITHMETIC_IF, EXEC_DO, EXEC_DO_WHILE, EXEC_SELECT,
EXEC_FORALL, EXEC_WHERE, EXEC_CYCLE, EXEC_EXIT, EXEC_CALL_PPC,
- EXEC_ALLOCATE, EXEC_DEALLOCATE,
+ EXEC_ALLOCATE, EXEC_DEALLOCATE, EXEC_END_PROCEDURE,
EXEC_OPEN, EXEC_CLOSE, EXEC_WAIT,
EXEC_READ, EXEC_WRITE, EXEC_IOLENGTH, EXEC_TRANSFER, EXEC_DT_END,
EXEC_BACKSPACE, EXEC_ENDFILE, EXEC_INQUIRE, EXEC_REWIND, EXEC_FLUSH,
@@ -1913,9 +1915,9 @@ typedef struct gfc_code
struct gfc_code *block, *next;
locus loc;
- gfc_st_label *here, *label, *label2, *label3;
+ gfc_st_label *here, *label1, *label2, *label3;
gfc_symtree *symtree;
- gfc_expr *expr, *expr2;
+ gfc_expr *expr1, *expr2;
/* A name isn't sufficient to identify a subroutine, we need the actual
symbol for the interface definition.
const char *sub_name; */
@@ -2060,7 +2062,6 @@ typedef struct
int warn_std;
int allow_std;
- int fshort_enums;
int convert;
int record_marker;
int max_subrecord_length;
@@ -2198,6 +2199,9 @@ unsigned int gfc_init_options (unsigned int, const char **);
int gfc_handle_option (size_t, const char *, int);
bool gfc_post_options (const char **);
+/* f95-lang.c */
+void gfc_maybe_initialize_eh (void);
+
/* iresolve.c */
const char * gfc_get_string (const char *, ...) ATTRIBUTE_PRINTF_1;
bool gfc_find_sym_in_expr (gfc_symbol *, gfc_expr *);
@@ -2245,13 +2249,14 @@ void gfc_get_errors (int *, int *);
/* arith.c */
void gfc_arith_init_1 (void);
void gfc_arith_done_1 (void);
-gfc_expr *gfc_enum_initializer (gfc_expr *, locus);
arith gfc_check_integer_range (mpz_t p, int kind);
bool gfc_check_character_range (gfc_char_t, int);
/* trans-types.c */
gfc_try gfc_check_any_c_kind (gfc_typespec *);
int gfc_validate_kind (bt, int, bool);
+int gfc_get_int_kind_from_width_isofortranenv (int size);
+int gfc_get_real_kind_from_width_isofortranenv (int size);
extern int gfc_index_integer_kind;
extern int gfc_default_integer_kind;
extern int gfc_max_integer_kind;
@@ -2478,7 +2483,7 @@ gfc_try gfc_specification_expr (gfc_expr *);
int gfc_numeric_ts (gfc_typespec *);
int gfc_kind_max (gfc_expr *, gfc_expr *);
-gfc_try gfc_check_conformance (const char *, gfc_expr *, gfc_expr *);
+gfc_try gfc_check_conformance (gfc_expr *, gfc_expr *, const char *, ...) ATTRIBUTE_PRINTF_3;
gfc_try gfc_check_assign (gfc_expr *, gfc_expr *, int);
gfc_try gfc_check_pointer_assign (gfc_expr *, gfc_expr *);
gfc_try gfc_check_assign_symbol (gfc_symbol *, gfc_expr *);
@@ -2562,7 +2567,7 @@ gfc_try gfc_ref_dimen_size (gfc_array_ref *, int dimen, mpz_t *);
void gfc_free_interface (gfc_interface *);
int gfc_compare_derived_types (gfc_symbol *, gfc_symbol *);
int gfc_compare_types (gfc_typespec *, gfc_typespec *);
-int gfc_compare_interfaces (gfc_symbol*, gfc_symbol*, int);
+int gfc_compare_interfaces (gfc_symbol*, gfc_symbol*, int, int, char *, int);
void gfc_check_interfaces (gfc_namespace *);
void gfc_procedure_use (gfc_symbol *, gfc_actual_arglist **, locus *);
gfc_symbol *gfc_search_interface (gfc_interface *, int,
diff --git a/gcc/fortran/gfortran.texi b/gcc/fortran/gfortran.texi
index b7c8b82537c..ab69c0aa3a6 100644
--- a/gcc/fortran/gfortran.texi
+++ b/gcc/fortran/gfortran.texi
@@ -182,6 +182,7 @@ Part I: Invoking GNU Fortran
Part II: Language Reference
* Fortran 2003 and 2008 status:: Fortran 2003 and 2008 features supported by GNU Fortran.
* Compiler Characteristics:: KIND type parameters supported.
+* Mixed-Language Programming:: Interoperability with C
* Extensions:: Language extensions implemented by GNU Fortran.
* Intrinsic Procedures:: Intrinsic procedures supported by GNU Fortran.
* Intrinsic Modules:: Intrinsic modules supported by GNU Fortran.
@@ -240,12 +241,10 @@ or alternative to, the unix @command{f95} command;
@node About GNU Fortran
@section About GNU Fortran
-The GNU Fortran compiler is still in an early state of development.
-It can generate code for most constructs and expressions,
-but much work remains to be done.
-
-When the GNU Fortran compiler is finished,
-it will do everything you expect from any decent compiler:
+The GNU Fortran compiler supports the Fortran 77, 90 and 95 standards
+completely, parts of the Fortran 2003 and Fortran 2008 standards, and
+several vendor extensions. The development goal is to provide the
+following features:
@itemize @bullet
@item
@@ -504,7 +503,7 @@ The primary work remaining to be done on GNU Fortran falls into three
categories: bug fixing (primarily regarding the treatment of invalid code
and providing useful error messages), improving the compiler optimizations
and the performance of compiled code, and extending the compiler to support
-future standards---in particular, Fortran 2003.
+future standards---in particular, Fortran 2003 and Fortran 2008.
@c ---------------------------------------------------------------------
@@ -515,6 +514,10 @@ future standards---in particular, Fortran 2003.
@section Standards
@cindex Standards
+@menu
+* Varying Length Character Strings::
+@end menu
+
The GNU Fortran compiler implements
ISO/IEC 1539:1997 (Fortran 95). As such, it can also compile essentially all
standard-compliant Fortran 90 and Fortran 77 programs. It also supports
@@ -528,13 +531,30 @@ of that standard is already provided; the current status of Fortran 2003
support is reported in the @ref{Fortran 2003 status} section of the
documentation.
-The next version of the Fortran standard after Fortran 2003 is currently
+The next version of the Fortran standard (Fortran 2008) is currently
being developed and the GNU Fortran compiler supports some of its new
features. This support is based on the latest draft of the standard
(available from @url{http://www.nag.co.uk/sc22wg5/}) and no guarantee of
future compatibility is made, as the final standard might differ from the
draft. For more information, see the @ref{Fortran 2008 status} section.
+Additionally, the GNU Fortran compilers supports the OpenMP specification
+(version 3.0, @url{http://openmp.org/wp/openmp-specifications/}).
+
+@node Varying Length Character Strings
+@subsection Varying Length Character Strings
+@cindex Varying length character strings
+@cindex Varying length strings
+@cindex strings, varying length
+
+The Fortran 95 standard specifies in Part 2 (ISO/IEC 1539-2:2000)
+varying length character strings. While GNU Fortran currently does not
+support such strings directly, there exist two Fortran implementations
+for them, which work with GNU Fortran. They can be found at
+@uref{http://www.fortran.com/@/iso_varying_string.f95} and at
+@uref{ftp://ftp.nag.co.uk/@/sc22wg5/@/ISO_VARYING_STRING/}.
+
+
@c =====================================================================
@c PART I: INVOCATION REFERENCE
@@ -787,9 +807,8 @@ was used.
@node Fortran 2003 status
@section Fortran 2003 status
-Although GNU Fortran focuses on implementing the Fortran 95
-standard for the time being, a few Fortran 2003 features are currently
-available.
+GNU Fortran supports several Fortran 2003 features; an incomplete
+list can be found below.
@itemize
@item
@@ -1241,7 +1260,7 @@ the real part is initialized unless @code{CMPLX} is used. In all other
cases, the BOZ literal constant is converted to an @code{INTEGER} value with
the largest decimal representation. This value is then converted
numerically to the type and kind of the variable in question.
-(For instance @code{real :: r = b'0000001' + 1} initializes @code{r}
+(For instance, @code{real :: r = b'0000001' + 1} initializes @code{r}
with @code{2.0}.) As different compilers implement the extension
differently, one should be careful when doing bitwise initialization
of non-integer variables.
@@ -1529,8 +1548,8 @@ It consists of a set of compiler directives, library routines,
and environment variables that influence run-time behavior.
GNU Fortran strives to be compatible to the
-@uref{http://www.openmp.org/drupal/mp-documents/spec25.pdf,
-OpenMP Application Program Interface v2.5}.
+@uref{http://www.openmp.org/mp-documents/spec30.pdf,
+OpenMP Application Program Interface v3.0}.
To enable the processing of the OpenMP directive @code{!$omp} in
free-form source code; the @code{c$omp}, @code{*$omp} and @code{!$omp}
@@ -1568,7 +1587,7 @@ this may lead to surprising results, especially to segmentation faults
if the stacksize is limited.
@item
-On glibc-based systems, OpenMP enabled applications can not be statically
+On glibc-based systems, OpenMP enabled applications cannot be statically
linked due to limitations of the underlying pthreads-implementation. It
might be possible to get a working solution if
@command{-Wl,--whole-archive -lpthread -Wl,--no-whole-archive} is added
@@ -1597,7 +1616,7 @@ are rebuilt using a new compiler or version of a compiler.
@code{%VAL} passes a scalar argument by value, @code{%REF} passes it by
reference and @code{%LOC} passes its memory location. Since gfortran
already passes scalar arguments by reference, @code{%REF} is in effect
-a do-nothing. @code{%LOC} has the same effect as a fortran pointer.
+a do-nothing. @code{%LOC} has the same effect as a Fortran pointer.
An example of passing an argument by value to a C subroutine foo.:
@smallexample
@@ -1614,9 +1633,8 @@ C
For details refer to the g77 manual
@uref{http://gcc.gnu.org/onlinedocs/gcc-3.4.6/g77/index.html#Top}.
-Also, the gfortran testsuite c_by_val.f and its partner c_by_val.c are
-worth a look.
-
+Also, @code{c_by_val.f} and its partner @code{c_by_val.c} of the
+GNU Fortran testsuite are worth a look.
@node Extensions not implemented in GNU Fortran
@@ -1634,7 +1652,7 @@ code that uses them running with the GNU Fortran compiler.
@c More can be found here:
@c -- http://gcc.gnu.org/onlinedocs/gcc-3.4.6/g77/Missing-Features.html
-@c -- the list of fortran and libgfortran bugs closed as WONTFIX:
+@c -- the list of Fortran and libgfortran bugs closed as WONTFIX:
@c http://tinyurl.com/2u4h5y
@menu
@@ -1822,9 +1840,503 @@ c
@end smallexample
+@c ---------------------------------------------------------------------
+@c Mixed-Language Programming
+@c ---------------------------------------------------------------------
+
+@node Mixed-Language Programming
+@chapter Mixed-Language Programming
+@cindex Interoperability
+@cindex Mixed-language programming
+
+@menu
+* Interoperability with C::
+* Non-Fortran Main Program::
+@end menu
+
+This chapter is about mixed-language interoperability, but also applies
+if one links Fortran code compiled by different compilers. In most cases,
+use of the C Binding features of the Fortran 2003 standard is sufficient,
+and their use is highly recommended.
+
+
+@node Interoperability with C
+@section Interoperability with C
+
+@menu
+* Intrinsic Types::
+* Further Interoperability of Fortran with C::
+* Derived Types and struct::
+* Interoperable Global Variables::
+* Interoperable Subroutines and Functions::
+@end menu
+
+Since Fortran 2003 (ISO/IEC 1539-1:2004(E)) there is a
+standardized way to generate procedure and derived-type
+declarations and global variables which are interoperable with C
+(ISO/IEC 9899:1999). The @code{bind(C)} attribute has been added
+to inform the compiler that a symbol shall be interoperable with C;
+also, some constraints are added. Note, however, that not
+all C features have a Fortran equivalent or vice versa. For instance,
+neither C's unsigned integers nor C's functions with variable number
+of arguments have an equivalent in Fortran.
+
+
+@node Intrinsic Types
+@subsection Intrinsic Types
+
+In order to ensure that exactly the same variable type and kind is used
+in C and Fortran, the named constants shall be used which are defined in the
+@code{ISO_C_BINDING} intrinsic module. That module contains named constants
+for kind parameters and character named constants for the escape sequences
+in C. For a list of the constants, see @ref{ISO_C_BINDING}.
+
+@node Derived Types and struct
+@subsection Derived Types and struct
+
+For compatibility of derived types with @code{struct}, one needs to use
+the @code{BIND(C)} attribute in the type declaration. For instance, the
+following type declaration
+
+@smallexample
+ USE ISO_C_BINDING
+ TYPE, BIND(C) :: myType
+ INTEGER(C_INT) :: i1, i2
+ INTEGER(C_SIGNED_CHAR) :: i3
+ REAL(C_DOUBLE) :: d1
+ COMPLEX(C_FLOAT_COMPLEX) :: c1
+ CHARACTER(KIND=C_CHAR) :: str(5)
+ END TYPE
+@end smallexample
+
+matches the following @code{struct} declaration in C
+
+@smallexample
+ struct @{
+ int i1, i2;
+ /* Note: "char" might be signed or unsigned. */
+ signed char i3;
+ double d1;
+ float _Complex c1;
+ char str[5];
+ @} myType;
+@end smallexample
+
+Derived types with the C binding attribute shall not have the @code{sequence}
+attribute, type parameters, the @code{extends} attribute, nor type-bound
+procedures. Every component must be of interoperable type and kind and may not
+have the @code{pointer} or @code{allocatable} attribute. The names of the
+variables are irrelevant for interoperability.
+
+As there exist no direct Fortran equivalents, neither unions nor structs
+with bit field or variable-length array members are interoperable.
+
+@node Interoperable Global Variables
+@subsection Interoperable Global Variables
+
+Variables can be made accessible from C using the C binding attribute,
+optionally together with specifying a binding name. Those variables
+have to be declared in the declaration part of a @code{MODULE},
+be of interoperable type, and have neither the @code{pointer} nor
+the @code{allocatable} attribute.
+
+@smallexample
+ MODULE m
+ USE myType_module
+ USE ISO_C_BINDING
+ integer(C_INT), bind(C, name="_MyProject_flags") :: global_flag
+ type(myType), bind(C) :: tp
+ END MODULE
+@end smallexample
+
+Here, @code{_MyProject_flags} is the case-sensitive name of the variable
+as seen from C programs while @code{global_flag} is the case-insensitive
+name as seen from Fortran. If no binding name is specified, as for
+@var{tp}, the C binding name is the (lowercase) Fortran binding name.
+If a binding name is specified, only a single variable may be after the
+double colon. Note of warning: You cannot use a global variable to
+access @var{errno} of the C library as the C standard allows it to be
+a macro. Use the @code{IERRNO} intrinsic (GNU extension) instead.
+
+@node Interoperable Subroutines and Functions
+@subsection Interoperable Subroutines and Functions
+
+Subroutines and functions have to have the @code{BIND(C)} attribute to
+be compatible with C. The dummy argument declaration is relatively
+straightforward. However, one needs to be careful because C uses
+call-by-value by default while GNU Fortran uses call-by-reference.
+Furthermore, strings and pointers are handled differently. Note that
+only explicit size and assumed-size arrays are supported but not
+assumed-shape or allocatable arrays.
+
+To pass a variable by value, use the @code{VALUE} attribute.
+Thus the following C prototype
+
+@smallexample
+@code{int func(int i, int *j)}
+@end smallexample
+
+matches the Fortran declaration
+
+@smallexample
+ integer(c_int) func(i,j)
+ integer, VALUE :: i
+ integer :: j
+@end smallexample
+
+Note that pointer arguments also frequently need the @code{VALUE} attribute.
+
+Strings are handled quite differently in C and Fortran. In C a string
+is a @code{NUL}-terminated array of characters while in Fortran each string
+has a length associated with it and is thus not terminated (by e.g.
+@code{NUL}). For example, if one wants to use the following C function,
+
+@smallexample
+ #include <stdio.h>
+ void print_C(char *string) /* equivalent: char string[] */
+ @{
+ printf("%s\n", string);
+ @}
+@end smallexample
+
+to print ``Hello World'' from Fortran, one can call it using
+
+@smallexample
+ use iso_c_binding, only: C_CHAR, C_NULL_CHAR
+ interface
+ subroutine print_c(string) bind(C, name="print_C")
+ use iso_c_binding, only: c_char
+ character(kind=c_char) :: string(*)
+ end subroutine print_c
+ end interface
+ call print_c(C_CHAR_"Hello World"//C_NULL_CHAR)
+@end smallexample
+
+As the example shows, one needs to ensure that the
+string is @code{NUL} terminated. Additionally, the dummy argument
+@var{string} of @code{print_C} is a length-one assumed-size
+array; using @code{character(len=*)} is not allowed. The example
+above uses @code{c_char_"Hello World"} to ensure the string
+literal has the right type; typically the default character
+kind and @code{c_char} are the same and thus @code{"Hello World"}
+is equivalent. However, the standard does not guarantee this.
+
+The use of pointers is now illustrated using the C library
+function @code{strncpy}, whose prototype is
+
+@smallexample
+ char *strncpy(char *restrict s1, const char *restrict s2, size_t n);
+@end smallexample
+
+The function @code{strncpy} copies at most @var{n} characters from
+string @var{s2} to @var{s1} and returns @var{s1}. In the following
+example, we ignore the return value:
+
+@smallexample
+ use iso_c_binding
+ implicit none
+ character(len=30) :: str,str2
+ interface
+ ! Ignore the return value of strncpy -> subroutine
+ ! "restrict" is always assumed if we do not pass a pointer
+ subroutine strncpy(dest, src, n) bind(C)
+ import
+ character(kind=c_char), intent(out) :: dest(*)
+ character(kind=c_char), intent(in) :: src(*)
+ integer(c_size_t), value, intent(in) :: n
+ end subroutine strncpy
+ end interface
+ str = repeat('X',30) ! Initialize whole string with 'X'
+ call strncpy(str, c_char_"Hello World"//C_NULL_CHAR, &
+ len(c_char_"Hello World",kind=c_size_t))
+ print '(a)', str ! prints: "Hello WorldXXXXXXXXXXXXXXXXXXX"
+ end
+@end smallexample
+
+C pointers are represented in Fortran via the special derived type
+@code{type(c_ptr)}, with private components. Thus one needs to
+use intrinsic conversion procedures to convert from or to C pointers.
+For example,
+
+@smallexample
+ use iso_c_binding
+ type(c_ptr) :: cptr1, cptr2
+ integer, target :: array(7), scalar
+ integer, pointer :: pa(:), ps
+ cptr1 = c_loc(array(1)) ! The programmer needs to ensure that the
+ ! array is contiguous if required by the C
+ ! procedure
+ cptr2 = c_loc(scalar)
+ call c_f_pointer(cptr2, ps)
+ call c_f_pointer(cptr2, pa, shape=[7])
+@end smallexample
+
+When converting C to Fortran arrays, the one-dimensional @code{SHAPE} argument
+has to be passed. Note: A pointer argument @code{void *} matches
+@code{TYPE(C_PTR), VALUE} while @code{TYPE(C_PTR)} matches @code{void **}.
+
+Procedure pointers are handled analogously to pointers; the C type is
+@code{TYPE(C_FUNPTR)} and the intrinsic conversion procedures are
+@code{C_F_PROC_POINTER} and @code{C_FUNLOC}.
+
+The intrinsic procedures are described in @ref{Intrinsic Procedures}.
+
+@node Further Interoperability of Fortran with C
+@subsection Further Interoperability of Fortran with C
+
+Assumed-shape and allocatable arrays are passed using an array descriptor
+(dope vector). The internal structure of the array descriptor used
+by GNU Fortran is not yet documented and will change. There will also be
+a Technical Report (TR 29113) which standardizes an interoperable
+array descriptor. Until then, you can use the Chasm Language
+Interoperability Tools, @url{http://chasm-interop.sourceforge.net/},
+which provide an interface to GNU Fortran's array descriptor.
+
+The technical report 29113 will presumably also include support for
+C-interoperable @code{OPTIONAL} and for assumed-rank and assumed-type
+dummy arguments. However, the TR has neither been approved nor implemented
+in GNU Fortran; therefore, these features are not yet available.
+
+@node Non-Fortran Main Program
+@section Non-Fortran Main Program
+
+@menu
+* _gfortran_set_args:: Save command-line arguments
+* _gfortran_set_options:: Set library option flags
+* _gfortran_set_convert:: Set endian conversion
+* _gfortran_set_record_marker:: Set length of record markers
+* _gfortran_set_max_subrecord_length:: Set subrecord length
+@end menu
+
+Even if you are doing mixed-language programming, it is very
+likely that you do not need to know or use the information in this
+section. Since it is about the internal structure of GNU Fortran,
+it may also change in GCC minor releases.
+
+When you compile a @code{PROGRAM} with GNU Fortran, a function
+with the name @code{main} (in the symbol table of the object file)
+is generated, which initializes the libgfortran library and then
+calls the actual program which uses the name @code{MAIN__}, for
+historic reasons. If you link GNU Fortran compiled procedures
+to, e.g., a C or C++ program or to a Fortran program compiled by
+a different compiler, the libgfortran library is not initialized
+and thus a few intrinsic procedures do not work properly, e.g.
+those for obtaining the command-line arguments.
+
+Therefore, if your @code{PROGRAM} is not compiled with
+GNU Fortran and the GNU Fortran compiled procedures require
+intrinsics relying on the library initialization, you need to
+initialize the library yourself. Using the default options,
+gfortran calls @code{_gfortran_set_args} and
+@code{_gfortran_set_options}. The initialization of the former
+is needed if the called procedures access the command line
+(and for backtracing); the latter sets some flags based on the
+standard chosen or to enable backtracing. In typical programs,
+it is not necessary to call any initialization function.
+
+If your @code{PROGRAM} is compiled with GNU Fortran, you shall
+not call any of the following functions. The libgfortran
+initialization functions are shown in C syntax but using C
+bindings they are also accessible from Fortran.
+
+
+@node _gfortran_set_args
+@subsection @code{_gfortran_set_args} --- Save command-line arguments
+@fnindex _gfortran_set_args
+@cindex libgfortran initialization, set_args
+
+@table @asis
+@item @emph{Description}:
+@code{_gfortran_set_args} saves the command-line arguments; this
+initialization is required if any of the command-line intrinsics
+is called. Additionally, it shall be called if backtracing is
+enabled (see @code{_gfortran_set_options}).
+
+@item @emph{Syntax}:
+@code{void _gfortran_set_args (int argc, char *argv[])}
+
+@item @emph{Arguments}:
+@multitable @columnfractions .15 .70
+@item @var{argc} @tab number of command line argument strings
+@item @var{argv} @tab the command-line argument strings; argv[0]
+is the pathname of the executable itself.
+@end multitable
+
+@item @emph{Example}:
+@smallexample
+int main (int argc, char *argv[])
+@{
+ /* Initialize libgfortran. */
+ _gfortran_set_args (argc, argv);
+ return 0;
+@}
+@end smallexample
+@end table
+
+
+@node _gfortran_set_options
+@subsection @code{_gfortran_set_options} --- Set library option flags
+@fnindex _gfortran_set_options
+@cindex libgfortran initialization, set_options
+
+@table @asis
+@item @emph{Description}:
+@code{_gfortran_set_options} sets several flags related to the Fortran
+standard to be used, whether backtracing or core dumps should be enabled
+and whether range checks should be performed. The syntax allows for
+upward compatibility since the number of passed flags is specified; for
+non-passed flags, the default value is used. See also
+@pxref{Code Gen Options}. Please note that not all flags are actually
+used.
+
+@item @emph{Syntax}:
+@code{void _gfortran_set_options (int num, int options[])}
+
+@item @emph{Arguments}:
+@multitable @columnfractions .15 .70
+@item @var{num} @tab number of options passed
+@item @var{argv} @tab The list of flag values
+@end multitable
+
+@item @emph{option flag list}:
+@multitable @columnfractions .15 .70
+@item @var{option}[0] @tab Allowed standard; can give run-time errors
+if e.g. an input-output edit descriptor is invalid in a given standard.
+Possible values are (bitwise or-ed) @code{GFC_STD_F77} (1),
+@code{GFC_STD_F95_OBS} (2), @code{GFC_STD_F95_DEL} (4), @code{GFC_STD_F95}
+(8), @code{GFC_STD_F2003} (16), @code{GFC_STD_GNU} (32),
+@code{GFC_STD_LEGACY} (64), and @code{GFC_STD_F2008} (128).
+Default: @code{GFC_STD_F95_OBS | GFC_STD_F95_DEL | GFC_STD_F2003
+| GFC_STD_F2008 | GFC_STD_F95 | GFC_STD_F77 | GFC_STD_GNU | GFC_STD_LEGACY}.
+@item @var{option}[1] @tab Standard-warning flag; prints a warning to
+standard error. Default: @code{GFC_STD_F95_DEL | GFC_STD_LEGACY}.
+@item @var{option}[2] @tab If non zero, enable pedantic checking.
+Default: off.
+@item @var{option}[3] @tab If non zero, enable core dumps on run-time
+errors. Default: off.
+@item @var{option}[4] @tab If non zero, enable backtracing on run-time
+errors. Default: off.
+Note: Installs a signal handler and requires command-line
+initialization using @code{_gfortran_set_args}.
+@item @var{option}[5] @tab If non zero, supports signed zeros.
+Default: enabled.
+@item @var{option}[6] @tab Enables run-time checking. Possible values
+are (bitwise or-ed): GFC_RTCHECK_BOUNDS (1), GFC_RTCHECK_ARRAY_TEMPS (2),
+GFC_RTCHECK_RECURSION (4), GFC_RTCHECK_DO (16).
+Default: disabled.
+@item @var{option}[7] @tab If non zero, range checking is enabled.
+Default: enabled. See -frange-check (@pxref{Code Gen Options}).
+@end multitable
+
+@item @emph{Example}:
+@smallexample
+ /* Use gfortran 4.5 default options. */
+ static int options[] = @{68, 255, 0, 0, 0, 1, 0, 1@};
+ _gfortran_set_options (8, &options);
+@end smallexample
+@end table
+
+
+@node _gfortran_set_convert
+@subsection @code{_gfortran_set_convert} --- Set endian conversion
+@fnindex _gfortran_set_convert
+@cindex libgfortran initialization, set_convert
+
+@table @asis
+@item @emph{Description}:
+@code{_gfortran_set_convert} set the representation of data for
+unformatted files.
+
+@item @emph{Syntax}:
+@code{void _gfortran_set_convert (int conv)}
+
+@item @emph{Arguments}:
+@multitable @columnfractions .15 .70
+@item @var{conv} @tab Endian conversion, possible values:
+GFC_CONVERT_NATIVE (0, default), GFC_CONVERT_SWAP (1),
+GFC_CONVERT_BIG (2), GFC_CONVERT_LITTLE (3).
+@end multitable
+
+@item @emph{Example}:
+@smallexample
+int main (int argc, char *argv[])
+@{
+ /* Initialize libgfortran. */
+ _gfortran_set_args (argc, argv);
+ _gfortran_set_convert (1);
+ return 0;
+@}
+@end smallexample
+@end table
+
+
+@node _gfortran_set_record_marker
+@subsection @code{_gfortran_set_record_marker} --- Set length of record markers
+@fnindex _gfortran_set_record_marker
+@cindex libgfortran initialization, set_record_marker
+
+@table @asis
+@item @emph{Description}:
+@code{_gfortran_set_record_marker} set the length of record markers
+for unformatted files.
+
+@item @emph{Syntax}:
+@code{void _gfortran_set_record_marker (int val)}
+
+@item @emph{Arguments}:
+@multitable @columnfractions .15 .70
+@item @var{val} @tab Length of the record marker; valid values
+are 4 and 8. Default is 4.
+@end multitable
+
+@item @emph{Example}:
+@smallexample
+int main (int argc, char *argv[])
+@{
+ /* Initialize libgfortran. */
+ _gfortran_set_args (argc, argv);
+ _gfortran_set_record_marker (8);
+ return 0;
+@}
+@end smallexample
+@end table
+
+
+@node _gfortran_set_max_subrecord_length
+@subsection @code{_gfortran_set_max_subrecord_length} --- Set subrecord length
+@fnindex _gfortran_set_max_subrecord_length
+@cindex libgfortran initialization, set_max_subrecord_length
+
+@table @asis
+@item @emph{Description}:
+@code{_gfortran_set_max_subrecord_length} set the maximum length
+for a subrecord. This option only makes sense for testing and
+debugging of unformatted I/O.
+
+@item @emph{Syntax}:
+@code{void _gfortran_set_max_subrecord_length (int val)}
+
+@item @emph{Arguments}:
+@multitable @columnfractions .15 .70
+@item @var{val} @tab the maximum length for a subrecord;
+the maximum permitted value is 2147483639, which is also
+the default.
+@end multitable
+
+@item @emph{Example}:
+@smallexample
+int main (int argc, char *argv[])
+@{
+ /* Initialize libgfortran. */
+ _gfortran_set_args (argc, argv);
+ _gfortran_set_max_subrecord_length (8);
+ return 0;
+@}
+@end smallexample
+@end table
+
-@c ---------------------------------------------------------------------
@c Intrinsic Procedures
@c ---------------------------------------------------------------------
@@ -1913,6 +2425,7 @@ ideas and significant help to the GNU Fortran project
@item Andy Vaught
@item Feng Wang
@item Janus Weil
+@item Daniel Kraft
@end itemize
The following people have contributed bug reports,
@@ -1925,6 +2438,7 @@ GNU Fortran project:
@item Dominique d'Humi@`eres
@item Kate Hedstrom
@item Erik Schnetter
+@item Joost VandeVondele
@end itemize
Many other individuals have helped debug,
diff --git a/gcc/fortran/gfortranspec.c b/gcc/fortran/gfortranspec.c
index 0e5e7913e97..a6f9b42b474 100644
--- a/gcc/fortran/gfortranspec.c
+++ b/gcc/fortran/gfortranspec.c
@@ -58,10 +58,6 @@ along with GCC; see the file COPYING3. If not see
#define MATH_LIBRARY "-lm"
#endif
-#ifndef FORTRAN_INIT
-#define FORTRAN_INIT "-lgfortranbegin"
-#endif
-
#ifndef FORTRAN_LIBRARY
#define FORTRAN_LIBRARY "-lgfortran"
#endif
@@ -278,10 +274,6 @@ lang_specific_driver (int *in_argc, const char *const **in_argv,
2 => last two args were -l<library> -lm. */
int saw_library = 0;
- /* 0 => initial/reset state
- 1 => FORTRAN_INIT linked in */
- int use_init = 0;
-
/* By default, we throw on the math library if we have one. */
int need_math = (MATH_LIBRARY[0] != '\0');
@@ -505,12 +497,6 @@ For more information about these matters, see the file named COPYING\n\n"));
saw_library = 2; /* -l<library> -lm. */
else
{
- if (0 == use_init)
- {
- append_arg (FORTRAN_INIT);
- use_init = 1;
- }
-
ADD_ARG_LIBGFORTRAN (FORTRAN_LIBRARY);
}
}
@@ -540,11 +526,6 @@ For more information about these matters, see the file named COPYING\n\n"));
switch (saw_library)
{
case 0:
- if (0 == use_init)
- {
- append_arg (FORTRAN_INIT);
- use_init = 1;
- }
ADD_ARG_LIBGFORTRAN (library);
/* Fall through. */
diff --git a/gcc/fortran/interface.c b/gcc/fortran/interface.c
index 3c03f959fb2..4954389848b 100644
--- a/gcc/fortran/interface.c
+++ b/gcc/fortran/interface.c
@@ -95,7 +95,7 @@ gfc_free_interface (gfc_interface *intr)
minus respectively, leaving the rest unchanged. */
static gfc_intrinsic_op
-fold_unary (gfc_intrinsic_op op)
+fold_unary_intrinsic (gfc_intrinsic_op op)
{
switch (op)
{
@@ -136,10 +136,11 @@ gfc_match_generic_spec (interface_type *type,
if (gfc_match (" operator ( %o )", &i) == MATCH_YES)
{ /* Operator i/f */
*type = INTERFACE_INTRINSIC_OP;
- *op = fold_unary (i);
+ *op = fold_unary_intrinsic (i);
return MATCH_YES;
}
+ *op = INTRINSIC_NONE;
if (gfc_match (" operator ( ") == MATCH_YES)
{
m = gfc_match_defined_op_name (buffer, 1);
@@ -777,7 +778,7 @@ bad_repl:
Since this test is asymmetric, it has to be called twice to make it
symmetric. Returns nonzero if the argument lists are incompatible
by this test. This subroutine implements rule 1 of section
- 14.1.2.3. */
+ 14.1.2.3 in the Fortran 95 standard. */
static int
count_types_test (gfc_formal_arglist *f1, gfc_formal_arglist *f2)
@@ -868,36 +869,6 @@ count_types_test (gfc_formal_arglist *f1, gfc_formal_arglist *f2)
}
-/* Perform the abbreviated correspondence test for operators. The
- arguments cannot be optional and are always ordered correctly,
- which makes this test much easier than that for generic tests.
-
- This subroutine is also used when comparing a formal and actual
- argument list when an actual parameter is a dummy procedure. At
- that point, two formal interfaces must be compared for equality
- which is what happens here. */
-
-static int
-operator_correspondence (gfc_formal_arglist *f1, gfc_formal_arglist *f2)
-{
- for (;;)
- {
- if (f1 == NULL && f2 == NULL)
- break;
- if (f1 == NULL || f2 == NULL)
- return 1;
-
- if (!compare_type_rank (f1->sym, f2->sym))
- return 1;
-
- f1 = f1->next;
- f2 = f2->next;
- }
-
- return 0;
-}
-
-
/* Perform the correspondence test in rule 2 of section 14.1.2.3.
Returns zero if no argument is found that satisfies rule 2, nonzero
otherwise.
@@ -958,16 +929,29 @@ generic_correspondence (gfc_formal_arglist *f1, gfc_formal_arglist *f2)
/* 'Compare' two formal interfaces associated with a pair of symbols.
We return nonzero if there exists an actual argument list that
- would be ambiguous between the two interfaces, zero otherwise. */
+ would be ambiguous between the two interfaces, zero otherwise.
+ 'intent_flag' specifies whether INTENT and OPTIONAL of the arguments are
+ required to match, which is not the case for ambiguity checks.*/
int
-gfc_compare_interfaces (gfc_symbol *s1, gfc_symbol *s2, int generic_flag)
+gfc_compare_interfaces (gfc_symbol *s1, gfc_symbol *s2, int generic_flag,
+ int intent_flag, char *errmsg, int err_len)
{
gfc_formal_arglist *f1, *f2;
- if ((s1->attr.function && !s2->attr.function)
- || (s1->attr.subroutine && s2->attr.function))
- return 0;
+ if (s1->attr.function && !s2->attr.function)
+ {
+ if (errmsg != NULL)
+ snprintf (errmsg, err_len, "'%s' is not a function", s2->name);
+ return 0;
+ }
+
+ if (s1->attr.subroutine && s2->attr.function)
+ {
+ if (errmsg != NULL)
+ snprintf (errmsg, err_len, "'%s' is not a subroutine", s2->name);
+ return 0;
+ }
/* If the arguments are functions, check type and kind
(only for dummy procedures and procedure pointer assignments). */
@@ -977,22 +961,25 @@ gfc_compare_interfaces (gfc_symbol *s1, gfc_symbol *s2, int generic_flag)
if (s1->ts.type == BT_UNKNOWN)
return 1;
if ((s1->ts.type != s2->ts.type) || (s1->ts.kind != s2->ts.kind))
- return 0;
+ {
+ if (errmsg != NULL)
+ snprintf (errmsg, err_len, "Type/kind mismatch in return value "
+ "of '%s'", s2->name);
+ return 0;
+ }
if (s1->attr.if_source == IFSRC_DECL)
return 1;
}
- if (s1->attr.if_source == IFSRC_UNKNOWN)
+ if (s1->attr.if_source == IFSRC_UNKNOWN
+ || s2->attr.if_source == IFSRC_UNKNOWN)
return 1;
f1 = s1->formal;
f2 = s2->formal;
if (f1 == NULL && f2 == NULL)
- return 1; /* Special case. */
-
- if (count_types_test (f1, f2) || count_types_test (f2, f1))
- return 0;
+ return 1; /* Special case: No arguments. */
if (generic_flag)
{
@@ -1000,9 +987,58 @@ gfc_compare_interfaces (gfc_symbol *s1, gfc_symbol *s2, int generic_flag)
return 0;
}
else
+ /* Perform the abbreviated correspondence test for operators (the
+ arguments cannot be optional and are always ordered correctly).
+ This is also done when comparing interfaces for dummy procedures and in
+ procedure pointer assignments. */
+
+ for (;;)
+ {
+ /* Check existence. */
+ if (f1 == NULL && f2 == NULL)
+ break;
+ if (f1 == NULL || f2 == NULL)
+ {
+ if (errmsg != NULL)
+ snprintf (errmsg, err_len, "'%s' has the wrong number of "
+ "arguments", s2->name);
+ return 0;
+ }
+
+ /* Check type and rank. */
+ if (!compare_type_rank (f1->sym, f2->sym))
+ {
+ if (errmsg != NULL)
+ snprintf (errmsg, err_len, "Type/rank mismatch in argument '%s'",
+ f1->sym->name);
+ return 0;
+ }
+
+ /* Check INTENT. */
+ if (intent_flag && (f1->sym->attr.intent != f2->sym->attr.intent))
+ {
+ snprintf (errmsg, err_len, "INTENT mismatch in argument '%s'",
+ f1->sym->name);
+ return 0;
+ }
+
+ /* Check OPTIONAL. */
+ if (intent_flag && (f1->sym->attr.optional != f2->sym->attr.optional))
+ {
+ snprintf (errmsg, err_len, "OPTIONAL mismatch in argument '%s'",
+ f1->sym->name);
+ return 0;
+ }
+
+ f1 = f1->next;
+ f2 = f2->next;
+ }
+
+ if (count_types_test (f1, f2) || count_types_test (f2, f1))
{
- if (operator_correspondence (f1, f2))
- return 0;
+ if (errmsg != NULL)
+ snprintf (errmsg, err_len, "Interface not matching");
+ return 0;
}
return 1;
@@ -1080,7 +1116,7 @@ check_interface1 (gfc_interface *p, gfc_interface *q0,
if (p->sym->name == q->sym->name && p->sym->module == q->sym->module)
continue;
- if (gfc_compare_interfaces (p->sym, q->sym, generic_flag))
+ if (gfc_compare_interfaces (p->sym, q->sym, generic_flag, 0, NULL, 0))
{
if (referenced)
{
@@ -1175,7 +1211,7 @@ gfc_check_interfaces (gfc_namespace *ns)
{
gfc_namespace *old_ns, *ns2;
char interface_name[100];
- gfc_intrinsic_op i;
+ int i;
old_ns = gfc_current_ns;
gfc_current_ns = ns;
@@ -1193,12 +1229,12 @@ gfc_check_interfaces (gfc_namespace *ns)
strcpy (interface_name, "intrinsic assignment operator");
else
sprintf (interface_name, "intrinsic '%s' operator",
- gfc_op2string (i));
+ gfc_op2string ((gfc_intrinsic_op) i));
if (check_interface0 (ns->op[i], interface_name))
continue;
- check_operator_interface (ns->op[i], i);
+ check_operator_interface (ns->op[i], (gfc_intrinsic_op) i);
for (ns2 = ns; ns2; ns2 = ns2->parent)
{
@@ -1351,27 +1387,25 @@ compare_parameter (gfc_symbol *formal, gfc_expr *actual,
if (actual->ts.type == BT_PROCEDURE)
{
- if (formal->attr.flavor != FL_PROCEDURE)
- goto proc_fail;
-
- if (formal->attr.function
- && !compare_type_rank (formal, actual->symtree->n.sym))
- goto proc_fail;
+ char err[200];
- if (formal->attr.if_source == IFSRC_UNKNOWN
- || actual->symtree->n.sym->attr.external)
- return 1; /* Assume match. */
+ if (formal->attr.flavor != FL_PROCEDURE)
+ {
+ if (where)
+ gfc_error ("Invalid procedure argument at %L", &actual->where);
+ return 0;
+ }
- if (!gfc_compare_interfaces (formal, actual->symtree->n.sym, 0))
- goto proc_fail;
+ if (!gfc_compare_interfaces (formal, actual->symtree->n.sym, 0, 1, err,
+ sizeof(err)))
+ {
+ if (where)
+ gfc_error ("Interface mismatch in dummy procedure '%s' at %L: %s",
+ formal->name, &actual->where, err);
+ return 0;
+ }
return 1;
-
- proc_fail:
- if (where)
- gfc_error ("Type/rank mismatch in argument '%s' at %L",
- formal->name, &actual->where);
- return 0;
}
if ((actual->expr_type != EXPR_NULL || actual->ts.type != BT_UNKNOWN)
@@ -2472,7 +2506,7 @@ gfc_extend_expr (gfc_expr *e)
actual->next->expr = e->value.op.op2;
}
- i = fold_unary (e->value.op.op);
+ i = fold_unary_intrinsic (e->value.op.op);
if (i == INTRINSIC_USER)
{
@@ -2591,7 +2625,7 @@ gfc_extend_assign (gfc_code *c, gfc_namespace *ns)
gfc_expr *lhs, *rhs;
gfc_symbol *sym;
- lhs = c->expr;
+ lhs = c->expr1;
rhs = c->expr2;
/* Don't allow an intrinsic assignment to be replaced. */
@@ -2626,7 +2660,7 @@ gfc_extend_assign (gfc_code *c, gfc_namespace *ns)
/* Replace the assignment with the call. */
c->op = EXEC_ASSIGN_CALL;
c->symtree = gfc_find_sym_in_symtree (sym);
- c->expr = NULL;
+ c->expr1 = NULL;
c->expr2 = NULL;
c->ext.actual = actual;
diff --git a/gcc/fortran/intrinsic.c b/gcc/fortran/intrinsic.c
index ca125a36335..7bb10ec245b 100644
--- a/gcc/fortran/intrinsic.c
+++ b/gcc/fortran/intrinsic.c
@@ -227,11 +227,12 @@ do_check (gfc_intrinsic_sym *specific, gfc_actual_arglist *arg)
simplify pointer to simplification function
resolve pointer to resolution function
- Optional arguments come in multiples of four:
- char * name of argument
- bt type of argument
- int kind of argument
- int arg optional flag (1=optional, 0=required)
+ Optional arguments come in multiples of five:
+ char * name of argument
+ bt type of argument
+ int kind of argument
+ int arg optional flag (1=optional, 0=required)
+ sym_intent intent of argument
The sequence is terminated by a NULL name.
@@ -249,6 +250,7 @@ add_sym (const char *name, gfc_isym_id id, enum klass cl, int actual_ok, bt type
{
char buf[GFC_MAX_SYMBOL_LEN + 11]; /* 10 for '_gfortran_', 1 for '\0' */
int optional, first_flag;
+ sym_intent intent;
va_list argp;
switch (sizing)
@@ -301,6 +303,7 @@ add_sym (const char *name, gfc_isym_id id, enum klass cl, int actual_ok, bt type
type = (bt) va_arg (argp, int);
kind = va_arg (argp, int);
optional = va_arg (argp, int);
+ intent = (sym_intent) va_arg (argp, int);
if (sizing != SZ_NOTHING)
nargs++;
@@ -319,6 +322,7 @@ add_sym (const char *name, gfc_isym_id id, enum klass cl, int actual_ok, bt type
next_arg->ts.type = type;
next_arg->ts.kind = kind;
next_arg->optional = optional;
+ next_arg->intent = intent;
}
}
@@ -390,7 +394,7 @@ add_sym_1 (const char *name, gfc_isym_id id, enum klass cl, int actual_ok, bt ty
rf.f1 = resolve;
add_sym (name, id, cl, actual_ok, type, kind, standard, cf, sf, rf,
- a1, type1, kind1, optional1,
+ a1, type1, kind1, optional1, INTENT_IN,
(void *) 0);
}
@@ -414,7 +418,59 @@ add_sym_1s (const char *name, gfc_isym_id id, enum klass cl, bt type, int kind,
rf.s1 = resolve;
add_sym (name, id, cl, ACTUAL_NO, type, kind, standard, cf, sf, rf,
- a1, type1, kind1, optional1,
+ a1, type1, kind1, optional1, INTENT_IN,
+ (void *) 0);
+}
+
+
+/* Add a symbol to the function list where the function takes
+ 1 arguments, specifying the intent of the argument. */
+
+static void
+add_sym_1_intent (const char *name, gfc_isym_id id, enum klass cl,
+ int actual_ok, bt type, int kind, int standard,
+ gfc_try (*check) (gfc_expr *),
+ gfc_expr *(*simplify) (gfc_expr *),
+ void (*resolve) (gfc_expr *, gfc_expr *),
+ const char *a1, bt type1, int kind1, int optional1,
+ sym_intent intent1)
+{
+ gfc_check_f cf;
+ gfc_simplify_f sf;
+ gfc_resolve_f rf;
+
+ cf.f1 = check;
+ sf.f1 = simplify;
+ rf.f1 = resolve;
+
+ add_sym (name, id, cl, actual_ok, type, kind, standard, cf, sf, rf,
+ a1, type1, kind1, optional1, intent1,
+ (void *) 0);
+}
+
+
+/* Add a symbol to the subroutine list where the subroutine takes
+ 1 arguments, specifying the intent of the argument. */
+
+static void
+add_sym_1s_intent (const char *name, gfc_isym_id id, enum klass cl, bt type,
+ int kind, int standard,
+ gfc_try (*check) (gfc_expr *),
+ gfc_expr *(*simplify) (gfc_expr *),
+ void (*resolve) (gfc_code *),
+ const char *a1, bt type1, int kind1, int optional1,
+ sym_intent intent1)
+{
+ gfc_check_f cf;
+ gfc_simplify_f sf;
+ gfc_resolve_f rf;
+
+ cf.f1 = check;
+ sf.f1 = simplify;
+ rf.s1 = resolve;
+
+ add_sym (name, id, cl, ACTUAL_NO, type, kind, standard, cf, sf, rf,
+ a1, type1, kind1, optional1, intent1,
(void *) 0);
}
@@ -440,8 +496,8 @@ add_sym_1m (const char *name, gfc_isym_id id, enum klass cl, int actual_ok, bt t
rf.f1m = resolve;
add_sym (name, id, cl, actual_ok, type, kind, standard, cf, sf, rf,
- a1, type1, kind1, optional1,
- a2, type2, kind2, optional2,
+ a1, type1, kind1, optional1, INTENT_IN,
+ a2, type2, kind2, optional2, INTENT_IN,
(void *) 0);
}
@@ -467,8 +523,8 @@ add_sym_2 (const char *name, gfc_isym_id id, enum klass cl, int actual_ok, bt ty
rf.f2 = resolve;
add_sym (name, id, cl, actual_ok, type, kind, standard, cf, sf, rf,
- a1, type1, kind1, optional1,
- a2, type2, kind2, optional2,
+ a1, type1, kind1, optional1, INTENT_IN,
+ a2, type2, kind2, optional2, INTENT_IN,
(void *) 0);
}
@@ -493,8 +549,36 @@ add_sym_2s (const char *name, gfc_isym_id id, enum klass cl, bt type, int kind,
rf.s1 = resolve;
add_sym (name, id, cl, ACTUAL_NO, type, kind, standard, cf, sf, rf,
- a1, type1, kind1, optional1,
- a2, type2, kind2, optional2,
+ a1, type1, kind1, optional1, INTENT_IN,
+ a2, type2, kind2, optional2, INTENT_IN,
+ (void *) 0);
+}
+
+
+/* Add a symbol to the subroutine list where the subroutine takes
+ 2 arguments, specifying the intent of the arguments. */
+
+static void
+add_sym_2s_intent (const char *name, gfc_isym_id id, enum klass cl, bt type,
+ int kind, int standard,
+ gfc_try (*check) (gfc_expr *, gfc_expr *),
+ gfc_expr *(*simplify) (gfc_expr *, gfc_expr *),
+ void (*resolve) (gfc_code *),
+ const char *a1, bt type1, int kind1, int optional1,
+ sym_intent intent1, const char *a2, bt type2, int kind2,
+ int optional2, sym_intent intent2)
+{
+ gfc_check_f cf;
+ gfc_simplify_f sf;
+ gfc_resolve_f rf;
+
+ cf.f2 = check;
+ sf.f2 = simplify;
+ rf.s1 = resolve;
+
+ add_sym (name, id, cl, ACTUAL_NO, type, kind, standard, cf, sf, rf,
+ a1, type1, kind1, optional1, intent1,
+ a2, type2, kind2, optional2, intent2,
(void *) 0);
}
@@ -521,9 +605,9 @@ add_sym_3 (const char *name, gfc_isym_id id, enum klass cl, int actual_ok, bt ty
rf.f3 = resolve;
add_sym (name, id, cl, actual_ok, type, kind, standard, cf, sf, rf,
- a1, type1, kind1, optional1,
- a2, type2, kind2, optional2,
- a3, type3, kind3, optional3,
+ a1, type1, kind1, optional1, INTENT_IN,
+ a2, type2, kind2, optional2, INTENT_IN,
+ a3, type3, kind3, optional3, INTENT_IN,
(void *) 0);
}
@@ -550,9 +634,9 @@ add_sym_3ml (const char *name, gfc_isym_id id, enum klass cl, int actual_ok, bt
rf.f3 = resolve;
add_sym (name, id, cl, actual_ok, type, kind, standard, cf, sf, rf,
- a1, type1, kind1, optional1,
- a2, type2, kind2, optional2,
- a3, type3, kind3, optional3,
+ a1, type1, kind1, optional1, INTENT_IN,
+ a2, type2, kind2, optional2, INTENT_IN,
+ a3, type3, kind3, optional3, INTENT_IN,
(void *) 0);
}
@@ -579,9 +663,9 @@ add_sym_3red (const char *name, gfc_isym_id id, enum klass cl, int actual_ok, bt
rf.f3 = resolve;
add_sym (name, id, cl, actual_ok, type, kind, standard, cf, sf, rf,
- a1, type1, kind1, optional1,
- a2, type2, kind2, optional2,
- a3, type3, kind3, optional3,
+ a1, type1, kind1, optional1, INTENT_IN,
+ a2, type2, kind2, optional2, INTENT_IN,
+ a3, type3, kind3, optional3, INTENT_IN,
(void *) 0);
}
@@ -607,9 +691,39 @@ add_sym_3s (const char *name, gfc_isym_id id, enum klass cl, bt type, int kind,
rf.s1 = resolve;
add_sym (name, id, cl, ACTUAL_NO, type, kind, standard, cf, sf, rf,
- a1, type1, kind1, optional1,
- a2, type2, kind2, optional2,
- a3, type3, kind3, optional3,
+ a1, type1, kind1, optional1, INTENT_IN,
+ a2, type2, kind2, optional2, INTENT_IN,
+ a3, type3, kind3, optional3, INTENT_IN,
+ (void *) 0);
+}
+
+
+/* Add a symbol to the subroutine list where the subroutine takes
+ 3 arguments, specifying the intent of the arguments. */
+
+static void
+add_sym_3s_intent (const char *name, gfc_isym_id id, enum klass cl, bt type,
+ int kind, int standard,
+ gfc_try (*check) (gfc_expr *, gfc_expr *, gfc_expr *),
+ gfc_expr *(*simplify) (gfc_expr *, gfc_expr *, gfc_expr *),
+ void (*resolve) (gfc_code *),
+ const char *a1, bt type1, int kind1, int optional1,
+ sym_intent intent1, const char *a2, bt type2, int kind2,
+ int optional2, sym_intent intent2, const char *a3, bt type3,
+ int kind3, int optional3, sym_intent intent3)
+{
+ gfc_check_f cf;
+ gfc_simplify_f sf;
+ gfc_resolve_f rf;
+
+ cf.f3 = check;
+ sf.f3 = simplify;
+ rf.s1 = resolve;
+
+ add_sym (name, id, cl, ACTUAL_NO, type, kind, standard, cf, sf, rf,
+ a1, type1, kind1, optional1, intent1,
+ a2, type2, kind2, optional2, intent2,
+ a3, type3, kind3, optional3, intent3,
(void *) 0);
}
@@ -639,10 +753,10 @@ add_sym_4 (const char *name, gfc_isym_id id, enum klass cl, int actual_ok, bt ty
rf.f4 = resolve;
add_sym (name, id, cl, actual_ok, type, kind, standard, cf, sf, rf,
- a1, type1, kind1, optional1,
- a2, type2, kind2, optional2,
- a3, type3, kind3, optional3,
- a4, type4, kind4, optional4,
+ a1, type1, kind1, optional1, INTENT_IN,
+ a2, type2, kind2, optional2, INTENT_IN,
+ a3, type3, kind3, optional3, INTENT_IN,
+ a4, type4, kind4, optional4, INTENT_IN,
(void *) 0);
}
@@ -651,15 +765,17 @@ add_sym_4 (const char *name, gfc_isym_id id, enum klass cl, int actual_ok, bt ty
4 arguments. */
static void
-add_sym_4s (const char *name, gfc_isym_id id, enum klass cl, bt type, int kind, int standard,
+add_sym_4s (const char *name, gfc_isym_id id, enum klass cl, bt type, int kind,
+ int standard,
gfc_try (*check) (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *),
gfc_expr *(*simplify) (gfc_expr *, gfc_expr *, gfc_expr *,
gfc_expr *),
void (*resolve) (gfc_code *),
const char *a1, bt type1, int kind1, int optional1,
- const char *a2, bt type2, int kind2, int optional2,
- const char *a3, bt type3, int kind3, int optional3,
- const char *a4, bt type4, int kind4, int optional4)
+ sym_intent intent1, const char *a2, bt type2, int kind2,
+ int optional2, sym_intent intent2, const char *a3, bt type3,
+ int kind3, int optional3, sym_intent intent3, const char *a4,
+ bt type4, int kind4, int optional4, sym_intent intent4)
{
gfc_check_f cf;
gfc_simplify_f sf;
@@ -670,10 +786,10 @@ add_sym_4s (const char *name, gfc_isym_id id, enum klass cl, bt type, int kind,
rf.s1 = resolve;
add_sym (name, id, cl, ACTUAL_NO, type, kind, standard, cf, sf, rf,
- a1, type1, kind1, optional1,
- a2, type2, kind2, optional2,
- a3, type3, kind3, optional3,
- a4, type4, kind4, optional4,
+ a1, type1, kind1, optional1, intent1,
+ a2, type2, kind2, optional2, intent2,
+ a3, type3, kind3, optional3, intent3,
+ a4, type4, kind4, optional4, intent4,
(void *) 0);
}
@@ -682,17 +798,20 @@ add_sym_4s (const char *name, gfc_isym_id id, enum klass cl, bt type, int kind,
5 arguments. */
static void
-add_sym_5s (const char *name, gfc_isym_id id, enum klass cl, bt type, int kind, int standard,
+add_sym_5s (const char *name, gfc_isym_id id, enum klass cl, bt type, int kind,
+ int standard,
gfc_try (*check) (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *,
gfc_expr *),
gfc_expr *(*simplify) (gfc_expr *, gfc_expr *, gfc_expr *,
gfc_expr *, gfc_expr *),
void (*resolve) (gfc_code *),
const char *a1, bt type1, int kind1, int optional1,
- const char *a2, bt type2, int kind2, int optional2,
- const char *a3, bt type3, int kind3, int optional3,
- const char *a4, bt type4, int kind4, int optional4,
- const char *a5, bt type5, int kind5, int optional5)
+ sym_intent intent1, const char *a2, bt type2, int kind2,
+ int optional2, sym_intent intent2, const char *a3, bt type3,
+ int kind3, int optional3, sym_intent intent3, const char *a4,
+ bt type4, int kind4, int optional4, sym_intent intent4,
+ const char *a5, bt type5, int kind5, int optional5,
+ sym_intent intent5)
{
gfc_check_f cf;
gfc_simplify_f sf;
@@ -703,11 +822,11 @@ add_sym_5s (const char *name, gfc_isym_id id, enum klass cl, bt type, int kind,
rf.s1 = resolve;
add_sym (name, id, cl, ACTUAL_NO, type, kind, standard, cf, sf, rf,
- a1, type1, kind1, optional1,
- a2, type2, kind2, optional2,
- a3, type3, kind3, optional3,
- a4, type4, kind4, optional4,
- a5, type5, kind5, optional5,
+ a1, type1, kind1, optional1, intent1,
+ a2, type2, kind2, optional2, intent2,
+ a3, type3, kind3, optional3, intent3,
+ a4, type4, kind4, optional4, intent4,
+ a5, type5, kind5, optional5, intent5,
(void *) 0);
}
@@ -962,7 +1081,8 @@ add_functions (void)
*x = "x", *sh = "shift", *stg = "string", *ssg = "substring",
*y = "y", *sz = "size", *sta = "string_a", *stb = "string_b",
*z = "z", *ln = "len", *ut = "unit", *han = "handler",
- *num = "number", *tm = "time", *nm = "name", *md = "mode";
+ *num = "number", *tm = "time", *nm = "name", *md = "mode",
+ *vl = "values", *p1 = "path1", *p2 = "path2", *com = "command";
int di, dr, dd, dl, dc, dz, ii;
@@ -1069,7 +1189,7 @@ add_functions (void)
make_generic ("aint", GFC_ISYM_AINT, GFC_STD_F77);
add_sym_2 ("all", GFC_ISYM_ALL, CLASS_TRANSFORMATIONAL, ACTUAL_NO, BT_LOGICAL, dl, GFC_STD_F95,
- gfc_check_all_any, NULL, gfc_resolve_all,
+ gfc_check_all_any, gfc_simplify_all, gfc_resolve_all,
msk, BT_LOGICAL, dl, REQUIRED, dm, BT_INTEGER, ii, OPTIONAL);
make_generic ("all", GFC_ISYM_ALL, GFC_STD_F95);
@@ -1091,7 +1211,7 @@ add_functions (void)
make_generic ("anint", GFC_ISYM_ANINT, GFC_STD_F77);
add_sym_2 ("any", GFC_ISYM_ANY, CLASS_TRANSFORMATIONAL, ACTUAL_NO, BT_LOGICAL, dl, GFC_STD_F95,
- gfc_check_all_any, NULL, gfc_resolve_any,
+ gfc_check_all_any, gfc_simplify_any, gfc_resolve_any,
msk, BT_LOGICAL, dl, REQUIRED, dm, BT_INTEGER, ii, OPTIONAL);
make_generic ("any", GFC_ISYM_ANY, GFC_STD_F95);
@@ -1331,7 +1451,7 @@ add_functions (void)
add_sym_3 ("count", GFC_ISYM_COUNT, CLASS_TRANSFORMATIONAL, ACTUAL_NO,
BT_INTEGER, di, GFC_STD_F95,
- gfc_check_count, NULL, gfc_resolve_count,
+ gfc_check_count, gfc_simplify_count, gfc_resolve_count,
msk, BT_LOGICAL, dl, REQUIRED, dm, BT_INTEGER, ii, OPTIONAL,
kind, BT_INTEGER, di, OPTIONAL);
@@ -1379,7 +1499,7 @@ add_functions (void)
make_generic ("dim", GFC_ISYM_DIM, GFC_STD_F77);
add_sym_2 ("dot_product", GFC_ISYM_DOT_PRODUCT, CLASS_TRANSFORMATIONAL, ACTUAL_NO, BT_REAL, dr,
- GFC_STD_F95, gfc_check_dot_product, NULL, gfc_resolve_dot_product,
+ GFC_STD_F95, gfc_check_dot_product, gfc_simplify_dot_product, gfc_resolve_dot_product,
va, BT_REAL, dr, REQUIRED, vb, BT_REAL, dr, REQUIRED);
make_generic ("dot_product", GFC_ISYM_DOT_PRODUCT, GFC_STD_F95);
@@ -1431,8 +1551,9 @@ add_functions (void)
make_generic ("erfc", GFC_ISYM_ERFC, GFC_STD_F2008);
add_sym_1 ("erfc_scaled", GFC_ISYM_ERFC_SCALED, CLASS_ELEMENTAL, ACTUAL_NO,
- BT_REAL, dr, GFC_STD_F2008, gfc_check_fn_r, NULL,
- gfc_resolve_g77_math1, x, BT_REAL, dr, REQUIRED);
+ BT_REAL, dr, GFC_STD_F2008, gfc_check_fn_r,
+ gfc_simplify_erfc_scaled, gfc_resolve_g77_math1, x, BT_REAL,
+ dr, REQUIRED);
make_generic ("erfc_scaled", GFC_ISYM_ERFC_SCALED, GFC_STD_F2008);
@@ -1499,9 +1620,9 @@ add_functions (void)
make_generic ("fraction", GFC_ISYM_FRACTION, GFC_STD_F95);
- add_sym_2 ("fstat", GFC_ISYM_FSTAT, NO_CLASS, ACTUAL_NO, BT_INTEGER, di, GFC_STD_GNU,
- gfc_check_fstat, NULL, gfc_resolve_fstat,
- a, BT_INTEGER, di, REQUIRED, b, BT_INTEGER, di, REQUIRED);
+ add_sym_2 ("fstat", GFC_ISYM_FSTAT, NO_CLASS, ACTUAL_NO, BT_INTEGER, di,
+ GFC_STD_GNU, gfc_check_fstat, NULL, gfc_resolve_fstat,
+ ut, BT_INTEGER, di, REQUIRED, vl, BT_INTEGER, di, REQUIRED);
make_generic ("fstat", GFC_ISYM_FSTAT, GFC_STD_GNU);
@@ -1724,18 +1845,21 @@ add_functions (void)
add_sym_1 ("is_iostat_end", GFC_ISYM_IS_IOSTAT_END,
CLASS_ELEMENTAL, ACTUAL_NO, BT_LOGICAL, dl, GFC_STD_F2003,
- gfc_check_i, NULL, NULL, i, BT_INTEGER, 0, REQUIRED);
+ gfc_check_i, gfc_simplify_is_iostat_end, NULL,
+ i, BT_INTEGER, 0, REQUIRED);
make_generic ("is_iostat_end", GFC_ISYM_IS_IOSTAT_END, GFC_STD_F2003);
add_sym_1 ("is_iostat_eor", GFC_ISYM_IS_IOSTAT_EOR,
CLASS_ELEMENTAL, ACTUAL_NO, BT_LOGICAL, dl, GFC_STD_F2003,
- gfc_check_i, NULL, NULL, i, BT_INTEGER, 0, REQUIRED);
+ gfc_check_i, gfc_simplify_is_iostat_eor, NULL,
+ i, BT_INTEGER, 0, REQUIRED);
make_generic ("is_iostat_eor", GFC_ISYM_IS_IOSTAT_EOR, GFC_STD_F2003);
- add_sym_1 ("isnan", GFC_ISYM_ISNAN, CLASS_ELEMENTAL, ACTUAL_NO, BT_LOGICAL,
- dl, GFC_STD_GNU, gfc_check_isnan, NULL, NULL,
+ add_sym_1 ("isnan", GFC_ISYM_ISNAN, CLASS_ELEMENTAL, ACTUAL_NO,
+ BT_LOGICAL, dl, GFC_STD_GNU,
+ gfc_check_isnan, gfc_simplify_isnan, NULL,
x, BT_REAL, 0, REQUIRED);
make_generic ("isnan", GFC_ISYM_ISNAN, GFC_STD_GNU);
@@ -1850,9 +1974,9 @@ add_functions (void)
make_generic ("llt", GFC_ISYM_LLT, GFC_STD_F77);
- add_sym_2 ("link", GFC_ISYM_LINK, NO_CLASS, ACTUAL_NO, BT_INTEGER, di, GFC_STD_GNU,
- gfc_check_link, NULL, gfc_resolve_link,
- a, BT_CHARACTER, dc, REQUIRED, b, BT_CHARACTER, dc, REQUIRED);
+ add_sym_2 ("link", GFC_ISYM_LINK, NO_CLASS, ACTUAL_NO, BT_INTEGER, di,
+ GFC_STD_GNU, gfc_check_link, NULL, gfc_resolve_link,
+ p1, BT_CHARACTER, dc, REQUIRED, p2, BT_CHARACTER, dc, REQUIRED);
make_generic ("link", GFC_ISYM_LINK, GFC_STD_GNU);
@@ -1900,20 +2024,20 @@ add_functions (void)
make_generic ("logical", GFC_ISYM_LOGICAL, GFC_STD_F95);
- add_sym_2 ("lstat", GFC_ISYM_LSTAT, NO_CLASS, ACTUAL_NO, BT_INTEGER, di, GFC_STD_GNU,
- gfc_check_stat, NULL, gfc_resolve_lstat,
- a, BT_CHARACTER, dc, REQUIRED, b, BT_INTEGER, di, REQUIRED);
+ add_sym_2 ("lstat", GFC_ISYM_LSTAT, NO_CLASS, ACTUAL_NO, BT_INTEGER, di,
+ GFC_STD_GNU, gfc_check_stat, NULL, gfc_resolve_lstat,
+ nm, BT_CHARACTER, dc, REQUIRED, vl, BT_INTEGER, di, REQUIRED);
make_generic ("lstat", GFC_ISYM_LSTAT, GFC_STD_GNU);
- add_sym_1 ("malloc", GFC_ISYM_MALLOC, NO_CLASS, ACTUAL_NO, BT_INTEGER, ii, GFC_STD_GNU,
- gfc_check_malloc, NULL, gfc_resolve_malloc, a, BT_INTEGER, di,
- REQUIRED);
+ add_sym_1 ("malloc", GFC_ISYM_MALLOC, NO_CLASS, ACTUAL_NO, BT_INTEGER, ii,
+ GFC_STD_GNU, gfc_check_malloc, NULL, gfc_resolve_malloc,
+ sz, BT_INTEGER, di, REQUIRED);
make_generic ("malloc", GFC_ISYM_MALLOC, GFC_STD_GNU);
add_sym_2 ("matmul", GFC_ISYM_MATMUL, CLASS_TRANSFORMATIONAL, ACTUAL_NO, BT_REAL, dr, GFC_STD_F95,
- gfc_check_matmul, NULL, gfc_resolve_matmul,
+ gfc_check_matmul, gfc_simplify_matmul, gfc_resolve_matmul,
ma, BT_REAL, dr, REQUIRED, mb, BT_REAL, dr, REQUIRED);
make_generic ("matmul", GFC_ISYM_MATMUL, GFC_STD_F95);
@@ -1967,13 +2091,13 @@ add_functions (void)
make_generic ("maxval", GFC_ISYM_MAXVAL, GFC_STD_F95);
- add_sym_0 ("mclock", GFC_ISYM_MCLOCK, NO_CLASS, ACTUAL_NO, BT_INTEGER, di, GFC_STD_GNU,
- NULL, NULL, gfc_resolve_mclock);
+ add_sym_0 ("mclock", GFC_ISYM_MCLOCK, NO_CLASS, ACTUAL_NO, BT_INTEGER, di,
+ GFC_STD_GNU, NULL, NULL, gfc_resolve_mclock);
make_generic ("mclock", GFC_ISYM_MCLOCK, GFC_STD_GNU);
- add_sym_0 ("mclock8", GFC_ISYM_MCLOCK8, NO_CLASS, ACTUAL_NO, BT_INTEGER, di, GFC_STD_GNU,
- NULL, NULL, gfc_resolve_mclock8);
+ add_sym_0 ("mclock8", GFC_ISYM_MCLOCK8, NO_CLASS, ACTUAL_NO, BT_INTEGER, di,
+ GFC_STD_GNU, NULL, NULL, gfc_resolve_mclock8);
make_generic ("mclock8", GFC_ISYM_MCLOCK8, GFC_STD_GNU);
@@ -2088,7 +2212,7 @@ add_functions (void)
make_generic ("null", GFC_ISYM_NULL, GFC_STD_F95);
add_sym_3 ("pack", GFC_ISYM_PACK, CLASS_TRANSFORMATIONAL, ACTUAL_NO, BT_REAL, dr, GFC_STD_F95,
- gfc_check_pack, NULL, gfc_resolve_pack,
+ gfc_check_pack, gfc_simplify_pack, gfc_resolve_pack,
ar, BT_REAL, dr, REQUIRED, msk, BT_LOGICAL, dl, REQUIRED,
v, BT_REAL, dr, OPTIONAL);
@@ -2100,14 +2224,14 @@ add_functions (void)
make_generic ("precision", GFC_ISYM_PRECISION, GFC_STD_F95);
- add_sym_1 ("present", GFC_ISYM_PRESENT, CLASS_INQUIRY, ACTUAL_NO, BT_LOGICAL, dl, GFC_STD_F95,
- gfc_check_present, NULL, NULL,
- a, BT_REAL, dr, REQUIRED);
+ add_sym_1_intent ("present", GFC_ISYM_PRESENT, CLASS_INQUIRY, ACTUAL_NO,
+ BT_LOGICAL, dl, GFC_STD_F95, gfc_check_present, NULL, NULL,
+ a, BT_REAL, dr, REQUIRED, INTENT_UNKNOWN);
make_generic ("present", GFC_ISYM_PRESENT, GFC_STD_F95);
add_sym_3red ("product", GFC_ISYM_PRODUCT, CLASS_TRANSFORMATIONAL, ACTUAL_NO, BT_REAL, dr, GFC_STD_F95,
- gfc_check_product_sum, NULL, gfc_resolve_product,
+ gfc_check_product_sum, gfc_simplify_product, gfc_resolve_product,
ar, BT_REAL, dr, REQUIRED, dm, BT_INTEGER, ii, OPTIONAL,
msk, BT_LOGICAL, dl, OPTIONAL);
@@ -2155,9 +2279,9 @@ add_functions (void)
make_generic ("real", GFC_ISYM_REAL, GFC_STD_F77);
- add_sym_2 ("rename", GFC_ISYM_RENAME, NO_CLASS, ACTUAL_NO, BT_INTEGER, di, GFC_STD_GNU,
- gfc_check_rename, NULL, gfc_resolve_rename,
- a, BT_CHARACTER, dc, REQUIRED, b, BT_CHARACTER, dc, REQUIRED);
+ add_sym_2 ("rename", GFC_ISYM_RENAME, NO_CLASS, ACTUAL_NO, BT_INTEGER, di,
+ GFC_STD_GNU, gfc_check_rename, NULL, gfc_resolve_rename,
+ p1, BT_CHARACTER, dc, REQUIRED, p2, BT_CHARACTER, dc, REQUIRED);
make_generic ("rename", GFC_ISYM_RENAME, GFC_STD_GNU);
@@ -2312,7 +2436,7 @@ add_functions (void)
make_generic ("spacing", GFC_ISYM_SPACING, GFC_STD_F95);
add_sym_3 ("spread", GFC_ISYM_SPREAD, CLASS_TRANSFORMATIONAL, ACTUAL_NO, BT_REAL, dr, GFC_STD_F95,
- gfc_check_spread, NULL, gfc_resolve_spread,
+ gfc_check_spread, gfc_simplify_spread, gfc_resolve_spread,
src, BT_REAL, dr, REQUIRED, dm, BT_INTEGER, ii, REQUIRED,
ncopies, BT_INTEGER, di, REQUIRED);
@@ -2338,28 +2462,28 @@ add_functions (void)
make_generic ("sqrt", GFC_ISYM_SQRT, GFC_STD_F77);
- add_sym_2 ("stat", GFC_ISYM_STAT, NO_CLASS, ACTUAL_NO, BT_INTEGER, di, GFC_STD_GNU,
- gfc_check_stat, NULL, gfc_resolve_stat,
- a, BT_CHARACTER, dc, REQUIRED, b, BT_INTEGER, di, REQUIRED);
+ add_sym_2 ("stat", GFC_ISYM_STAT, NO_CLASS, ACTUAL_NO, BT_INTEGER, di,
+ GFC_STD_GNU, gfc_check_stat, NULL, gfc_resolve_stat,
+ nm, BT_CHARACTER, dc, REQUIRED, vl, BT_INTEGER, di, REQUIRED);
make_generic ("stat", GFC_ISYM_STAT, GFC_STD_GNU);
add_sym_3red ("sum", GFC_ISYM_SUM, CLASS_TRANSFORMATIONAL, ACTUAL_NO, BT_REAL, dr, GFC_STD_F95,
- gfc_check_product_sum, NULL, gfc_resolve_sum,
+ gfc_check_product_sum, gfc_simplify_sum, gfc_resolve_sum,
ar, BT_REAL, dr, REQUIRED, dm, BT_INTEGER, ii, OPTIONAL,
msk, BT_LOGICAL, dl, OPTIONAL);
make_generic ("sum", GFC_ISYM_SUM, GFC_STD_F95);
- add_sym_2 ("symlnk", GFC_ISYM_SYMLNK, NO_CLASS, ACTUAL_NO, BT_INTEGER, di, GFC_STD_GNU,
- gfc_check_symlnk, NULL, gfc_resolve_symlnk,
- a, BT_CHARACTER, dc, REQUIRED, b, BT_CHARACTER, dc, REQUIRED);
+ add_sym_2 ("symlnk", GFC_ISYM_SYMLNK, NO_CLASS, ACTUAL_NO, BT_INTEGER, di,
+ GFC_STD_GNU, gfc_check_symlnk, NULL, gfc_resolve_symlnk,
+ p1, BT_CHARACTER, dc, REQUIRED, p2, BT_CHARACTER, dc, REQUIRED);
make_generic ("symlnk", GFC_ISYM_SYMLNK, GFC_STD_GNU);
- add_sym_1 ("system", GFC_ISYM_SYSTEM, NO_CLASS, ACTUAL_NO, BT_INTEGER, di, GFC_STD_GNU,
- NULL, NULL, NULL,
- c, BT_CHARACTER, dc, REQUIRED);
+ add_sym_1 ("system", GFC_ISYM_SYSTEM, NO_CLASS, ACTUAL_NO, BT_INTEGER, di,
+ GFC_STD_GNU, NULL, NULL, NULL,
+ com, BT_CHARACTER, dc, REQUIRED);
make_generic ("system", GFC_ISYM_SYSTEM, GFC_STD_GNU);
@@ -2414,7 +2538,7 @@ add_functions (void)
make_generic ("transfer", GFC_ISYM_TRANSFER, GFC_STD_F95);
add_sym_1 ("transpose", GFC_ISYM_TRANSPOSE, CLASS_TRANSFORMATIONAL, ACTUAL_NO, BT_REAL, dr, GFC_STD_F95,
- gfc_check_transpose, NULL, gfc_resolve_transpose,
+ gfc_check_transpose, gfc_simplify_transpose, gfc_resolve_transpose,
m, BT_REAL, dr, REQUIRED);
make_generic ("transpose", GFC_ISYM_TRANSPOSE, GFC_STD_F95);
@@ -2440,21 +2564,21 @@ add_functions (void)
make_generic ("ubound", GFC_ISYM_UBOUND, GFC_STD_F95);
/* g77 compatibility for UMASK. */
- add_sym_1 ("umask", GFC_ISYM_UMASK, NO_CLASS, ACTUAL_NO, BT_INTEGER, di, GFC_STD_GNU,
- gfc_check_umask, NULL, gfc_resolve_umask,
- a, BT_INTEGER, di, REQUIRED);
+ add_sym_1 ("umask", GFC_ISYM_UMASK, NO_CLASS, ACTUAL_NO, BT_INTEGER, di,
+ GFC_STD_GNU, gfc_check_umask, NULL, gfc_resolve_umask,
+ msk, BT_INTEGER, di, REQUIRED);
make_generic ("umask", GFC_ISYM_UMASK, GFC_STD_GNU);
/* g77 compatibility for UNLINK. */
add_sym_1 ("unlink", GFC_ISYM_UNLINK, NO_CLASS, ACTUAL_NO, BT_INTEGER, di, GFC_STD_GNU,
gfc_check_unlink, NULL, gfc_resolve_unlink,
- a, BT_CHARACTER, dc, REQUIRED);
+ "path", BT_CHARACTER, dc, REQUIRED);
make_generic ("unlink", GFC_ISYM_UNLINK, GFC_STD_GNU);
add_sym_3 ("unpack", GFC_ISYM_UNPACK, CLASS_TRANSFORMATIONAL, ACTUAL_NO, BT_REAL, dr, GFC_STD_F95,
- gfc_check_unpack, NULL, gfc_resolve_unpack,
+ gfc_check_unpack, gfc_simplify_unpack, gfc_resolve_unpack,
v, BT_REAL, dr, REQUIRED, msk, BT_LOGICAL, dl, REQUIRED,
f, BT_REAL, dr, REQUIRED);
@@ -2468,9 +2592,9 @@ add_functions (void)
make_generic ("verify", GFC_ISYM_VERIFY, GFC_STD_F95);
- add_sym_1 ("loc", GFC_ISYM_LOC, NO_CLASS, ACTUAL_NO, BT_INTEGER, ii, GFC_STD_GNU,
- gfc_check_loc, NULL, gfc_resolve_loc,
- ar, BT_UNKNOWN, 0, REQUIRED);
+ add_sym_1 ("loc", GFC_ISYM_LOC, NO_CLASS, ACTUAL_NO, BT_INTEGER, ii,
+ GFC_STD_GNU, gfc_check_loc, NULL, gfc_resolve_loc,
+ x, BT_UNKNOWN, 0, REQUIRED);
make_generic ("loc", GFC_ISYM_LOC, GFC_STD_GNU);
}
@@ -2491,7 +2615,8 @@ add_subroutines (void)
*val = "value", *num = "number", *name = "name",
*trim_name = "trim_name", *ut = "unit", *han = "handler",
*sec = "seconds", *res = "result", *of = "offset", *md = "mode",
- *whence = "whence", *pos = "pos";
+ *whence = "whence", *pos = "pos", *ptr = "ptr", *p1 = "path1",
+ *p2 = "path2", *msk = "mask", *old = "old";
int di, dr, dc, dl, ii;
@@ -2505,9 +2630,10 @@ add_subroutines (void)
make_noreturn();
- add_sym_1s ("cpu_time", GFC_ISYM_CPU_TIME, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_F95,
- gfc_check_cpu_time, NULL, gfc_resolve_cpu_time,
- tm, BT_REAL, dr, REQUIRED);
+ add_sym_1s_intent ("cpu_time", GFC_ISYM_CPU_TIME, NO_CLASS, BT_UNKNOWN, 0,
+ GFC_STD_F95, gfc_check_cpu_time, NULL,
+ gfc_resolve_cpu_time,
+ tm, BT_REAL, dr, REQUIRED, INTENT_OUT);
/* More G77 compatibility garbage. */
add_sym_2s ("ctime", GFC_ISYM_CTIME, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
@@ -2543,10 +2669,12 @@ add_subroutines (void)
name, BT_CHARACTER, dc, REQUIRED, md, BT_CHARACTER, dc, REQUIRED,
st, BT_INTEGER, di, OPTIONAL);
- add_sym_4s ("date_and_time", GFC_ISYM_DATE_AND_TIME, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_F95,
- gfc_check_date_and_time, NULL, NULL,
- dt, BT_CHARACTER, dc, OPTIONAL, tm, BT_CHARACTER, dc, OPTIONAL,
- zn, BT_CHARACTER, dc, OPTIONAL, vl, BT_INTEGER, di, OPTIONAL);
+ add_sym_4s ("date_and_time", GFC_ISYM_DATE_AND_TIME, NO_CLASS, BT_UNKNOWN, 0,
+ GFC_STD_F95, gfc_check_date_and_time, NULL, NULL,
+ dt, BT_CHARACTER, dc, OPTIONAL, INTENT_OUT,
+ tm, BT_CHARACTER, dc, OPTIONAL, INTENT_OUT,
+ zn, BT_CHARACTER, dc, OPTIONAL, INTENT_OUT,
+ vl, BT_INTEGER, di, OPTIONAL, INTENT_OUT);
/* More G77 compatibility garbage. */
add_sym_2s ("etime", GFC_ISYM_ETIME, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
@@ -2584,46 +2712,56 @@ add_subroutines (void)
/* F2003 commandline routines. */
- add_sym_3s ("get_command", GFC_ISYM_GET_COMMAND, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_F2003,
- NULL, NULL, gfc_resolve_get_command,
- com, BT_CHARACTER, dc, OPTIONAL,
- length, BT_INTEGER, di, OPTIONAL,
- st, BT_INTEGER, di, OPTIONAL);
+ add_sym_3s_intent ("get_command", GFC_ISYM_GET_COMMAND, NO_CLASS, BT_UNKNOWN,
+ 0, GFC_STD_F2003, NULL, NULL, gfc_resolve_get_command,
+ com, BT_CHARACTER, dc, OPTIONAL, INTENT_OUT,
+ length, BT_INTEGER, di, OPTIONAL, INTENT_OUT,
+ st, BT_INTEGER, di, OPTIONAL, INTENT_OUT);
- add_sym_4s ("get_command_argument", GFC_ISYM_GET_COMMAND_ARGUMENT, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_F2003,
- NULL, NULL, gfc_resolve_get_command_argument,
- num, BT_INTEGER, di, REQUIRED, val, BT_CHARACTER, dc, OPTIONAL,
- length, BT_INTEGER, di, OPTIONAL, st, BT_INTEGER, di, OPTIONAL);
+ add_sym_4s ("get_command_argument", GFC_ISYM_GET_COMMAND_ARGUMENT, NO_CLASS,
+ BT_UNKNOWN, 0, GFC_STD_F2003, NULL, NULL,
+ gfc_resolve_get_command_argument,
+ num, BT_INTEGER, di, REQUIRED, INTENT_IN,
+ val, BT_CHARACTER, dc, OPTIONAL, INTENT_OUT,
+ length, BT_INTEGER, di, OPTIONAL, INTENT_OUT,
+ st, BT_INTEGER, di, OPTIONAL, INTENT_OUT);
/* F2003 subroutine to get environment variables. */
- add_sym_5s ("get_environment_variable", GFC_ISYM_GET_ENVIRONMENT_VARIABLE, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_F2003,
+ add_sym_5s ("get_environment_variable", GFC_ISYM_GET_ENVIRONMENT_VARIABLE,
+ NO_CLASS, BT_UNKNOWN, 0, GFC_STD_F2003,
NULL, NULL, gfc_resolve_get_environment_variable,
- name, BT_CHARACTER, dc, REQUIRED,
- val, BT_CHARACTER, dc, OPTIONAL,
- length, BT_INTEGER, di, OPTIONAL, st, BT_INTEGER, di, OPTIONAL,
- trim_name, BT_LOGICAL, dl, OPTIONAL);
-
- add_sym_2s ("move_alloc", GFC_ISYM_MOVE_ALLOC, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_F2003,
- gfc_check_move_alloc, NULL, NULL,
- f, BT_UNKNOWN, 0, REQUIRED,
- t, BT_UNKNOWN, 0, REQUIRED);
-
- add_sym_5s ("mvbits", GFC_ISYM_MVBITS, CLASS_ELEMENTAL, BT_UNKNOWN, 0, GFC_STD_F95,
- gfc_check_mvbits, gfc_simplify_mvbits, gfc_resolve_mvbits,
- f, BT_INTEGER, di, REQUIRED, fp, BT_INTEGER, di, REQUIRED,
- ln, BT_INTEGER, di, REQUIRED, t, BT_INTEGER, di, REQUIRED,
- tp, BT_INTEGER, di, REQUIRED);
-
- add_sym_1s ("random_number", GFC_ISYM_RANDOM_NUMBER, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_F95,
- gfc_check_random_number, NULL, gfc_resolve_random_number,
- h, BT_REAL, dr, REQUIRED);
-
- add_sym_3s ("random_seed", GFC_ISYM_RANDOM_SEED, NO_CLASS,
- BT_UNKNOWN, 0, GFC_STD_F95,
- gfc_check_random_seed, NULL, gfc_resolve_random_seed,
- sz, BT_INTEGER, di, OPTIONAL, pt, BT_INTEGER, di, OPTIONAL,
- gt, BT_INTEGER, di, OPTIONAL);
+ name, BT_CHARACTER, dc, REQUIRED, INTENT_IN,
+ val, BT_CHARACTER, dc, OPTIONAL, INTENT_OUT,
+ length, BT_INTEGER, di, OPTIONAL, INTENT_OUT,
+ st, BT_INTEGER, di, OPTIONAL, INTENT_OUT,
+ trim_name, BT_LOGICAL, dl, OPTIONAL, INTENT_IN);
+
+ add_sym_2s_intent ("move_alloc", GFC_ISYM_MOVE_ALLOC, NO_CLASS, BT_UNKNOWN, 0,
+ GFC_STD_F2003, gfc_check_move_alloc, NULL, NULL,
+ f, BT_UNKNOWN, 0, REQUIRED, INTENT_INOUT,
+ t, BT_UNKNOWN, 0, REQUIRED, INTENT_OUT);
+
+ add_sym_5s ("mvbits", GFC_ISYM_MVBITS, CLASS_ELEMENTAL, BT_UNKNOWN, 0,
+ GFC_STD_F95, gfc_check_mvbits, gfc_simplify_mvbits,
+ gfc_resolve_mvbits,
+ f, BT_INTEGER, di, REQUIRED, INTENT_IN,
+ fp, BT_INTEGER, di, REQUIRED, INTENT_IN,
+ ln, BT_INTEGER, di, REQUIRED, INTENT_IN,
+ t, BT_INTEGER, di, REQUIRED, INTENT_INOUT,
+ tp, BT_INTEGER, di, REQUIRED, INTENT_IN);
+
+ add_sym_1s_intent ("random_number", GFC_ISYM_RANDOM_NUMBER, NO_CLASS,
+ BT_UNKNOWN, 0, GFC_STD_F95, gfc_check_random_number, NULL,
+ gfc_resolve_random_number,
+ h, BT_REAL, dr, REQUIRED, INTENT_OUT);
+
+ add_sym_3s_intent ("random_seed", GFC_ISYM_RANDOM_SEED, NO_CLASS,
+ BT_UNKNOWN, 0, GFC_STD_F95,
+ gfc_check_random_seed, NULL, gfc_resolve_random_seed,
+ sz, BT_INTEGER, di, OPTIONAL, INTENT_OUT,
+ pt, BT_INTEGER, di, OPTIONAL, INTENT_IN,
+ gt, BT_INTEGER, di, OPTIONAL, INTENT_OUT);
/* More G77 compatibility garbage. */
add_sym_3s ("alarm", GFC_ISYM_ALARM, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
@@ -2633,7 +2771,7 @@ add_subroutines (void)
add_sym_1s ("srand", GFC_ISYM_SRAND, NO_CLASS, BT_UNKNOWN, di, GFC_STD_GNU,
gfc_check_srand, NULL, gfc_resolve_srand,
- c, BT_INTEGER, 4, REQUIRED);
+ "seed", BT_INTEGER, 4, REQUIRED);
add_sym_1s ("exit", GFC_ISYM_EXIT, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
gfc_check_exit, NULL, gfc_resolve_exit,
@@ -2663,13 +2801,16 @@ add_subroutines (void)
gfc_check_fgetput_sub, NULL, gfc_resolve_fput_sub,
c, BT_CHARACTER, dc, REQUIRED, st, BT_INTEGER, di, OPTIONAL);
- add_sym_1s ("free", GFC_ISYM_FREE, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU, gfc_check_free,
- NULL, gfc_resolve_free, c, BT_INTEGER, ii, REQUIRED);
+ add_sym_1s ("free", GFC_ISYM_FREE, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
+ gfc_check_free, NULL, gfc_resolve_free,
+ ptr, BT_INTEGER, ii, REQUIRED);
add_sym_4s ("fseek", GFC_ISYM_FSEEK, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
gfc_check_fseek_sub, NULL, gfc_resolve_fseek_sub,
- ut, BT_INTEGER, di, REQUIRED, of, BT_INTEGER, di, REQUIRED,
- whence, BT_INTEGER, di, REQUIRED, st, BT_INTEGER, di, OPTIONAL);
+ ut, BT_INTEGER, di, REQUIRED, INTENT_IN,
+ of, BT_INTEGER, di, REQUIRED, INTENT_IN,
+ whence, BT_INTEGER, di, REQUIRED, INTENT_IN,
+ st, BT_INTEGER, di, OPTIONAL, INTENT_OUT);
add_sym_2s ("ftell", GFC_ISYM_FTELL, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
gfc_check_ftell_sub, NULL, gfc_resolve_ftell_sub,
@@ -2685,21 +2826,21 @@ add_subroutines (void)
add_sym_3s ("link", GFC_ISYM_LINK, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
gfc_check_link_sub, NULL, gfc_resolve_link_sub,
- name, BT_CHARACTER, dc, REQUIRED, val, BT_CHARACTER,
+ p1, BT_CHARACTER, dc, REQUIRED, p2, BT_CHARACTER,
dc, REQUIRED, st, BT_INTEGER, di, OPTIONAL);
add_sym_1s ("perror", GFC_ISYM_PERROR, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
gfc_check_perror, NULL, gfc_resolve_perror,
- c, BT_CHARACTER, dc, REQUIRED);
+ "string", BT_CHARACTER, dc, REQUIRED);
add_sym_3s ("rename", GFC_ISYM_RENAME, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
gfc_check_rename_sub, NULL, gfc_resolve_rename_sub,
- name, BT_CHARACTER, dc, REQUIRED, val, BT_CHARACTER,
+ p1, BT_CHARACTER, dc, REQUIRED, p2, BT_CHARACTER,
dc, REQUIRED, st, BT_INTEGER, di, OPTIONAL);
add_sym_1s ("sleep", GFC_ISYM_SLEEP, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
gfc_check_sleep_sub, NULL, gfc_resolve_sleep_sub,
- val, BT_INTEGER, di, REQUIRED);
+ sec, BT_INTEGER, di, REQUIRED);
add_sym_3s ("fstat", GFC_ISYM_FSTAT, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
gfc_check_fstat_sub, NULL, gfc_resolve_fstat_sub,
@@ -2723,17 +2864,19 @@ add_subroutines (void)
add_sym_3s ("symlnk", GFC_ISYM_SYMLINK, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
gfc_check_symlnk_sub, NULL, gfc_resolve_symlnk_sub,
- name, BT_CHARACTER, dc, REQUIRED, val, BT_CHARACTER,
+ p1, BT_CHARACTER, dc, REQUIRED, p2, BT_CHARACTER,
dc, REQUIRED, st, BT_INTEGER, di, OPTIONAL);
add_sym_2s ("system", GFC_ISYM_SYSTEM, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
NULL, NULL, gfc_resolve_system_sub,
com, BT_CHARACTER, dc, REQUIRED, st, BT_INTEGER, di, OPTIONAL);
- add_sym_3s ("system_clock", GFC_ISYM_SYSTEM_CLOCK, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_F95,
- gfc_check_system_clock, NULL, gfc_resolve_system_clock,
- c, BT_INTEGER, di, OPTIONAL, cr, BT_INTEGER, di, OPTIONAL,
- cm, BT_INTEGER, di, OPTIONAL);
+ add_sym_3s_intent ("system_clock", GFC_ISYM_SYSTEM_CLOCK, NO_CLASS,
+ BT_UNKNOWN, 0, GFC_STD_F95,
+ gfc_check_system_clock, NULL, gfc_resolve_system_clock,
+ c, BT_INTEGER, di, OPTIONAL, INTENT_OUT,
+ cr, BT_INTEGER, di, OPTIONAL, INTENT_OUT,
+ cm, BT_INTEGER, di, OPTIONAL, INTENT_OUT);
add_sym_2s ("ttynam", GFC_ISYM_TTYNAM, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
gfc_check_ttynam_sub, NULL, gfc_resolve_ttynam_sub,
@@ -2741,11 +2884,11 @@ add_subroutines (void)
add_sym_2s ("umask", GFC_ISYM_UMASK, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
gfc_check_umask_sub, NULL, gfc_resolve_umask_sub,
- val, BT_INTEGER, di, REQUIRED, num, BT_INTEGER, di, OPTIONAL);
+ msk, BT_INTEGER, di, REQUIRED, old, BT_INTEGER, di, OPTIONAL);
add_sym_2s ("unlink", GFC_ISYM_UNLINK, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
gfc_check_unlink_sub, NULL, gfc_resolve_unlink_sub,
- c, BT_CHARACTER, dc, REQUIRED, st, BT_INTEGER, di, OPTIONAL);
+ "path", BT_CHARACTER, dc, REQUIRED, st, BT_INTEGER, di, OPTIONAL);
}
@@ -3477,14 +3620,13 @@ check_specific (gfc_intrinsic_sym *specific, gfc_expr *expr, int error_flag)
first_expr = arg->expr;
for ( ; arg && arg->expr; arg = arg->next, n++)
- {
- char buffer[80];
- snprintf (buffer, 80, "arguments '%s' and '%s' for intrinsic '%s'",
- gfc_current_intrinsic_arg[0], gfc_current_intrinsic_arg[n],
- gfc_current_intrinsic);
- if (gfc_check_conformance (buffer, first_expr, arg->expr) == FAILURE)
- return FAILURE;
- }
+ if (gfc_check_conformance (first_expr, arg->expr,
+ "arguments '%s' and '%s' for "
+ "intrinsic '%s'",
+ gfc_current_intrinsic_arg[0],
+ gfc_current_intrinsic_arg[n],
+ gfc_current_intrinsic) == FAILURE)
+ return FAILURE;
}
if (t == FAILURE)
diff --git a/gcc/fortran/intrinsic.h b/gcc/fortran/intrinsic.h
index 83c5207785b..d1bf846c264 100644
--- a/gcc/fortran/intrinsic.h
+++ b/gcc/fortran/intrinsic.h
@@ -200,10 +200,12 @@ gfc_expr *gfc_simplify_adjustl (gfc_expr *);
gfc_expr *gfc_simplify_adjustr (gfc_expr *);
gfc_expr *gfc_simplify_aimag (gfc_expr *);
gfc_expr *gfc_simplify_aint (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_simplify_all (gfc_expr *, gfc_expr *);
gfc_expr *gfc_simplify_dint (gfc_expr *);
gfc_expr *gfc_simplify_anint (gfc_expr *, gfc_expr *);
gfc_expr *gfc_simplify_dnint (gfc_expr *);
gfc_expr *gfc_simplify_and (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_simplify_any (gfc_expr *, gfc_expr *);
gfc_expr *gfc_simplify_asin (gfc_expr *);
gfc_expr *gfc_simplify_asinh (gfc_expr *);
gfc_expr *gfc_simplify_atan (gfc_expr *);
@@ -224,14 +226,17 @@ gfc_expr *gfc_simplify_complex (gfc_expr *, gfc_expr *);
gfc_expr *gfc_simplify_conjg (gfc_expr *);
gfc_expr *gfc_simplify_cos (gfc_expr *);
gfc_expr *gfc_simplify_cosh (gfc_expr *);
+gfc_expr *gfc_simplify_count (gfc_expr *, gfc_expr *, gfc_expr *);
gfc_expr *gfc_simplify_dcmplx (gfc_expr *, gfc_expr *);
gfc_expr *gfc_simplify_dble (gfc_expr *);
gfc_expr *gfc_simplify_digits (gfc_expr *);
gfc_expr *gfc_simplify_dim (gfc_expr *, gfc_expr *);
gfc_expr *gfc_simplify_dprod (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_simplify_dot_product (gfc_expr *, gfc_expr *);
gfc_expr *gfc_simplify_epsilon (gfc_expr *);
gfc_expr *gfc_simplify_erf (gfc_expr *);
gfc_expr *gfc_simplify_erfc (gfc_expr *);
+gfc_expr *gfc_simplify_erfc_scaled (gfc_expr *);
gfc_expr *gfc_simplify_exp (gfc_expr *);
gfc_expr *gfc_simplify_exponent (gfc_expr *);
gfc_expr *gfc_simplify_float (gfc_expr *);
@@ -255,6 +260,9 @@ gfc_expr *gfc_simplify_long (gfc_expr *);
gfc_expr *gfc_simplify_ifix (gfc_expr *);
gfc_expr *gfc_simplify_idint (gfc_expr *);
gfc_expr *gfc_simplify_ior (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_simplify_is_iostat_end (gfc_expr *);
+gfc_expr *gfc_simplify_is_iostat_eor (gfc_expr *);
+gfc_expr *gfc_simplify_isnan (gfc_expr *);
gfc_expr *gfc_simplify_ishft (gfc_expr *, gfc_expr *);
gfc_expr *gfc_simplify_ishftc (gfc_expr *, gfc_expr *, gfc_expr *);
gfc_expr *gfc_simplify_kind (gfc_expr *);
@@ -270,6 +278,7 @@ gfc_expr *gfc_simplify_llt (gfc_expr *, gfc_expr *);
gfc_expr *gfc_simplify_log (gfc_expr *);
gfc_expr *gfc_simplify_log10 (gfc_expr *);
gfc_expr *gfc_simplify_logical (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_simplify_matmul (gfc_expr *, gfc_expr *);
gfc_expr *gfc_simplify_merge (gfc_expr *, gfc_expr *, gfc_expr *);
gfc_expr *gfc_simplify_min (gfc_expr *);
gfc_expr *gfc_simplify_minval (gfc_expr *, gfc_expr*, gfc_expr*);
@@ -288,7 +297,9 @@ gfc_expr *gfc_simplify_null (gfc_expr *);
gfc_expr *gfc_simplify_idnint (gfc_expr *);
gfc_expr *gfc_simplify_not (gfc_expr *);
gfc_expr *gfc_simplify_or (gfc_expr *, gfc_expr *);
+gfc_expr *gfc_simplify_pack (gfc_expr *, gfc_expr *, gfc_expr *);
gfc_expr *gfc_simplify_precision (gfc_expr *);
+gfc_expr *gfc_simplify_product (gfc_expr *, gfc_expr *, gfc_expr *);
gfc_expr *gfc_simplify_radix (gfc_expr *);
gfc_expr *gfc_simplify_range (gfc_expr *);
gfc_expr *gfc_simplify_real (gfc_expr *, gfc_expr *);
@@ -310,14 +321,18 @@ gfc_expr *gfc_simplify_sinh (gfc_expr *);
gfc_expr *gfc_simplify_size (gfc_expr *, gfc_expr *, gfc_expr *);
gfc_expr *gfc_simplify_sngl (gfc_expr *);
gfc_expr *gfc_simplify_spacing (gfc_expr *);
+gfc_expr *gfc_simplify_spread (gfc_expr *, gfc_expr *, gfc_expr *);
gfc_expr *gfc_simplify_sqrt (gfc_expr *);
+gfc_expr *gfc_simplify_sum (gfc_expr *, gfc_expr *, gfc_expr *);
gfc_expr *gfc_simplify_tan (gfc_expr *);
gfc_expr *gfc_simplify_tanh (gfc_expr *);
gfc_expr *gfc_simplify_tiny (gfc_expr *);
gfc_expr *gfc_simplify_trailz (gfc_expr *);
gfc_expr *gfc_simplify_transfer (gfc_expr *, gfc_expr *, gfc_expr *);
+gfc_expr *gfc_simplify_transpose (gfc_expr *);
gfc_expr *gfc_simplify_trim (gfc_expr *);
gfc_expr *gfc_simplify_ubound (gfc_expr *, gfc_expr *, gfc_expr *);
+gfc_expr *gfc_simplify_unpack (gfc_expr *, gfc_expr *, gfc_expr *);
gfc_expr *gfc_simplify_verify (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *);
gfc_expr *gfc_simplify_xor (gfc_expr *, gfc_expr *);
diff --git a/gcc/fortran/intrinsic.texi b/gcc/fortran/intrinsic.texi
index 06cdff0c828..eb0956adb22 100644
--- a/gcc/fortran/intrinsic.texi
+++ b/gcc/fortran/intrinsic.texi
@@ -167,7 +167,6 @@ Some basic guidelines for editing this document:
* @code{LEADZ}: LEADZ, Number of leading zero bits of an integer
* @code{LEN}: LEN, Length of a character entity
* @code{LEN_TRIM}: LEN_TRIM, Length of a character entity without trailing blank characters
-* @code{LOG_GAMMA}: LOG_GAMMA, Logarithm of the Gamma function
* @code{LGE}: LGE, Lexical greater than or equal
* @code{LGT}: LGT, Lexical greater than
* @code{LINK}: LINK, Create a hard link
@@ -177,6 +176,7 @@ Some basic guidelines for editing this document:
* @code{LOC}: LOC, Returns the address of a variable
* @code{LOG}: LOG, Logarithm function
* @code{LOG10}: LOG10, Base 10 logarithm function
+* @code{LOG_GAMMA}: LOG_GAMMA, Logarithm of the Gamma function
* @code{LOGICAL}: LOGICAL, Convert to logical type
* @code{LONG}: LONG, Convert to integer type
* @code{LSHIFT}: LSHIFT, Left shift bits
@@ -1435,7 +1435,7 @@ end program test_atan2
@item @emph{Specific names}:
@multitable @columnfractions .20 .20 .20 .25
@item Name @tab Argument @tab Return type @tab Standard
-@item @code{DATAN2(X)} @tab @code{REAL(8) X} @tab @code{REAL(8)} @tab Fortran 77 and later
+@item @code{DATAN2(X, Y)} @tab @code{REAL(8) X}, @code{REAL(8) Y} @tab @code{REAL(8)} @tab Fortran 77 and later
@end multitable
@end table
@@ -1634,9 +1634,9 @@ end program test_besjn
@item @emph{Specific names}:
@multitable @columnfractions .20 .20 .20 .25
-@item Name @tab Argument @tab Return type @tab Standard
-@item @code{DBESJN(X)} @tab @code{INTEGER N} @tab @code{REAL(8)} @tab GNU extension
-@item @tab @code{REAL(8) X} @tab @tab
+@item Name @tab Argument @tab Return type @tab Standard
+@item @code{DBESJN(N, X)} @tab @code{INTEGER N} @tab @code{REAL(8)} @tab GNU extension
+@item @tab @code{REAL(8) X} @tab @tab
@end multitable
@end table
@@ -2488,7 +2488,7 @@ Inquiry function
@end multitable
@item @emph{Return value}:
-The return value is of type @code{INTEGER(4)}
+The return value is an @code{INTEGER} of default kind.
@item @emph{Example}:
@smallexample
@@ -3397,11 +3397,11 @@ end program test_dreal
@table @asis
@item @emph{Description}:
-@code{DTIME(TARRAY, RESULT)} initially returns the number of seconds of runtime
-since the start of the process's execution in @var{RESULT}. @var{TARRAY}
-returns the user and system components of this time in @code{TARRAY(1)} and
-@code{TARRAY(2)} respectively. @var{RESULT} is equal to @code{TARRAY(1) +
-TARRAY(2)}.
+@code{DTIME(VALUES, TIME)} initially returns the number of seconds of runtime
+since the start of the process's execution in @var{TIME}. @var{VALUES}
+returns the user and system components of this time in @code{VALUES(1)} and
+@code{VALUES(2)} respectively. @var{TIME} is equal to @code{VALUES(1) +
+VALUES(2)}.
Subsequent invocations of @code{DTIME} return values accumulated since the
previous invocation.
@@ -3421,12 +3421,12 @@ results. If possible, use @code{CPU_TIME} instead.
This intrinsic is provided in both subroutine and function forms; however,
only one form can be used in any given program unit.
-@var{TARRAY} and @var{RESULT} are @code{INTENT(OUT)} and provide the following:
+@var{VALUES} and @var{TIME} are @code{INTENT(OUT)} and provide the following:
@multitable @columnfractions .15 .30 .40
-@item @tab @code{TARRAY(1)}: @tab User time in seconds.
-@item @tab @code{TARRAY(2)}: @tab System time in seconds.
-@item @tab @code{RESULT}: @tab Run time since start in seconds.
+@item @tab @code{VALUES(1)}: @tab User time in seconds.
+@item @tab @code{VALUES(2)}: @tab System time in seconds.
+@item @tab @code{TIME}: @tab Run time since start in seconds.
@end multitable
@item @emph{Standard}:
@@ -3437,14 +3437,14 @@ Subroutine, function
@item @emph{Syntax}:
@multitable @columnfractions .80
-@item @code{CALL DTIME(TARRAY, RESULT)}.
-@item @code{RESULT = DTIME(TARRAY)}, (not recommended).
+@item @code{CALL DTIME(VALUES, TIME)}.
+@item @code{TIME = DTIME(VALUES)}, (not recommended).
@end multitable
@item @emph{Arguments}:
@multitable @columnfractions .15 .70
-@item @var{TARRAY}@tab The type shall be @code{REAL, DIMENSION(2)}.
-@item @var{RESULT}@tab The type shall be @code{REAL}.
+@item @var{VALUES}@tab The type shall be @code{REAL, DIMENSION(2)}.
+@item @var{TIME}@tab The type shall be @code{REAL}.
@end multitable
@item @emph{Return value}:
@@ -3716,10 +3716,10 @@ end program test_erfc_scaled
@table @asis
@item @emph{Description}:
-@code{ETIME(TARRAY, RESULT)} returns the number of seconds of runtime
-since the start of the process's execution in @var{RESULT}. @var{TARRAY}
-returns the user and system components of this time in @code{TARRAY(1)} and
-@code{TARRAY(2)} respectively. @var{RESULT} is equal to @code{TARRAY(1) + TARRAY(2)}.
+@code{ETIME(VALUES, TIME)} returns the number of seconds of runtime
+since the start of the process's execution in @var{TIME}. @var{VALUES}
+returns the user and system components of this time in @code{VALUES(1)} and
+@code{VALUES(2)} respectively. @var{TIME} is equal to @code{VALUES(1) + VALUES(2)}.
On some systems, the underlying timings are represented using types with
sufficiently small limits that overflows (wrap around) are possible, such as
@@ -3730,12 +3730,12 @@ run of the compiled program.
This intrinsic is provided in both subroutine and function forms; however,
only one form can be used in any given program unit.
-@var{TARRAY} and @var{RESULT} are @code{INTENT(OUT)} and provide the following:
+@var{VALUES} and @var{TIME} are @code{INTENT(OUT)} and provide the following:
@multitable @columnfractions .15 .30 .60
-@item @tab @code{TARRAY(1)}: @tab User time in seconds.
-@item @tab @code{TARRAY(2)}: @tab System time in seconds.
-@item @tab @code{RESULT}: @tab Run time since start in seconds.
+@item @tab @code{VALUES(1)}: @tab User time in seconds.
+@item @tab @code{VALUES(2)}: @tab System time in seconds.
+@item @tab @code{TIME}: @tab Run time since start in seconds.
@end multitable
@item @emph{Standard}:
@@ -3746,14 +3746,14 @@ Subroutine, function
@item @emph{Syntax}:
@multitable @columnfractions .80
-@item @code{CALL ETIME(TARRAY, RESULT)}.
-@item @code{RESULT = ETIME(TARRAY)}, (not recommended).
+@item @code{CALL ETIME(VALUES, TIME)}.
+@item @code{TIME = ETIME(VALUES)}, (not recommended).
@end multitable
@item @emph{Arguments}:
@multitable @columnfractions .15 .70
-@item @var{TARRAY}@tab The type shall be @code{REAL, DIMENSION(2)}.
-@item @var{RESULT}@tab The type shall be @code{REAL}.
+@item @var{VALUES}@tab The type shall be @code{REAL, DIMENSION(2)}.
+@item @var{TIME}@tab The type shall be @code{REAL}.
@end multitable
@item @emph{Return value}:
@@ -4557,7 +4557,7 @@ END PROGRAM
@code{FSTAT} is identical to @ref{STAT}, except that information about an
already opened file is obtained.
-The elements in @code{BUFF} are the same as described by @ref{STAT}.
+The elements in @code{VALUES} are the same as described by @ref{STAT}.
This intrinsic is provided in both subroutine and function forms; however,
only one form can be used in any given program unit.
@@ -4569,12 +4569,12 @@ GNU extension
Subroutine, function
@item @emph{Syntax}:
-@code{CALL FSTAT(UNIT, BUFF [, STATUS])}
+@code{CALL FSTAT(UNIT, VALUES [, STATUS])}
@item @emph{Arguments}:
@multitable @columnfractions .15 .70
@item @var{UNIT} @tab An open I/O unit number of type @code{INTEGER}.
-@item @var{BUFF} @tab The type shall be @code{INTEGER(4), DIMENSION(13)}.
+@item @var{VALUES} @tab The type shall be @code{INTEGER(4), DIMENSION(13)}.
@item @var{STATUS} @tab (Optional) status flag of type @code{INTEGER(4)}. Returns 0
on success and a system specific error code otherwise.
@end multitable
@@ -4817,18 +4817,24 @@ Fortran 2003 and later
Subroutine
@item @emph{Syntax}:
-@code{CALL GET_COMMAND(COMMAND)}
+@code{CALL GET_COMMAND([COMMAND, LENGTH, STATUS])}
@item @emph{Arguments}:
@multitable @columnfractions .15 .70
-@item @var{COMMAND} @tab Shall be of type @code{CHARACTER} and of default
-kind.
+@item @var{COMMAND} @tab (Optional) shall be of type @code{CHARACTER} and
+of default kind.
+@item @var{LENGTH} @tab (Optional) Shall be of type @code{INTEGER} and of
+default kind.
+@item @var{STATUS} @tab (Optional) Shall be of type @code{INTEGER} and of
+default kind.
@end multitable
@item @emph{Return value}:
-Stores the entire command line that was used to invoke the program in
-@var{COMMAND}. If @var{COMMAND} is not large enough, the command will be
-truncated.
+If @var{COMMAND} is present, stores the entire command line that was used
+to invoke the program in @var{COMMAND}. If @var{LENGTH} is present, it is
+assigned the length of the command line. If @var{STATUS} is present, it
+is assigned 0 upon success of the command, -1 if @var{COMMAND} is too
+short to store the command line, or a positive value in case of an error.
@item @emph{Example}:
@smallexample
@@ -4867,12 +4873,14 @@ Subroutine
@item @emph{Arguments}:
@multitable @columnfractions .15 .70
-@item @var{NUMBER} @tab Shall be a scalar of type @code{INTEGER(4)},
-@math{@var{NUMBER} \geq 0}
+@item @var{NUMBER} @tab Shall be a scalar of type @code{INTEGER} and of
+default kind, @math{@var{NUMBER} \geq 0}
@item @var{VALUE} @tab Shall be a scalar of type @code{CHARACTER}
and of default kind.
-@item @var{LENGTH} @tab (Option) Shall be a scalar of type @code{INTEGER(4)}.
-@item @var{STATUS} @tab (Option) Shall be a scalar of type @code{INTEGER(4)}.
+@item @var{LENGTH} @tab (Option) Shall be a scalar of type @code{INTEGER}
+and of default kind.
+@item @var{STATUS} @tab (Option) Shall be a scalar of type @code{INTEGER}
+and of default kind.
@end multitable
@item @emph{Return value}:
@@ -5022,11 +5030,16 @@ Subroutine
@item @emph{Arguments}:
@multitable @columnfractions .15 .70
-@item @var{NAME} @tab Shall be a scalar of type @code{CHARACTER(1)}.
-@item @var{VALUE} @tab Shall be a scalar of type @code{CHARACTER(1)}.
-@item @var{LENGTH} @tab Shall be a scalar of type @code{INTEGER(4)}.
-@item @var{STATUS} @tab Shall be a scalar of type @code{INTEGER(4)}.
-@item @var{TRIM_NAME} @tab Shall be a scalar of type @code{LOGICAL(4)}.
+@item @var{NAME} @tab Shall be a scalar of type @code{CHARACTER}
+and of default kind.
+@item @var{VALUE} @tab Shall be a scalar of type @code{CHARACTER}
+and of default kind.
+@item @var{LENGTH} @tab Shall be a scalar of type @code{INTEGER}
+and of default kind.
+@item @var{STATUS} @tab Shall be a scalar of type @code{INTEGER}
+and of default kind.
+@item @var{TRIM_NAME} @tab Shall be a scalar of type @code{LOGICAL}
+and of default kind.
@end multitable
@item @emph{Return value}:
@@ -5707,9 +5720,9 @@ end program read_val
@table @asis
@item @emph{Description}:
-@code{IDATE(TARRAY)} Fills @var{TARRAY} with the numerical values at the
+@code{IDATE(VALUES)} Fills @var{VALUES} with the numerical values at the
current local time. The day (in the range 1-31), month (in the range 1-12),
-and year appear in elements 1, 2, and 3 of @var{TARRAY}, respectively.
+and year appear in elements 1, 2, and 3 of @var{VALUES}, respectively.
The year has four significant digits.
@item @emph{Standard}:
@@ -7212,13 +7225,14 @@ The return value is of type @code{INTEGER} and of the same kind as
@table @asis
@item @emph{Description}:
-@code{LSTAT} is identical to @ref{STAT}, except that if path is a symbolic link,
-then the link itself is statted, not the file that it refers to.
+@code{LSTAT} is identical to @ref{STAT}, except that if path is a
+symbolic link, then the link itself is statted, not the file that it
+refers to.
-The elements in @code{BUFF} are the same as described by @ref{STAT}.
+The elements in @code{VALUES} are the same as described by @ref{STAT}.
-This intrinsic is provided in both subroutine and function forms; however,
-only one form can be used in any given program unit.
+This intrinsic is provided in both subroutine and function forms;
+however, only one form can be used in any given program unit.
@item @emph{Standard}:
GNU extension
@@ -7227,13 +7241,13 @@ GNU extension
Subroutine, function
@item @emph{Syntax}:
-@code{CALL LSTAT(FILE, BUFF [, STATUS])}
+@code{CALL LSTAT(NAME, VALUES [, STATUS])}
@item @emph{Arguments}:
@multitable @columnfractions .15 .70
-@item @var{FILE} @tab The type shall be @code{CHARACTER} of the default
+@item @var{NAME} @tab The type shall be @code{CHARACTER} of the default
kind, a valid path within the file system.
-@item @var{BUFF} @tab The type shall be @code{INTEGER(4), DIMENSION(13)}.
+@item @var{VALUES} @tab The type shall be @code{INTEGER(4), DIMENSION(13)}.
@item @var{STATUS} @tab (Optional) status flag of type @code{INTEGER(4)}.
Returns 0 on success and a system specific error code otherwise.
@end multitable
@@ -7254,8 +7268,8 @@ To stat an open file: @ref{FSTAT}, to stat a file: @ref{STAT}
@table @asis
@item @emph{Description}:
-Given a system time value @var{STIME} (as provided by the @code{TIME8()}
-intrinsic), fills @var{TARRAY} with values extracted from it appropriate
+Given a system time value @var{TIME} (as provided by the @code{TIME8()}
+intrinsic), fills @var{VALUES} with values extracted from it appropriate
to the local time zone using @code{localtime(3)}.
@item @emph{Standard}:
@@ -7265,18 +7279,18 @@ GNU extension
Subroutine
@item @emph{Syntax}:
-@code{CALL LTIME(STIME, TARRAY)}
+@code{CALL LTIME(TIME, VALUES)}
@item @emph{Arguments}:
@multitable @columnfractions .15 .70
-@item @var{STIME} @tab An @code{INTEGER} scalar expression
+@item @var{TIME} @tab An @code{INTEGER} scalar expression
corresponding to a system time, with @code{INTENT(IN)}.
-@item @var{TARRAY} @tab A default @code{INTEGER} array with 9 elements,
+@item @var{VALUES} @tab A default @code{INTEGER} array with 9 elements,
with @code{INTENT(OUT)}.
@end multitable
@item @emph{Return value}:
-The elements of @var{TARRAY} are assigned as follows:
+The elements of @var{VALUES} are assigned as follows:
@enumerate
@item Seconds after the minute, range 0--59 or 0--61 to allow for leap
seconds
@@ -8046,8 +8060,8 @@ end program
@table @asis
@item @emph{Description}:
-@code{MOVE_ALLOC(SRC, DEST)} moves the allocation from @var{SRC} to
-@var{DEST}. @var{SRC} will become deallocated in the process.
+@code{MOVE_ALLOC(FROM, TO)} moves the allocation from @var{FROM} to
+@var{TO}. @var{FROM} will become deallocated in the process.
@item @emph{Standard}:
Fortran 2003 and later
@@ -8056,14 +8070,14 @@ Fortran 2003 and later
Subroutine
@item @emph{Syntax}:
-@code{CALL MOVE_ALLOC(SRC, DEST)}
+@code{CALL MOVE_ALLOC(FROM, TO)}
@item @emph{Arguments}:
@multitable @columnfractions .15 .70
-@item @var{SRC} @tab @code{ALLOCATABLE}, @code{INTENT(INOUT)}, may be
+@item @var{FROM} @tab @code{ALLOCATABLE}, @code{INTENT(INOUT)}, may be
of any type and kind.
-@item @var{DEST} @tab @code{ALLOCATABLE}, @code{INTENT(OUT)}, shall be
-of the same type, kind and rank as @var{SRC}.
+@item @var{TO} @tab @code{ALLOCATABLE}, @code{INTENT(OUT)}, shall be
+of the same type, kind and rank as @var{FROM}.
@end multitable
@item @emph{Return value}:
@@ -8219,7 +8233,7 @@ end program newline
@table @asis
@item @emph{Description}:
-@code{NINT(X)} rounds its argument to the nearest whole number.
+@code{NINT(A)} rounds its argument to the nearest whole number.
@item @emph{Standard}:
Fortran 77 and later, with @var{KIND} argument Fortran 90 and later
@@ -8228,11 +8242,11 @@ Fortran 77 and later, with @var{KIND} argument Fortran 90 and later
Elemental function
@item @emph{Syntax}:
-@code{RESULT = NINT(X [, KIND])}
+@code{RESULT = NINT(A [, KIND])}
@item @emph{Arguments}:
@multitable @columnfractions .15 .70
-@item @var{X} @tab The type of the argument shall be @code{REAL}.
+@item @var{A} @tab The type of the argument shall be @code{REAL}.
@item @var{KIND} @tab (Optional) An @code{INTEGER} initialization
expression indicating the kind parameter of the result.
@end multitable
@@ -8368,13 +8382,13 @@ GNU extension
Function
@item @emph{Syntax}:
-@code{RESULT = OR(X, Y)}
+@code{RESULT = OR(I, J)}
@item @emph{Arguments}:
@multitable @columnfractions .15 .70
-@item @var{X} @tab The type shall be either a scalar @code{INTEGER}
+@item @var{I} @tab The type shall be either a scalar @code{INTEGER}
type or a scalar @code{LOGICAL} type.
-@item @var{Y} @tab The type shall be the same as the type of @var{X}.
+@item @var{J} @tab The type shall be the same as the type of @var{J}.
@end multitable
@item @emph{Return value}:
@@ -8606,8 +8620,10 @@ Fortran 95 and later
Transformational function
@item @emph{Syntax}:
-@code{RESULT = PRODUCT(ARRAY[, MASK])}
-@code{RESULT = PRODUCT(ARRAY, DIM[, MASK])}
+@multitable @columnfractions .80
+@item @code{RESULT = PRODUCT(ARRAY[, MASK])}
+@item @code{RESULT = PRODUCT(ARRAY, DIM[, MASK])}
+@end multitable
@item @emph{Arguments}:
@multitable @columnfractions .15 .70
@@ -8732,11 +8748,11 @@ GNU extension
Function
@item @emph{Syntax}:
-@code{RESULT = RAND(FLAG)}
+@code{RESULT = RAND(I)}
@item @emph{Arguments}:
@multitable @columnfractions .15 .70
-@item @var{FLAG} @tab Shall be a scalar @code{INTEGER} of kind 4.
+@item @var{I} @tab Shall be a scalar @code{INTEGER} of kind 4.
@end multitable
@item @emph{Return value}:
@@ -8839,7 +8855,7 @@ Fortran 95 and later
Subroutine
@item @emph{Syntax}:
-@code{CALL RANDOM_SEED(SIZE, PUT, GET)}
+@code{CALL RANDOM_SEED([SIZE, PUT, GET])}
@item @emph{Arguments}:
@multitable @columnfractions .15 .70
@@ -8924,8 +8940,8 @@ See @code{PRECISION} for an example.
@table @asis
@item @emph{Description}:
-@code{REAL(X [, KIND])} converts its argument @var{X} to a real type. The
-@code{REALPART(X)} function is provided for compatibility with @command{g77},
+@code{REAL(A [, KIND])} converts its argument @var{A} to a real type. The
+@code{REALPART} function is provided for compatibility with @command{g77},
and its use is strongly discouraged.
@item @emph{Standard}:
@@ -8936,13 +8952,13 @@ Elemental function
@item @emph{Syntax}:
@multitable @columnfractions .80
-@item @code{RESULT = REAL(X [, KIND])}
+@item @code{RESULT = REAL(A [, KIND])}
@item @code{RESULT = REALPART(Z)}
@end multitable
@item @emph{Arguments}:
@multitable @columnfractions .15 .70
-@item @var{X} @tab Shall be @code{INTEGER}, @code{REAL}, or
+@item @var{A} @tab Shall be @code{INTEGER}, @code{REAL}, or
@code{COMPLEX}.
@item @var{KIND} @tab (Optional) An @code{INTEGER} initialization
expression indicating the kind parameter of the result.
@@ -8954,14 +8970,14 @@ the following rules:
@table @asis
@item (A)
-@code{REAL(X)} is converted to a default real type if @var{X} is an
+@code{REAL(A)} is converted to a default real type if @var{A} is an
integer or real variable.
@item (B)
-@code{REAL(X)} is converted to a real type with the kind type parameter
-of @var{X} if @var{X} is a complex variable.
+@code{REAL(A)} is converted to a real type with the kind type parameter
+of @var{A} if @var{A} is a complex variable.
@item (C)
-@code{REAL(X, KIND)} is converted to a real type with kind type
-parameter @var{KIND} if @var{X} is a complex, integer, or real
+@code{REAL(A, KIND)} is converted to a real type with kind type
+parameter @var{KIND} if @var{A} is a complex, integer, or real
variable.
@end table
@@ -9432,9 +9448,9 @@ end program ascii_kind
@table @asis
@item @emph{Description}:
-@code{SELECTED_INT_KIND(I)} return the kind value of the smallest integer
-type that can represent all values ranging from @math{-10^I} (exclusive)
-to @math{10^I} (exclusive). If there is no integer kind that accommodates
+@code{SELECTED_INT_KIND(R)} return the kind value of the smallest integer
+type that can represent all values ranging from @math{-10^R} (exclusive)
+to @math{10^R} (exclusive). If there is no integer kind that accommodates
this range, @code{SELECTED_INT_KIND} returns @math{-1}.
@item @emph{Standard}:
@@ -9444,11 +9460,11 @@ Fortran 95 and later
Transformational function
@item @emph{Syntax}:
-@code{RESULT = SELECTED_INT_KIND(I)}
+@code{RESULT = SELECTED_INT_KIND(R)}
@item @emph{Arguments}:
@multitable @columnfractions .15 .70
-@item @var{I} @tab Shall be a scalar and of type @code{INTEGER}.
+@item @var{R} @tab Shall be a scalar and of type @code{INTEGER}.
@end multitable
@item @emph{Example}:
@@ -9489,7 +9505,7 @@ Fortran 95 and later
Transformational function
@item @emph{Syntax}:
-@code{RESULT = SELECTED_REAL_KIND(P, R)}
+@code{RESULT = SELECTED_REAL_KIND([P, R])}
@item @emph{Arguments}:
@multitable @columnfractions .15 .70
@@ -10212,21 +10228,21 @@ This function returns information about a file. No permissions are required on
the file itself, but execute (search) permission is required on all of the
directories in path that lead to the file.
-The elements that are obtained and stored in the array @code{BUFF}:
+The elements that are obtained and stored in the array @code{VALUES}:
@multitable @columnfractions .15 .70
-@item @code{buff(1)} @tab Device ID
-@item @code{buff(2)} @tab Inode number
-@item @code{buff(3)} @tab File mode
-@item @code{buff(4)} @tab Number of links
-@item @code{buff(5)} @tab Owner's uid
-@item @code{buff(6)} @tab Owner's gid
-@item @code{buff(7)} @tab ID of device containing directory entry for file (0 if not available)
-@item @code{buff(8)} @tab File size (bytes)
-@item @code{buff(9)} @tab Last access time
-@item @code{buff(10)} @tab Last modification time
-@item @code{buff(11)} @tab Last file status change time
-@item @code{buff(12)} @tab Preferred I/O block size (-1 if not available)
-@item @code{buff(13)} @tab Number of blocks allocated (-1 if not available)
+@item @code{VALUES(1)} @tab Device ID
+@item @code{VALUES(2)} @tab Inode number
+@item @code{VALUES(3)} @tab File mode
+@item @code{VALUES(4)} @tab Number of links
+@item @code{VALUES(5)} @tab Owner's uid
+@item @code{VALUES(6)} @tab Owner's gid
+@item @code{VALUES(7)} @tab ID of device containing directory entry for file (0 if not available)
+@item @code{VALUES(8)} @tab File size (bytes)
+@item @code{VALUES(9)} @tab Last access time
+@item @code{VALUES(10)} @tab Last modification time
+@item @code{VALUES(11)} @tab Last file status change time
+@item @code{VALUES(12)} @tab Preferred I/O block size (-1 if not available)
+@item @code{VALUES(13)} @tab Number of blocks allocated (-1 if not available)
@end multitable
Not all these elements are relevant on all systems.
@@ -10242,13 +10258,13 @@ GNU extension
Subroutine, function
@item @emph{Syntax}:
-@code{CALL STAT(FILE,BUFF[,STATUS])}
+@code{CALL STAT(NAME, VALUES [, STATUS])}
@item @emph{Arguments}:
@multitable @columnfractions .15 .70
-@item @var{FILE} @tab The type shall be @code{CHARACTER}, of the
+@item @var{NAME} @tab The type shall be @code{CHARACTER}, of the
default kind and a valid path within the file system.
-@item @var{BUFF} @tab The type shall be @code{INTEGER(4), DIMENSION(13)}.
+@item @var{VALUES} @tab The type shall be @code{INTEGER(4), DIMENSION(13)}.
@item @var{STATUS} @tab (Optional) status flag of type @code{INTEGER(4)}. Returns 0
on success and a system specific error code otherwise.
@end multitable
@@ -10305,8 +10321,10 @@ Fortran 95 and later
Transformational function
@item @emph{Syntax}:
-@code{RESULT = SUM(ARRAY[, MASK])}
-@code{RESULT = SUM(ARRAY, DIM[, MASK])}
+@multitable @columnfractions .80
+@item @code{RESULT = SUM(ARRAY[, MASK])}
+@item @code{RESULT = SUM(ARRAY, DIM[, MASK])}
+@end multitable
@item @emph{Arguments}:
@multitable @columnfractions .15 .70
@@ -10965,22 +10983,24 @@ the relevant dimension.
@table @asis
@item @emph{Description}:
-Sets the file creation mask to @var{MASK} and returns the old value in
-argument @var{OLD} if it is supplied. See @code{umask(2)}.
+Sets the file creation mask to @var{MASK}. If called as a function, it
+returns the old value. If called as a subroutine and argument @var{OLD}
+if it is supplied, it is set to the old value. See @code{umask(2)}.
@item @emph{Standard}:
GNU extension
@item @emph{Class}:
-Subroutine
+Subroutine, function
@item @emph{Syntax}:
@code{CALL UMASK(MASK [, OLD])}
+@code{OLD = UMASK(MASK)}
@item @emph{Arguments}:
@multitable @columnfractions .15 .70
@item @var{MASK} @tab Shall be a scalar of type @code{INTEGER}.
-@item @var{MASK} @tab (Optional) Shall be a scalar of type
+@item @var{OLD} @tab (Optional) Shall be a scalar of type
@code{INTEGER}.
@end multitable
@@ -11154,13 +11174,13 @@ GNU extension
Function
@item @emph{Syntax}:
-@code{RESULT = XOR(X, Y)}
+@code{RESULT = XOR(I, J)}
@item @emph{Arguments}:
@multitable @columnfractions .15 .70
-@item @var{X} @tab The type shall be either a scalar @code{INTEGER}
+@item @var{I} @tab The type shall be either a scalar @code{INTEGER}
type or a scalar @code{LOGICAL} type.
-@item @var{Y} @tab The type shall be the same as the type of @var{I}.
+@item @var{J} @tab The type shall be the same as the type of @var{I}.
@end multitable
@item @emph{Return value}:
@@ -11191,7 +11211,13 @@ Fortran 95 elemental function: @ref{IEOR}
@chapter Intrinsic Modules
@cindex intrinsic Modules
-@c @node ISO_FORTRAN_ENV
+@menu
+* ISO_FORTRAN_ENV::
+* ISO_C_BINDING::
+* OpenMP Modules OMP_LIB and OMP_LIB_KINDS::
+@end menu
+
+@node ISO_FORTRAN_ENV
@section @code{ISO_FORTRAN_ENV}
@table @asis
@item @emph{Standard}:
@@ -11215,6 +11241,11 @@ Size in bits of the file-storage unit.
Identifies the preconnected unit identified by the asterisk
(@code{*}) in @code{READ} statement.
+@item @code{INT8}, @code{INT16}, @code{INT32}, @code{INT64}
+Kind type parameters to specify an INTEGER type with a storage
+size of 16, 32, and 64 bits. It is negative if a target platform
+does not support the particular kind.
+
@item @code{IOSTAT_END}:
The value assigned to the variable passed to the IOSTAT= specifier of
an input/output statement if an end-of-file condition occurred.
@@ -11229,9 +11260,16 @@ The size in bits of the numeric storage unit.
@item @code{OUTPUT_UNIT}:
Identifies the preconnected unit identified by the asterisk
(@code{*}) in @code{WRITE} statement.
+
+@item @code{REAL32}, @code{REAL64}, @code{REAL128}
+Kind type parameters to specify a REAL type with a storage
+size of 32, 64, and 128 bits. It is negative if a target platform
+does not support the particular kind.
@end table
-@c @node ISO_C_BINDING
+
+
+@node ISO_C_BINDING
@section @code{ISO_C_BINDING}
@table @asis
@item @emph{Standard}:
@@ -11252,12 +11290,8 @@ manual.
@c TODO: Vertical spacing between C_FUNLOC and C_LOC wrong in PDF,
@c don't really know why.
-The @code{ISO_C_BINDING} module provides the following named constants of the
-type integer, which can be used as KIND type parameter. Note that GNU
-Fortran currently does not support the @code{C_INT_FAST...} KIND type
-parameters (marked by an asterisk (@code{*}) in the list below).
-The @code{C_INT_FAST...} parameters have therefore the value @math{-2}
-and cannot be used as KIND type parameter of the @code{INTEGER} type.
+The @code{ISO_C_BINDING} module provides the following named constants of
+type default integer, which can be used as KIND type parameters.
In addition to the integer named constants required by the Fortran 2003
standard, GNU Fortran provides as an extension named constants for the
@@ -11276,17 +11310,17 @@ C_INT_LEAST128_T, C_INT_FAST128_T}.
@item @code{INTEGER}@tab @code{C_INT16_T} @tab @code{int16_t}
@item @code{INTEGER}@tab @code{C_INT32_T} @tab @code{int32_t}
@item @code{INTEGER}@tab @code{C_INT64_T} @tab @code{int64_t}
-@item @code{INTEGER}@tab @code{C_INT128_T} @tab @code{int128_t} @tab Ext.
+@item @code{INTEGER}@tab @code{C_INT128_T} @tab @code{int128_t} @tab Ext.
@item @code{INTEGER}@tab @code{C_INT_LEAST8_T} @tab @code{int_least8_t}
@item @code{INTEGER}@tab @code{C_INT_LEAST16_T} @tab @code{int_least16_t}
@item @code{INTEGER}@tab @code{C_INT_LEAST32_T} @tab @code{int_least32_t}
@item @code{INTEGER}@tab @code{C_INT_LEAST64_T} @tab @code{int_least64_t}
-@item @code{INTEGER}@tab @code{C_INT_LEAST128_T} @tab @code{int_least128_t} @tab Ext.
-@item @code{INTEGER}@tab @code{C_INT_FAST8_T}* @tab @code{int_fast8_t}
-@item @code{INTEGER}@tab @code{C_INT_FAST16_T}* @tab @code{int_fast16_t}
-@item @code{INTEGER}@tab @code{C_INT_FAST32_T}* @tab @code{int_fast32_t}
-@item @code{INTEGER}@tab @code{C_INT_FAST64_T}* @tab @code{int_fast64_t}
-@item @code{INTEGER}@tab @code{C_INT_FAST128_T}* @tab @code{int_fast128_t} @tab Ext.
+@item @code{INTEGER}@tab @code{C_INT_LEAST128_T}@tab @code{int_least128_t} @tab Ext.
+@item @code{INTEGER}@tab @code{C_INT_FAST8_T} @tab @code{int_fast8_t}
+@item @code{INTEGER}@tab @code{C_INT_FAST16_T} @tab @code{int_fast16_t}
+@item @code{INTEGER}@tab @code{C_INT_FAST32_T} @tab @code{int_fast32_t}
+@item @code{INTEGER}@tab @code{C_INT_FAST64_T} @tab @code{int_fast64_t}
+@item @code{INTEGER}@tab @code{C_INT_FAST128_T} @tab @code{int_fast128_t} @tab Ext.
@item @code{INTEGER}@tab @code{C_INTMAX_T} @tab @code{intmax_t}
@item @code{INTEGER}@tab @code{C_INTPTR_T} @tab @code{intptr_t}
@item @code{REAL} @tab @code{C_FLOAT} @tab @code{float}
@@ -11314,7 +11348,7 @@ defined.
@item @code{C_VERTICAL_TAB} @tab vertical tab @tab @code{'\v'}
@end multitable
-@c @node OpenMP Modules OMP_LIB and OMP_LIB_KINDS
+@node OpenMP Modules OMP_LIB and OMP_LIB_KINDS
@section OpenMP Modules @code{OMP_LIB} and @code{OMP_LIB_KINDS}
@table @asis
@item @emph{Standard}:
diff --git a/gcc/fortran/io.c b/gcc/fortran/io.c
index 57e65f85422..ea562923f05 100644
--- a/gcc/fortran/io.c
+++ b/gcc/fortran/io.c
@@ -1,5 +1,5 @@
/* Deal with I/O statements & related stuff.
- Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
Free Software Foundation, Inc.
Contributed by Andy Vaught
@@ -38,8 +38,8 @@ typedef struct
io_tag;
static const io_tag
- tag_file = { "FILE", " file =", " %e", BT_CHARACTER },
- tag_status = { "STATUS", " status =", " %e", BT_CHARACTER},
+ tag_file = {"FILE", " file =", " %e", BT_CHARACTER },
+ tag_status = {"STATUS", " status =", " %e", BT_CHARACTER},
tag_e_access = {"ACCESS", " access =", " %e", BT_CHARACTER},
tag_e_form = {"FORM", " form =", " %e", BT_CHARACTER},
tag_e_recl = {"RECL", " recl =", " %e", BT_INTEGER},
@@ -94,7 +94,8 @@ static const io_tag
tag_end = {"END", " end =", " %l", BT_UNKNOWN},
tag_eor = {"EOR", " eor =", " %l", BT_UNKNOWN},
tag_id = {"ID", " id =", " %v", BT_INTEGER},
- tag_pending = {"PENDING", " pending =", " %v", BT_LOGICAL};
+ tag_pending = {"PENDING", " pending =", " %v", BT_LOGICAL},
+ tag_newunit = {"NEWUNIT", " newunit =", " %v", BT_INTEGER};
static gfc_dt *current_dt;
@@ -1234,8 +1235,11 @@ resolve_tag_format (const gfc_expr *e)
/* If e's rank is zero and e is not an element of an array, it should be
of integer or character type. The integer variable should be
ASSIGNED. */
- if (e->symtree == NULL || e->symtree->n.sym->as == NULL
- || e->symtree->n.sym->as->rank == 0)
+ if (e->rank == 0
+ && (e->expr_type != EXPR_VARIABLE
+ || e->symtree == NULL
+ || e->symtree->n.sym->as == NULL
+ || e->symtree->n.sym->as->rank == 0))
{
if (e->ts.type != BT_CHARACTER && e->ts.type != BT_INTEGER)
{
@@ -1266,20 +1270,34 @@ resolve_tag_format (const gfc_expr *e)
return SUCCESS;
}
- /* If rank is nonzero, we allow the type to be character under GFC_STD_GNU
- and other type under GFC_STD_LEGACY. It may be assigned an Hollerith
- constant. */
- if (e->ts.type == BT_CHARACTER)
- {
- if (gfc_notify_std (GFC_STD_GNU, "Extension: Character array "
- "in FORMAT tag at %L", &e->where) == FAILURE)
- return FAILURE;
- }
- else
+ /* If rank is nonzero and type is not character, we allow it under GFC_STD_LEGACY.
+ It may be assigned an Hollerith constant. */
+ if (e->ts.type != BT_CHARACTER)
{
if (gfc_notify_std (GFC_STD_LEGACY, "Extension: Non-character "
"in FORMAT tag at %L", &e->where) == FAILURE)
return FAILURE;
+
+ if (e->rank == 0 && e->symtree->n.sym->as->type == AS_ASSUMED_SHAPE)
+ {
+ gfc_error ("Non-character assumed shape array element in FORMAT"
+ " tag at %L", &e->where);
+ return FAILURE;
+ }
+
+ if (e->rank == 0 && e->symtree->n.sym->as->type == AS_ASSUMED_SIZE)
+ {
+ gfc_error ("Non-character assumed size array element in FORMAT"
+ " tag at %L", &e->where);
+ return FAILURE;
+ }
+
+ if (e->rank == 0 && e->symtree->n.sym->attr.pointer)
+ {
+ gfc_error ("Non-character pointer array element in FORMAT tag at %L",
+ &e->where);
+ return FAILURE;
+ }
}
return SUCCESS;
@@ -1407,6 +1425,9 @@ match_open_element (gfc_open *open)
m = match_etag (&tag_convert, &open->convert);
if (m != MATCH_NO)
return m;
+ m = match_out_tag (&tag_newunit, &open->newunit);
+ if (m != MATCH_NO)
+ return m;
return MATCH_NO;
}
@@ -1439,6 +1460,7 @@ gfc_free_open (gfc_open *open)
gfc_free_expr (open->sign);
gfc_free_expr (open->convert);
gfc_free_expr (open->asynchronous);
+ gfc_free_expr (open->newunit);
gfc_free (open);
}
@@ -1468,6 +1490,7 @@ gfc_resolve_open (gfc_open *open)
RESOLVE_TAG (&tag_e_round, open->round);
RESOLVE_TAG (&tag_e_sign, open->sign);
RESOLVE_TAG (&tag_convert, open->convert);
+ RESOLVE_TAG (&tag_newunit, open->newunit);
if (gfc_reference_st_label (open->err, ST_LABEL_TARGET) == FAILURE)
return FAILURE;
@@ -1628,6 +1651,26 @@ gfc_match_open (void)
}
warn = (open->err || open->iostat) ? true : false;
+
+ /* Checks on NEWUNIT specifier. */
+ if (open->newunit)
+ {
+ if (open->unit)
+ {
+ gfc_error ("UNIT specifier not allowed with NEWUNIT at %C");
+ goto cleanup;
+ }
+
+ if (!(open->file || (open->status
+ && gfc_wide_strncasecmp (open->status->value.character.string,
+ "scratch", 7) == 0)))
+ {
+ gfc_error ("NEWUNIT specifier must have FILE= "
+ "or STATUS='scratch' at %C");
+ goto cleanup;
+ }
+ }
+
/* Checks on the ACCESS specifier. */
if (open->access && open->access->expr_type == EXPR_CONSTANT)
{
@@ -2055,6 +2098,14 @@ gfc_resolve_close (gfc_close *close)
if (gfc_reference_st_label (close->err, ST_LABEL_TARGET) == FAILURE)
return FAILURE;
+ if (close->unit->expr_type == EXPR_CONSTANT
+ && close->unit->ts.type == BT_INTEGER
+ && mpz_sgn (close->unit->value.integer) < 0)
+ {
+ gfc_error ("UNIT number in CLOSE statement at %L must be non-negative",
+ &close->unit->where);
+ }
+
return SUCCESS;
}
@@ -2177,6 +2228,14 @@ gfc_resolve_filepos (gfc_filepos *fp)
if (gfc_reference_st_label (fp->err, ST_LABEL_TARGET) == FAILURE)
return FAILURE;
+ if (fp->unit->expr_type == EXPR_CONSTANT
+ && fp->unit->ts.type == BT_INTEGER
+ && mpz_sgn (fp->unit->value.integer) < 0)
+ {
+ gfc_error ("UNIT number in statement at %L must be non-negative",
+ &fp->unit->where);
+ }
+
return SUCCESS;
}
@@ -2572,6 +2631,12 @@ gfc_resolve_dt (gfc_dt *dt)
return FAILURE;
}
+ if (e->expr_type == EXPR_CONSTANT && e->ts.type == BT_INTEGER
+ && mpz_sgn (e->value.integer) < 0)
+ {
+ gfc_error ("UNIT number in statement at %L must be non-negative", &e->where);
+ }
+
if (dt->extra_comma
&& gfc_notify_std (GFC_STD_GNU, "Extension: Comma before i/o "
"item list at %L", &dt->extra_comma->where) == FAILURE)
@@ -2830,7 +2895,7 @@ match_io_element (io_kind k, gfc_code **cpp)
cp = gfc_get_code ();
cp->op = EXEC_TRANSFER;
- cp->expr = expr;
+ cp->expr1 = expr;
*cpp = cp;
return MATCH_YES;
@@ -3662,7 +3727,7 @@ gfc_match_inquire (void)
goto syntax;
new_st.op = EXEC_IOLENGTH;
- new_st.expr = inquire->iolength;
+ new_st.expr1 = inquire->iolength;
new_st.ext.inquire = inquire;
if (gfc_pure (NULL))
diff --git a/gcc/fortran/ioparm.def b/gcc/fortran/ioparm.def
index ddef6937026..7de7a5101dc 100644
--- a/gcc/fortran/ioparm.def
+++ b/gcc/fortran/ioparm.def
@@ -49,6 +49,7 @@ IOPARM (open, encoding, 1 << 19, char1)
IOPARM (open, round, 1 << 20, char2)
IOPARM (open, sign, 1 << 21, char1)
IOPARM (open, asynchronous, 1 << 22, char2)
+IOPARM (open, newunit, 1 << 23, pint4)
IOPARM (close, common, 0, common)
IOPARM (close, status, 1 << 7, char1)
IOPARM (filepos, common, 0, common)
diff --git a/gcc/fortran/iso-c-binding.def b/gcc/fortran/iso-c-binding.def
index 98c3c982267..aeeb41de298 100644
--- a/gcc/fortran/iso-c-binding.def
+++ b/gcc/fortran/iso-c-binding.def
@@ -54,45 +54,49 @@ NAMED_INTCST (ISOCBINDING_LONG_LONG, "c_long_long", \
get_int_kind_from_node (long_long_integer_type_node), GFC_STD_F2003)
NAMED_INTCST (ISOCBINDING_INTMAX_T, "c_intmax_t", \
- get_int_kind_from_node (intmax_type_node), GFC_STD_F2003)
+ get_int_kind_from_name (INTMAX_TYPE), GFC_STD_F2003)
NAMED_INTCST (ISOCBINDING_INTPTR_T, "c_intptr_t", \
- get_int_kind_from_node (ptr_type_node), GFC_STD_F2003)
+ get_int_kind_from_name (INTPTR_TYPE), GFC_STD_F2003)
NAMED_INTCST (ISOCBINDING_SIZE_T, "c_size_t", \
gfc_index_integer_kind, GFC_STD_F2003)
NAMED_INTCST (ISOCBINDING_SIGNED_CHAR, "c_signed_char", \
get_int_kind_from_node (signed_char_type_node), GFC_STD_F2003)
-NAMED_INTCST (ISOCBINDING_INT8_T, "c_int8_t", get_int_kind_from_width (8), \
- GFC_STD_F2003)
-NAMED_INTCST (ISOCBINDING_INT16_T, "c_int16_t", get_int_kind_from_width (16), \
- GFC_STD_F2003)
-NAMED_INTCST (ISOCBINDING_INT32_T, "c_int32_t", get_int_kind_from_width (32), \
- GFC_STD_F2003)
-NAMED_INTCST (ISOCBINDING_INT64_T, "c_int64_t", get_int_kind_from_width (64), \
- GFC_STD_F2003)
+NAMED_INTCST (ISOCBINDING_INT8_T, "c_int8_t", \
+ get_int_kind_from_name (INT8_TYPE), GFC_STD_F2003)
+NAMED_INTCST (ISOCBINDING_INT16_T, "c_int16_t", \
+ get_int_kind_from_name (INT16_TYPE), GFC_STD_F2003)
+NAMED_INTCST (ISOCBINDING_INT32_T, "c_int32_t", \
+ get_int_kind_from_name (INT32_TYPE), GFC_STD_F2003)
+NAMED_INTCST (ISOCBINDING_INT64_T, "c_int64_t", \
+ get_int_kind_from_name (INT64_TYPE), GFC_STD_F2003)
/* GNU Extension. */
-NAMED_INTCST (ISOCBINDING_INT128_T, "c_int128_t", get_int_kind_from_width (128), \
- GFC_STD_GNU)
+NAMED_INTCST (ISOCBINDING_INT128_T, "c_int128_t", \
+ get_int_kind_from_width (128), GFC_STD_GNU)
NAMED_INTCST (ISOCBINDING_INT_LEAST8_T, "c_int_least8_t", \
- get_int_kind_from_minimal_width (8), GFC_STD_F2003)
+ get_int_kind_from_name (INT_LEAST8_TYPE), GFC_STD_F2003)
NAMED_INTCST (ISOCBINDING_INT_LEAST16_T, "c_int_least16_t", \
- get_int_kind_from_minimal_width (16), GFC_STD_F2003)
+ get_int_kind_from_name (INT_LEAST16_TYPE), GFC_STD_F2003)
NAMED_INTCST (ISOCBINDING_INT_LEAST32_T, "c_int_least32_t", \
- get_int_kind_from_minimal_width (32), GFC_STD_F2003)
+ get_int_kind_from_name (INT_LEAST32_TYPE), GFC_STD_F2003)
NAMED_INTCST (ISOCBINDING_INT_LEAST64_T, "c_int_least64_t", \
- get_int_kind_from_minimal_width (64), GFC_STD_F2003)
+ get_int_kind_from_name (INT_LEAST64_TYPE), GFC_STD_F2003)
/* GNU Extension. */
NAMED_INTCST (ISOCBINDING_INT_LEAST128_T, "c_int_least128_t", \
get_int_kind_from_minimal_width (128), GFC_STD_GNU)
-/* TODO: Implement c_int_fast*_t. Depends on PR 448. */
-NAMED_INTCST (ISOCBINDING_INT_FAST8_T, "c_int_fast8_t", -2, GFC_STD_F2003)
-NAMED_INTCST (ISOCBINDING_INT_FAST16_T, "c_int_fast16_t", -2, GFC_STD_F2003)
-NAMED_INTCST (ISOCBINDING_INT_FAST32_T, "c_int_fast32_t", -2, GFC_STD_F2003)
-NAMED_INTCST (ISOCBINDING_INT_FAST64_T, "c_int_fast64_t", -2, GFC_STD_F2003)
+NAMED_INTCST (ISOCBINDING_INT_FAST8_T, "c_int_fast8_t", \
+ get_int_kind_from_name (INT_FAST8_TYPE), GFC_STD_F2003)
+NAMED_INTCST (ISOCBINDING_INT_FAST16_T, "c_int_fast16_t", \
+ get_int_kind_from_name (INT_FAST16_TYPE), GFC_STD_F2003)
+NAMED_INTCST (ISOCBINDING_INT_FAST32_T, "c_int_fast32_t", \
+ get_int_kind_from_name (INT_FAST32_TYPE), GFC_STD_F2003)
+NAMED_INTCST (ISOCBINDING_INT_FAST64_T, "c_int_fast64_t", \
+ get_int_kind_from_name (INT_FAST64_TYPE), GFC_STD_F2003)
/* GNU Extension. */
-NAMED_INTCST (ISOCBINDING_INT_FAST128_T, "c_int_fast128_t", -2, GFC_STD_GNU)
+NAMED_INTCST (ISOCBINDING_INT_FAST128_T, "c_int_fast128_t",
+ get_int_kind_from_width (128), GFC_STD_GNU)
NAMED_REALCST (ISOCBINDING_FLOAT, "c_float", \
get_real_kind_from_node (float_type_node))
diff --git a/gcc/fortran/iso-fortran-env.def b/gcc/fortran/iso-fortran-env.def
index 5f2c04231c5..fa6071f45b2 100644
--- a/gcc/fortran/iso-fortran-env.def
+++ b/gcc/fortran/iso-fortran-env.def
@@ -33,6 +33,14 @@ NAMED_INTCST (ISOFORTRANENV_FILE_STORAGE_SIZE, "file_storage_size", 8, \
GFC_STD_F2003)
NAMED_INTCST (ISOFORTRANENV_INPUT_UNIT, "input_unit", GFC_STDIN_UNIT_NUMBER, \
GFC_STD_F2003)
+NAMED_INTCST (ISOFORTRANENV_INT8, "int8", \
+ gfc_get_int_kind_from_width_isofortranenv (8), GFC_STD_F2008)
+NAMED_INTCST (ISOFORTRANENV_INT16, "int16", \
+ gfc_get_int_kind_from_width_isofortranenv (16), GFC_STD_F2008)
+NAMED_INTCST (ISOFORTRANENV_INT32, "int32", \
+ gfc_get_int_kind_from_width_isofortranenv (32), GFC_STD_F2008)
+NAMED_INTCST (ISOFORTRANENV_INT64, "int64", \
+ gfc_get_int_kind_from_width_isofortranenv (64), GFC_STD_F2008)
NAMED_INTCST (ISOFORTRANENV_IOSTAT_END, "iostat_end", LIBERROR_END, \
GFC_STD_F2003)
NAMED_INTCST (ISOFORTRANENV_IOSTAT_EOR, "iostat_eor", LIBERROR_EOR, \
@@ -41,3 +49,9 @@ NAMED_INTCST (ISOFORTRANENV_NUMERIC_STORAGE_SIZE, "numeric_storage_size", \
gfc_numeric_storage_size, GFC_STD_F2003)
NAMED_INTCST (ISOFORTRANENV_OUTPUT_UNIT, "output_unit", GFC_STDOUT_UNIT_NUMBER, \
GFC_STD_F2003)
+NAMED_INTCST (ISOFORTRANENV_REAL32, "real32", \
+ gfc_get_real_kind_from_width_isofortranenv (32), GFC_STD_F2008)
+NAMED_INTCST (ISOFORTRANENV_REAL64, "real64", \
+ gfc_get_real_kind_from_width_isofortranenv (64), GFC_STD_F2008)
+NAMED_INTCST (ISOFORTRANENV_REAL128, "real128", \
+ gfc_get_real_kind_from_width_isofortranenv (128), GFC_STD_F2008)
diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt
index 9da290c81fa..d29dddee8e1 100644
--- a/gcc/fortran/lang.opt
+++ b/gcc/fortran/lang.opt
@@ -350,7 +350,7 @@ Append a second underscore if the name already contains an underscore
fshort-enums
Fortran
-Use the narrowest integer type possible for enumeration types
+; Documented in C
fsign-zero
Fortran
diff --git a/gcc/fortran/libgfortran.h b/gcc/fortran/libgfortran.h
index d7e254f3635..839279e413e 100644
--- a/gcc/fortran/libgfortran.h
+++ b/gcc/fortran/libgfortran.h
@@ -19,7 +19,9 @@ along with GCC; see the file COPYING3. If not see
/* Flags to specify which standard/extension contains a feature.
- Note that no features were obsoleted nor deleted in F2003. */
+ Note that no features were obsoleted nor deleted in F2003.
+ Please remember to keep those definitions in sync with
+ gfortran.texi. */
#define GFC_STD_F2008 (1<<7) /* New in F2008. */
#define GFC_STD_LEGACY (1<<6) /* Backward compatibility. */
#define GFC_STD_GNU (1<<5) /* GNU Fortran extension. */
diff --git a/gcc/fortran/match.c b/gcc/fortran/match.c
index 6faedec1ce8..cf558b54e1b 100644
--- a/gcc/fortran/match.c
+++ b/gcc/fortran/match.c
@@ -1306,7 +1306,7 @@ gfc_match_assignment (void)
gfc_set_sym_referenced (lvalue->symtree->n.sym);
new_st.op = EXEC_ASSIGN;
- new_st.expr = lvalue;
+ new_st.expr1 = lvalue;
new_st.expr2 = rvalue;
gfc_check_do_variable (lvalue->symtree);
@@ -1346,7 +1346,7 @@ gfc_match_pointer_assignment (void)
goto cleanup;
new_st.op = EXEC_POINTER_ASSIGN;
- new_st.expr = lvalue;
+ new_st.expr1 = lvalue;
new_st.expr2 = rvalue;
return MATCH_YES;
@@ -1388,8 +1388,8 @@ match_arithmetic_if (void)
return MATCH_ERROR;
new_st.op = EXEC_ARITHMETIC_IF;
- new_st.expr = expr;
- new_st.label = l1;
+ new_st.expr1 = expr;
+ new_st.label1 = l1;
new_st.label2 = l2;
new_st.label3 = l3;
@@ -1469,8 +1469,8 @@ gfc_match_if (gfc_statement *if_type)
return MATCH_ERROR;
new_st.op = EXEC_ARITHMETIC_IF;
- new_st.expr = expr;
- new_st.label = l1;
+ new_st.expr1 = expr;
+ new_st.label1 = l1;
new_st.label2 = l2;
new_st.label3 = l3;
@@ -1481,7 +1481,7 @@ gfc_match_if (gfc_statement *if_type)
if (gfc_match (" then%t") == MATCH_YES)
{
new_st.op = EXEC_IF;
- new_st.expr = expr;
+ new_st.expr1 = expr;
*if_type = ST_IF_BLOCK;
return MATCH_YES;
}
@@ -1601,7 +1601,7 @@ got_match:
*p->next = new_st;
p->next->loc = gfc_current_locus;
- p->expr = expr;
+ p->expr1 = expr;
p->op = EXEC_IF;
gfc_clear_new_st ();
@@ -1677,7 +1677,7 @@ gfc_match_elseif (void)
done:
new_st.op = EXEC_IF;
- new_st.expr = expr;
+ new_st.expr1 = expr;
return MATCH_YES;
cleanup:
@@ -1789,10 +1789,10 @@ done:
&& gfc_reference_st_label (label, ST_LABEL_TARGET) == FAILURE)
goto cleanup;
- new_st.label = label;
+ new_st.label1 = label;
if (new_st.op == EXEC_DO_WHILE)
- new_st.expr = iter.end;
+ new_st.expr1 = iter.end;
else
{
new_st.ext.iterator = ip = gfc_get_iterator ();
@@ -1952,7 +1952,7 @@ gfc_match_stopcode (gfc_statement st)
}
new_st.op = st == ST_STOP ? EXEC_STOP : EXEC_PAUSE;
- new_st.expr = e;
+ new_st.expr1 = e;
new_st.ext.stop_code = stop_code;
return MATCH_YES;
@@ -2033,8 +2033,8 @@ gfc_match_assign (void)
expr->symtree->n.sym->attr.assign = 1;
new_st.op = EXEC_LABEL_ASSIGN;
- new_st.label = label;
- new_st.expr = expr;
+ new_st.label1 = label;
+ new_st.expr1 = expr;
return MATCH_YES;
}
}
@@ -2063,7 +2063,7 @@ gfc_match_goto (void)
return MATCH_ERROR;
new_st.op = EXEC_GOTO;
- new_st.label = label;
+ new_st.label1 = label;
return MATCH_YES;
}
@@ -2077,7 +2077,7 @@ gfc_match_goto (void)
return MATCH_ERROR;
new_st.op = EXEC_GOTO;
- new_st.expr = expr;
+ new_st.expr1 = expr;
if (gfc_match_eos () == MATCH_YES)
return MATCH_YES;
@@ -2108,7 +2108,7 @@ gfc_match_goto (void)
tail = tail->block;
}
- tail->label = label;
+ tail->label1 = label;
tail->op = EXEC_GOTO;
}
while (gfc_match_char (',') == MATCH_YES);
@@ -2161,7 +2161,7 @@ gfc_match_goto (void)
tail->next = gfc_get_code ();
tail->next->op = EXEC_GOTO;
- tail->next->label = label;
+ tail->next->label1 = label;
}
while (gfc_match_char (',') == MATCH_YES);
@@ -2184,7 +2184,7 @@ gfc_match_goto (void)
equivalent SELECT statement constructed. */
new_st.op = EXEC_SELECT;
- new_st.expr = NULL;
+ new_st.expr1 = NULL;
/* Hack: For a "real" SELECT, the expression is in expr. We put
it in expr2 so we can distinguish then and produce the correct
@@ -2337,7 +2337,7 @@ alloc_opt_list:
goto syntax;
new_st.op = EXEC_ALLOCATE;
- new_st.expr = stat;
+ new_st.expr1 = stat;
new_st.expr2 = errmsg;
new_st.ext.alloc_list = head;
@@ -2402,7 +2402,7 @@ gfc_match_nullify (void)
}
tail->op = EXEC_POINTER_ASSIGN;
- tail->expr = p;
+ tail->expr1 = p;
tail->expr2 = e;
if (gfc_match (" )%t") == MATCH_YES)
@@ -2418,6 +2418,11 @@ syntax:
cleanup:
gfc_free_statements (new_st.next);
+ new_st.next = NULL;
+ gfc_free_expr (new_st.expr1);
+ new_st.expr1 = NULL;
+ gfc_free_expr (new_st.expr2);
+ new_st.expr2 = NULL;
return MATCH_ERROR;
}
@@ -2538,7 +2543,7 @@ dealloc_opt_list:
goto syntax;
new_st.op = EXEC_DEALLOCATE;
- new_st.expr = stat;
+ new_st.expr1 = stat;
new_st.expr2 = errmsg;
new_st.ext.alloc_list = head;
@@ -2606,7 +2611,7 @@ done:
return MATCH_ERROR;
new_st.op = EXEC_RETURN;
- new_st.expr = e;
+ new_st.expr1 = e;
return MATCH_YES;
}
@@ -2652,7 +2657,7 @@ match_typebound_call (gfc_symtree* varst)
"at %C");
return MATCH_ERROR;
}
- new_st.expr = base;
+ new_st.expr1 = base;
return MATCH_YES;
}
@@ -2755,11 +2760,11 @@ gfc_match_call (void)
select_sym->ts.type = BT_INTEGER;
select_sym->ts.kind = gfc_default_integer_kind;
gfc_set_sym_referenced (select_sym);
- c->expr = gfc_get_expr ();
- c->expr->expr_type = EXPR_VARIABLE;
- c->expr->symtree = select_st;
- c->expr->ts = select_sym->ts;
- c->expr->where = gfc_current_locus;
+ c->expr1 = gfc_get_expr ();
+ c->expr1->expr_type = EXPR_VARIABLE;
+ c->expr1->symtree = select_st;
+ c->expr1->ts = select_sym->ts;
+ c->expr1->where = gfc_current_locus;
i = 0;
for (a = arglist; a; a = a->next)
@@ -2782,7 +2787,7 @@ gfc_match_call (void)
c->next = gfc_get_code ();
c->next->op = EXEC_GOTO;
- c->next->label = a->label;
+ c->next->label1 = a->label;
}
}
@@ -3655,7 +3660,7 @@ gfc_match_select (void)
return m;
new_st.op = EXEC_SELECT;
- new_st.expr = expr;
+ new_st.expr1 = expr;
return MATCH_YES;
}
@@ -3760,7 +3765,7 @@ match_simple_where (void)
c = gfc_get_code ();
c->op = EXEC_WHERE;
- c->expr = expr;
+ c->expr1 = expr;
c->next = gfc_get_code ();
*c->next = new_st;
@@ -3801,7 +3806,7 @@ gfc_match_where (gfc_statement *st)
{
*st = ST_WHERE_BLOCK;
new_st.op = EXEC_WHERE;
- new_st.expr = expr;
+ new_st.expr1 = expr;
return MATCH_YES;
}
@@ -3820,7 +3825,7 @@ gfc_match_where (gfc_statement *st)
c = gfc_get_code ();
c->op = EXEC_WHERE;
- c->expr = expr;
+ c->expr1 = expr;
c->next = gfc_get_code ();
*c->next = new_st;
@@ -3890,7 +3895,7 @@ gfc_match_elsewhere (void)
}
new_st.op = EXEC_WHERE;
- new_st.expr = expr;
+ new_st.expr1 = expr;
return MATCH_YES;
syntax:
@@ -4107,7 +4112,7 @@ match_simple_forall (void)
gfc_clear_new_st ();
new_st.op = EXEC_FORALL;
- new_st.expr = mask;
+ new_st.expr1 = mask;
new_st.ext.forall_iterator = head;
new_st.block = gfc_get_code ();
@@ -4159,7 +4164,7 @@ gfc_match_forall (gfc_statement *st)
{
*st = ST_FORALL_BLOCK;
new_st.op = EXEC_FORALL;
- new_st.expr = mask;
+ new_st.expr1 = mask;
new_st.ext.forall_iterator = head;
return MATCH_YES;
}
@@ -4182,7 +4187,7 @@ gfc_match_forall (gfc_statement *st)
gfc_clear_new_st ();
new_st.op = EXEC_FORALL;
- new_st.expr = mask;
+ new_st.expr1 = mask;
new_st.ext.forall_iterator = head;
new_st.block = gfc_get_code ();
new_st.block->op = EXEC_FORALL;
diff --git a/gcc/fortran/misc.c b/gcc/fortran/misc.c
index 136b751a196..94d61c9ec86 100644
--- a/gcc/fortran/misc.c
+++ b/gcc/fortran/misc.c
@@ -42,22 +42,15 @@ gfc_getmem (size_t n)
}
-/* gfortran.h defines free to something that triggers a syntax error,
- but we need free() here. */
-
-#define temp free
-#undef free
-
void
gfc_free (void *p)
{
+ /* The parentheses around free are needed in order to call not
+ the redefined free of gfortran.h. */
if (p != NULL)
- free (p);
+ (free) (p);
}
-#define free temp
-#undef temp
-
/* Get terminal width. */
diff --git a/gcc/fortran/module.c b/gcc/fortran/module.c
index ae15f18c286..5bd7c27eea5 100644
--- a/gcc/fortran/module.c
+++ b/gcc/fortran/module.c
@@ -4017,7 +4017,7 @@ read_module (void)
module_locus operator_interfaces, user_operators;
const char *p;
char name[GFC_MAX_SYMBOL_LEN + 1];
- gfc_intrinsic_op i;
+ int i;
int ambiguous, j, nuse, symbol;
pointer_info *info, *q;
gfc_use_rename *u;
@@ -4225,7 +4225,7 @@ read_module (void)
if (only_flag)
{
- u = find_use_operator (i);
+ u = find_use_operator ((gfc_intrinsic_op) i);
if (u == NULL)
{
@@ -4677,7 +4677,7 @@ write_symtree (gfc_symtree *st)
static void
write_module (void)
{
- gfc_intrinsic_op i;
+ int i;
/* Write the operator interfaces. */
mio_lparen ();
@@ -4759,7 +4759,7 @@ read_md5_from_module_file (const char * filename, unsigned char md5[16])
if ((file = fopen (filename, "r")) == NULL)
return -1;
- /* Read two lines. */
+ /* Read the first line. */
if (fgets (buf, sizeof (buf) - 1, file) == NULL)
{
fclose (file);
@@ -4769,8 +4769,12 @@ read_md5_from_module_file (const char * filename, unsigned char md5[16])
/* The file also needs to be overwritten if the version number changed. */
n = strlen ("GFORTRAN module version '" MOD_VERSION "' created");
if (strncmp (buf, "GFORTRAN module version '" MOD_VERSION "' created", n) != 0)
- return -1;
+ {
+ fclose (file);
+ return -1;
+ }
+ /* Read a second line. */
if (fgets (buf, sizeof (buf) - 1, file) == NULL)
{
fclose (file);
diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c
index 9ac9a4aec91..608d605c951 100644
--- a/gcc/fortran/openmp.c
+++ b/gcc/fortran/openmp.c
@@ -1072,20 +1072,20 @@ resolve_omp_atomic (gfc_code *code)
gcc_assert (code->op == EXEC_ASSIGN);
gcc_assert (code->next == NULL);
- if (code->expr->expr_type != EXPR_VARIABLE
- || code->expr->symtree == NULL
- || code->expr->rank != 0
- || (code->expr->ts.type != BT_INTEGER
- && code->expr->ts.type != BT_REAL
- && code->expr->ts.type != BT_COMPLEX
- && code->expr->ts.type != BT_LOGICAL))
+ if (code->expr1->expr_type != EXPR_VARIABLE
+ || code->expr1->symtree == NULL
+ || code->expr1->rank != 0
+ || (code->expr1->ts.type != BT_INTEGER
+ && code->expr1->ts.type != BT_REAL
+ && code->expr1->ts.type != BT_COMPLEX
+ && code->expr1->ts.type != BT_LOGICAL))
{
gfc_error ("!$OMP ATOMIC statement must set a scalar variable of "
"intrinsic type at %L", &code->loc);
return;
}
- var = code->expr->symtree->n.sym;
+ var = code->expr1->symtree->n.sym;
expr2 = is_conversion (code->expr2, false);
if (expr2 == NULL)
expr2 = code->expr2;
@@ -1503,6 +1503,9 @@ resolve_omp_do (gfc_code *code)
void
gfc_resolve_omp_directive (gfc_code *code, gfc_namespace *ns ATTRIBUTE_UNUSED)
{
+ if (code->op != EXEC_OMP_ATOMIC)
+ gfc_maybe_initialize_eh ();
+
switch (code->op)
{
case EXEC_OMP_DO:
diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c
index d23dc9b8e9f..82f777fe6a6 100644
--- a/gcc/fortran/options.c
+++ b/gcc/fortran/options.c
@@ -137,7 +137,7 @@ gfc_init_options (unsigned int argc, const char **argv)
set_default_std_flags ();
/* -fshort-enums can be default on some targets. */
- gfc_option.fshort_enums = targetm.default_short_enums ();
+ flag_short_enums = targetm.default_short_enums ();
/* Initialize cpp-related options. */
gfc_cpp_init_options(argc, argv);
@@ -238,9 +238,9 @@ gfc_post_options (const char **pfilename)
sorry ("-fexcess-precision=standard for Fortran");
flag_excess_precision_cmdline = EXCESS_PRECISION_FAST;
- /* Issue an error if -fwhole-program was used. */
+ /* Whole program needs whole file mode. */
if (flag_whole_program)
- gfc_fatal_error ("Option -fwhole-program is not supported for Fortran");
+ gfc_option.flag_whole_file = 1;
if (flag_compare_debug)
gfc_option.dump_parse_tree = 0;
@@ -249,6 +249,9 @@ gfc_post_options (const char **pfilename)
if (flag_bounds_check)
gfc_option.rtcheck |= GFC_RTCHECK_BOUNDS;
+ if (flag_compare_debug)
+ gfc_option.dump_parse_tree = 0;
+
/* Verify the input file name. */
if (!filename || strcmp (filename, "-") == 0)
{
@@ -861,7 +864,7 @@ gfc_handle_option (size_t scode, const char *arg, int value)
break;
case OPT_fshort_enums:
- gfc_option.fshort_enums = 1;
+ flag_short_enums = 1;
break;
case OPT_fconvert_little_endian:
diff --git a/gcc/fortran/parse.c b/gcc/fortran/parse.c
index d387f543c94..0b2cbf3cb0e 100644
--- a/gcc/fortran/parse.c
+++ b/gcc/fortran/parse.c
@@ -1496,6 +1496,11 @@ accept_statement (gfc_statement st)
new_st.op = EXEC_RETURN;
add_statement ();
}
+ else
+ {
+ new_st.op = EXEC_END_PROCEDURE;
+ add_statement ();
+ }
break;
@@ -2503,10 +2508,10 @@ parse_where_block (void)
push_state (&s, COMP_WHERE, gfc_new_block);
d = add_statement ();
- d->expr = top->expr;
+ d->expr1 = top->expr1;
d->op = EXEC_WHERE;
- top->expr = NULL;
+ top->expr1 = NULL;
top->block = d;
seen_empty_else = 0;
@@ -2536,12 +2541,12 @@ parse_where_block (void)
break;
}
- if (new_st.expr == NULL)
+ if (new_st.expr1 == NULL)
seen_empty_else = 1;
d = new_level (gfc_state_stack->head);
d->op = EXEC_WHERE;
- d->expr = new_st.expr;
+ d->expr1 = new_st.expr1;
accept_statement (st);
@@ -2646,8 +2651,8 @@ parse_if_block (void)
new_st.op = EXEC_IF;
d = add_statement ();
- d->expr = top->expr;
- top->expr = NULL;
+ d->expr1 = top->expr1;
+ top->expr1 = NULL;
top->block = d;
do
@@ -2671,7 +2676,7 @@ parse_if_block (void)
d = new_level (gfc_state_stack->head);
d->op = EXEC_IF;
- d->expr = new_st.expr;
+ d->expr1 = new_st.expr1;
accept_statement (st);
@@ -2862,7 +2867,7 @@ parse_do_block (void)
gfc_state_data s;
gfc_symtree *stree;
- s.ext.end_do_label = new_st.label;
+ s.ext.end_do_label = new_st.label1;
if (new_st.ext.iterator != NULL)
stree = new_st.ext.iterator->var->symtree;
diff --git a/gcc/fortran/primary.c b/gcc/fortran/primary.c
index 96fbddce92a..1a03165fcbe 100644
--- a/gcc/fortran/primary.c
+++ b/gcc/fortran/primary.c
@@ -1726,7 +1726,8 @@ gfc_match_varspec (gfc_expr *primary, int equiv_flag, bool sub_flag,
tail = NULL;
gfc_gobble_whitespace ();
- if ((equiv_flag && gfc_peek_ascii_char () == '(') || sym->attr.dimension)
+ if ((equiv_flag && gfc_peek_ascii_char () == '(')
+ || (sym->attr.dimension && !sym->attr.proc_pointer))
{
/* In EQUIVALENCE, we don't know yet whether we are seeing
an array, character variable or array of character
@@ -1843,7 +1844,7 @@ gfc_match_varspec (gfc_expr *primary, int equiv_flag, bool sub_flag,
break;
}
- if (component->as != NULL)
+ if (component->as != NULL && !component->attr.proc_pointer)
{
tail = extend_ref (primary, tail);
tail->type = REF_ARRAY;
@@ -2558,7 +2559,7 @@ gfc_match_rvalue (gfc_expr **result)
if (gfc_matching_procptr_assignment)
{
gfc_gobble_whitespace ();
- if (gfc_peek_ascii_char () == '(')
+ if (!sym->attr.dimension && gfc_peek_ascii_char () == '(')
/* Parse functions returning a procptr. */
goto function0;
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index b7550f5780e..3a670423d7f 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -1584,8 +1584,8 @@ resolve_elemental_actual (gfc_expr *expr, gfc_code *c)
/* Elemental procedure's array actual arguments must conform. */
if (e != NULL)
{
- if (gfc_check_conformance ("elemental procedure", arg->expr, e)
- == FAILURE)
+ if (gfc_check_conformance (arg->expr, e,
+ "elemental procedure") == FAILURE)
return FAILURE;
}
else
@@ -3897,6 +3897,8 @@ resolve_array_ref (gfc_array_ref *ar)
static gfc_try
resolve_substring (gfc_ref *ref)
{
+ int k = gfc_validate_kind (BT_INTEGER, gfc_charlen_int_kind, false);
+
if (ref->u.ss.start != NULL)
{
if (gfc_resolve_expr (ref->u.ss.start) == FAILURE)
@@ -3954,6 +3956,16 @@ resolve_substring (gfc_ref *ref)
&ref->u.ss.start->where);
return FAILURE;
}
+
+ if (compare_bound_mpz_t (ref->u.ss.end,
+ gfc_integer_kinds[k].huge) == CMP_GT
+ && (compare_bound (ref->u.ss.end, ref->u.ss.start) == CMP_EQ
+ || compare_bound (ref->u.ss.end, ref->u.ss.start) == CMP_GT))
+ {
+ gfc_error ("Substring end index at %L is too large",
+ &ref->u.ss.end->where);
+ return FAILURE;
+ }
}
return SUCCESS;
@@ -4016,7 +4028,7 @@ gfc_resolve_substring_charlen (gfc_expr *e)
e->ts.cl->length = gfc_add (e->ts.cl->length, gfc_int_expr (1));
e->ts.cl->length->ts.type = BT_INTEGER;
- e->ts.cl->length->ts.kind = gfc_charlen_int_kind;;
+ e->ts.cl->length->ts.kind = gfc_charlen_int_kind;
/* Make sure that the length is simplified. */
gfc_simplify_expr (e->ts.cl->length, 1);
@@ -4475,7 +4487,7 @@ gfc_resolve_character_operator (gfc_expr *e)
e->ts.cl->length = gfc_add (e1, e2);
e->ts.cl->length->ts.type = BT_INTEGER;
- e->ts.cl->length->ts.kind = gfc_charlen_int_kind;;
+ e->ts.cl->length->ts.kind = gfc_charlen_int_kind;
gfc_simplify_expr (e->ts.cl->length, 0);
gfc_resolve_expr (e->ts.cl->length);
@@ -4738,31 +4750,31 @@ resolve_typebound_call (gfc_code* c)
gfc_symtree* target;
/* Check that's really a SUBROUTINE. */
- if (!c->expr->value.compcall.tbp->subroutine)
+ if (!c->expr1->value.compcall.tbp->subroutine)
{
gfc_error ("'%s' at %L should be a SUBROUTINE",
- c->expr->value.compcall.name, &c->loc);
+ c->expr1->value.compcall.name, &c->loc);
return FAILURE;
}
- if (check_typebound_baseobject (c->expr) == FAILURE)
+ if (check_typebound_baseobject (c->expr1) == FAILURE)
return FAILURE;
- if (resolve_typebound_generic_call (c->expr) == FAILURE)
+ if (resolve_typebound_generic_call (c->expr1) == FAILURE)
return FAILURE;
/* Transform into an ordinary EXEC_CALL for now. */
- if (resolve_typebound_static (c->expr, &target, &newactual) == FAILURE)
+ if (resolve_typebound_static (c->expr1, &target, &newactual) == FAILURE)
return FAILURE;
c->ext.actual = newactual;
c->symtree = target;
c->op = EXEC_CALL;
- gcc_assert (!c->expr->ref && !c->expr->value.compcall.actual);
- gfc_free_expr (c->expr);
- c->expr = NULL;
+ gcc_assert (!c->expr1->ref && !c->expr1->value.compcall.actual);
+ gfc_free_expr (c->expr1);
+ c->expr1 = NULL;
return resolve_call (c);
}
@@ -4819,22 +4831,25 @@ static gfc_try
resolve_ppc_call (gfc_code* c)
{
gfc_component *comp;
- gcc_assert (is_proc_ptr_comp (c->expr, &comp));
+ gcc_assert (is_proc_ptr_comp (c->expr1, &comp));
- c->resolved_sym = c->expr->symtree->n.sym;
- c->expr->expr_type = EXPR_VARIABLE;
- c->ext.actual = c->expr->value.compcall.actual;
+ c->resolved_sym = c->expr1->symtree->n.sym;
+ c->expr1->expr_type = EXPR_VARIABLE;
+ c->ext.actual = c->expr1->value.compcall.actual;
if (!comp->attr.subroutine)
- gfc_add_subroutine (&comp->attr, comp->name, &c->expr->where);
+ gfc_add_subroutine (&comp->attr, comp->name, &c->expr1->where);
+
+ if (resolve_ref (c->expr1) == FAILURE)
+ return FAILURE;
if (resolve_actual_arglist (c->ext.actual, comp->attr.proc,
comp->formal == NULL) == FAILURE)
return FAILURE;
/* TODO: Check actual arguments.
- gfc_procedure_use (stree->n.sym, &c->expr->value.compcall.actual,
- &c->expr->where);*/
+ gfc_procedure_use (stree->n.sym, &c->expr1->value.compcall.actual,
+ &c->expr1->where);*/
return SUCCESS;
}
@@ -4853,10 +4868,15 @@ resolve_expr_ppc (gfc_expr* e)
e->value.function.isym = NULL;
e->value.function.actual = e->value.compcall.actual;
e->ts = comp->ts;
+ if (comp->as != NULL)
+ e->rank = comp->as->rank;
if (!comp->attr.function)
gfc_add_function (&comp->attr, comp->name, &e->where);
+ if (resolve_ref (e) == FAILURE)
+ return FAILURE;
+
if (resolve_actual_arglist (e->value.function.actual, comp->attr.proc,
comp->formal == NULL) == FAILURE)
return FAILURE;
@@ -5412,7 +5432,7 @@ resolve_allocate_expr (gfc_expr *e, gfc_code *code)
init_st = gfc_get_code ();
init_st->loc = code->loc;
init_st->op = EXEC_INIT_ASSIGN;
- init_st->expr = expr_to_initialize (e);
+ init_st->expr1 = expr_to_initialize (e);
init_st->expr2 = init_e;
init_st->next = code->next;
code->next = init_st;
@@ -5492,7 +5512,7 @@ resolve_allocate_deallocate (gfc_code *code, const char *fcn)
gfc_expr *stat, *errmsg, *pe, *qe;
gfc_alloc *a, *p, *q;
- stat = code->expr ? code->expr : NULL;
+ stat = code->expr1 ? code->expr1 : NULL;
errmsg = code->expr2 ? code->expr2 : NULL;
@@ -5843,7 +5863,7 @@ resolve_select (gfc_code *code)
bt type;
gfc_try t;
- if (code->expr == NULL)
+ if (code->expr1 == NULL)
{
/* This was actually a computed GOTO statement. */
case_expr = code->expr2;
@@ -5856,12 +5876,12 @@ resolve_select (gfc_code *code)
by the compiler, so it should always be OK. Just move the
case_expr from expr2 to expr so that we can handle computed
GOTOs as normal SELECTs from here on. */
- code->expr = code->expr2;
+ code->expr1 = code->expr2;
code->expr2 = NULL;
return;
}
- case_expr = code->expr;
+ case_expr = code->expr1;
type = case_expr->ts.type;
if (type != BT_LOGICAL && type != BT_INTEGER && type != BT_CHARACTER)
@@ -6114,7 +6134,7 @@ resolve_transfer (gfc_code *code)
gfc_ref *ref;
gfc_expr *exp;
- exp = code->expr;
+ exp = code->expr1;
if (exp->expr_type != EXPR_VARIABLE && exp->expr_type != EXPR_FUNCTION)
return;
@@ -6123,7 +6143,7 @@ resolve_transfer (gfc_code *code)
ts = &sym->ts;
/* Go to actual component transferred. */
- for (ref = code->expr->ref; ref; ref = ref->next)
+ for (ref = code->expr1->ref; ref; ref = ref->next)
if (ref->type == REF_COMPONENT)
ts = &ref->u.c.component->ts;
@@ -6319,19 +6339,19 @@ resolve_where (gfc_code *code, gfc_expr *mask)
/* Store the first WHERE mask-expr of the WHERE statement or construct.
In case of nested WHERE, only the outmost one is stored. */
if (mask == NULL) /* outmost WHERE */
- e = cblock->expr;
+ e = cblock->expr1;
else /* inner WHERE */
e = mask;
while (cblock)
{
- if (cblock->expr)
+ if (cblock->expr1)
{
/* Check if the mask-expr has a consistent shape with the
outmost WHERE mask-expr. */
- if (resolve_where_shape (cblock->expr, e) == FAILURE)
+ if (resolve_where_shape (cblock->expr1, e) == FAILURE)
gfc_error ("WHERE mask at %L has inconsistent shape",
- &cblock->expr->where);
+ &cblock->expr1->where);
}
/* the assignment statement of a WHERE statement, or the first
@@ -6345,9 +6365,9 @@ resolve_where (gfc_code *code, gfc_expr *mask)
case EXEC_ASSIGN:
/* Check shape consistent for WHERE assignment target. */
- if (e && resolve_where_shape (cnext->expr, e) == FAILURE)
+ if (e && resolve_where_shape (cnext->expr1, e) == FAILURE)
gfc_error ("WHERE assignment target at %L has "
- "inconsistent shape", &cnext->expr->where);
+ "inconsistent shape", &cnext->expr1->where);
break;
@@ -6393,21 +6413,21 @@ gfc_resolve_assign_in_forall (gfc_code *code, int nvar, gfc_expr **var_expr)
/* Check whether the assignment target is one of the FORALL index
variable. */
- if ((code->expr->expr_type == EXPR_VARIABLE)
- && (code->expr->symtree->n.sym == forall_index))
+ if ((code->expr1->expr_type == EXPR_VARIABLE)
+ && (code->expr1->symtree->n.sym == forall_index))
gfc_error ("Assignment to a FORALL index variable at %L",
- &code->expr->where);
+ &code->expr1->where);
else
{
/* If one of the FORALL index variables doesn't appear in the
assignment variable, then there could be a many-to-one
assignment. Emit a warning rather than an error because the
mask could be resolving this problem. */
- if (find_forall_index (code->expr, forall_index, 0) == FAILURE)
+ if (find_forall_index (code->expr1, forall_index, 0) == FAILURE)
gfc_warning ("The FORALL with index '%s' is not used on the "
"left side of the assignment at %L and so might "
"cause multiple assignment to this object",
- var_expr[n]->symtree->name, &code->expr->where);
+ var_expr[n]->symtree->name, &code->expr1->where);
}
}
}
@@ -6623,29 +6643,29 @@ gfc_resolve_blocks (gfc_code *b, gfc_namespace *ns)
for (; b; b = b->block)
{
- t = gfc_resolve_expr (b->expr);
+ t = gfc_resolve_expr (b->expr1);
if (gfc_resolve_expr (b->expr2) == FAILURE)
t = FAILURE;
switch (b->op)
{
case EXEC_IF:
- if (t == SUCCESS && b->expr != NULL
- && (b->expr->ts.type != BT_LOGICAL || b->expr->rank != 0))
+ if (t == SUCCESS && b->expr1 != NULL
+ && (b->expr1->ts.type != BT_LOGICAL || b->expr1->rank != 0))
gfc_error ("IF clause at %L requires a scalar LOGICAL expression",
- &b->expr->where);
+ &b->expr1->where);
break;
case EXEC_WHERE:
if (t == SUCCESS
- && b->expr != NULL
- && (b->expr->ts.type != BT_LOGICAL || b->expr->rank == 0))
+ && b->expr1 != NULL
+ && (b->expr1->ts.type != BT_LOGICAL || b->expr1->rank == 0))
gfc_error ("WHERE/ELSEWHERE clause at %L requires a LOGICAL array",
- &b->expr->where);
+ &b->expr1->where);
break;
case EXEC_GOTO:
- resolve_branch (b->label, b);
+ resolve_branch (b->label1, b);
break;
case EXEC_SELECT:
@@ -6719,7 +6739,7 @@ resolve_ordinary_assign (gfc_code *code, gfc_namespace *ns)
return true;
}
- lhs = code->expr;
+ lhs = code->expr1;
rhs = code->expr2;
if (rhs->is_boz
@@ -6888,7 +6908,7 @@ resolve_code (gfc_code *code, gfc_namespace *ns)
t = SUCCESS;
if (code->op != EXEC_COMPCALL && code->op != EXEC_CALL_PPC)
- t = gfc_resolve_expr (code->expr);
+ t = gfc_resolve_expr (code->expr1);
forall_flag = forall_save;
if (gfc_resolve_expr (code->expr2) == FAILURE)
@@ -6916,28 +6936,29 @@ resolve_code (gfc_code *code, gfc_namespace *ns)
break;
case EXEC_GOTO:
- if (code->expr != NULL)
+ if (code->expr1 != NULL)
{
- if (code->expr->ts.type != BT_INTEGER)
+ if (code->expr1->ts.type != BT_INTEGER)
gfc_error ("ASSIGNED GOTO statement at %L requires an "
- "INTEGER variable", &code->expr->where);
- else if (code->expr->symtree->n.sym->attr.assign != 1)
+ "INTEGER variable", &code->expr1->where);
+ else if (code->expr1->symtree->n.sym->attr.assign != 1)
gfc_error ("Variable '%s' has not been assigned a target "
- "label at %L", code->expr->symtree->n.sym->name,
- &code->expr->where);
+ "label at %L", code->expr1->symtree->n.sym->name,
+ &code->expr1->where);
}
else
- resolve_branch (code->label, code);
+ resolve_branch (code->label1, code);
break;
case EXEC_RETURN:
- if (code->expr != NULL
- && (code->expr->ts.type != BT_INTEGER || code->expr->rank))
+ if (code->expr1 != NULL
+ && (code->expr1->ts.type != BT_INTEGER || code->expr1->rank))
gfc_error ("Alternate RETURN statement at %L requires a SCALAR-"
- "INTEGER return specifier", &code->expr->where);
+ "INTEGER return specifier", &code->expr1->where);
break;
case EXEC_INIT_ASSIGN:
+ case EXEC_END_PROCEDURE:
break;
case EXEC_ASSIGN:
@@ -6950,44 +6971,44 @@ resolve_code (gfc_code *code, gfc_namespace *ns)
break;
case EXEC_LABEL_ASSIGN:
- if (code->label->defined == ST_LABEL_UNKNOWN)
+ if (code->label1->defined == ST_LABEL_UNKNOWN)
gfc_error ("Label %d referenced at %L is never defined",
- code->label->value, &code->label->where);
+ code->label1->value, &code->label1->where);
if (t == SUCCESS
- && (code->expr->expr_type != EXPR_VARIABLE
- || code->expr->symtree->n.sym->ts.type != BT_INTEGER
- || code->expr->symtree->n.sym->ts.kind
+ && (code->expr1->expr_type != EXPR_VARIABLE
+ || code->expr1->symtree->n.sym->ts.type != BT_INTEGER
+ || code->expr1->symtree->n.sym->ts.kind
!= gfc_default_integer_kind
- || code->expr->symtree->n.sym->as != NULL))
+ || code->expr1->symtree->n.sym->as != NULL))
gfc_error ("ASSIGN statement at %L requires a scalar "
- "default INTEGER variable", &code->expr->where);
+ "default INTEGER variable", &code->expr1->where);
break;
case EXEC_POINTER_ASSIGN:
if (t == FAILURE)
break;
- gfc_check_pointer_assign (code->expr, code->expr2);
+ gfc_check_pointer_assign (code->expr1, code->expr2);
break;
case EXEC_ARITHMETIC_IF:
if (t == SUCCESS
- && code->expr->ts.type != BT_INTEGER
- && code->expr->ts.type != BT_REAL)
+ && code->expr1->ts.type != BT_INTEGER
+ && code->expr1->ts.type != BT_REAL)
gfc_error ("Arithmetic IF statement at %L requires a numeric "
- "expression", &code->expr->where);
+ "expression", &code->expr1->where);
- resolve_branch (code->label, code);
+ resolve_branch (code->label1, code);
resolve_branch (code->label2, code);
resolve_branch (code->label3, code);
break;
case EXEC_IF:
- if (t == SUCCESS && code->expr != NULL
- && (code->expr->ts.type != BT_LOGICAL
- || code->expr->rank != 0))
+ if (t == SUCCESS && code->expr1 != NULL
+ && (code->expr1->ts.type != BT_LOGICAL
+ || code->expr1->rank != 0))
gfc_error ("IF clause at %L requires a scalar LOGICAL expression",
- &code->expr->where);
+ &code->expr1->where);
break;
case EXEC_CALL:
@@ -7019,13 +7040,13 @@ resolve_code (gfc_code *code, gfc_namespace *ns)
break;
case EXEC_DO_WHILE:
- if (code->expr == NULL)
+ if (code->expr1 == NULL)
gfc_internal_error ("resolve_code(): No expression on DO WHILE");
if (t == SUCCESS
- && (code->expr->rank != 0
- || code->expr->ts.type != BT_LOGICAL))
+ && (code->expr1->rank != 0
+ || code->expr1->ts.type != BT_LOGICAL))
gfc_error ("Exit condition of DO WHILE loop at %L must be "
- "a scalar LOGICAL expression", &code->expr->where);
+ "a scalar LOGICAL expression", &code->expr1->where);
break;
case EXEC_ALLOCATE:
@@ -7105,9 +7126,9 @@ resolve_code (gfc_code *code, gfc_namespace *ns)
case EXEC_FORALL:
resolve_forall_iterators (code->ext.forall_iterator);
- if (code->expr != NULL && code->expr->ts.type != BT_LOGICAL)
+ if (code->expr1 != NULL && code->expr1->ts.type != BT_LOGICAL)
gfc_error ("FORALL mask clause at %L requires a LOGICAL "
- "expression", &code->expr->where);
+ "expression", &code->expr1->where);
break;
case EXEC_OMP_ATOMIC:
@@ -7382,7 +7403,7 @@ resolve_index_expr (gfc_expr *e)
static gfc_try
resolve_charlen (gfc_charlen *cl)
{
- int i;
+ int i, k;
if (cl->resolved)
return SUCCESS;
@@ -7406,6 +7427,16 @@ resolve_charlen (gfc_charlen *cl)
gfc_replace_expr (cl->length, gfc_int_expr (0));
}
+ /* Check that the character length is not too large. */
+ k = gfc_validate_kind (BT_INTEGER, gfc_charlen_int_kind, false);
+ if (cl->length && cl->length->expr_type == EXPR_CONSTANT
+ && cl->length->ts.type == BT_INTEGER
+ && mpz_cmp (cl->length->value.integer, gfc_integer_kinds[k].huge) > 0)
+ {
+ gfc_error ("String length at %L is too large", &cl->length->where);
+ return FAILURE;
+ }
+
return SUCCESS;
}
@@ -7478,7 +7509,7 @@ build_init_assign (gfc_symbol *sym, gfc_expr *init)
/* Assign the default initializer to the l-value. */
init_st->loc = sym->declared_at;
init_st->op = EXEC_INIT_ASSIGN;
- init_st->expr = lval;
+ init_st->expr1 = lval;
init_st->expr2 = init;
}
@@ -8562,7 +8593,7 @@ check_generic_tbp_ambiguity (gfc_tbp_generic* t1, gfc_tbp_generic* t2,
}
/* Compare the interfaces. */
- if (gfc_compare_interfaces (sym1, sym2, 1))
+ if (gfc_compare_interfaces (sym1, sym2, 1, 0, NULL, 0))
{
gfc_error ("'%s' and '%s' for GENERIC '%s' at %L are ambiguous",
sym1->name, sym2->name, generic_name, &where);
@@ -9124,7 +9155,8 @@ resolve_fl_derived (gfc_symbol *sym)
&& sym != c->ts.derived)
add_dt_to_dt_list (c->ts.derived);
- if (c->attr.pointer || c->attr.allocatable || c->as == NULL)
+ if (c->attr.pointer || c->attr.proc_pointer || c->attr.allocatable
+ || c->as == NULL)
continue;
for (i = 0; i < c->as->rank; i++)
@@ -9374,16 +9406,26 @@ resolve_symbol (gfc_symbol *sym)
if (sym->attr.procedure && sym->ts.interface
&& sym->attr.if_source != IFSRC_DECL)
{
+ if (sym->ts.interface == sym)
+ {
+ gfc_error ("PROCEDURE '%s' at %L may not be used as its own "
+ "interface", sym->name, &sym->declared_at);
+ return;
+ }
if (sym->ts.interface->attr.procedure)
- gfc_error ("Interface '%s', used by procedure '%s' at %L, is declared "
- "in a later PROCEDURE statement", sym->ts.interface->name,
- sym->name,&sym->declared_at);
+ {
+ gfc_error ("Interface '%s', used by procedure '%s' at %L, is declared"
+ " in a later PROCEDURE statement", sym->ts.interface->name,
+ sym->name,&sym->declared_at);
+ return;
+ }
/* Get the attributes from the interface (now resolved). */
if (sym->ts.interface->attr.if_source
|| sym->ts.interface->attr.intrinsic)
{
gfc_symbol *ifc = sym->ts.interface;
+ resolve_symbol (ifc);
if (ifc->attr.intrinsic)
resolve_intrinsic (ifc, &ifc->declared_at);
@@ -9819,9 +9861,12 @@ values;
static gfc_try
next_data_value (void)
{
-
while (mpz_cmp_ui (values.left, 0) == 0)
{
+ if (!gfc_is_constant_expr (values.vnode->expr))
+ gfc_error ("non-constant DATA value at %L",
+ &values.vnode->expr->where);
+
if (values.vnode->next == NULL)
return FAILURE;
diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c
index 7be4671acfb..5269e8f206e 100644
--- a/gcc/fortran/simplify.c
+++ b/gcc/fortran/simplify.c
@@ -27,6 +27,10 @@ along with GCC; see the file COPYING3. If not see
#include "intrinsic.h"
#include "target-memory.h"
+/* Savely advance an array constructor by 'n' elements.
+ Mainly used by simplifiers of transformational intrinsics. */
+#define ADVANCE(ctor, n) do { int i; for (i = 0; i < n && ctor; ++i) ctor = ctor->next; } while (0)
+
gfc_expr gfc_bad_expr;
@@ -210,6 +214,418 @@ convert_mpz_to_signed (mpz_t x, int bitsize)
}
}
+/* Helper function to convert to/from mpfr_t & mpc_t and call the
+ supplied mpc function on the respective values. */
+
+#ifdef HAVE_mpc
+static void
+call_mpc_func (mpfr_ptr result_re, mpfr_ptr result_im,
+ mpfr_srcptr input_re, mpfr_srcptr input_im,
+ int (*func)(mpc_ptr, mpc_srcptr, mpc_rnd_t))
+{
+ mpc_t c;
+ mpc_init2 (c, mpfr_get_default_prec());
+ mpc_set_fr_fr (c, input_re, input_im, GFC_MPC_RND_MODE);
+ func (c, c, GFC_MPC_RND_MODE);
+ mpfr_set (result_re, mpc_realref (c), GFC_RND_MODE);
+ mpfr_set (result_im, mpc_imagref (c), GFC_RND_MODE);
+ mpc_clear (c);
+}
+#endif
+
+
+/* Test that the expression is an constant array. */
+
+static bool
+is_constant_array_expr (gfc_expr *e)
+{
+ gfc_constructor *c;
+
+ if (e == NULL)
+ return true;
+
+ if (e->expr_type != EXPR_ARRAY || !gfc_is_constant_expr (e))
+ return false;
+
+ for (c = e->value.constructor; c; c = c->next)
+ if (c->expr->expr_type != EXPR_CONSTANT)
+ return false;
+
+ return true;
+}
+
+
+/* Initialize a transformational result expression with a given value. */
+
+static void
+init_result_expr (gfc_expr *e, int init, gfc_expr *array)
+{
+ if (e && e->expr_type == EXPR_ARRAY)
+ {
+ gfc_constructor *ctor = e->value.constructor;
+ while (ctor)
+ {
+ init_result_expr (ctor->expr, init, array);
+ ctor = ctor->next;
+ }
+ }
+ else if (e && e->expr_type == EXPR_CONSTANT)
+ {
+ int i = gfc_validate_kind (e->ts.type, e->ts.kind, false);
+ int length;
+ gfc_char_t *string;
+
+ switch (e->ts.type)
+ {
+ case BT_LOGICAL:
+ e->value.logical = (init ? 1 : 0);
+ break;
+
+ case BT_INTEGER:
+ if (init == INT_MIN)
+ mpz_set (e->value.integer, gfc_integer_kinds[i].min_int);
+ else if (init == INT_MAX)
+ mpz_set (e->value.integer, gfc_integer_kinds[i].huge);
+ else
+ mpz_set_si (e->value.integer, init);
+ break;
+
+ case BT_REAL:
+ if (init == INT_MIN)
+ {
+ mpfr_set (e->value.real, gfc_real_kinds[i].huge, GFC_RND_MODE);
+ mpfr_neg (e->value.real, e->value.real, GFC_RND_MODE);
+ }
+ else if (init == INT_MAX)
+ mpfr_set (e->value.real, gfc_real_kinds[i].huge, GFC_RND_MODE);
+ else
+ mpfr_set_si (e->value.real, init, GFC_RND_MODE);
+ break;
+
+ case BT_COMPLEX:
+ mpfr_set_si (e->value.complex.r, init, GFC_RND_MODE);
+ mpfr_set_si (e->value.complex.i, 0, GFC_RND_MODE);
+ break;
+
+ case BT_CHARACTER:
+ if (init == INT_MIN)
+ {
+ gfc_expr *len = gfc_simplify_len (array, NULL);
+ gfc_extract_int (len, &length);
+ string = gfc_get_wide_string (length + 1);
+ gfc_wide_memset (string, 0, length);
+ }
+ else if (init == INT_MAX)
+ {
+ gfc_expr *len = gfc_simplify_len (array, NULL);
+ gfc_extract_int (len, &length);
+ string = gfc_get_wide_string (length + 1);
+ gfc_wide_memset (string, 255, length);
+ }
+ else
+ {
+ length = 0;
+ string = gfc_get_wide_string (1);
+ }
+
+ string[length] = '\0';
+ e->value.character.length = length;
+ e->value.character.string = string;
+ break;
+
+ default:
+ gcc_unreachable();
+ }
+ }
+ else
+ gcc_unreachable();
+}
+
+
+/* Helper function for gfc_simplify_dot_product() and gfc_simplify_matmul. */
+
+static gfc_expr *
+compute_dot_product (gfc_constructor *ctor_a, int stride_a,
+ gfc_constructor *ctor_b, int stride_b)
+{
+ gfc_expr *result;
+ gfc_expr *a = ctor_a->expr, *b = ctor_b->expr;
+
+ gcc_assert (gfc_compare_types (&a->ts, &b->ts));
+
+ result = gfc_constant_result (a->ts.type, a->ts.kind, &a->where);
+ init_result_expr (result, 0, NULL);
+
+ while (ctor_a && ctor_b)
+ {
+ /* Copying of expressions is required as operands are free'd
+ by the gfc_arith routines. */
+ switch (result->ts.type)
+ {
+ case BT_LOGICAL:
+ result = gfc_or (result,
+ gfc_and (gfc_copy_expr (ctor_a->expr),
+ gfc_copy_expr (ctor_b->expr)));
+ break;
+
+ case BT_INTEGER:
+ case BT_REAL:
+ case BT_COMPLEX:
+ result = gfc_add (result,
+ gfc_multiply (gfc_copy_expr (ctor_a->expr),
+ gfc_copy_expr (ctor_b->expr)));
+ break;
+
+ default:
+ gcc_unreachable();
+ }
+
+ ADVANCE (ctor_a, stride_a);
+ ADVANCE (ctor_b, stride_b);
+ }
+
+ return result;
+}
+
+
+/* Build a result expression for transformational intrinsics,
+ depending on DIM. */
+
+static gfc_expr *
+transformational_result (gfc_expr *array, gfc_expr *dim, bt type,
+ int kind, locus* where)
+{
+ gfc_expr *result;
+ int i, nelem;
+
+ if (!dim || array->rank == 1)
+ return gfc_constant_result (type, kind, where);
+
+ result = gfc_start_constructor (type, kind, where);
+ result->shape = gfc_copy_shape_excluding (array->shape, array->rank, dim);
+ result->rank = array->rank - 1;
+
+ /* gfc_array_size() would count the number of elements in the constructor,
+ we have not built those yet. */
+ nelem = 1;
+ for (i = 0; i < result->rank; ++i)
+ nelem *= mpz_get_ui (result->shape[i]);
+
+ for (i = 0; i < nelem; ++i)
+ {
+ gfc_expr *e = gfc_constant_result (type, kind, where);
+ gfc_append_constructor (result, e);
+ }
+
+ return result;
+}
+
+
+typedef gfc_expr* (*transformational_op)(gfc_expr*, gfc_expr*);
+
+/* Wrapper function, implements 'op1 += 1'. Only called if MASK
+ of COUNT intrinsic is .TRUE..
+
+ Interface and implimentation mimics arith functions as
+ gfc_add, gfc_multiply, etc. */
+
+static gfc_expr* gfc_count (gfc_expr *op1, gfc_expr *op2)
+{
+ gfc_expr *result;
+
+ gcc_assert (op1->ts.type == BT_INTEGER);
+ gcc_assert (op2->ts.type == BT_LOGICAL);
+ gcc_assert (op2->value.logical);
+
+ result = gfc_copy_expr (op1);
+ mpz_add_ui (result->value.integer, result->value.integer, 1);
+
+ gfc_free_expr (op1);
+ gfc_free_expr (op2);
+ return result;
+}
+
+
+/* Transforms an ARRAY with operation OP, according to MASK, to a
+ scalar RESULT. E.g. called if
+
+ REAL, PARAMETER :: array(n, m) = ...
+ REAL, PARAMETER :: s = SUM(array)
+
+ where OP == gfc_add(). */
+
+static gfc_expr *
+simplify_transformation_to_scalar (gfc_expr *result, gfc_expr *array, gfc_expr *mask,
+ transformational_op op)
+{
+ gfc_expr *a, *m;
+ gfc_constructor *array_ctor, *mask_ctor;
+
+ /* Shortcut for constant .FALSE. MASK. */
+ if (mask
+ && mask->expr_type == EXPR_CONSTANT
+ && !mask->value.logical)
+ return result;
+
+ array_ctor = array->value.constructor;
+ mask_ctor = NULL;
+ if (mask && mask->expr_type == EXPR_ARRAY)
+ mask_ctor = mask->value.constructor;
+
+ while (array_ctor)
+ {
+ a = array_ctor->expr;
+ array_ctor = array_ctor->next;
+
+ /* A constant MASK equals .TRUE. here and can be ignored. */
+ if (mask_ctor)
+ {
+ m = mask_ctor->expr;
+ mask_ctor = mask_ctor->next;
+ if (!m->value.logical)
+ continue;
+ }
+
+ result = op (result, gfc_copy_expr (a));
+ }
+
+ return result;
+}
+
+/* Transforms an ARRAY with operation OP, according to MASK, to an
+ array RESULT. E.g. called if
+
+ REAL, PARAMETER :: array(n, m) = ...
+ REAL, PARAMETER :: s(n) = PROD(array, DIM=1)
+
+ where OP == gfc_multiply(). */
+
+static gfc_expr *
+simplify_transformation_to_array (gfc_expr *result, gfc_expr *array, gfc_expr *dim,
+ gfc_expr *mask, transformational_op op)
+{
+ mpz_t size;
+ int done, i, n, arraysize, resultsize, dim_index, dim_extent, dim_stride;
+ gfc_expr **arrayvec, **resultvec, **base, **src, **dest;
+ gfc_constructor *array_ctor, *mask_ctor, *result_ctor;
+
+ int count[GFC_MAX_DIMENSIONS], extent[GFC_MAX_DIMENSIONS],
+ sstride[GFC_MAX_DIMENSIONS], dstride[GFC_MAX_DIMENSIONS],
+ tmpstride[GFC_MAX_DIMENSIONS];
+
+ /* Shortcut for constant .FALSE. MASK. */
+ if (mask
+ && mask->expr_type == EXPR_CONSTANT
+ && !mask->value.logical)
+ return result;
+
+ /* Build an indexed table for array element expressions to minimize
+ linked-list traversal. Masked elements are set to NULL. */
+ gfc_array_size (array, &size);
+ arraysize = mpz_get_ui (size);
+
+ arrayvec = (gfc_expr**) gfc_getmem (sizeof (gfc_expr*) * arraysize);
+
+ array_ctor = array->value.constructor;
+ mask_ctor = NULL;
+ if (mask && mask->expr_type == EXPR_ARRAY)
+ mask_ctor = mask->value.constructor;
+
+ for (i = 0; i < arraysize; ++i)
+ {
+ arrayvec[i] = array_ctor->expr;
+ array_ctor = array_ctor->next;
+
+ if (mask_ctor)
+ {
+ if (!mask_ctor->expr->value.logical)
+ arrayvec[i] = NULL;
+
+ mask_ctor = mask_ctor->next;
+ }
+ }
+
+ /* Same for the result expression. */
+ gfc_array_size (result, &size);
+ resultsize = mpz_get_ui (size);
+ mpz_clear (size);
+
+ resultvec = (gfc_expr**) gfc_getmem (sizeof (gfc_expr*) * resultsize);
+ result_ctor = result->value.constructor;
+ for (i = 0; i < resultsize; ++i)
+ {
+ resultvec[i] = result_ctor->expr;
+ result_ctor = result_ctor->next;
+ }
+
+ gfc_extract_int (dim, &dim_index);
+ dim_index -= 1; /* zero-base index */
+ dim_extent = 0;
+ dim_stride = 0;
+
+ for (i = 0, n = 0; i < array->rank; ++i)
+ {
+ count[i] = 0;
+ tmpstride[i] = (i == 0) ? 1 : tmpstride[i-1] * mpz_get_si (array->shape[i-1]);
+ if (i == dim_index)
+ {
+ dim_extent = mpz_get_si (array->shape[i]);
+ dim_stride = tmpstride[i];
+ continue;
+ }
+
+ extent[n] = mpz_get_si (array->shape[i]);
+ sstride[n] = tmpstride[i];
+ dstride[n] = (n == 0) ? 1 : dstride[n-1] * extent[n-1];
+ n += 1;
+ }
+
+ done = false;
+ base = arrayvec;
+ dest = resultvec;
+ while (!done)
+ {
+ for (src = base, n = 0; n < dim_extent; src += dim_stride, ++n)
+ if (*src)
+ *dest = op (*dest, gfc_copy_expr (*src));
+
+ count[0]++;
+ base += sstride[0];
+ dest += dstride[0];
+
+ n = 0;
+ while (!done && count[n] == extent[n])
+ {
+ count[n] = 0;
+ base -= sstride[n] * extent[n];
+ dest -= dstride[n] * extent[n];
+
+ n++;
+ if (n < result->rank)
+ {
+ count [n]++;
+ base += sstride[n];
+ dest += dstride[n];
+ }
+ else
+ done = true;
+ }
+ }
+
+ /* Place updated expression in result constructor. */
+ result_ctor = result->value.constructor;
+ for (i = 0; i < resultsize; ++i)
+ {
+ result_ctor->expr = resultvec[i];
+ result_ctor = result_ctor->next;
+ }
+
+ gfc_free (arrayvec);
+ gfc_free (resultvec);
+ return result;
+}
+
+
/********************** Simplification functions *****************************/
@@ -482,6 +898,25 @@ gfc_simplify_aint (gfc_expr *e, gfc_expr *k)
gfc_expr *
+gfc_simplify_all (gfc_expr *mask, gfc_expr *dim)
+{
+ gfc_expr *result;
+
+ if (!is_constant_array_expr (mask)
+ || !gfc_is_constant_expr (dim))
+ return NULL;
+
+ result = transformational_result (mask, dim, mask->ts.type,
+ mask->ts.kind, &mask->where);
+ init_result_expr (result, true, NULL);
+
+ return !dim || mask->rank == 1 ?
+ simplify_transformation_to_scalar (result, mask, NULL, gfc_and) :
+ simplify_transformation_to_array (result, mask, dim, NULL, gfc_and);
+}
+
+
+gfc_expr *
gfc_simplify_dint (gfc_expr *e)
{
gfc_expr *rtrunc, *result;
@@ -547,6 +982,25 @@ gfc_simplify_and (gfc_expr *x, gfc_expr *y)
gfc_expr *
+gfc_simplify_any (gfc_expr *mask, gfc_expr *dim)
+{
+ gfc_expr *result;
+
+ if (!is_constant_array_expr (mask)
+ || !gfc_is_constant_expr (dim))
+ return NULL;
+
+ result = transformational_result (mask, dim, mask->ts.type,
+ mask->ts.kind, &mask->where);
+ init_result_expr (result, false, NULL);
+
+ return !dim || mask->rank == 1 ?
+ simplify_transformation_to_scalar (result, mask, NULL, gfc_or) :
+ simplify_transformation_to_array (result, mask, dim, NULL, gfc_or);
+}
+
+
+gfc_expr *
gfc_simplify_dnint (gfc_expr *e)
{
gfc_expr *result;
@@ -985,7 +1439,6 @@ gfc_expr *
gfc_simplify_cos (gfc_expr *x)
{
gfc_expr *result;
- mpfr_t xp, xq;
if (x->expr_type != EXPR_CONSTANT)
return NULL;
@@ -999,6 +1452,12 @@ gfc_simplify_cos (gfc_expr *x)
break;
case BT_COMPLEX:
gfc_set_model_kind (x->ts.kind);
+#ifdef HAVE_mpc
+ call_mpc_func (result->value.complex.r, result->value.complex.i,
+ x->value.complex.r, x->value.complex.i, mpc_cos);
+#else
+ {
+ mpfr_t xp, xq;
mpfr_init (xp);
mpfr_init (xq);
@@ -1012,6 +1471,8 @@ gfc_simplify_cos (gfc_expr *x)
mpfr_neg (result->value.complex.i, xp, GFC_RND_MODE );
mpfr_clears (xp, xq, NULL);
+ }
+#endif
break;
default:
gfc_internal_error ("in gfc_simplify_cos(): Bad type");
@@ -1039,6 +1500,32 @@ gfc_simplify_cosh (gfc_expr *x)
gfc_expr *
+gfc_simplify_count (gfc_expr *mask, gfc_expr *dim, gfc_expr *kind)
+{
+ gfc_expr *result;
+
+ if (!is_constant_array_expr (mask)
+ || !gfc_is_constant_expr (dim)
+ || !gfc_is_constant_expr (kind))
+ return NULL;
+
+ result = transformational_result (mask, dim,
+ BT_INTEGER,
+ get_kind (BT_INTEGER, kind, "COUNT",
+ gfc_default_integer_kind),
+ &mask->where);
+
+ init_result_expr (result, 0, NULL);
+
+ /* Passing MASK twice, once as data array, once as mask.
+ Whenever gfc_count is called, '1' is added to the result. */
+ return !dim || mask->rank == 1 ?
+ simplify_transformation_to_scalar (result, mask, mask, gfc_count) :
+ simplify_transformation_to_array (result, mask, dim, mask, gfc_count);
+}
+
+
+gfc_expr *
gfc_simplify_dcmplx (gfc_expr *x, gfc_expr *y)
{
@@ -1159,6 +1646,32 @@ gfc_simplify_dim (gfc_expr *x, gfc_expr *y)
}
+gfc_expr*
+gfc_simplify_dot_product (gfc_expr *vector_a, gfc_expr *vector_b)
+{
+ gfc_expr *result;
+
+ if (!is_constant_array_expr (vector_a)
+ || !is_constant_array_expr (vector_b))
+ return NULL;
+
+ gcc_assert (vector_a->rank == 1);
+ gcc_assert (vector_b->rank == 1);
+ gcc_assert (gfc_compare_types (&vector_a->ts, &vector_b->ts));
+
+ if (vector_a->value.constructor && vector_b->value.constructor)
+ return compute_dot_product (vector_a->value.constructor, 1,
+ vector_b->value.constructor, 1);
+
+ /* Zero sized array ... */
+ result = gfc_constant_result (vector_a->ts.type,
+ vector_a->ts.kind,
+ &vector_a->where);
+ init_result_expr (result, 0, NULL);
+ return result;
+}
+
+
gfc_expr *
gfc_simplify_dprod (gfc_expr *x, gfc_expr *y)
{
@@ -1213,6 +1726,143 @@ gfc_simplify_erfc (gfc_expr *x)
}
+/* Helper functions to simplify ERFC_SCALED(x) = ERFC(x) * EXP(X**2). */
+
+#define MAX_ITER 200
+#define ARG_LIMIT 12
+
+/* Calculate ERFC_SCALED directly by its definition:
+
+ ERFC_SCALED(x) = ERFC(x) * EXP(X**2)
+
+ using a large precision for intermediate results. This is used for all
+ but large values of the argument. */
+static void
+fullprec_erfc_scaled (mpfr_t res, mpfr_t arg)
+{
+ mp_prec_t prec;
+ mpfr_t a, b;
+
+ prec = mpfr_get_default_prec ();
+ mpfr_set_default_prec (10 * prec);
+
+ mpfr_init (a);
+ mpfr_init (b);
+
+ mpfr_set (a, arg, GFC_RND_MODE);
+ mpfr_sqr (b, a, GFC_RND_MODE);
+ mpfr_exp (b, b, GFC_RND_MODE);
+ mpfr_erfc (a, a, GFC_RND_MODE);
+ mpfr_mul (a, a, b, GFC_RND_MODE);
+
+ mpfr_set (res, a, GFC_RND_MODE);
+ mpfr_set_default_prec (prec);
+
+ mpfr_clear (a);
+ mpfr_clear (b);
+}
+
+/* Calculate ERFC_SCALED using a power series expansion in 1/arg:
+
+ ERFC_SCALED(x) = 1 / (x * sqrt(pi))
+ * (1 + Sum_n (-1)**n * (1 * 3 * 5 * ... * (2n-1))
+ / (2 * x**2)**n)
+
+ This is used for large values of the argument. Intermediate calculations
+ are performed with twice the precision. We don't do a fixed number of
+ iterations of the sum, but stop when it has converged to the required
+ precision. */
+static void
+asympt_erfc_scaled (mpfr_t res, mpfr_t arg)
+{
+ mpfr_t sum, x, u, v, w, oldsum, sumtrunc;
+ mpz_t num;
+ mp_prec_t prec;
+ unsigned i;
+
+ prec = mpfr_get_default_prec ();
+ mpfr_set_default_prec (2 * prec);
+
+ mpfr_init (sum);
+ mpfr_init (x);
+ mpfr_init (u);
+ mpfr_init (v);
+ mpfr_init (w);
+ mpz_init (num);
+
+ mpfr_init (oldsum);
+ mpfr_init (sumtrunc);
+ mpfr_set_prec (oldsum, prec);
+ mpfr_set_prec (sumtrunc, prec);
+
+ mpfr_set (x, arg, GFC_RND_MODE);
+ mpfr_set_ui (sum, 1, GFC_RND_MODE);
+ mpz_set_ui (num, 1);
+
+ mpfr_set (u, x, GFC_RND_MODE);
+ mpfr_sqr (u, u, GFC_RND_MODE);
+ mpfr_mul_ui (u, u, 2, GFC_RND_MODE);
+ mpfr_pow_si (u, u, -1, GFC_RND_MODE);
+
+ for (i = 1; i < MAX_ITER; i++)
+ {
+ mpfr_set (oldsum, sum, GFC_RND_MODE);
+
+ mpz_mul_ui (num, num, 2 * i - 1);
+ mpz_neg (num, num);
+
+ mpfr_set (w, u, GFC_RND_MODE);
+ mpfr_pow_ui (w, w, i, GFC_RND_MODE);
+
+ mpfr_set_z (v, num, GFC_RND_MODE);
+ mpfr_mul (v, v, w, GFC_RND_MODE);
+
+ mpfr_add (sum, sum, v, GFC_RND_MODE);
+
+ mpfr_set (sumtrunc, sum, GFC_RND_MODE);
+ if (mpfr_cmp (sumtrunc, oldsum) == 0)
+ break;
+ }
+
+ /* We should have converged by now; otherwise, ARG_LIMIT is probably
+ set too low. */
+ gcc_assert (i < MAX_ITER);
+
+ /* Divide by x * sqrt(Pi). */
+ mpfr_const_pi (u, GFC_RND_MODE);
+ mpfr_sqrt (u, u, GFC_RND_MODE);
+ mpfr_mul (u, u, x, GFC_RND_MODE);
+ mpfr_div (sum, sum, u, GFC_RND_MODE);
+
+ mpfr_set (res, sum, GFC_RND_MODE);
+ mpfr_set_default_prec (prec);
+
+ mpfr_clears (sum, x, u, v, w, oldsum, sumtrunc, NULL);
+ mpz_clear (num);
+}
+
+
+gfc_expr *
+gfc_simplify_erfc_scaled (gfc_expr *x)
+{
+ gfc_expr *result;
+
+ if (x->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ result = gfc_constant_result (x->ts.type, x->ts.kind, &x->where);
+ if (mpfr_cmp_d (x->value.real, ARG_LIMIT) >= 0)
+ asympt_erfc_scaled (result->value.real, x->value.real);
+ else
+ fullprec_erfc_scaled (result->value.real, x->value.real);
+
+ return range_check (result, "ERFC_SCALED");
+}
+
+#undef MAX_ITER
+#undef ARG_LIMIT
+
+
gfc_expr *
gfc_simplify_epsilon (gfc_expr *e)
{
@@ -1233,7 +1883,6 @@ gfc_expr *
gfc_simplify_exp (gfc_expr *x)
{
gfc_expr *result;
- mpfr_t xp, xq;
if (x->expr_type != EXPR_CONSTANT)
return NULL;
@@ -1248,6 +1897,12 @@ gfc_simplify_exp (gfc_expr *x)
case BT_COMPLEX:
gfc_set_model_kind (x->ts.kind);
+#ifdef HAVE_mpc
+ call_mpc_func (result->value.complex.r, result->value.complex.i,
+ x->value.complex.r, x->value.complex.i, mpc_exp);
+#else
+ {
+ mpfr_t xp, xq;
mpfr_init (xp);
mpfr_init (xq);
mpfr_exp (xq, x->value.complex.r, GFC_RND_MODE);
@@ -1256,6 +1911,8 @@ gfc_simplify_exp (gfc_expr *x)
mpfr_sin (xp, x->value.complex.i, GFC_RND_MODE);
mpfr_mul (result->value.complex.i, xq, xp, GFC_RND_MODE);
mpfr_clears (xp, xq, NULL);
+ }
+#endif
break;
default:
@@ -1969,6 +2626,54 @@ gfc_simplify_ior (gfc_expr *x, gfc_expr *y)
gfc_expr *
+gfc_simplify_is_iostat_end (gfc_expr *x)
+{
+ gfc_expr *result;
+
+ if (x->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ result = gfc_constant_result (BT_LOGICAL, gfc_default_logical_kind,
+ &x->where);
+ result->value.logical = (mpz_cmp_si (x->value.integer, LIBERROR_END) == 0);
+
+ return result;
+}
+
+
+gfc_expr *
+gfc_simplify_is_iostat_eor (gfc_expr *x)
+{
+ gfc_expr *result;
+
+ if (x->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ result = gfc_constant_result (BT_LOGICAL, gfc_default_logical_kind,
+ &x->where);
+ result->value.logical = (mpz_cmp_si (x->value.integer, LIBERROR_EOR) == 0);
+
+ return result;
+}
+
+
+gfc_expr *
+gfc_simplify_isnan (gfc_expr *x)
+{
+ gfc_expr *result;
+
+ if (x->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ result = gfc_constant_result (BT_LOGICAL, gfc_default_logical_kind,
+ &x->where);
+ result->value.logical = mpfr_nan_p (x->value.real);
+
+ return result;
+}
+
+
+gfc_expr *
gfc_simplify_ishft (gfc_expr *e, gfc_expr *s)
{
gfc_expr *result;
@@ -2410,10 +3115,13 @@ gfc_simplify_leadz (gfc_expr *e)
bs = gfc_integer_kinds[i].bit_size;
if (mpz_cmp_si (e->value.integer, 0) == 0)
lz = bs;
+ else if (mpz_cmp_si (e->value.integer, 0) < 0)
+ lz = 0;
else
lz = bs - mpz_sizeinbase (e->value.integer, 2);
- result = gfc_constant_result (BT_INTEGER, gfc_default_integer_kind, &e->where);
+ result = gfc_constant_result (BT_INTEGER, gfc_default_integer_kind,
+ &e->where);
mpz_set_ui (result->value.integer, lz);
return result;
@@ -2433,7 +3141,13 @@ gfc_simplify_len (gfc_expr *e, gfc_expr *kind)
{
result = gfc_constant_result (BT_INTEGER, k, &e->where);
mpz_set_si (result->value.integer, e->value.character.length);
- return range_check (result, "LEN");
+ if (gfc_range_check (result) == ARITH_OK)
+ return result;
+ else
+ {
+ gfc_free_expr (result);
+ return NULL;
+ }
}
if (e->ts.cl != NULL && e->ts.cl->length != NULL
@@ -2442,7 +3156,13 @@ gfc_simplify_len (gfc_expr *e, gfc_expr *kind)
{
result = gfc_constant_result (BT_INTEGER, k, &e->where);
mpz_set (result->value.integer, e->ts.cl->length->value.integer);
- return range_check (result, "LEN");
+ if (gfc_range_check (result) == ARITH_OK)
+ return result;
+ else
+ {
+ gfc_free_expr (result);
+ return NULL;
+ }
}
return NULL;
@@ -2539,7 +3259,6 @@ gfc_expr *
gfc_simplify_log (gfc_expr *x)
{
gfc_expr *result;
- mpfr_t xr, xi;
if (x->expr_type != EXPR_CONSTANT)
return NULL;
@@ -2572,6 +3291,12 @@ gfc_simplify_log (gfc_expr *x)
}
gfc_set_model_kind (x->ts.kind);
+#ifdef HAVE_mpc
+ call_mpc_func (result->value.complex.r, result->value.complex.i,
+ x->value.complex.r, x->value.complex.i, mpc_log);
+#else
+ {
+ mpfr_t xr, xi;
mpfr_init (xr);
mpfr_init (xi);
@@ -2585,7 +3310,8 @@ gfc_simplify_log (gfc_expr *x)
mpfr_log (result->value.complex.r, xr, GFC_RND_MODE);
mpfr_clears (xr, xi, NULL);
-
+ }
+#endif
break;
default:
@@ -2640,6 +3366,84 @@ gfc_simplify_logical (gfc_expr *e, gfc_expr *k)
}
+gfc_expr*
+gfc_simplify_matmul (gfc_expr *matrix_a, gfc_expr *matrix_b)
+{
+ gfc_expr *result;
+ gfc_constructor *ma_ctor, *mb_ctor;
+ int row, result_rows, col, result_columns, stride_a, stride_b;
+
+ if (!is_constant_array_expr (matrix_a)
+ || !is_constant_array_expr (matrix_b))
+ return NULL;
+
+ gcc_assert (gfc_compare_types (&matrix_a->ts, &matrix_b->ts));
+ result = gfc_start_constructor (matrix_a->ts.type,
+ matrix_a->ts.kind,
+ &matrix_a->where);
+
+ if (matrix_a->rank == 1 && matrix_b->rank == 2)
+ {
+ result_rows = 1;
+ result_columns = mpz_get_si (matrix_b->shape[0]);
+ stride_a = 1;
+ stride_b = mpz_get_si (matrix_b->shape[0]);
+
+ result->rank = 1;
+ result->shape = gfc_get_shape (result->rank);
+ mpz_init_set_si (result->shape[0], result_columns);
+ }
+ else if (matrix_a->rank == 2 && matrix_b->rank == 1)
+ {
+ result_rows = mpz_get_si (matrix_b->shape[0]);
+ result_columns = 1;
+ stride_a = mpz_get_si (matrix_a->shape[0]);
+ stride_b = 1;
+
+ result->rank = 1;
+ result->shape = gfc_get_shape (result->rank);
+ mpz_init_set_si (result->shape[0], result_rows);
+ }
+ else if (matrix_a->rank == 2 && matrix_b->rank == 2)
+ {
+ result_rows = mpz_get_si (matrix_a->shape[0]);
+ result_columns = mpz_get_si (matrix_b->shape[1]);
+ stride_a = mpz_get_si (matrix_a->shape[1]);
+ stride_b = mpz_get_si (matrix_b->shape[0]);
+
+ result->rank = 2;
+ result->shape = gfc_get_shape (result->rank);
+ mpz_init_set_si (result->shape[0], result_rows);
+ mpz_init_set_si (result->shape[1], result_columns);
+ }
+ else
+ gcc_unreachable();
+
+ ma_ctor = matrix_a->value.constructor;
+ mb_ctor = matrix_b->value.constructor;
+
+ for (col = 0; col < result_columns; ++col)
+ {
+ ma_ctor = matrix_a->value.constructor;
+
+ for (row = 0; row < result_rows; ++row)
+ {
+ gfc_expr *e;
+ e = compute_dot_product (ma_ctor, stride_a,
+ mb_ctor, 1);
+
+ gfc_append_constructor (result, e);
+
+ ADVANCE (ma_ctor, 1);
+ }
+
+ ADVANCE (mb_ctor, stride_b);
+ }
+
+ return result;
+}
+
+
gfc_expr *
gfc_simplify_merge (gfc_expr *tsource, gfc_expr *fsource, gfc_expr *mask)
{
@@ -3170,6 +3974,75 @@ gfc_simplify_or (gfc_expr *x, gfc_expr *y)
gfc_expr *
+gfc_simplify_pack (gfc_expr *array, gfc_expr *mask, gfc_expr *vector)
+{
+ gfc_expr *result;
+ gfc_constructor *array_ctor, *mask_ctor, *vector_ctor;
+
+ if (!is_constant_array_expr(array)
+ || !is_constant_array_expr(vector)
+ || (!gfc_is_constant_expr (mask)
+ && !is_constant_array_expr(mask)))
+ return NULL;
+
+ result = gfc_start_constructor (array->ts.type,
+ array->ts.kind,
+ &array->where);
+
+ array_ctor = array->value.constructor;
+ vector_ctor = vector ? vector->value.constructor : NULL;
+
+ if (mask->expr_type == EXPR_CONSTANT
+ && mask->value.logical)
+ {
+ /* Copy all elements of ARRAY to RESULT. */
+ while (array_ctor)
+ {
+ gfc_append_constructor (result,
+ gfc_copy_expr (array_ctor->expr));
+
+ ADVANCE (array_ctor, 1);
+ ADVANCE (vector_ctor, 1);
+ }
+ }
+ else if (mask->expr_type == EXPR_ARRAY)
+ {
+ /* Copy only those elements of ARRAY to RESULT whose
+ MASK equals .TRUE.. */
+ mask_ctor = mask->value.constructor;
+ while (mask_ctor)
+ {
+ if (mask_ctor->expr->value.logical)
+ {
+ gfc_append_constructor (result,
+ gfc_copy_expr (array_ctor->expr));
+ ADVANCE (vector_ctor, 1);
+ }
+
+ ADVANCE (array_ctor, 1);
+ ADVANCE (mask_ctor, 1);
+ }
+ }
+
+ /* Append any left-over elements from VECTOR to RESULT. */
+ while (vector_ctor)
+ {
+ gfc_append_constructor (result,
+ gfc_copy_expr (vector_ctor->expr));
+ ADVANCE (vector_ctor, 1);
+ }
+
+ result->shape = gfc_get_shape (1);
+ gfc_array_size (result, &result->shape[0]);
+
+ if (array->ts.type == BT_CHARACTER)
+ result->ts.cl = array->ts.cl;
+
+ return result;
+}
+
+
+gfc_expr *
gfc_simplify_precision (gfc_expr *e)
{
gfc_expr *result;
@@ -3185,6 +4058,30 @@ gfc_simplify_precision (gfc_expr *e)
gfc_expr *
+gfc_simplify_product (gfc_expr *array, gfc_expr *dim, gfc_expr *mask)
+{
+ gfc_expr *result;
+
+ if (!is_constant_array_expr (array)
+ || !gfc_is_constant_expr (dim))
+ return NULL;
+
+ if (mask
+ && !is_constant_array_expr (mask)
+ && mask->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ result = transformational_result (array, dim, array->ts.type,
+ array->ts.kind, &array->where);
+ init_result_expr (result, 1, NULL);
+
+ return !dim || array->rank == 1 ?
+ simplify_transformation_to_scalar (result, array, mask, gfc_multiply) :
+ simplify_transformation_to_array (result, array, dim, mask, gfc_multiply);
+}
+
+
+gfc_expr *
gfc_simplify_radix (gfc_expr *e)
{
gfc_expr *result;
@@ -3431,27 +4328,6 @@ gfc_simplify_repeat (gfc_expr *e, gfc_expr *n)
}
-/* Test that the expression is an constant array. */
-
-static bool
-is_constant_array_expr (gfc_expr *e)
-{
- gfc_constructor *c;
-
- if (e == NULL)
- return true;
-
- if (e->expr_type != EXPR_ARRAY || !gfc_is_constant_expr (e))
- return false;
-
- for (c = e->value.constructor; c; c = c->next)
- if (c->expr->expr_type != EXPR_CONSTANT)
- return false;
-
- return true;
-}
-
-
/* This one is a bear, but mainly has to do with shuffling elements. */
gfc_expr *
@@ -3467,16 +4343,10 @@ gfc_simplify_reshape (gfc_expr *source, gfc_expr *shape_exp,
gfc_expr *e;
/* Check that argument expression types are OK. */
- if (!is_constant_array_expr (source))
- return NULL;
-
- if (!is_constant_array_expr (shape_exp))
- return NULL;
-
- if (!is_constant_array_expr (pad))
- return NULL;
-
- if (!is_constant_array_expr (order_exp))
+ if (!is_constant_array_expr (source)
+ || !is_constant_array_expr (shape_exp)
+ || !is_constant_array_expr (pad)
+ || !is_constant_array_expr (order_exp))
return NULL;
/* Proceed with simplification, unpacking the array. */
@@ -3491,40 +4361,16 @@ gfc_simplify_reshape (gfc_expr *source, gfc_expr *shape_exp,
if (e == NULL)
break;
- if (gfc_extract_int (e, &shape[rank]) != NULL)
- {
- gfc_error ("Integer too large in shape specification at %L",
- &e->where);
- gfc_free_expr (e);
- goto bad_reshape;
- }
-
- if (rank >= GFC_MAX_DIMENSIONS)
- {
- gfc_error ("Too many dimensions in shape specification for RESHAPE "
- "at %L", &e->where);
- gfc_free_expr (e);
- goto bad_reshape;
- }
+ gfc_extract_int (e, &shape[rank]);
- if (shape[rank] < 0)
- {
- gfc_error ("Shape specification at %L cannot be negative",
- &e->where);
- gfc_free_expr (e);
- goto bad_reshape;
- }
+ gcc_assert (rank >= 0 && rank < GFC_MAX_DIMENSIONS);
+ gcc_assert (shape[rank] >= 0);
gfc_free_expr (e);
rank++;
}
- if (rank == 0)
- {
- gfc_error ("Shape specification at %L cannot be the null array",
- &shape_exp->where);
- goto bad_reshape;
- }
+ gcc_assert (rank > 0);
/* Now unpack the order array if present. */
if (order_exp == NULL)
@@ -3540,41 +4386,14 @@ gfc_simplify_reshape (gfc_expr *source, gfc_expr *shape_exp,
for (i = 0; i < rank; i++)
{
e = gfc_get_array_element (order_exp, i);
- if (e == NULL)
- {
- gfc_error ("ORDER parameter of RESHAPE at %L is not the same "
- "size as SHAPE parameter", &order_exp->where);
- goto bad_reshape;
- }
-
- if (gfc_extract_int (e, &order[i]) != NULL)
- {
- gfc_error ("Error in ORDER parameter of RESHAPE at %L",
- &e->where);
- gfc_free_expr (e);
- goto bad_reshape;
- }
-
- if (order[i] < 1 || order[i] > rank)
- {
- gfc_error ("ORDER parameter of RESHAPE at %L is out of range",
- &e->where);
- gfc_free_expr (e);
- goto bad_reshape;
- }
-
- order[i]--;
-
- if (x[order[i]])
- {
- gfc_error ("Invalid permutation in ORDER parameter at %L",
- &e->where);
- gfc_free_expr (e);
- goto bad_reshape;
- }
+ gcc_assert (e);
+ gfc_extract_int (e, &order[i]);
gfc_free_expr (e);
+ gcc_assert (order[i] >= 1 && order[i] <= rank);
+ order[i]--;
+ gcc_assert (x[order[i]] == 0);
x[order[i]] = 1;
}
}
@@ -3601,7 +4420,7 @@ gfc_simplify_reshape (gfc_expr *source, gfc_expr *shape_exp,
for (i = 0; i < rank; i++)
x[i] = 0;
- for (;;)
+ while (nsource > 0 || npad > 0)
{
/* Figure out which element to extract. */
mpz_set_ui (index, 0);
@@ -3622,18 +4441,13 @@ gfc_simplify_reshape (gfc_expr *source, gfc_expr *shape_exp,
e = gfc_get_array_element (source, j);
else
{
- j = j - nsource;
-
- if (npad == 0)
- {
- gfc_error ("PAD parameter required for short SOURCE parameter "
- "at %L", &source->where);
- goto bad_reshape;
- }
+ gcc_assert (npad > 0);
+ j = j - nsource;
j = j % npad;
e = gfc_get_array_element (pad, j);
}
+ gcc_assert (e);
if (head == NULL)
head = tail = gfc_get_constructor ();
@@ -3643,9 +4457,6 @@ gfc_simplify_reshape (gfc_expr *source, gfc_expr *shape_exp,
tail = tail->next;
}
- if (e == NULL)
- goto bad_reshape;
-
tail->where = e->where;
tail->expr = e;
@@ -3677,11 +4488,6 @@ inc:
e->rank = rank;
return e;
-
-bad_reshape:
- gfc_free_constructor (head);
- mpz_clear (index);
- return &gfc_bad_expr;
}
@@ -4165,7 +4971,6 @@ gfc_expr *
gfc_simplify_sin (gfc_expr *x)
{
gfc_expr *result;
- mpfr_t xp, xq;
if (x->expr_type != EXPR_CONSTANT)
return NULL;
@@ -4180,6 +4985,12 @@ gfc_simplify_sin (gfc_expr *x)
case BT_COMPLEX:
gfc_set_model (x->value.real);
+#ifdef HAVE_mpc
+ call_mpc_func (result->value.complex.r, result->value.complex.i,
+ x->value.complex.r, x->value.complex.i, mpc_sin);
+#else
+ {
+ mpfr_t xp, xq;
mpfr_init (xp);
mpfr_init (xq);
@@ -4192,6 +5003,8 @@ gfc_simplify_sin (gfc_expr *x)
mpfr_mul (result->value.complex.i, xp, xq, GFC_RND_MODE);
mpfr_clears (xp, xq, NULL);
+ }
+#endif
break;
default:
@@ -4273,10 +5086,102 @@ gfc_simplify_spacing (gfc_expr *x)
gfc_expr *
+gfc_simplify_spread (gfc_expr *source, gfc_expr *dim_expr, gfc_expr *ncopies_expr)
+{
+ gfc_expr *result = 0L;
+ int i, j, dim, ncopies;
+
+ if ((!gfc_is_constant_expr (source)
+ && !is_constant_array_expr (source))
+ || !gfc_is_constant_expr (dim_expr)
+ || !gfc_is_constant_expr (ncopies_expr))
+ return NULL;
+
+ gcc_assert (dim_expr->ts.type == BT_INTEGER);
+ gfc_extract_int (dim_expr, &dim);
+ dim -= 1; /* zero-base DIM */
+
+ gcc_assert (ncopies_expr->ts.type == BT_INTEGER);
+ gfc_extract_int (ncopies_expr, &ncopies);
+ ncopies = MAX (ncopies, 0);
+
+ if (source->expr_type == EXPR_CONSTANT)
+ {
+ gcc_assert (dim == 0);
+
+ result = gfc_start_constructor (source->ts.type,
+ source->ts.kind,
+ &source->where);
+ result->rank = 1;
+ result->shape = gfc_get_shape (result->rank);
+ mpz_init_set_si (result->shape[0], ncopies);
+
+ for (i = 0; i < ncopies; ++i)
+ gfc_append_constructor (result, gfc_copy_expr (source));
+ }
+ else if (source->expr_type == EXPR_ARRAY)
+ {
+ int result_size, rstride[GFC_MAX_DIMENSIONS], extent[GFC_MAX_DIMENSIONS];
+ gfc_constructor *ctor, *source_ctor, *result_ctor;
+
+ gcc_assert (source->rank < GFC_MAX_DIMENSIONS);
+ gcc_assert (dim >= 0 && dim <= source->rank);
+
+ result = gfc_start_constructor (source->ts.type,
+ source->ts.kind,
+ &source->where);
+ result->rank = source->rank + 1;
+ result->shape = gfc_get_shape (result->rank);
+
+ result_size = 1;
+ for (i = 0, j = 0; i < result->rank; ++i)
+ {
+ if (i != dim)
+ mpz_init_set (result->shape[i], source->shape[j++]);
+ else
+ mpz_init_set_si (result->shape[i], ncopies);
+
+ extent[i] = mpz_get_si (result->shape[i]);
+ rstride[i] = (i == 0) ? 1 : rstride[i-1] * extent[i-1];
+ result_size *= extent[i];
+ }
+
+ for (i = 0; i < result_size; ++i)
+ gfc_append_constructor (result, NULL);
+
+ source_ctor = source->value.constructor;
+ result_ctor = result->value.constructor;
+ while (source_ctor)
+ {
+ ctor = result_ctor;
+
+ for (i = 0; i < ncopies; ++i)
+ {
+ ctor->expr = gfc_copy_expr (source_ctor->expr);
+ ADVANCE (ctor, rstride[dim]);
+ }
+
+ ADVANCE (result_ctor, (dim == 0 ? ncopies : 1));
+ ADVANCE (source_ctor, 1);
+ }
+ }
+ else
+ /* FIXME: Returning here avoids a regression in array_simplify_1.f90.
+ Replace NULL with gcc_unreachable() after implementing
+ gfc_simplify_cshift(). */
+ return NULL;
+
+ if (source->ts.type == BT_CHARACTER)
+ result->ts.cl = source->ts.cl;
+
+ return result;
+}
+
+
+gfc_expr *
gfc_simplify_sqrt (gfc_expr *e)
{
gfc_expr *result;
- mpfr_t ac, ad, s, t, w;
if (e->expr_type != EXPR_CONSTANT)
return NULL;
@@ -4293,10 +5198,16 @@ gfc_simplify_sqrt (gfc_expr *e)
break;
case BT_COMPLEX:
+ gfc_set_model (e->value.real);
+#ifdef HAVE_mpc
+ call_mpc_func (result->value.complex.r, result->value.complex.i,
+ e->value.complex.r, e->value.complex.i, mpc_sqrt);
+#else
+ {
/* Formula taken from Numerical Recipes to avoid over- and
underflow. */
- gfc_set_model (e->value.real);
+ mpfr_t ac, ad, s, t, w;
mpfr_init (ac);
mpfr_init (ad);
mpfr_init (s);
@@ -4368,7 +5279,8 @@ gfc_simplify_sqrt (gfc_expr *e)
&e->where);
mpfr_clears (s, t, ac, ad, w, NULL);
-
+ }
+#endif
break;
default:
@@ -4385,6 +5297,30 @@ negative_arg:
gfc_expr *
+gfc_simplify_sum (gfc_expr *array, gfc_expr *dim, gfc_expr *mask)
+{
+ gfc_expr *result;
+
+ if (!is_constant_array_expr (array)
+ || !gfc_is_constant_expr (dim))
+ return NULL;
+
+ if (mask
+ && !is_constant_array_expr (mask)
+ && mask->expr_type != EXPR_CONSTANT)
+ return NULL;
+
+ result = transformational_result (array, dim, array->ts.type,
+ array->ts.kind, &array->where);
+ init_result_expr (result, 0, NULL);
+
+ return !dim || array->rank == 1 ?
+ simplify_transformation_to_scalar (result, array, mask, gfc_add) :
+ simplify_transformation_to_array (result, array, dim, mask, gfc_add);
+}
+
+
+gfc_expr *
gfc_simplify_tan (gfc_expr *x)
{
int i;
@@ -4554,6 +5490,47 @@ gfc_simplify_transfer (gfc_expr *source, gfc_expr *mold, gfc_expr *size)
gfc_expr *
+gfc_simplify_transpose (gfc_expr *matrix)
+{
+ int i, matrix_rows;
+ gfc_expr *result;
+ gfc_constructor *matrix_ctor;
+
+ if (!is_constant_array_expr (matrix))
+ return NULL;
+
+ gcc_assert (matrix->rank == 2);
+
+ result = gfc_start_constructor (matrix->ts.type, matrix->ts.kind, &matrix->where);
+ result->rank = 2;
+ result->shape = gfc_get_shape (result->rank);
+ mpz_set (result->shape[0], matrix->shape[1]);
+ mpz_set (result->shape[1], matrix->shape[0]);
+
+ if (matrix->ts.type == BT_CHARACTER)
+ result->ts.cl = matrix->ts.cl;
+
+ matrix_rows = mpz_get_si (matrix->shape[0]);
+ matrix_ctor = matrix->value.constructor;
+ for (i = 0; i < matrix_rows; ++i)
+ {
+ gfc_constructor *column_ctor = matrix_ctor;
+ while (column_ctor)
+ {
+ gfc_append_constructor (result,
+ gfc_copy_expr (column_ctor->expr));
+
+ ADVANCE (column_ctor, matrix_rows);
+ }
+
+ ADVANCE (matrix_ctor, 1);
+ }
+
+ return result;
+}
+
+
+gfc_expr *
gfc_simplify_trim (gfc_expr *e)
{
gfc_expr *result;
@@ -4596,6 +5573,54 @@ gfc_simplify_ubound (gfc_expr *array, gfc_expr *dim, gfc_expr *kind)
gfc_expr *
+gfc_simplify_unpack (gfc_expr *vector, gfc_expr *mask, gfc_expr *field)
+{
+ gfc_expr *result, *e;
+ gfc_constructor *vector_ctor, *mask_ctor, *field_ctor;
+
+ if (!is_constant_array_expr (vector)
+ || !is_constant_array_expr (mask)
+ || (!gfc_is_constant_expr (field)
+ && !is_constant_array_expr(field)))
+ return NULL;
+
+ result = gfc_start_constructor (vector->ts.type,
+ vector->ts.kind,
+ &vector->where);
+ result->rank = mask->rank;
+ result->shape = gfc_copy_shape (mask->shape, mask->rank);
+
+ if (vector->ts.type == BT_CHARACTER)
+ result->ts.cl = vector->ts.cl;
+
+ vector_ctor = vector->value.constructor;
+ mask_ctor = mask->value.constructor;
+ field_ctor = field->expr_type == EXPR_ARRAY ? field->value.constructor : NULL;
+
+ while (mask_ctor)
+ {
+ if (mask_ctor->expr->value.logical)
+ {
+ gcc_assert (vector_ctor);
+ e = gfc_copy_expr (vector_ctor->expr);
+ ADVANCE (vector_ctor, 1);
+ }
+ else if (field->expr_type == EXPR_ARRAY)
+ e = gfc_copy_expr (field_ctor->expr);
+ else
+ e = gfc_copy_expr (field);
+
+ gfc_append_constructor (result, e);
+
+ ADVANCE (mask_ctor, 1);
+ ADVANCE (field_ctor, 1);
+ }
+
+ return result;
+}
+
+
+gfc_expr *
gfc_simplify_verify (gfc_expr *s, gfc_expr *set, gfc_expr *b, gfc_expr *kind)
{
gfc_expr *result;
diff --git a/gcc/fortran/st.c b/gcc/fortran/st.c
index d0cdb0e868c..d77ef81822c 100644
--- a/gcc/fortran/st.c
+++ b/gcc/fortran/st.c
@@ -80,8 +80,8 @@ gfc_append_code (gfc_code *tail, gfc_code *new_code)
void
gfc_free_statement (gfc_code *p)
{
- if (p->expr)
- gfc_free_expr (p->expr);
+ if (p->expr1)
+ gfc_free_expr (p->expr1);
if (p->expr2)
gfc_free_expr (p->expr2);
@@ -94,6 +94,7 @@ gfc_free_statement (gfc_code *p)
case EXEC_GOTO:
case EXEC_CYCLE:
case EXEC_RETURN:
+ case EXEC_END_PROCEDURE:
case EXEC_IF:
case EXEC_PAUSE:
case EXEC_STOP:
diff --git a/gcc/fortran/symbol.c b/gcc/fortran/symbol.c
index 2160afa14c0..326d73e3ebf 100644
--- a/gcc/fortran/symbol.c
+++ b/gcc/fortran/symbol.c
@@ -1559,31 +1559,30 @@ gfc_try
gfc_add_type (gfc_symbol *sym, gfc_typespec *ts, locus *where)
{
sym_flavor flavor;
+ bt type;
if (where == NULL)
where = &gfc_current_locus;
- if (sym->ts.type != BT_UNKNOWN)
+ if (sym->result)
+ type = sym->result->ts.type;
+ else
+ type = sym->ts.type;
+
+ if (sym->attr.result && type == BT_UNKNOWN && sym->ns->proc_name)
+ type = sym->ns->proc_name->ts.type;
+
+ if (type != BT_UNKNOWN && !(sym->attr.function && sym->attr.implicit_type))
{
- const char *msg = "Symbol '%s' at %L already has basic type of %s";
- if (!(sym->ts.type == ts->type && sym->attr.result)
- || gfc_notification_std (GFC_STD_GNU) == ERROR
- || pedantic)
- {
- gfc_error (msg, sym->name, where, gfc_basic_typename (sym->ts.type));
- return FAILURE;
- }
- if (gfc_notify_std (GFC_STD_GNU, msg, sym->name, where,
- gfc_basic_typename (sym->ts.type)) == FAILURE)
- return FAILURE;
- if (gfc_option.warn_surprising)
- gfc_warning (msg, sym->name, where, gfc_basic_typename (sym->ts.type));
+ gfc_error ("Symbol '%s' at %L already has basic type of %s", sym->name,
+ where, gfc_basic_typename (type));
+ return FAILURE;
}
if (sym->attr.procedure && sym->ts.interface)
{
- gfc_error ("Procedure '%s' at %L may not have basic type of %s", sym->name, where,
- gfc_basic_typename (ts->type));
+ gfc_error ("Procedure '%s' at %L may not have basic type of %s",
+ sym->name, where, gfc_basic_typename (ts->type));
return FAILURE;
}
@@ -2198,7 +2197,7 @@ gfc_get_namespace (gfc_namespace *parent, int parent_types)
{
gfc_namespace *ns;
gfc_typespec *ts;
- gfc_intrinsic_op in;
+ int in;
int i;
ns = XCNEW (gfc_namespace);
@@ -3089,7 +3088,7 @@ void
gfc_free_namespace (gfc_namespace *ns)
{
gfc_namespace *p, *q;
- gfc_intrinsic_op i;
+ int i;
if (ns == NULL)
return;
@@ -3915,6 +3914,7 @@ gfc_copy_formal_args_intr (gfc_symbol *dest, gfc_intrinsic_sym *src)
/* May need to copy more info for the symbol. */
formal_arg->sym->ts = curr_arg->ts;
formal_arg->sym->attr.optional = curr_arg->optional;
+ formal_arg->sym->attr.intent = curr_arg->intent;
formal_arg->sym->attr.flavor = FL_VARIABLE;
formal_arg->sym->attr.dummy = 1;
@@ -4495,4 +4495,3 @@ gfc_get_tbp_symtree (gfc_symtree **root, const char *name)
return result;
}
-
diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c
index 71db46d18b2..cf38fc371be 100644
--- a/gcc/fortran/trans-array.c
+++ b/gcc/fortran/trans-array.c
@@ -197,7 +197,7 @@ gfc_conv_descriptor_data_addr (tree desc)
return gfc_build_addr_expr (NULL_TREE, t);
}
-tree
+static tree
gfc_conv_descriptor_offset (tree desc)
{
tree type;
@@ -214,6 +214,21 @@ gfc_conv_descriptor_offset (tree desc)
}
tree
+gfc_conv_descriptor_offset_get (tree desc)
+{
+ return gfc_conv_descriptor_offset (desc);
+}
+
+void
+gfc_conv_descriptor_offset_set (stmtblock_t *block, tree desc,
+ tree value)
+{
+ tree t = gfc_conv_descriptor_offset (desc);
+ gfc_add_modify (block, t, fold_convert (TREE_TYPE (t), value));
+}
+
+
+tree
gfc_conv_descriptor_dtype (tree desc)
{
tree field;
@@ -250,7 +265,7 @@ gfc_conv_descriptor_dimension (tree desc, tree dim)
return tmp;
}
-tree
+static tree
gfc_conv_descriptor_stride (tree desc, tree dim)
{
tree tmp;
@@ -267,6 +282,20 @@ gfc_conv_descriptor_stride (tree desc, tree dim)
}
tree
+gfc_conv_descriptor_stride_get (tree desc, tree dim)
+{
+ return gfc_conv_descriptor_stride (desc, dim);
+}
+
+void
+gfc_conv_descriptor_stride_set (stmtblock_t *block, tree desc,
+ tree dim, tree value)
+{
+ tree t = gfc_conv_descriptor_stride (desc, dim);
+ gfc_add_modify (block, t, fold_convert (TREE_TYPE (t), value));
+}
+
+static tree
gfc_conv_descriptor_lbound (tree desc, tree dim)
{
tree tmp;
@@ -283,6 +312,20 @@ gfc_conv_descriptor_lbound (tree desc, tree dim)
}
tree
+gfc_conv_descriptor_lbound_get (tree desc, tree dim)
+{
+ return gfc_conv_descriptor_lbound (desc, dim);
+}
+
+void
+gfc_conv_descriptor_lbound_set (stmtblock_t *block, tree desc,
+ tree dim, tree value)
+{
+ tree t = gfc_conv_descriptor_lbound (desc, dim);
+ gfc_add_modify (block, t, fold_convert (TREE_TYPE (t), value));
+}
+
+static tree
gfc_conv_descriptor_ubound (tree desc, tree dim)
{
tree tmp;
@@ -298,6 +341,19 @@ gfc_conv_descriptor_ubound (tree desc, tree dim)
return tmp;
}
+tree
+gfc_conv_descriptor_ubound_get (tree desc, tree dim)
+{
+ return gfc_conv_descriptor_ubound (desc, dim);
+}
+
+void
+gfc_conv_descriptor_ubound_set (stmtblock_t *block, tree desc,
+ tree dim, tree value)
+{
+ tree t = gfc_conv_descriptor_ubound (desc, dim);
+ gfc_add_modify (block, t, fold_convert (TREE_TYPE (t), value));
+}
/* Build a null array descriptor constructor. */
@@ -579,7 +635,8 @@ gfc_trans_allocate_array_storage (stmtblock_t * pre, stmtblock_t * post,
was_packed = fold_build2 (EQ_EXPR, boolean_type_node,
packed, source_data);
tmp = gfc_finish_block (&do_copying);
- tmp = build3_v (COND_EXPR, was_packed, tmp, build_empty_stmt ());
+ tmp = build3_v (COND_EXPR, was_packed, tmp,
+ build_empty_stmt (input_location));
gfc_add_expr_to_block (pre, tmp);
tmp = fold_convert (pvoid_type_node, packed);
@@ -592,8 +649,7 @@ gfc_trans_allocate_array_storage (stmtblock_t * pre, stmtblock_t * post,
/* The offset is zero because we create temporaries with a zero
lower bound. */
- tmp = gfc_conv_descriptor_offset (desc);
- gfc_add_modify (pre, tmp, gfc_index_zero_node);
+ gfc_conv_descriptor_offset_set (pre, desc, gfc_index_zero_node);
if (dealloc && !onstack)
{
@@ -704,21 +760,19 @@ gfc_trans_create_temp_array (stmtblock_t * pre, stmtblock_t * post,
of the descriptor fields. */
tmp =
fold_build2 (MINUS_EXPR, gfc_array_index_type,
- gfc_conv_descriptor_ubound (desc, gfc_rank_cst[n]),
- gfc_conv_descriptor_lbound (desc, gfc_rank_cst[n]));
+ gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[n]),
+ gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[n]));
loop->to[n] = tmp;
continue;
}
/* Store the stride and bound components in the descriptor. */
- tmp = gfc_conv_descriptor_stride (desc, gfc_rank_cst[n]);
- gfc_add_modify (pre, tmp, size);
+ gfc_conv_descriptor_stride_set (pre, desc, gfc_rank_cst[n], size);
- tmp = gfc_conv_descriptor_lbound (desc, gfc_rank_cst[n]);
- gfc_add_modify (pre, tmp, gfc_index_zero_node);
+ gfc_conv_descriptor_lbound_set (pre, desc, gfc_rank_cst[n],
+ gfc_index_zero_node);
- tmp = gfc_conv_descriptor_ubound (desc, gfc_rank_cst[n]);
- gfc_add_modify (pre, tmp, loop->to[n]);
+ gfc_conv_descriptor_ubound_set (pre, desc, gfc_rank_cst[n], loop->to[n]);
tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
loop->to[n], gfc_index_one_node);
@@ -820,25 +874,22 @@ gfc_conv_array_transpose (gfc_se * se, gfc_expr * expr)
dest_index = gfc_rank_cst[n];
src_index = gfc_rank_cst[1 - n];
- gfc_add_modify (&se->pre,
- gfc_conv_descriptor_stride (dest, dest_index),
- gfc_conv_descriptor_stride (src, src_index));
+ gfc_conv_descriptor_stride_set (&se->pre, dest, dest_index,
+ gfc_conv_descriptor_stride_get (src, src_index));
- gfc_add_modify (&se->pre,
- gfc_conv_descriptor_lbound (dest, dest_index),
- gfc_conv_descriptor_lbound (src, src_index));
+ gfc_conv_descriptor_lbound_set (&se->pre, dest, dest_index,
+ gfc_conv_descriptor_lbound_get (src, src_index));
- gfc_add_modify (&se->pre,
- gfc_conv_descriptor_ubound (dest, dest_index),
- gfc_conv_descriptor_ubound (src, src_index));
+ gfc_conv_descriptor_ubound_set (&se->pre, dest, dest_index,
+ gfc_conv_descriptor_ubound_get (src, src_index));
if (!loop->to[n])
{
gcc_assert (integer_zerop (loop->from[n]));
loop->to[n] =
fold_build2 (MINUS_EXPR, gfc_array_index_type,
- gfc_conv_descriptor_ubound (dest, dest_index),
- gfc_conv_descriptor_lbound (dest, dest_index));
+ gfc_conv_descriptor_ubound_get (dest, dest_index),
+ gfc_conv_descriptor_lbound_get (dest, dest_index));
}
}
@@ -850,13 +901,12 @@ gfc_conv_array_transpose (gfc_se * se, gfc_expr * expr)
element is still at the same offset as before, except where the loop
starts at zero. */
if (!integer_zerop (loop->from[0]))
- dest_info->offset = gfc_conv_descriptor_offset (src);
+ dest_info->offset = gfc_conv_descriptor_offset_get (src);
else
dest_info->offset = gfc_index_zero_node;
- gfc_add_modify (&se->pre,
- gfc_conv_descriptor_offset (dest),
- dest_info->offset);
+ gfc_conv_descriptor_offset_set (&se->pre, dest,
+ dest_info->offset);
if (dest_info->dimen > loop->temp_dim)
loop->temp_dim = dest_info->dimen;
@@ -894,11 +944,11 @@ gfc_grow_array (stmtblock_t * pblock, tree desc, tree extra)
if (integer_zerop (extra))
return;
- ubound = gfc_conv_descriptor_ubound (desc, gfc_rank_cst[0]);
+ ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[0]);
/* Add EXTRA to the upper bound. */
tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type, ubound, extra);
- gfc_add_modify (pblock, ubound, tmp);
+ gfc_conv_descriptor_ubound_set (pblock, desc, gfc_rank_cst[0], tmp);
/* Get the value of the current data pointer. */
arg0 = gfc_conv_descriptor_data_get (desc);
@@ -1393,7 +1443,8 @@ gfc_trans_array_constructor_value (stmtblock_t * pblock, tree type,
shadow_loopvar, end));
tmp = build1_v (GOTO_EXPR, exit_label);
TREE_USED (exit_label) = 1;
- tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
+ tmp = build3_v (COND_EXPR, cond, tmp,
+ build_empty_stmt (input_location));
gfc_add_expr_to_block (&body, tmp);
/* The main loop body. */
@@ -1877,7 +1928,7 @@ gfc_trans_array_constructor (gfc_loopinfo * loop, gfc_ss * ss, locus * where)
/* If the array grows dynamically, the upper bound of the loop variable
is determined by the array's final upper bound. */
if (dynamic)
- loop->to[0] = gfc_conv_descriptor_ubound (desc, gfc_rank_cst[0]);
+ loop->to[0] = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[0]);
if (TREE_USED (offsetvar))
pushdecl (offsetvar);
@@ -1931,8 +1982,8 @@ gfc_set_vector_loop_bounds (gfc_loopinfo * loop, gfc_ss_info * info)
desc = info->subscript[dim]->data.info.descriptor;
zero = gfc_rank_cst[0];
tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
- gfc_conv_descriptor_ubound (desc, zero),
- gfc_conv_descriptor_lbound (desc, zero));
+ gfc_conv_descriptor_ubound_get (desc, zero),
+ gfc_conv_descriptor_lbound_get (desc, zero));
tmp = gfc_evaluate_now (tmp, &loop->pre);
loop->to[n] = tmp;
}
@@ -2160,7 +2211,7 @@ gfc_conv_array_offset (tree descriptor)
if (GFC_ARRAY_TYPE_P (type))
return GFC_TYPE_ARRAY_OFFSET (type);
else
- return gfc_conv_descriptor_offset (descriptor);
+ return gfc_conv_descriptor_offset_get (descriptor);
}
@@ -2179,7 +2230,7 @@ gfc_conv_array_stride (tree descriptor, int dim)
if (tmp != NULL_TREE)
return tmp;
- tmp = gfc_conv_descriptor_stride (descriptor, gfc_rank_cst[dim]);
+ tmp = gfc_conv_descriptor_stride_get (descriptor, gfc_rank_cst[dim]);
return tmp;
}
@@ -2198,7 +2249,7 @@ gfc_conv_array_lbound (tree descriptor, int dim)
if (tmp != NULL_TREE)
return tmp;
- tmp = gfc_conv_descriptor_lbound (descriptor, gfc_rank_cst[dim]);
+ tmp = gfc_conv_descriptor_lbound_get (descriptor, gfc_rank_cst[dim]);
return tmp;
}
@@ -2222,7 +2273,7 @@ gfc_conv_array_ubound (tree descriptor, int dim)
if (GFC_ARRAY_TYPE_P (TREE_TYPE (descriptor)))
return gfc_index_zero_node;
- tmp = gfc_conv_descriptor_ubound (descriptor, gfc_rank_cst[dim]);
+ tmp = gfc_conv_descriptor_ubound_get (descriptor, gfc_rank_cst[dim]);
return tmp;
}
@@ -2727,12 +2778,13 @@ gfc_trans_scalarized_loop_end (gfc_loopinfo * loop, int n,
TREE_TYPE (stmt) = void_type_node;
OMP_FOR_BODY (stmt) = loopbody = gfc_finish_block (pbody);
- OMP_FOR_CLAUSES (stmt) = build_omp_clause (OMP_CLAUSE_SCHEDULE);
+ OMP_FOR_CLAUSES (stmt) = build_omp_clause (input_location,
+ OMP_CLAUSE_SCHEDULE);
OMP_CLAUSE_SCHEDULE_KIND (OMP_FOR_CLAUSES (stmt))
= OMP_CLAUSE_SCHEDULE_STATIC;
if (ompws_flags & OMPWS_NOWAIT)
OMP_CLAUSE_CHAIN (OMP_FOR_CLAUSES (stmt))
- = build_omp_clause (OMP_CLAUSE_NOWAIT);
+ = build_omp_clause (input_location, OMP_CLAUSE_NOWAIT);
/* Initialize the loopvar. */
TREE_VEC_ELT (init, 0) = build2_v (MODIFY_EXPR, loop->loopvar[n],
@@ -2769,7 +2821,7 @@ gfc_trans_scalarized_loop_end (gfc_loopinfo * loop, int n,
loop->loopvar[n], loop->to[n]);
tmp = build1_v (GOTO_EXPR, exit_label);
TREE_USED (exit_label) = 1;
- tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
+ tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt (input_location));
gfc_add_expr_to_block (&block, tmp);
/* The main body. */
@@ -3256,6 +3308,8 @@ gfc_conv_ss_startstride (gfc_loopinfo * loop)
info->start[n]);
tmp = fold_build2 (FLOOR_DIV_EXPR, gfc_array_index_type, tmp,
info->stride[n]);
+ tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
+ gfc_index_one_node, tmp);
tmp = fold_build2 (MAX_EXPR, gfc_array_index_type, tmp,
build_int_cst (gfc_array_index_type, 0));
/* We remember the size of the first section, and check all the
@@ -3286,7 +3340,7 @@ gfc_conv_ss_startstride (gfc_loopinfo * loop)
|| ss->expr->symtree->n.sym->attr.not_always_present)
tmp = build3_v (COND_EXPR,
gfc_conv_expr_present (ss->expr->symtree->n.sym),
- tmp, build_empty_stmt ());
+ tmp, build_empty_stmt (input_location));
gfc_add_expr_to_block (&block, tmp);
@@ -3782,8 +3836,8 @@ gfc_array_init_size (tree descriptor, int rank, tree * poffset,
ubound = lower[n];
}
}
- tmp = gfc_conv_descriptor_lbound (descriptor, gfc_rank_cst[n]);
- gfc_add_modify (pblock, tmp, se.expr);
+ gfc_conv_descriptor_lbound_set (pblock, descriptor, gfc_rank_cst[n],
+ se.expr);
/* Work out the offset for this component. */
tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, se.expr, stride);
@@ -3799,12 +3853,10 @@ gfc_array_init_size (tree descriptor, int rank, tree * poffset,
gfc_conv_expr_type (&se, ubound, gfc_array_index_type);
gfc_add_block_to_block (pblock, &se.pre);
- tmp = gfc_conv_descriptor_ubound (descriptor, gfc_rank_cst[n]);
- gfc_add_modify (pblock, tmp, se.expr);
+ gfc_conv_descriptor_ubound_set (pblock, descriptor, gfc_rank_cst[n], se.expr);
/* Store the stride. */
- tmp = gfc_conv_descriptor_stride (descriptor, gfc_rank_cst[n]);
- gfc_add_modify (pblock, tmp, stride);
+ gfc_conv_descriptor_stride_set (pblock, descriptor, gfc_rank_cst[n], stride);
/* Calculate the size of this dimension. */
size = fold_build2 (PLUS_EXPR, gfc_array_index_type, se.expr, size);
@@ -3933,8 +3985,7 @@ gfc_array_allocate (gfc_se * se, gfc_expr * expr, tree pstat)
tmp = fold_build2 (MODIFY_EXPR, void_type_node, pointer, tmp);
gfc_add_expr_to_block (&se->pre, tmp);
- tmp = gfc_conv_descriptor_offset (se->expr);
- gfc_add_modify (&se->pre, tmp, offset);
+ gfc_conv_descriptor_offset_set (&se->pre, se->expr, offset);
if (expr->ts.type == BT_DERIVED
&& expr->ts.derived->attr.alloc_comp)
@@ -4343,7 +4394,7 @@ gfc_trans_g77_array (gfc_symbol * sym, tree body)
if (sym->attr.optional || sym->attr.not_always_present)
{
tmp = gfc_conv_expr_present (sym);
- stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
+ stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt (input_location));
}
gfc_add_expr_to_block (&block, stmt);
@@ -4424,7 +4475,7 @@ gfc_trans_dummy_array_bias (gfc_symbol * sym, tree tmpdesc, tree body)
anything as we still don't know the array stride. */
partial = gfc_create_var (boolean_type_node, "partial");
TREE_USED (partial) = 1;
- tmp = gfc_conv_descriptor_stride (dumdesc, gfc_rank_cst[0]);
+ tmp = gfc_conv_descriptor_stride_get (dumdesc, gfc_rank_cst[0]);
tmp = fold_build2 (EQ_EXPR, boolean_type_node, tmp, gfc_index_one_node);
gfc_add_modify (&block, partial, tmp);
}
@@ -4438,7 +4489,7 @@ gfc_trans_dummy_array_bias (gfc_symbol * sym, tree tmpdesc, tree body)
if (no_repack)
{
/* Set the first stride. */
- stride = gfc_conv_descriptor_stride (dumdesc, gfc_rank_cst[0]);
+ stride = gfc_conv_descriptor_stride_get (dumdesc, gfc_rank_cst[0]);
stride = gfc_evaluate_now (stride, &block);
tmp = fold_build2 (EQ_EXPR, boolean_type_node,
@@ -4491,8 +4542,8 @@ gfc_trans_dummy_array_bias (gfc_symbol * sym, tree tmpdesc, tree body)
if (checkparm || !sym->as->upper[n])
{
/* Get the bounds of the actual parameter. */
- dubound = gfc_conv_descriptor_ubound (dumdesc, gfc_rank_cst[n]);
- dlbound = gfc_conv_descriptor_lbound (dumdesc, gfc_rank_cst[n]);
+ dubound = gfc_conv_descriptor_ubound_get (dumdesc, gfc_rank_cst[n]);
+ dlbound = gfc_conv_descriptor_lbound_get (dumdesc, gfc_rank_cst[n]);
}
else
{
@@ -4562,7 +4613,7 @@ gfc_trans_dummy_array_bias (gfc_symbol * sym, tree tmpdesc, tree body)
if (no_repack || partial != NULL_TREE)
{
stmt_unpacked =
- gfc_conv_descriptor_stride (dumdesc, gfc_rank_cst[n+1]);
+ gfc_conv_descriptor_stride_get (dumdesc, gfc_rank_cst[n+1]);
}
/* Figure out the stride if not a known constant. */
@@ -4627,7 +4678,7 @@ gfc_trans_dummy_array_bias (gfc_symbol * sym, tree tmpdesc, tree body)
if (optional_arg)
{
tmp = gfc_conv_expr_present (sym);
- stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
+ stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt (input_location));
}
gfc_add_expr_to_block (&block, stmt);
@@ -4656,12 +4707,13 @@ gfc_trans_dummy_array_bias (gfc_symbol * sym, tree tmpdesc, tree body)
tmp = build_fold_indirect_ref (dumdesc);
tmp = gfc_conv_descriptor_data_get (tmp);
tmp = fold_build2 (NE_EXPR, boolean_type_node, tmp, tmpdesc);
- stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
+ stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt (input_location));
if (optional_arg)
{
tmp = gfc_conv_expr_present (sym);
- stmt = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
+ stmt = build3_v (COND_EXPR, tmp, stmt,
+ build_empty_stmt (input_location));
}
gfc_add_expr_to_block (&block, stmt);
}
@@ -5264,19 +5316,21 @@ gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss)
to = fold_build2 (PLUS_EXPR, gfc_array_index_type, to, tmp);
from = gfc_index_one_node;
}
- tmp = gfc_conv_descriptor_lbound (parm, gfc_rank_cst[dim]);
- gfc_add_modify (&loop.pre, tmp, from);
+ gfc_conv_descriptor_lbound_set (&loop.pre, parm,
+ gfc_rank_cst[dim], from);
/* Set the new upper bound. */
- tmp = gfc_conv_descriptor_ubound (parm, gfc_rank_cst[dim]);
- gfc_add_modify (&loop.pre, tmp, to);
+ gfc_conv_descriptor_ubound_set (&loop.pre, parm,
+ gfc_rank_cst[dim], to);
/* Multiply the stride by the section stride to get the
total stride. */
stride = fold_build2 (MULT_EXPR, gfc_array_index_type,
stride, info->stride[dim]);
- if (se->direct_byref && info->ref && info->ref->u.ar.type != AR_FULL)
+ if (se->direct_byref
+ && info->ref
+ && info->ref->u.ar.type != AR_FULL)
{
base = fold_build2 (MINUS_EXPR, TREE_TYPE (base),
base, stride);
@@ -5293,16 +5347,17 @@ gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss)
}
/* Store the new stride. */
- tmp = gfc_conv_descriptor_stride (parm, gfc_rank_cst[dim]);
- gfc_add_modify (&loop.pre, tmp, stride);
+ gfc_conv_descriptor_stride_set (&loop.pre, parm,
+ gfc_rank_cst[dim], stride);
dim++;
}
if (se->data_not_needed)
- gfc_conv_descriptor_data_set (&loop.pre, parm, gfc_index_zero_node);
+ gfc_conv_descriptor_data_set (&loop.pre, parm,
+ gfc_index_zero_node);
else
- /* Point the data pointer at the first element in the section. */
+ /* Point the data pointer at the 1st element in the section. */
gfc_get_dataptr_offset (&loop.pre, parm, desc, offset,
subref_array_target, expr);
@@ -5310,15 +5365,13 @@ gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss)
&& !se->data_not_needed)
{
/* Set the offset. */
- tmp = gfc_conv_descriptor_offset (parm);
- gfc_add_modify (&loop.pre, tmp, base);
+ gfc_conv_descriptor_offset_set (&loop.pre, parm, base);
}
else
{
/* Only the callee knows what the correct offset it, so just set
it to zero here. */
- tmp = gfc_conv_descriptor_offset (parm);
- gfc_add_modify (&loop.pre, tmp, gfc_index_zero_node);
+ gfc_conv_descriptor_offset_set (&loop.pre, parm, gfc_index_zero_node);
}
desc = parm;
}
@@ -5339,13 +5392,41 @@ gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss)
gfc_cleanup_loop (&loop);
}
+/* Helper function for gfc_conv_array_parameter if array size needs to be
+ computed. */
+
+static void
+array_parameter_size (tree desc, gfc_expr *expr, tree *size)
+{
+ tree elem;
+ if (GFC_ARRAY_TYPE_P (TREE_TYPE (desc)))
+ *size = GFC_TYPE_ARRAY_SIZE (TREE_TYPE (desc));
+ else if (expr->rank > 1)
+ *size = build_call_expr (gfor_fndecl_size0, 1,
+ gfc_build_addr_expr (NULL, desc));
+ else
+ {
+ tree ubound = gfc_conv_descriptor_ubound_get (desc, gfc_index_zero_node);
+ tree lbound = gfc_conv_descriptor_lbound_get (desc, gfc_index_zero_node);
+
+ *size = fold_build2 (MINUS_EXPR, gfc_array_index_type, ubound, lbound);
+ *size = fold_build2 (PLUS_EXPR, gfc_array_index_type, *size,
+ gfc_index_one_node);
+ *size = fold_build2 (MAX_EXPR, gfc_array_index_type, *size,
+ gfc_index_zero_node);
+ }
+ elem = TYPE_SIZE_UNIT (gfc_get_element_type (TREE_TYPE (desc)));
+ *size = fold_build2 (MULT_EXPR, gfc_array_index_type, *size,
+ fold_convert (gfc_array_index_type, elem));
+}
/* Convert an array for passing as an actual parameter. */
/* TODO: Optimize passing g77 arrays. */
void
gfc_conv_array_parameter (gfc_se * se, gfc_expr * expr, gfc_ss * ss, int g77,
- const gfc_symbol *fsym, const char *proc_name)
+ const gfc_symbol *fsym, const char *proc_name,
+ tree *size)
{
tree ptr;
tree desc;
@@ -5394,6 +5475,8 @@ gfc_conv_array_parameter (gfc_se * se, gfc_expr * expr, gfc_ss * ss, int g77,
se->expr = tmp;
else
se->expr = gfc_build_addr_expr (NULL_TREE, tmp);
+ if (size)
+ array_parameter_size (tmp, expr, size);
return;
}
if (sym->attr.allocatable)
@@ -5401,10 +5484,11 @@ gfc_conv_array_parameter (gfc_se * se, gfc_expr * expr, gfc_ss * ss, int g77,
if (sym->attr.dummy || sym->attr.result)
{
gfc_conv_expr_descriptor (se, expr, ss);
- se->expr = gfc_conv_array_data (se->expr);
+ tmp = se->expr;
}
- else
- se->expr = gfc_conv_array_data (tmp);
+ if (size)
+ array_parameter_size (tmp, expr, size);
+ se->expr = gfc_conv_array_data (tmp);
return;
}
}
@@ -5413,6 +5497,8 @@ gfc_conv_array_parameter (gfc_se * se, gfc_expr * expr, gfc_ss * ss, int g77,
{
/* Result of the enclosing function. */
gfc_conv_expr_descriptor (se, expr, ss);
+ if (size)
+ array_parameter_size (se->expr, expr, size);
se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
if (g77 && TREE_TYPE (TREE_TYPE (se->expr)) != NULL_TREE
@@ -5426,6 +5512,9 @@ gfc_conv_array_parameter (gfc_se * se, gfc_expr * expr, gfc_ss * ss, int g77,
/* Every other type of array. */
se->want_pointer = 1;
gfc_conv_expr_descriptor (se, expr, ss);
+ if (size)
+ array_parameter_size (build_fold_indirect_ref (se->expr),
+ expr, size);
}
/* Deallocate the allocatable components of structures that are
@@ -5518,7 +5607,7 @@ gfc_conv_array_parameter (gfc_se * se, gfc_expr * expr, gfc_ss * ss, int g77,
tmp = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
gfc_conv_expr_present (sym), tmp);
- tmp = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
+ tmp = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt (input_location));
gfc_add_expr_to_block (&block, tmp);
gfc_add_block_to_block (&block, &se->post);
@@ -5567,14 +5656,14 @@ get_full_array_size (stmtblock_t *block, tree decl, int rank)
tree nelems;
tree tmp;
idx = gfc_rank_cst[rank - 1];
- nelems = gfc_conv_descriptor_ubound (decl, idx);
- tmp = gfc_conv_descriptor_lbound (decl, idx);
+ nelems = gfc_conv_descriptor_ubound_get (decl, idx);
+ tmp = gfc_conv_descriptor_lbound_get (decl, idx);
tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, nelems, tmp);
tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
tmp, gfc_index_one_node);
tmp = gfc_evaluate_now (tmp, block);
- nelems = gfc_conv_descriptor_stride (decl, idx);
+ nelems = gfc_conv_descriptor_stride_get (decl, idx);
tmp = fold_build2 (MULT_EXPR, gfc_array_index_type, nelems, tmp);
return gfc_evaluate_now (tmp, block);
}
@@ -5722,7 +5811,8 @@ structure_alloc_comps (gfc_symbol * der_type, tree decl,
tmp = gfc_finish_block (&fnblock);
if (null_cond != NULL_TREE)
- tmp = build3_v (COND_EXPR, null_cond, tmp, build_empty_stmt ());
+ tmp = build3_v (COND_EXPR, null_cond, tmp,
+ build_empty_stmt (input_location));
return tmp;
}
@@ -6257,6 +6347,7 @@ gfc_walk_function_expr (gfc_ss * ss, gfc_expr * expr)
gfc_ss *newss;
gfc_intrinsic_sym *isym;
gfc_symbol *sym;
+ gfc_component *comp = NULL;
isym = expr->value.function.isym;
@@ -6269,7 +6360,9 @@ gfc_walk_function_expr (gfc_ss * ss, gfc_expr * expr)
sym = expr->symtree->n.sym;
/* A function that returns arrays. */
- if (gfc_return_by_reference (sym) && sym->result->attr.dimension)
+ is_proc_ptr_comp (expr, &comp);
+ if ((!comp && gfc_return_by_reference (sym) && sym->result->attr.dimension)
+ || (comp && comp->attr.dimension))
{
newss = gfc_get_ss ();
newss->type = GFC_SS_FUNCTION;
diff --git a/gcc/fortran/trans-array.h b/gcc/fortran/trans-array.h
index 49818d4fe6d..9b0b830d92e 100644
--- a/gcc/fortran/trans-array.h
+++ b/gcc/fortran/trans-array.h
@@ -106,7 +106,7 @@ void gfc_conv_tmp_ref (gfc_se *);
void gfc_conv_expr_descriptor (gfc_se *, gfc_expr *, gfc_ss *);
/* Convert an array for passing as an actual function parameter. */
void gfc_conv_array_parameter (gfc_se *, gfc_expr *, gfc_ss *, int,
- const gfc_symbol *, const char *);
+ const gfc_symbol *, const char *, tree *);
/* Evaluate and transpose a matrix expression. */
void gfc_conv_array_transpose (gfc_se *, gfc_expr *);
@@ -120,13 +120,18 @@ tree gfc_conv_array_ubound (tree, int);
/* Build expressions for accessing components of an array descriptor. */
tree gfc_conv_descriptor_data_get (tree);
-void gfc_conv_descriptor_data_set (stmtblock_t *, tree, tree);
tree gfc_conv_descriptor_data_addr (tree);
-tree gfc_conv_descriptor_offset (tree);
+tree gfc_conv_descriptor_offset_get (tree);
tree gfc_conv_descriptor_dtype (tree);
-tree gfc_conv_descriptor_stride (tree, tree);
-tree gfc_conv_descriptor_lbound (tree, tree);
-tree gfc_conv_descriptor_ubound (tree, tree);
+tree gfc_conv_descriptor_stride_get (tree, tree);
+tree gfc_conv_descriptor_lbound_get (tree, tree);
+tree gfc_conv_descriptor_ubound_get (tree, tree);
+
+void gfc_conv_descriptor_data_set (stmtblock_t *, tree, tree);
+void gfc_conv_descriptor_offset_set (stmtblock_t *, tree, tree);
+void gfc_conv_descriptor_stride_set (stmtblock_t *, tree, tree, tree);
+void gfc_conv_descriptor_lbound_set (stmtblock_t *, tree, tree, tree);
+void gfc_conv_descriptor_ubound_set (stmtblock_t *, tree, tree, tree);
/* Add pre-loop scalarization code for intrinsic functions which require
special handling. */
diff --git a/gcc/fortran/trans-common.c b/gcc/fortran/trans-common.c
index 6cf9d5b0979..f4bbb467bc9 100644
--- a/gcc/fortran/trans-common.c
+++ b/gcc/fortran/trans-common.c
@@ -278,8 +278,8 @@ build_field (segment_info *h, tree union_type, record_layout_info rli)
unsigned HOST_WIDE_INT desired_align, known_align;
name = get_identifier (h->sym->name);
- field = build_decl (FIELD_DECL, name, h->field);
- gfc_set_decl_location (field, &h->sym->declared_at);
+ field = build_decl (h->sym->declared_at.lb->location,
+ FIELD_DECL, name, h->field);
known_align = (offset & -offset) * BITS_PER_UNIT;
if (known_align == 0 || known_align > BIGGEST_ALIGNMENT)
known_align = BIGGEST_ALIGNMENT;
@@ -349,7 +349,8 @@ build_equiv_decl (tree union_type, bool is_init, bool is_saved)
}
snprintf (name, sizeof (name), "equiv.%d", serial++);
- decl = build_decl (VAR_DECL, get_identifier (name), union_type);
+ decl = build_decl (input_location,
+ VAR_DECL, get_identifier (name), union_type);
DECL_ARTIFICIAL (decl) = 1;
DECL_IGNORED_P (decl) = 1;
@@ -412,7 +413,8 @@ build_common_decl (gfc_common_head *com, tree union_type, bool is_init)
/* If there is no backend_decl for the common block, build it. */
if (decl == NULL_TREE)
{
- decl = build_decl (VAR_DECL, get_identifier (com->name), union_type);
+ decl = build_decl (input_location,
+ VAR_DECL, get_identifier (com->name), union_type);
SET_DECL_ASSEMBLER_NAME (decl, gfc_sym_mangled_common_id (com));
TREE_PUBLIC (decl) = 1;
TREE_STATIC (decl) = 1;
@@ -527,8 +529,8 @@ get_init_field (segment_info *head, tree union_type, tree *field_init,
tmp = build_range_type (gfc_array_index_type,
gfc_index_zero_node, tmp);
tmp = build_array_type (type, tmp);
- field = build_decl (FIELD_DECL, NULL_TREE, tmp);
- gfc_set_decl_location (field, &gfc_current_locus);
+ field = build_decl (gfc_current_locus.lb->location,
+ FIELD_DECL, NULL_TREE, tmp);
known_align = BIGGEST_ALIGNMENT;
@@ -675,9 +677,9 @@ create_common (gfc_common_head *com, segment_info *head, bool saw_equiv)
{
tree var_decl;
- var_decl = build_decl (VAR_DECL, DECL_NAME (s->field),
+ var_decl = build_decl (s->sym->declared_at.lb->location,
+ VAR_DECL, DECL_NAME (s->field),
TREE_TYPE (s->field));
- gfc_set_decl_location (var_decl, &s->sym->declared_at);
TREE_PUBLIC (var_decl) = TREE_PUBLIC (decl);
TREE_STATIC (var_decl) = TREE_STATIC (decl);
TREE_USED (var_decl) = TREE_USED (decl);
diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c
index f5d6d4cb6a2..5af00a91a03 100644
--- a/gcc/fortran/trans-decl.c
+++ b/gcc/fortran/trans-decl.c
@@ -86,6 +86,7 @@ tree gfor_fndecl_runtime_error_at;
tree gfor_fndecl_runtime_warning_at;
tree gfor_fndecl_os_error;
tree gfor_fndecl_generate_error;
+tree gfor_fndecl_set_args;
tree gfor_fndecl_set_fpe;
tree gfor_fndecl_set_options;
tree gfor_fndecl_set_convert;
@@ -144,6 +145,8 @@ tree gfor_fndecl_convert_char4_to_char1;
tree gfor_fndecl_size0;
tree gfor_fndecl_size1;
tree gfor_fndecl_iargc;
+tree gfor_fndecl_clz128;
+tree gfor_fndecl_ctz128;
/* Intrinsic functions implemented in Fortran. */
tree gfor_fndecl_sc_kind;
@@ -200,7 +203,8 @@ gfc_build_label_decl (tree label_id)
label_name = NULL;
/* Build the LABEL_DECL node. Labels have no type. */
- label_decl = build_decl (LABEL_DECL, label_id, void_type_node);
+ label_decl = build_decl (input_location,
+ LABEL_DECL, label_id, void_type_node);
DECL_CONTEXT (label_decl) = current_function_decl;
DECL_MODE (label_decl) = VOIDmode;
@@ -286,7 +290,10 @@ gfc_get_label_decl (gfc_st_label * lp)
static tree
gfc_sym_identifier (gfc_symbol * sym)
{
- return (get_identifier (sym->name));
+ if (sym->attr.is_main_program && strcmp (sym->name, "main") == 0)
+ return (get_identifier ("MAIN__"));
+ else
+ return (get_identifier (sym->name));
}
@@ -744,7 +751,8 @@ gfc_build_qualified_array (tree decl, gfc_symbol * sym)
DECL_IGNORED_P (GFC_TYPE_ARRAY_UBOUND (type, dim)) = 0;
}
}
- TYPE_NAME (type) = type_decl = build_decl (TYPE_DECL, NULL, gtype);
+ TYPE_NAME (type) = type_decl = build_decl (input_location,
+ TYPE_DECL, NULL, gtype);
DECL_ORIGINAL_TYPE (type_decl) = gtype;
}
}
@@ -836,7 +844,8 @@ gfc_build_dummy_array_decl (gfc_symbol * sym, tree dummy)
}
ASM_FORMAT_PRIVATE_NAME (name, IDENTIFIER_POINTER (DECL_NAME (dummy)), 0);
- decl = build_decl (VAR_DECL, get_identifier (name), type);
+ decl = build_decl (input_location,
+ VAR_DECL, get_identifier (name), type);
DECL_ARTIFICIAL (decl) = 1;
TREE_PUBLIC (decl) = 0;
@@ -886,7 +895,7 @@ gfc_nonlocal_dummy_array_decl (gfc_symbol *sym)
return;
dummy = GFC_DECL_SAVED_DESCRIPTOR (sym->backend_decl);
- decl = build_decl (VAR_DECL, DECL_NAME (dummy),
+ decl = build_decl (input_location, VAR_DECL, DECL_NAME (dummy),
TREE_TYPE (sym->backend_decl));
DECL_ARTIFICIAL (decl) = 0;
TREE_USED (decl) = 1;
@@ -920,7 +929,8 @@ gfc_create_string_length (gfc_symbol * sym)
/* Also prefix the mangled name. */
strcpy (&name[1], sym->name);
name[0] = '.';
- length = build_decl (VAR_DECL, get_identifier (name),
+ length = build_decl (input_location,
+ VAR_DECL, get_identifier (name),
gfc_charlen_type_node);
DECL_ARTIFICIAL (length) = 1;
TREE_USED (length) = 1;
@@ -949,9 +959,11 @@ gfc_add_assign_aux_vars (gfc_symbol * sym)
decl = sym->backend_decl;
gfc_allocate_lang_decl (decl);
GFC_DECL_ASSIGN (decl) = 1;
- length = build_decl (VAR_DECL, create_tmp_var_name (sym->name),
+ length = build_decl (input_location,
+ VAR_DECL, create_tmp_var_name (sym->name),
gfc_charlen_type_node);
- addr = build_decl (VAR_DECL, create_tmp_var_name (sym->name),
+ addr = build_decl (input_location,
+ VAR_DECL, create_tmp_var_name (sym->name),
pvoid_type_node);
gfc_finish_var_decl (length, sym);
gfc_finish_var_decl (addr, sym);
@@ -1073,9 +1085,8 @@ gfc_get_symbol_decl (gfc_symbol * sym)
length = gfc_create_string_length (sym);
/* Create the decl for the variable. */
- decl = build_decl (VAR_DECL, gfc_sym_identifier (sym), gfc_sym_type (sym));
-
- gfc_set_decl_location (decl, &sym->declared_at);
+ decl = build_decl (sym->declared_at.lb->location,
+ VAR_DECL, gfc_sym_identifier (sym), gfc_sym_type (sym));
/* Symbols from modules should have their assembler names mangled.
This is done here rather than in gfc_finish_var_decl because it
@@ -1144,7 +1155,8 @@ gfc_get_symbol_decl (gfc_symbol * sym)
{
tree span;
GFC_DECL_SUBREF_ARRAY_P (decl) = 1;
- span = build_decl (VAR_DECL, create_tmp_var_name ("span"),
+ span = build_decl (input_location,
+ VAR_DECL, create_tmp_var_name ("span"),
gfc_array_index_type);
gfc_finish_var_decl (span, sym);
TREE_STATIC (span) = TREE_STATIC (decl);
@@ -1216,7 +1228,8 @@ get_proc_pointer_decl (gfc_symbol *sym)
if (decl)
return decl;
- decl = build_decl (VAR_DECL, get_identifier (sym->name),
+ decl = build_decl (input_location,
+ VAR_DECL, get_identifier (sym->name),
build_pointer_type (gfc_get_function_type (sym)));
if ((sym->ns->proc_name
@@ -1374,7 +1387,8 @@ gfc_get_extern_function_decl (gfc_symbol * sym)
}
type = gfc_get_function_type (sym);
- fndecl = build_decl (FUNCTION_DECL, name, type);
+ fndecl = build_decl (input_location,
+ FUNCTION_DECL, name, type);
SET_DECL_ASSEMBLER_NAME (fndecl, mangled_name);
/* If the return type is a pointer, avoid alias issues by setting
@@ -1455,7 +1469,8 @@ build_function_decl (gfc_symbol * sym)
== NAMESPACE_DECL);
type = gfc_get_function_type (sym);
- fndecl = build_decl (FUNCTION_DECL, gfc_sym_identifier (sym), type);
+ fndecl = build_decl (input_location,
+ FUNCTION_DECL, gfc_sym_identifier (sym), type);
/* Perform name mangling if this is a top level or module procedure. */
if (current_function_decl == NULL_TREE)
@@ -1499,7 +1514,8 @@ build_function_decl (gfc_symbol * sym)
type = void_type_node;
}
- result_decl = build_decl (RESULT_DECL, result_decl, type);
+ result_decl = build_decl (input_location,
+ RESULT_DECL, result_decl, type);
DECL_ARTIFICIAL (result_decl) = 1;
DECL_IGNORED_P (result_decl) = 1;
DECL_CONTEXT (result_decl) = fndecl;
@@ -1522,7 +1538,7 @@ build_function_decl (gfc_symbol * sym)
/* This specifies if a function is globally visible, i.e. it is
the opposite of declaring static in C. */
if (DECL_CONTEXT (fndecl) == NULL_TREE
- && !sym->attr.entry_master)
+ && !sym->attr.entry_master && !sym->attr.is_main_program)
TREE_PUBLIC (fndecl) = 1;
/* TREE_STATIC means the function body is defined here. */
@@ -1541,12 +1557,6 @@ build_function_decl (gfc_symbol * sym)
TREE_SIDE_EFFECTS (fndecl) = 0;
}
- /* For -fwhole-program to work well, the main program needs to have the
- "externally_visible" attribute. */
- if (attr.is_main_program)
- DECL_ATTRIBUTES (fndecl)
- = tree_cons (get_identifier("externally_visible"), NULL_TREE, NULL_TREE);
-
/* Layout the function declaration and put it in the binding level
of the current function. */
pushdecl (fndecl);
@@ -1578,7 +1588,8 @@ create_function_arglist (gfc_symbol * sym)
if (sym->attr.entry_master)
{
type = TREE_VALUE (typelist);
- parm = build_decl (PARM_DECL, get_identifier ("__entry"), type);
+ parm = build_decl (input_location,
+ PARM_DECL, get_identifier ("__entry"), type);
DECL_CONTEXT (parm) = fndecl;
DECL_ARG_TYPE (parm) = type;
@@ -1600,7 +1611,8 @@ create_function_arglist (gfc_symbol * sym)
tree len_type = TREE_VALUE (TREE_CHAIN (typelist));
gcc_assert (len_type == gfc_charlen_type_node);
- length = build_decl (PARM_DECL,
+ length = build_decl (input_location,
+ PARM_DECL,
get_identifier (".__result"),
len_type);
if (!sym->ts.cl->length)
@@ -1622,7 +1634,8 @@ create_function_arglist (gfc_symbol * sym)
if (sym->ts.cl->backend_decl == NULL)
{
- tree len = build_decl (VAR_DECL,
+ tree len = build_decl (input_location,
+ VAR_DECL,
get_identifier ("..__result"),
gfc_charlen_type_node);
DECL_ARTIFICIAL (len) = 1;
@@ -1642,7 +1655,8 @@ create_function_arglist (gfc_symbol * sym)
}
}
- parm = build_decl (PARM_DECL, get_identifier ("__result"), type);
+ parm = build_decl (input_location,
+ PARM_DECL, get_identifier ("__result"), type);
DECL_CONTEXT (parm) = fndecl;
DECL_ARG_TYPE (parm) = TREE_VALUE (typelist);
@@ -1684,7 +1698,8 @@ create_function_arglist (gfc_symbol * sym)
strcpy (&name[1], f->sym->name);
name[0] = '_';
- length = build_decl (PARM_DECL, get_identifier (name), len_type);
+ length = build_decl (input_location,
+ PARM_DECL, get_identifier (name), len_type);
hidden_arglist = chainon (hidden_arglist, length);
DECL_CONTEXT (length) = fndecl;
@@ -1694,6 +1709,22 @@ create_function_arglist (gfc_symbol * sym)
gfc_finish_decl (length);
/* Remember the passed value. */
+ if (f->sym->ts.cl->passed_length != NULL)
+ {
+ /* This can happen if the same type is used for multiple
+ arguments. We need to copy cl as otherwise
+ cl->passed_length gets overwritten. */
+ gfc_charlen *cl, *cl2;
+ cl = f->sym->ts.cl;
+ f->sym->ts.cl = gfc_get_charlen();
+ f->sym->ts.cl->length = cl->length;
+ f->sym->ts.cl->backend_decl = cl->backend_decl;
+ f->sym->ts.cl->length_from_typespec = cl->length_from_typespec;
+ f->sym->ts.cl->resolved = cl->resolved;
+ cl2 = f->sym->ts.cl->next;
+ f->sym->ts.cl->next = cl;
+ cl->next = cl2;
+ }
f->sym->ts.cl->passed_length = length;
/* Use the passed value for assumed length variables. */
@@ -1739,7 +1770,8 @@ create_function_arglist (gfc_symbol * sym)
type = build_pointer_type (type);
/* Build the argument declaration. */
- parm = build_decl (PARM_DECL, gfc_sym_identifier (f->sym), type);
+ parm = build_decl (input_location,
+ PARM_DECL, gfc_sym_identifier (f->sym), type);
/* Fill in arg stuff. */
DECL_CONTEXT (parm) = fndecl;
@@ -1929,7 +1961,8 @@ build_entry_thunks (gfc_namespace * ns)
tree union_decl, field;
tree master_type = TREE_TYPE (ns->proc_name->backend_decl);
- union_decl = build_decl (VAR_DECL, get_identifier ("__result"),
+ union_decl = build_decl (input_location,
+ VAR_DECL, get_identifier ("__result"),
TREE_TYPE (master_type));
DECL_ARTIFICIAL (union_decl) = 1;
DECL_EXTERNAL (union_decl) = 0;
@@ -2144,10 +2177,12 @@ gfc_get_fake_result_decl (gfc_symbol * sym, int parent_flag)
IDENTIFIER_POINTER (DECL_NAME (this_function_decl)));
if (!sym->attr.mixed_entry_master && sym->attr.function)
- decl = build_decl (VAR_DECL, get_identifier (name),
+ decl = build_decl (input_location,
+ VAR_DECL, get_identifier (name),
gfc_sym_type (sym));
else
- decl = build_decl (VAR_DECL, get_identifier (name),
+ decl = build_decl (input_location,
+ VAR_DECL, get_identifier (name),
TREE_TYPE (TREE_TYPE (this_function_decl)));
DECL_ARTIFICIAL (decl) = 1;
DECL_EXTERNAL (decl) = 0;
@@ -2207,7 +2242,8 @@ gfc_build_library_function_decl (tree name, tree rettype, int nargs, ...)
/* Build the function type and decl. */
fntype = build_function_type (rettype, arglist);
- fndecl = build_decl (FUNCTION_DECL, name, fntype);
+ fndecl = build_decl (input_location,
+ FUNCTION_DECL, name, fntype);
/* Mark this decl as external. */
DECL_EXTERNAL (fndecl) = 1;
@@ -2572,6 +2608,19 @@ gfc_build_intrinsic_function_decls (void)
gfc_build_library_function_decl (get_identifier (PREFIX ("iargc")),
gfc_int4_type_node,
0);
+
+ if (gfc_type_for_size (128, true))
+ {
+ tree uint128 = gfc_type_for_size (128, true);
+
+ gfor_fndecl_clz128 =
+ gfc_build_library_function_decl (get_identifier (PREFIX ("clz128")),
+ integer_type_node, 1, uint128);
+
+ gfor_fndecl_ctz128 =
+ gfc_build_library_function_decl (get_identifier (PREFIX ("ctz128")),
+ integer_type_node, 1, uint128);
+ }
}
@@ -2632,6 +2681,11 @@ gfc_build_builtin_function_decls (void)
/* The runtime_error function does not return. */
TREE_THIS_VOLATILE (gfor_fndecl_os_error) = 1;
+ gfor_fndecl_set_args =
+ gfc_build_library_function_decl (get_identifier (PREFIX("set_args")),
+ void_type_node, 2, integer_type_node,
+ build_pointer_type (pchar_type_node));
+
gfor_fndecl_set_fpe =
gfc_build_library_function_decl (get_identifier (PREFIX("set_fpe")),
void_type_node, 1, integer_type_node);
@@ -2640,7 +2694,7 @@ gfc_build_builtin_function_decls (void)
gfor_fndecl_set_options =
gfc_build_library_function_decl (get_identifier (PREFIX("set_options")),
void_type_node, 2, integer_type_node,
- pvoid_type_node);
+ build_pointer_type (integer_type_node));
gfor_fndecl_set_convert =
gfc_build_library_function_decl (get_identifier (PREFIX("set_convert")),
@@ -2870,7 +2924,7 @@ gfc_init_default_dt (gfc_symbol * sym, tree body)
{
present = gfc_conv_expr_present (sym);
tmp = build3 (COND_EXPR, TREE_TYPE (tmp), present,
- tmp, build_empty_stmt ());
+ tmp, build_empty_stmt (input_location));
}
gfc_add_expr_to_block (&fnblock, tmp);
gfc_free_expr (e);
@@ -2905,7 +2959,7 @@ init_intent_out_dt (gfc_symbol * proc_sym, tree body)
present = gfc_conv_expr_present (f->sym);
tmp = build3 (COND_EXPR, TREE_TYPE (tmp), present,
- tmp, build_empty_stmt ());
+ tmp, build_empty_stmt (input_location));
gfc_add_expr_to_block (&fnblock, tmp);
}
@@ -3293,7 +3347,8 @@ gfc_trans_use_stmts (gfc_namespace * ns)
if (entry->namespace_decl == NULL)
{
entry->namespace_decl
- = build_decl (NAMESPACE_DECL,
+ = build_decl (input_location,
+ NAMESPACE_DECL,
get_identifier (use_stmt->module_name),
void_type_node);
DECL_EXTERNAL (entry->namespace_decl) = 1;
@@ -3470,7 +3525,8 @@ gfc_emit_parameter_debug_info (gfc_symbol *sym)
return;
/* Create the decl for the variable or constant. */
- decl = build_decl (sym->attr.flavor == FL_PARAMETER ? CONST_DECL : VAR_DECL,
+ decl = build_decl (input_location,
+ sym->attr.flavor == FL_PARAMETER ? CONST_DECL : VAR_DECL,
gfc_sym_identifier (sym), gfc_sym_type (sym));
if (sym->attr.flavor == FL_PARAMETER)
TREE_READONLY (decl) = 1;
@@ -3832,6 +3888,221 @@ add_argument_checking (stmtblock_t *block, gfc_symbol *sym)
}
+static void
+create_main_function (tree fndecl)
+{
+ tree old_context;
+ tree ftn_main;
+ tree tmp, decl, result_decl, argc, argv, typelist, arglist;
+ stmtblock_t body;
+
+ old_context = current_function_decl;
+
+ if (old_context)
+ {
+ push_function_context ();
+ saved_parent_function_decls = saved_function_decls;
+ saved_function_decls = NULL_TREE;
+ }
+
+ /* main() function must be declared with global scope. */
+ gcc_assert (current_function_decl == NULL_TREE);
+
+ /* Declare the function. */
+ tmp = build_function_type_list (integer_type_node, integer_type_node,
+ build_pointer_type (pchar_type_node),
+ NULL_TREE);
+ main_identifier_node = get_identifier ("main");
+ ftn_main = build_decl (input_location, FUNCTION_DECL,
+ main_identifier_node, tmp);
+ DECL_EXTERNAL (ftn_main) = 0;
+ TREE_PUBLIC (ftn_main) = 1;
+ TREE_STATIC (ftn_main) = 1;
+ DECL_ATTRIBUTES (ftn_main)
+ = tree_cons (get_identifier("externally_visible"), NULL_TREE, NULL_TREE);
+
+ /* Setup the result declaration (for "return 0"). */
+ result_decl = build_decl (input_location,
+ RESULT_DECL, NULL_TREE, integer_type_node);
+ DECL_ARTIFICIAL (result_decl) = 1;
+ DECL_IGNORED_P (result_decl) = 1;
+ DECL_CONTEXT (result_decl) = ftn_main;
+ DECL_RESULT (ftn_main) = result_decl;
+
+ pushdecl (ftn_main);
+
+ /* Get the arguments. */
+
+ arglist = NULL_TREE;
+ typelist = TYPE_ARG_TYPES (TREE_TYPE (ftn_main));
+
+ tmp = TREE_VALUE (typelist);
+ argc = build_decl (input_location, PARM_DECL, get_identifier ("argc"), tmp);
+ DECL_CONTEXT (argc) = ftn_main;
+ DECL_ARG_TYPE (argc) = TREE_VALUE (typelist);
+ TREE_READONLY (argc) = 1;
+ gfc_finish_decl (argc);
+ arglist = chainon (arglist, argc);
+
+ typelist = TREE_CHAIN (typelist);
+ tmp = TREE_VALUE (typelist);
+ argv = build_decl (input_location, PARM_DECL, get_identifier ("argv"), tmp);
+ DECL_CONTEXT (argv) = ftn_main;
+ DECL_ARG_TYPE (argv) = TREE_VALUE (typelist);
+ TREE_READONLY (argv) = 1;
+ DECL_BY_REFERENCE (argv) = 1;
+ gfc_finish_decl (argv);
+ arglist = chainon (arglist, argv);
+
+ DECL_ARGUMENTS (ftn_main) = arglist;
+ current_function_decl = ftn_main;
+ announce_function (ftn_main);
+
+ rest_of_decl_compilation (ftn_main, 1, 0);
+ make_decl_rtl (ftn_main);
+ init_function_start (ftn_main);
+ pushlevel (0);
+
+ gfc_init_block (&body);
+
+ /* Call some libgfortran initialization routines, call then MAIN__(). */
+
+ /* Call _gfortran_set_args (argc, argv). */
+ TREE_USED (argc) = 1;
+ TREE_USED (argv) = 1;
+ tmp = build_call_expr (gfor_fndecl_set_args, 2, argc, argv);
+ gfc_add_expr_to_block (&body, tmp);
+
+ /* Add a call to set_options to set up the runtime library Fortran
+ language standard parameters. */
+ {
+ tree array_type, array, var;
+
+ /* Passing a new option to the library requires four modifications:
+ + add it to the tree_cons list below
+ + change the array size in the call to build_array_type
+ + change the first argument to the library call
+ gfor_fndecl_set_options
+ + modify the library (runtime/compile_options.c)! */
+
+ array = tree_cons (NULL_TREE, build_int_cst (integer_type_node,
+ gfc_option.warn_std), NULL_TREE);
+ array = tree_cons (NULL_TREE, build_int_cst (integer_type_node,
+ gfc_option.allow_std), array);
+ array = tree_cons (NULL_TREE, build_int_cst (integer_type_node, pedantic),
+ array);
+ array = tree_cons (NULL_TREE, build_int_cst (integer_type_node,
+ gfc_option.flag_dump_core), array);
+ array = tree_cons (NULL_TREE, build_int_cst (integer_type_node,
+ gfc_option.flag_backtrace), array);
+ array = tree_cons (NULL_TREE, build_int_cst (integer_type_node,
+ gfc_option.flag_sign_zero), array);
+
+ array = tree_cons (NULL_TREE, build_int_cst (integer_type_node,
+ (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)), array);
+
+ array = tree_cons (NULL_TREE, build_int_cst (integer_type_node,
+ gfc_option.flag_range_check), array);
+
+ array_type = build_array_type (integer_type_node,
+ build_index_type (build_int_cst (NULL_TREE, 7)));
+ array = build_constructor_from_list (array_type, nreverse (array));
+ TREE_CONSTANT (array) = 1;
+ TREE_STATIC (array) = 1;
+
+ /* Create a static variable to hold the jump table. */
+ var = gfc_create_var (array_type, "options");
+ TREE_CONSTANT (var) = 1;
+ TREE_STATIC (var) = 1;
+ TREE_READONLY (var) = 1;
+ DECL_INITIAL (var) = array;
+ var = gfc_build_addr_expr (build_pointer_type (integer_type_node), var);
+
+ tmp = build_call_expr (gfor_fndecl_set_options, 2,
+ build_int_cst (integer_type_node, 8), var);
+ gfc_add_expr_to_block (&body, tmp);
+ }
+
+ /* If -ffpe-trap option was provided, add a call to set_fpe so that
+ the library will raise a FPE when needed. */
+ if (gfc_option.fpe != 0)
+ {
+ tmp = build_call_expr (gfor_fndecl_set_fpe, 1,
+ build_int_cst (integer_type_node,
+ gfc_option.fpe));
+ gfc_add_expr_to_block (&body, tmp);
+ }
+
+ /* If this is the main program and an -fconvert option was provided,
+ add a call to set_convert. */
+
+ if (gfc_option.convert != GFC_CONVERT_NATIVE)
+ {
+ tmp = build_call_expr (gfor_fndecl_set_convert, 1,
+ build_int_cst (integer_type_node,
+ gfc_option.convert));
+ gfc_add_expr_to_block (&body, tmp);
+ }
+
+ /* If this is the main program and an -frecord-marker option was provided,
+ add a call to set_record_marker. */
+
+ if (gfc_option.record_marker != 0)
+ {
+ tmp = build_call_expr (gfor_fndecl_set_record_marker, 1,
+ build_int_cst (integer_type_node,
+ gfc_option.record_marker));
+ gfc_add_expr_to_block (&body, tmp);
+ }
+
+ if (gfc_option.max_subrecord_length != 0)
+ {
+ tmp = build_call_expr (gfor_fndecl_set_max_subrecord_length, 1,
+ build_int_cst (integer_type_node,
+ gfc_option.max_subrecord_length));
+ gfc_add_expr_to_block (&body, tmp);
+ }
+
+ /* Call MAIN__(). */
+ tmp = build_call_expr (fndecl, 0);
+ gfc_add_expr_to_block (&body, tmp);
+
+ /* Mark MAIN__ as used. */
+ TREE_USED (fndecl) = 1;
+
+ /* "return 0". */
+ tmp = fold_build2 (MODIFY_EXPR, integer_type_node, DECL_RESULT (ftn_main),
+ build_int_cst (integer_type_node, 0));
+ tmp = build1_v (RETURN_EXPR, tmp);
+ gfc_add_expr_to_block (&body, tmp);
+
+
+ DECL_SAVED_TREE (ftn_main) = gfc_finish_block (&body);
+ decl = getdecls ();
+
+ /* Finish off this function and send it for code generation. */
+ poplevel (1, 0, 1);
+ BLOCK_SUPERCONTEXT (DECL_INITIAL (ftn_main)) = ftn_main;
+
+ DECL_SAVED_TREE (ftn_main)
+ = build3_v (BIND_EXPR, decl, DECL_SAVED_TREE (ftn_main),
+ DECL_INITIAL (ftn_main));
+
+ /* Output the GENERIC tree. */
+ dump_function (TDI_original, ftn_main);
+
+ gfc_gimplify_function (ftn_main);
+ cgraph_finalize_function (ftn_main, false);
+
+ if (old_context)
+ {
+ pop_function_context ();
+ saved_function_decls = saved_parent_function_decls;
+ }
+ current_function_decl = old_context;
+}
+
+
/* Generate code for a function. */
void
@@ -3916,107 +4187,6 @@ gfc_generate_function_code (gfc_namespace * ns)
/* Now generate the code for the body of this function. */
gfc_init_block (&body);
- /* If this is the main program, add a call to set_options to set up the
- runtime library Fortran language standard parameters. */
- if (sym->attr.is_main_program)
- {
- tree array_type, array, var;
-
- /* Passing a new option to the library requires four modifications:
- + add it to the tree_cons list below
- + change the array size in the call to build_array_type
- + change the first argument to the library call
- gfor_fndecl_set_options
- + modify the library (runtime/compile_options.c)! */
- array = tree_cons (NULL_TREE,
- build_int_cst (integer_type_node,
- gfc_option.warn_std), NULL_TREE);
- array = tree_cons (NULL_TREE,
- build_int_cst (integer_type_node,
- gfc_option.allow_std), array);
- array = tree_cons (NULL_TREE,
- build_int_cst (integer_type_node, pedantic), array);
- array = tree_cons (NULL_TREE,
- build_int_cst (integer_type_node,
- gfc_option.flag_dump_core), array);
- array = tree_cons (NULL_TREE,
- build_int_cst (integer_type_node,
- gfc_option.flag_backtrace), array);
- array = tree_cons (NULL_TREE,
- build_int_cst (integer_type_node,
- gfc_option.flag_sign_zero), array);
-
- array = tree_cons (NULL_TREE,
- build_int_cst (integer_type_node,
- (gfc_option.rtcheck
- & GFC_RTCHECK_BOUNDS)), array);
-
- array = tree_cons (NULL_TREE,
- build_int_cst (integer_type_node,
- gfc_option.flag_range_check), array);
-
- array_type = build_array_type (integer_type_node,
- build_index_type (build_int_cst (NULL_TREE,
- 7)));
- array = build_constructor_from_list (array_type, nreverse (array));
- TREE_CONSTANT (array) = 1;
- TREE_STATIC (array) = 1;
-
- /* Create a static variable to hold the jump table. */
- var = gfc_create_var (array_type, "options");
- TREE_CONSTANT (var) = 1;
- TREE_STATIC (var) = 1;
- TREE_READONLY (var) = 1;
- DECL_INITIAL (var) = array;
- var = gfc_build_addr_expr (pvoid_type_node, var);
-
- tmp = build_call_expr (gfor_fndecl_set_options, 2,
- build_int_cst (integer_type_node, 8), var);
- gfc_add_expr_to_block (&body, tmp);
- }
-
- /* If this is the main program and a -ffpe-trap option was provided,
- add a call to set_fpe so that the library will raise a FPE when
- needed. */
- if (sym->attr.is_main_program && gfc_option.fpe != 0)
- {
- tmp = build_call_expr (gfor_fndecl_set_fpe, 1,
- build_int_cst (integer_type_node,
- gfc_option.fpe));
- gfc_add_expr_to_block (&body, tmp);
- }
-
- /* If this is the main program and an -fconvert option was provided,
- add a call to set_convert. */
-
- if (sym->attr.is_main_program && gfc_option.convert != GFC_CONVERT_NATIVE)
- {
- tmp = build_call_expr (gfor_fndecl_set_convert, 1,
- build_int_cst (integer_type_node,
- gfc_option.convert));
- gfc_add_expr_to_block (&body, tmp);
- }
-
- /* If this is the main program and an -frecord-marker option was provided,
- add a call to set_record_marker. */
-
- if (sym->attr.is_main_program && gfc_option.record_marker != 0)
- {
- tmp = build_call_expr (gfor_fndecl_set_record_marker, 1,
- build_int_cst (integer_type_node,
- gfc_option.record_marker));
- gfc_add_expr_to_block (&body, tmp);
- }
-
- if (sym->attr.is_main_program && gfc_option.max_subrecord_length != 0)
- {
- tmp = build_call_expr (gfor_fndecl_set_max_subrecord_length,
- 1,
- build_int_cst (integer_type_node,
- gfc_option.max_subrecord_length));
- gfc_add_expr_to_block (&body, tmp);
- }
-
is_recursive = sym->attr.recursive
|| (sym->attr.entry_master
&& sym->ns->entries->sym->attr.recursive);
@@ -4054,7 +4224,7 @@ gfc_generate_function_code (gfc_namespace * ns)
/* If bounds-checking is enabled, generate code to check passed in actual
arguments against the expected dummy argument attributes (e.g. string
lengths). */
- if (flag_bounds_check)
+ if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
add_argument_checking (&body, sym);
tmp = gfc_trans_code (ns->code);
@@ -4200,8 +4370,12 @@ gfc_generate_function_code (gfc_namespace * ns)
gfc_trans_use_stmts (ns);
gfc_traverse_ns (ns, gfc_emit_parameter_debug_info);
+
+ if (sym->attr.is_main_program)
+ create_main_function (fndecl);
}
+
void
gfc_generate_constructors (void)
{
@@ -4220,10 +4394,12 @@ gfc_generate_constructors (void)
type = build_function_type (void_type_node,
gfc_chainon_list (NULL_TREE, void_type_node));
- fndecl = build_decl (FUNCTION_DECL, fnname, type);
+ fndecl = build_decl (input_location,
+ FUNCTION_DECL, fnname, type);
TREE_PUBLIC (fndecl) = 1;
- decl = build_decl (RESULT_DECL, NULL_TREE, void_type_node);
+ decl = build_decl (input_location,
+ RESULT_DECL, NULL_TREE, void_type_node);
DECL_ARTIFICIAL (decl) = 1;
DECL_IGNORED_P (decl) = 1;
DECL_CONTEXT (decl) = fndecl;
@@ -4244,7 +4420,7 @@ gfc_generate_constructors (void)
for (; gfc_static_ctors; gfc_static_ctors = TREE_CHAIN (gfc_static_ctors))
{
tmp = build_call_expr (TREE_VALUE (gfc_static_ctors), 0);
- DECL_SAVED_TREE (fndecl) = build_stmt (EXPR_STMT, tmp);
+ DECL_SAVED_TREE (fndecl) = build_stmt (input_location, EXPR_STMT, tmp);
}
decl = getdecls ();
@@ -4292,7 +4468,8 @@ gfc_generate_block_data (gfc_namespace * ns)
else
id = get_identifier ("__BLOCK_DATA__");
- decl = build_decl (VAR_DECL, id, gfc_array_index_type);
+ decl = build_decl (input_location,
+ VAR_DECL, id, gfc_array_index_type);
TREE_PUBLIC (decl) = 1;
TREE_STATIC (decl) = 1;
DECL_IGNORED_P (decl) = 1;
diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c
index 14f64c96ab8..a4d00df7fa7 100644
--- a/gcc/fortran/trans-expr.c
+++ b/gcc/fortran/trans-expr.c
@@ -476,8 +476,8 @@ gfc_conv_component_ref (gfc_se * se, gfc_ref * ref)
se->string_length = tmp;
}
- if ((c->attr.pointer || c->attr.proc_pointer) && c->attr.dimension == 0
- && c->ts.type != BT_CHARACTER)
+ if ((c->attr.pointer && c->attr.dimension == 0 && c->ts.type != BT_CHARACTER)
+ || c->attr.proc_pointer)
se->expr = build_fold_indirect_ref (se->expr);
}
@@ -1628,15 +1628,15 @@ gfc_set_interface_mapping_bounds (stmtblock_t * block, tree type, tree desc)
if (GFC_TYPE_ARRAY_LBOUND (type, n) == NULL_TREE)
{
GFC_TYPE_ARRAY_LBOUND (type, n)
- = gfc_conv_descriptor_lbound (desc, dim);
+ = gfc_conv_descriptor_lbound_get (desc, dim);
GFC_TYPE_ARRAY_UBOUND (type, n)
- = gfc_conv_descriptor_ubound (desc, dim);
+ = gfc_conv_descriptor_ubound_get (desc, dim);
}
else if (GFC_TYPE_ARRAY_UBOUND (type, n) == NULL_TREE)
{
tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
- gfc_conv_descriptor_ubound (desc, dim),
- gfc_conv_descriptor_lbound (desc, dim));
+ gfc_conv_descriptor_ubound_get (desc, dim),
+ gfc_conv_descriptor_lbound_get (desc, dim));
tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
GFC_TYPE_ARRAY_LBOUND (type, n),
tmp);
@@ -2396,6 +2396,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
gfc_symbol *fsym;
stmtblock_t post;
enum {MISSING = 0, ELEMENTAL, SCALAR, SCALAR_POINTER, ARRAY};
+ gfc_component *comp = NULL;
arglist = NULL_TREE;
retargs = NULL_TREE;
@@ -2424,7 +2425,8 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
f = f || !sym->attr.always_explicit;
argss = gfc_walk_expr (arg->expr);
- gfc_conv_array_parameter (se, arg->expr, argss, f, NULL, NULL);
+ gfc_conv_array_parameter (se, arg->expr, argss, f,
+ NULL, NULL, NULL);
}
/* TODO -- the following two lines shouldn't be necessary, but
@@ -2549,11 +2551,13 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
gfc_init_block (&post);
gfc_init_interface_mapping (&mapping);
+ is_proc_ptr_comp (expr, &comp);
need_interface_mapping = ((sym->ts.type == BT_CHARACTER
&& sym->ts.cl->length
&& sym->ts.cl->length->expr_type
!= EXPR_CONSTANT)
- || sym->attr.dimension);
+ || (comp && comp->attr.dimension)
+ || (!comp && sym->attr.dimension));
formal = sym->formal;
/* Evaluate the arguments. */
for (; arg != NULL; arg = arg->next, formal = formal ? formal->next : NULL)
@@ -2676,7 +2680,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
fsym ? fsym->attr.intent : INTENT_INOUT);
else
gfc_conv_array_parameter (&parmse, e, argss, f, fsym,
- sym->name);
+ sym->name, NULL);
/* If an ALLOCATABLE dummy argument has INTENT(OUT) and is
allocated on entry, it must be deallocated. */
@@ -2824,7 +2828,8 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
len = cl.backend_decl;
}
- byref = gfc_return_by_reference (sym);
+ byref = (comp && comp->attr.dimension)
+ || (!comp && gfc_return_by_reference (sym));
if (byref)
{
if (se->direct_byref)
@@ -3047,7 +3052,8 @@ fill_with_spaces (tree start, tree type, tree size)
cond = fold_build2 (LE_EXPR, boolean_type_node, i,
fold_convert (sizetype, integer_zero_node));
tmp = build1_v (GOTO_EXPR, exit_label);
- tmp = fold_build3 (COND_EXPR, void_type_node, cond, tmp, build_empty_stmt ());
+ tmp = fold_build3 (COND_EXPR, void_type_node, cond, tmp,
+ build_empty_stmt (input_location));
gfc_add_expr_to_block (&loop, tmp);
/* Assignment. */
@@ -3200,7 +3206,8 @@ gfc_trans_string_copy (stmtblock_t * block, tree dlength, tree dest,
/* The whole copy_string function is there. */
tmp = fold_build3 (COND_EXPR, void_type_node, cond2, tmp2, tmp3);
- tmp = fold_build3 (COND_EXPR, void_type_node, cond, tmp, build_empty_stmt ());
+ tmp = fold_build3 (COND_EXPR, void_type_node, cond, tmp,
+ build_empty_stmt (input_location));
gfc_add_expr_to_block (block, tmp);
}
@@ -3615,7 +3622,7 @@ gfc_trans_subcomponent_assign (tree dest, gfc_component * cm, gfc_expr * expr)
/* Shift the lbound and ubound of temporaries to being unity, rather
than zero, based. Calculate the offset for all cases. */
- offset = gfc_conv_descriptor_offset (dest);
+ offset = gfc_conv_descriptor_offset_get (dest);
gfc_add_modify (&block, offset, gfc_index_zero_node);
tmp2 =gfc_create_var (gfc_array_index_type, NULL);
for (n = 0; n < expr->rank; n++)
@@ -3624,24 +3631,24 @@ gfc_trans_subcomponent_assign (tree dest, gfc_component * cm, gfc_expr * expr)
&& expr->expr_type != EXPR_CONSTANT)
{
tree span;
- tmp = gfc_conv_descriptor_ubound (dest, gfc_rank_cst[n]);
+ tmp = gfc_conv_descriptor_ubound_get (dest, gfc_rank_cst[n]);
span = fold_build2 (MINUS_EXPR, gfc_array_index_type, tmp,
- gfc_conv_descriptor_lbound (dest, gfc_rank_cst[n]));
- gfc_add_modify (&block, tmp,
- fold_build2 (PLUS_EXPR,
- gfc_array_index_type,
- span, gfc_index_one_node));
- tmp = gfc_conv_descriptor_lbound (dest, gfc_rank_cst[n]);
- gfc_add_modify (&block, tmp, gfc_index_one_node);
+ gfc_conv_descriptor_lbound_get (dest, gfc_rank_cst[n]));
+ tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
+ span, gfc_index_one_node);
+ gfc_conv_descriptor_ubound_set (&block, dest, gfc_rank_cst[n],
+ tmp);
+ gfc_conv_descriptor_lbound_set (&block, dest, gfc_rank_cst[n],
+ gfc_index_one_node);
}
tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
- gfc_conv_descriptor_lbound (dest,
+ gfc_conv_descriptor_lbound_get (dest,
gfc_rank_cst[n]),
- gfc_conv_descriptor_stride (dest,
+ gfc_conv_descriptor_stride_get (dest,
gfc_rank_cst[n]));
gfc_add_modify (&block, tmp2, tmp);
tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, offset, tmp2);
- gfc_add_modify (&block, offset, tmp);
+ gfc_conv_descriptor_offset_set (&block, dest, tmp);
}
if (expr->expr_type == EXPR_FUNCTION
@@ -3994,7 +4001,8 @@ gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr)
{
tree tmp = se->expr;
STRIP_TYPE_NOPS (tmp);
- var = build_decl (CONST_DECL, NULL, TREE_TYPE (tmp));
+ var = build_decl (input_location,
+ CONST_DECL, NULL, TREE_TYPE (tmp));
DECL_INITIAL (var) = tmp;
TREE_STATIC (var) = 1;
pushdecl (var);
@@ -4014,7 +4022,7 @@ gfc_conv_expr_reference (gfc_se * se, gfc_expr * expr)
tree
gfc_trans_pointer_assign (gfc_code * code)
{
- return gfc_trans_pointer_assignment (code->expr, code->expr2);
+ return gfc_trans_pointer_assignment (code->expr1, code->expr2);
}
@@ -4052,6 +4060,10 @@ gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
&& expr1->symtree->n.sym->attr.dummy)
lse.expr = build_fold_indirect_ref (lse.expr);
+ if (expr2->symtree && expr2->symtree->n.sym->attr.proc_pointer
+ && expr2->symtree->n.sym->attr.dummy)
+ rse.expr = build_fold_indirect_ref (rse.expr);
+
gfc_add_block_to_block (&block, &lse.pre);
gfc_add_block_to_block (&block, &rse.pre);
@@ -4237,7 +4249,8 @@ gfc_trans_scalar_assign (gfc_se * lse, gfc_se * rse, gfc_typespec ts,
tmp = gfc_evaluate_now (lse->expr, &lse->pre);
tmp = gfc_deallocate_alloc_comp (ts.derived, tmp, 0);
if (r_is_var)
- tmp = build3_v (COND_EXPR, cond, build_empty_stmt (), tmp);
+ tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
+ tmp);
gfc_add_expr_to_block (&lse->post, tmp);
}
@@ -4252,7 +4265,8 @@ gfc_trans_scalar_assign (gfc_se * lse, gfc_se * rse, gfc_typespec ts,
if (r_is_var)
{
tmp = gfc_copy_alloc_comp (ts.derived, rse->expr, lse->expr, 0);
- tmp = build3_v (COND_EXPR, cond, build_empty_stmt (), tmp);
+ tmp = build3_v (COND_EXPR, cond, build_empty_stmt (input_location),
+ tmp);
gfc_add_expr_to_block (&block, tmp);
}
}
@@ -4283,6 +4297,7 @@ gfc_trans_arrayfunc_assign (gfc_expr * expr1, gfc_expr * expr2)
gfc_ss *ss;
gfc_ref * ref;
bool seen_array_ref;
+ gfc_component *comp = NULL;
/* The caller has already checked rank>0 and expr_type == EXPR_FUNCTION. */
if (expr2->value.function.isym && !gfc_is_intrinsic_libcall (expr2))
@@ -4342,8 +4357,10 @@ gfc_trans_arrayfunc_assign (gfc_expr * expr1, gfc_expr * expr2)
/* The frontend doesn't seem to bother filling in expr->symtree for intrinsic
functions. */
+ is_proc_ptr_comp(expr2, &comp);
gcc_assert (expr2->value.function.isym
- || (gfc_return_by_reference (expr2->value.function.esym)
+ || (comp && comp->attr.dimension)
+ || (!comp && gfc_return_by_reference (expr2->value.function.esym)
&& expr2->value.function.esym->result->attr.dimension));
ss = gfc_walk_expr (expr1);
@@ -4352,7 +4369,7 @@ gfc_trans_arrayfunc_assign (gfc_expr * expr1, gfc_expr * expr2)
gfc_start_block (&se.pre);
se.want_pointer = 1;
- gfc_conv_array_parameter (&se, expr1, ss, 0, NULL, NULL);
+ gfc_conv_array_parameter (&se, expr1, ss, 0, NULL, NULL, NULL);
se.direct_byref = 1;
se.ss = gfc_walk_expr (expr2);
@@ -4427,11 +4444,14 @@ gfc_trans_zero_assign (gfc_expr * expr)
len = fold_build2 (MULT_EXPR, gfc_array_index_type, len,
fold_convert (gfc_array_index_type, tmp));
- /* Convert arguments to the correct types. */
+ /* If we are zeroing a local array avoid taking its address by emitting
+ a = {} instead. */
if (!POINTER_TYPE_P (TREE_TYPE (dest)))
- dest = gfc_build_addr_expr (pvoid_type_node, dest);
- else
- dest = fold_convert (pvoid_type_node, dest);
+ return build2 (MODIFY_EXPR, void_type_node,
+ dest, build_constructor (TREE_TYPE (dest), NULL));
+
+ /* Convert arguments to the correct types. */
+ dest = fold_convert (pvoid_type_node, dest);
len = fold_convert (size_type_node, len);
/* Construct call to __builtin_memset. */
@@ -4839,11 +4859,11 @@ gfc_trans_assignment (gfc_expr * expr1, gfc_expr * expr2, bool init_flag)
tree
gfc_trans_init_assign (gfc_code * code)
{
- return gfc_trans_assignment (code->expr, code->expr2, true);
+ return gfc_trans_assignment (code->expr1, code->expr2, true);
}
tree
gfc_trans_assign (gfc_code * code)
{
- return gfc_trans_assignment (code->expr, code->expr2, false);
+ return gfc_trans_assignment (code->expr1, code->expr2, false);
}
diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c
index d00a35b5eb8..21694e41b36 100644
--- a/gcc/fortran/trans-intrinsic.c
+++ b/gcc/fortran/trans-intrinsic.c
@@ -693,7 +693,8 @@ gfc_get_intrinsic_lib_fndecl (gfc_intrinsic_map_t * m, gfc_expr * expr)
}
argtypes = gfc_chainon_list (argtypes, void_type_node);
type = build_function_type (gfc_typenode_for_spec (ts), argtypes);
- fndecl = build_decl (FUNCTION_DECL, get_identifier (name), type);
+ fndecl = build_decl (input_location,
+ FUNCTION_DECL, get_identifier (name), type);
/* Mark the decl as external. */
DECL_EXTERNAL (fndecl) = 1;
@@ -899,8 +900,8 @@ gfc_conv_intrinsic_bound (gfc_se * se, gfc_expr * expr, int upper)
}
}
- ubound = gfc_conv_descriptor_ubound (desc, bound);
- lbound = gfc_conv_descriptor_lbound (desc, bound);
+ ubound = gfc_conv_descriptor_ubound_get (desc, bound);
+ lbound = gfc_conv_descriptor_lbound_get (desc, bound);
/* Follow any component references. */
if (arg->expr->expr_type == EXPR_VARIABLE
@@ -962,7 +963,7 @@ gfc_conv_intrinsic_bound (gfc_se * se, gfc_expr * expr, int upper)
if (as)
{
- tree stride = gfc_conv_descriptor_stride (desc, bound);
+ tree stride = gfc_conv_descriptor_stride_get (desc, bound);
cond1 = fold_build2 (GE_EXPR, boolean_type_node, ubound, lbound);
cond2 = fold_build2 (LE_EXPR, boolean_type_node, ubound, lbound);
@@ -1388,7 +1389,7 @@ gfc_conv_intrinsic_ctime (gfc_se * se, gfc_expr * expr)
cond = fold_build2 (GT_EXPR, boolean_type_node,
len, build_int_cst (TREE_TYPE (len), 0));
tmp = gfc_call_free (var);
- tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
+ tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt (input_location));
gfc_add_expr_to_block (&se->post, tmp);
se->expr = var;
@@ -1426,7 +1427,7 @@ gfc_conv_intrinsic_fdate (gfc_se * se, gfc_expr * expr)
cond = fold_build2 (GT_EXPR, boolean_type_node,
len, build_int_cst (TREE_TYPE (len), 0));
tmp = gfc_call_free (var);
- tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
+ tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt (input_location));
gfc_add_expr_to_block (&se->post, tmp);
se->expr = var;
@@ -1466,7 +1467,7 @@ gfc_conv_intrinsic_ttynam (gfc_se * se, gfc_expr * expr)
cond = fold_build2 (GT_EXPR, boolean_type_node,
len, build_int_cst (TREE_TYPE (len), 0));
tmp = gfc_call_free (var);
- tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
+ tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt (input_location));
gfc_add_expr_to_block (&se->post, tmp);
se->expr = var;
@@ -1551,10 +1552,12 @@ gfc_conv_intrinsic_minmax (gfc_se * se, gfc_expr * expr, enum tree_code op)
tmp = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, tmp,
fold_convert (boolean_type_node, isnan));
}
- tmp = build3_v (COND_EXPR, tmp, thencase, build_empty_stmt ());
+ tmp = build3_v (COND_EXPR, tmp, thencase,
+ build_empty_stmt (input_location));
if (cond != NULL_TREE)
- tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
+ tmp = build3_v (COND_EXPR, cond, tmp,
+ build_empty_stmt (input_location));
gfc_add_expr_to_block (&se->pre, tmp);
argexpr = argexpr->next;
@@ -1601,7 +1604,7 @@ gfc_conv_intrinsic_minmax_char (gfc_se * se, gfc_expr * expr, int op)
cond = fold_build2 (GT_EXPR, boolean_type_node,
len, build_int_cst (TREE_TYPE (len), 0));
tmp = gfc_call_free (var);
- tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
+ tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt (input_location));
gfc_add_expr_to_block (&se->post, tmp);
se->expr = var;
@@ -1798,7 +1801,7 @@ gfc_conv_intrinsic_anyall (gfc_se * se, gfc_expr * expr, enum tree_code op)
gfc_add_block_to_block (&body, &arrayse.pre);
tmp = fold_build2 (op, boolean_type_node, arrayse.expr,
build_int_cst (TREE_TYPE (arrayse.expr), 0));
- tmp = build3_v (COND_EXPR, tmp, found, build_empty_stmt ());
+ tmp = build3_v (COND_EXPR, tmp, found, build_empty_stmt (input_location));
gfc_add_expr_to_block (&body, tmp);
gfc_add_block_to_block (&body, &arrayse.post);
@@ -1865,7 +1868,8 @@ gfc_conv_intrinsic_count (gfc_se * se, gfc_expr * expr)
gfc_copy_loopinfo_to_se (&arrayse, &loop);
arrayse.ss = arrayss;
gfc_conv_expr_val (&arrayse, actual->expr);
- tmp = build3_v (COND_EXPR, arrayse.expr, tmp, build_empty_stmt ());
+ tmp = build3_v (COND_EXPR, arrayse.expr, tmp,
+ build_empty_stmt (input_location));
gfc_add_block_to_block (&body, &arrayse.pre);
gfc_add_expr_to_block (&body, tmp);
@@ -1977,7 +1981,8 @@ gfc_conv_intrinsic_arith (gfc_se * se, gfc_expr * expr, enum tree_code op)
/* We enclose the above in if (mask) {...} . */
tmp = gfc_finish_block (&block);
- tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
+ tmp = build3_v (COND_EXPR, maskse.expr, tmp,
+ build_empty_stmt (input_location));
}
else
tmp = gfc_finish_block (&block);
@@ -1995,7 +2000,8 @@ gfc_conv_intrinsic_arith (gfc_se * se, gfc_expr * expr, enum tree_code op)
gfc_add_block_to_block (&block, &loop.post);
tmp = gfc_finish_block (&block);
- tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
+ tmp = build3_v (COND_EXPR, maskse.expr, tmp,
+ build_empty_stmt (input_location));
gfc_add_expr_to_block (&block, tmp);
gfc_add_block_to_block (&se->pre, &block);
}
@@ -2266,7 +2272,7 @@ gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, enum tree_code op)
tmp = fold_build2 (TRUTH_OR_EXPR, boolean_type_node,
fold_build2 (op, boolean_type_node,
arrayse.expr, limit), tmp);
- tmp = build3_v (COND_EXPR, tmp, ifbody, build_empty_stmt ());
+ tmp = build3_v (COND_EXPR, tmp, ifbody, build_empty_stmt (input_location));
gfc_add_expr_to_block (&block, tmp);
if (maskss)
@@ -2274,7 +2280,8 @@ gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, enum tree_code op)
/* We enclose the above in if (mask) {...}. */
tmp = gfc_finish_block (&block);
- tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
+ tmp = build3_v (COND_EXPR, maskse.expr, tmp,
+ build_empty_stmt (input_location));
}
else
tmp = gfc_finish_block (&block);
@@ -2428,14 +2435,15 @@ gfc_conv_intrinsic_minmaxval (gfc_se * se, gfc_expr * expr, enum tree_code op)
/* If it is a more extreme value. */
tmp = fold_build2 (op, boolean_type_node, arrayse.expr, limit);
- tmp = build3_v (COND_EXPR, tmp, ifbody, build_empty_stmt ());
+ tmp = build3_v (COND_EXPR, tmp, ifbody, build_empty_stmt (input_location));
gfc_add_expr_to_block (&block, tmp);
gfc_add_block_to_block (&block, &arrayse.post);
tmp = gfc_finish_block (&block);
if (maskss)
/* We enclose the above in if (mask) {...}. */
- tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
+ tmp = build3_v (COND_EXPR, maskse.expr, tmp,
+ build_empty_stmt (input_location));
gfc_add_expr_to_block (&body, tmp);
gfc_trans_scalarizing_loops (&loop, &body);
@@ -2450,7 +2458,8 @@ gfc_conv_intrinsic_minmaxval (gfc_se * se, gfc_expr * expr, enum tree_code op)
gfc_add_block_to_block (&block, &loop.post);
tmp = gfc_finish_block (&block);
- tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
+ tmp = build3_v (COND_EXPR, maskse.expr, tmp,
+ build_empty_stmt (input_location));
gfc_add_expr_to_block (&block, tmp);
gfc_add_block_to_block (&se->pre, &block);
}
@@ -2710,53 +2719,51 @@ gfc_conv_intrinsic_leadz (gfc_se * se, gfc_expr * expr)
tree leadz;
tree bit_size;
tree tmp;
- int arg_kind;
- int i, n, s;
+ tree func;
+ int s, argsize;
gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
+ argsize = TYPE_PRECISION (TREE_TYPE (arg));
/* Which variant of __builtin_clz* should we call? */
- arg_kind = expr->value.function.actual->expr->ts.kind;
- i = gfc_validate_kind (BT_INTEGER, arg_kind, false);
- switch (arg_kind)
+ if (argsize <= INT_TYPE_SIZE)
{
- case 1:
- case 2:
- case 4:
- arg_type = unsigned_type_node;
- n = BUILT_IN_CLZ;
- break;
-
- case 8:
- arg_type = long_unsigned_type_node;
- n = BUILT_IN_CLZL;
- break;
-
- case 16:
- arg_type = long_long_unsigned_type_node;
- n = BUILT_IN_CLZLL;
- break;
-
- default:
- gcc_unreachable ();
+ arg_type = unsigned_type_node;
+ func = built_in_decls[BUILT_IN_CLZ];
+ }
+ else if (argsize <= LONG_TYPE_SIZE)
+ {
+ arg_type = long_unsigned_type_node;
+ func = built_in_decls[BUILT_IN_CLZL];
+ }
+ else if (argsize <= LONG_LONG_TYPE_SIZE)
+ {
+ arg_type = long_long_unsigned_type_node;
+ func = built_in_decls[BUILT_IN_CLZLL];
+ }
+ else
+ {
+ gcc_assert (argsize == 128);
+ arg_type = gfc_build_uint_type (argsize);
+ func = gfor_fndecl_clz128;
}
- /* Convert the actual argument to the proper argument type for the built-in
+ /* Convert the actual argument twice: first, to the unsigned type of the
+ same size; then, to the proper argument type for the built-in
function. But the return type is of the default INTEGER kind. */
+ arg = fold_convert (gfc_build_uint_type (argsize), arg);
arg = fold_convert (arg_type, arg);
result_type = gfc_get_int_type (gfc_default_integer_kind);
/* Compute LEADZ for the case i .ne. 0. */
- s = TYPE_PRECISION (arg_type) - gfc_integer_kinds[i].bit_size;
- tmp = fold_convert (result_type, build_call_expr (built_in_decls[n], 1, arg));
+ s = TYPE_PRECISION (arg_type) - argsize;
+ tmp = fold_convert (result_type, build_call_expr (func, 1, arg));
leadz = fold_build2 (MINUS_EXPR, result_type,
tmp, build_int_cst (result_type, s));
/* Build BIT_SIZE. */
- bit_size = build_int_cst (result_type, gfc_integer_kinds[i].bit_size);
+ bit_size = build_int_cst (result_type, argsize);
- /* ??? For some combinations of targets and integer kinds, the condition
- can be avoided if CLZ_DEFINED_VALUE_AT_ZERO is used. Later. */
cond = fold_build2 (EQ_EXPR, boolean_type_node,
arg, build_int_cst (arg_type, 0));
se->expr = fold_build3 (COND_EXPR, result_type, cond, bit_size, leadz);
@@ -2777,50 +2784,48 @@ gfc_conv_intrinsic_trailz (gfc_se * se, gfc_expr *expr)
tree result_type;
tree trailz;
tree bit_size;
- int arg_kind;
- int i, n;
+ tree func;
+ int argsize;
gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
+ argsize = TYPE_PRECISION (TREE_TYPE (arg));
- /* Which variant of __builtin_clz* should we call? */
- arg_kind = expr->value.function.actual->expr->ts.kind;
- i = gfc_validate_kind (BT_INTEGER, arg_kind, false);
- switch (expr->ts.kind)
+ /* Which variant of __builtin_ctz* should we call? */
+ if (argsize <= INT_TYPE_SIZE)
{
- case 1:
- case 2:
- case 4:
- arg_type = unsigned_type_node;
- n = BUILT_IN_CTZ;
- break;
-
- case 8:
- arg_type = long_unsigned_type_node;
- n = BUILT_IN_CTZL;
- break;
-
- case 16:
- arg_type = long_long_unsigned_type_node;
- n = BUILT_IN_CTZLL;
- break;
-
- default:
- gcc_unreachable ();
+ arg_type = unsigned_type_node;
+ func = built_in_decls[BUILT_IN_CTZ];
+ }
+ else if (argsize <= LONG_TYPE_SIZE)
+ {
+ arg_type = long_unsigned_type_node;
+ func = built_in_decls[BUILT_IN_CTZL];
+ }
+ else if (argsize <= LONG_LONG_TYPE_SIZE)
+ {
+ arg_type = long_long_unsigned_type_node;
+ func = built_in_decls[BUILT_IN_CTZLL];
+ }
+ else
+ {
+ gcc_assert (argsize == 128);
+ arg_type = gfc_build_uint_type (argsize);
+ func = gfor_fndecl_ctz128;
}
- /* Convert the actual argument to the proper argument type for the built-in
+ /* Convert the actual argument twice: first, to the unsigned type of the
+ same size; then, to the proper argument type for the built-in
function. But the return type is of the default INTEGER kind. */
+ arg = fold_convert (gfc_build_uint_type (argsize), arg);
arg = fold_convert (arg_type, arg);
result_type = gfc_get_int_type (gfc_default_integer_kind);
/* Compute TRAILZ for the case i .ne. 0. */
- trailz = fold_convert (result_type, build_call_expr (built_in_decls[n], 1, arg));
+ trailz = fold_convert (result_type, build_call_expr (func, 1, arg));
/* Build BIT_SIZE. */
- bit_size = build_int_cst (result_type, gfc_integer_kinds[i].bit_size);
+ bit_size = build_int_cst (result_type, argsize);
- /* ??? For some combinations of targets and integer kinds, the condition
- can be avoided if CTZ_DEFINED_VALUE_AT_ZERO is used. Later. */
cond = fold_build2 (EQ_EXPR, boolean_type_node,
arg, build_int_cst (arg_type, 0));
se->expr = fold_build3 (COND_EXPR, result_type, cond, bit_size, trailz);
@@ -3324,7 +3329,7 @@ gfc_conv_intrinsic_rrspacing (gfc_se * se, gfc_expr * expr)
cond = fold_build2 (NE_EXPR, boolean_type_node, x,
build_real_from_int_cst (type, integer_zero_node));
- tmp = build3_v (COND_EXPR, cond, stmt, build_empty_stmt ());
+ tmp = build3_v (COND_EXPR, cond, stmt, build_empty_stmt (input_location));
gfc_add_expr_to_block (&se->pre, tmp);
se->expr = fold_convert (type, x);
@@ -3480,8 +3485,8 @@ gfc_conv_intrinsic_size (gfc_se * se, gfc_expr * expr)
tree ubound, lbound;
arg1 = build_fold_indirect_ref (arg1);
- ubound = gfc_conv_descriptor_ubound (arg1, argse.expr);
- lbound = gfc_conv_descriptor_lbound (arg1, argse.expr);
+ ubound = gfc_conv_descriptor_ubound_get (arg1, argse.expr);
+ lbound = gfc_conv_descriptor_lbound_get (arg1, argse.expr);
se->expr = fold_build2 (MINUS_EXPR, gfc_array_index_type,
ubound, lbound);
se->expr = fold_build2 (PLUS_EXPR, gfc_array_index_type, se->expr,
@@ -3567,8 +3572,8 @@ gfc_conv_intrinsic_sizeof (gfc_se *se, gfc_expr *expr)
{
tree idx;
idx = gfc_rank_cst[n];
- lower = gfc_conv_descriptor_lbound (argse.expr, idx);
- upper = gfc_conv_descriptor_ubound (argse.expr, idx);
+ lower = gfc_conv_descriptor_lbound_get (argse.expr, idx);
+ upper = gfc_conv_descriptor_ubound_get (argse.expr, idx);
tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
upper, lower);
tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
@@ -3734,7 +3739,8 @@ gfc_conv_intrinsic_transfer (gfc_se * se, gfc_expr * expr)
gfc_init_block (&block);
tmp = gfc_conv_array_data (argse.expr);
tmp = fold_build2 (NE_EXPR, boolean_type_node, source, tmp);
- tmp = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
+ tmp = build3_v (COND_EXPR, tmp, stmt,
+ build_empty_stmt (input_location));
gfc_add_expr_to_block (&block, tmp);
gfc_add_block_to_block (&block, &se->post);
gfc_init_block (&se->post);
@@ -3756,9 +3762,9 @@ gfc_conv_intrinsic_transfer (gfc_se * se, gfc_expr * expr)
tree idx;
idx = gfc_rank_cst[n];
gfc_add_modify (&argse.pre, source_bytes, tmp);
- stride = gfc_conv_descriptor_stride (argse.expr, idx);
- lower = gfc_conv_descriptor_lbound (argse.expr, idx);
- upper = gfc_conv_descriptor_ubound (argse.expr, idx);
+ stride = gfc_conv_descriptor_stride_get (argse.expr, idx);
+ lower = gfc_conv_descriptor_lbound_get (argse.expr, idx);
+ upper = gfc_conv_descriptor_ubound_get (argse.expr, idx);
tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
upper, lower);
gfc_add_modify (&argse.pre, extent, tmp);
@@ -4074,7 +4080,7 @@ gfc_conv_associated (gfc_se *se, gfc_expr *expr)
present. */
arg1se.descriptor_only = 1;
gfc_conv_expr_lhs (&arg1se, arg1->expr);
- tmp = gfc_conv_descriptor_stride (arg1se.expr,
+ tmp = gfc_conv_descriptor_stride_get (arg1se.expr,
gfc_rank_cst[arg1->expr->rank - 1]);
nonzero_arraylen = fold_build2 (NE_EXPR, boolean_type_node, tmp,
build_int_cst (TREE_TYPE (tmp), 0));
@@ -4225,7 +4231,7 @@ gfc_conv_intrinsic_trim (gfc_se * se, gfc_expr * expr)
cond = fold_build2 (GT_EXPR, boolean_type_node,
len, build_int_cst (TREE_TYPE (len), 0));
tmp = gfc_call_free (var);
- tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
+ tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt (input_location));
gfc_add_expr_to_block (&se->post, tmp);
se->expr = var;
@@ -4316,7 +4322,7 @@ gfc_conv_intrinsic_repeat (gfc_se * se, gfc_expr * expr)
tmp = build1_v (GOTO_EXPR, exit_label);
TREE_USED (exit_label) = 1;
tmp = fold_build3 (COND_EXPR, void_type_node, cond, tmp,
- build_empty_stmt ());
+ build_empty_stmt (input_location));
gfc_add_expr_to_block (&body, tmp);
/* Call memmove (dest + (i*slen*size), src, slen*size). */
@@ -4394,7 +4400,7 @@ gfc_conv_intrinsic_loc (gfc_se * se, gfc_expr * expr)
if (ss == gfc_ss_terminator)
gfc_conv_expr_reference (se, arg_expr);
else
- gfc_conv_array_parameter (se, arg_expr, ss, 1, NULL, NULL);
+ gfc_conv_array_parameter (se, arg_expr, ss, 1, NULL, NULL, NULL);
se->expr= convert (gfc_get_int_type (gfc_index_integer_kind), se->expr);
/* Create a temporary variable for loc return value. Without this,
diff --git a/gcc/fortran/trans-io.c b/gcc/fortran/trans-io.c
index b1543051259..f8b943d7c0b 100644
--- a/gcc/fortran/trans-io.c
+++ b/gcc/fortran/trans-io.c
@@ -264,7 +264,7 @@ gfc_trans_io_runtime_check (tree cond, tree var, int error_code,
cond = build_call_expr (built_in_decls[BUILT_IN_EXPECT], 2, cond, tmp);
cond = fold_convert (boolean_type_node, cond);
- tmp = build3_v (COND_EXPR, cond, body, build_empty_stmt ());
+ tmp = build3_v (COND_EXPR, cond, body, build_empty_stmt (input_location));
gfc_add_expr_to_block (pblock, tmp);
}
}
@@ -279,7 +279,7 @@ gfc_build_io_library_fndecls (void)
tree gfc_intio_type_node;
tree parm_type, dt_parm_type;
HOST_WIDE_INT pad_size;
- enum ioparam_type ptype;
+ unsigned int ptype;
types[IOPARM_type_int4] = gfc_int4_type_node = gfc_get_int_type (4);
types[IOPARM_type_intio] = gfc_intio_type_node
@@ -302,7 +302,7 @@ gfc_build_io_library_fndecls (void)
TYPE_ALIGN (gfc_get_int_type (gfc_intio_kind)));
for (ptype = IOPARM_ptype_common; ptype < IOPARM_ptype_num; ptype++)
- gfc_build_st_parameter (ptype, types);
+ gfc_build_st_parameter ((enum ioparam_type) ptype, types);
/* Define the transfer functions. */
@@ -469,26 +469,27 @@ set_parameter_value (stmtblock_t *block, tree var, enum iofield type,
gfc_conv_expr_val (&se, e);
/* If we're storing a UNIT number, we need to check it first. */
- if (type == IOPARM_common_unit && e->ts.kind != 4)
+ if (type == IOPARM_common_unit && e->ts.kind > 4)
{
- tree cond, max;
+ tree cond, val;
int i;
/* Don't evaluate the UNIT number multiple times. */
se.expr = gfc_evaluate_now (se.expr, &se.pre);
- /* UNIT numbers should be nonnegative. */
+ /* UNIT numbers should be greater than the min. */
+ i = gfc_validate_kind (BT_INTEGER, 4, false);
+ val = gfc_conv_mpz_to_tree (gfc_integer_kinds[i].pedantic_min_int, 4);
cond = fold_build2 (LT_EXPR, boolean_type_node, se.expr,
- build_int_cst (TREE_TYPE (se.expr),0));
+ fold_convert (TREE_TYPE (se.expr), val));
gfc_trans_io_runtime_check (cond, var, LIBERROR_BAD_UNIT,
- "Negative unit number in I/O statement",
+ "Unit number in I/O statement too small",
&se.pre);
/* UNIT numbers should be less than the max. */
- i = gfc_validate_kind (BT_INTEGER, 4, false);
- max = gfc_conv_mpz_to_tree (gfc_integer_kinds[i].huge, 4);
+ val = gfc_conv_mpz_to_tree (gfc_integer_kinds[i].huge, 4);
cond = fold_build2 (GT_EXPR, boolean_type_node, se.expr,
- fold_convert (TREE_TYPE (se.expr), max));
+ fold_convert (TREE_TYPE (se.expr), val));
gfc_trans_io_runtime_check (cond, var, LIBERROR_BAD_UNIT,
"Unit number in I/O statement too large",
&se.pre);
@@ -567,65 +568,57 @@ set_parameter_ref (stmtblock_t *block, stmtblock_t *postblock,
/* Given an array expr, find its address and length to get a string. If the
array is full, the string's address is the address of array's first element
- and the length is the size of the whole array. If it is an element, the
+ and the length is the size of the whole array. If it is an element, the
string's address is the element's address and the length is the rest size of
- the array.
-*/
+ the array. */
static void
gfc_convert_array_to_string (gfc_se * se, gfc_expr * e)
{
- tree tmp;
- tree array;
- tree type;
tree size;
- int rank;
- gfc_symbol *sym;
-
- sym = e->symtree->n.sym;
- rank = sym->as->rank - 1;
- if (e->ref->u.ar.type == AR_FULL)
- {
- se->expr = gfc_get_symbol_decl (sym);
- se->expr = gfc_conv_array_data (se->expr);
- }
- else
+ if (e->rank == 0)
{
+ tree type, array, tmp;
+ gfc_symbol *sym;
+ int rank;
+
+ /* If it is an element, we need its address and size of the rest. */
+ gcc_assert (e->expr_type == EXPR_VARIABLE);
+ gcc_assert (e->ref->u.ar.type == AR_ELEMENT);
+ sym = e->symtree->n.sym;
+ rank = sym->as->rank - 1;
gfc_conv_expr (se, e);
- }
- array = sym->backend_decl;
- type = TREE_TYPE (array);
+ array = sym->backend_decl;
+ type = TREE_TYPE (array);
- if (GFC_ARRAY_TYPE_P (type))
- size = GFC_TYPE_ARRAY_SIZE (type);
- else
- {
- gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
- size = gfc_conv_array_stride (array, rank);
- tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
- gfc_conv_array_ubound (array, rank),
- gfc_conv_array_lbound (array, rank));
- tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type, tmp,
- gfc_index_one_node);
- size = fold_build2 (MULT_EXPR, gfc_array_index_type, tmp, size);
- }
-
- gcc_assert (size);
+ if (GFC_ARRAY_TYPE_P (type))
+ size = GFC_TYPE_ARRAY_SIZE (type);
+ else
+ {
+ gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
+ size = gfc_conv_array_stride (array, rank);
+ tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
+ gfc_conv_array_ubound (array, rank),
+ gfc_conv_array_lbound (array, rank));
+ tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type, tmp,
+ gfc_index_one_node);
+ size = fold_build2 (MULT_EXPR, gfc_array_index_type, tmp, size);
+ }
+ gcc_assert (size);
- /* If it is an element, we need the its address and size of the rest. */
- if (e->ref->u.ar.type == AR_ELEMENT)
- {
size = fold_build2 (MINUS_EXPR, gfc_array_index_type, size,
- TREE_OPERAND (se->expr, 1));
+ TREE_OPERAND (se->expr, 1));
se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
+ tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
+ size = fold_build2 (MULT_EXPR, gfc_array_index_type, size,
+ fold_convert (gfc_array_index_type, tmp));
+ se->string_length = fold_convert (gfc_charlen_type_node, size);
+ return;
}
- tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
- size = fold_build2 (MULT_EXPR, gfc_array_index_type, size,
- fold_convert (gfc_array_index_type, tmp));
-
+ gfc_conv_array_parameter (se, e, gfc_walk_expr (e), 1, NULL, NULL, &size);
se->string_length = fold_convert (gfc_charlen_type_node, size);
}
@@ -654,7 +647,9 @@ set_string (stmtblock_t * block, stmtblock_t * postblock, tree var,
var, p->field_len, NULL_TREE);
/* Integer variable assigned a format label. */
- if (e->ts.type == BT_INTEGER && e->symtree->n.sym->attr.assign == 1)
+ if (e->ts.type == BT_INTEGER
+ && e->rank == 0
+ && e->symtree->n.sym->attr.assign == 1)
{
char * msg;
tree cond;
@@ -680,7 +675,7 @@ set_string (stmtblock_t * block, stmtblock_t * postblock, tree var,
if (e->ts.type == BT_CHARACTER && e->rank == 0)
gfc_conv_expr (&se, e);
/* Array assigned Hollerith constant or character array. */
- else if (e->symtree && (e->symtree->n.sym->as->rank > 0))
+ else if (e->rank > 0 || (e->symtree && e->symtree->n.sym->as->rank > 0))
gfc_convert_array_to_string (&se, e);
else
gcc_unreachable ();
@@ -956,6 +951,10 @@ gfc_trans_open (gfc_code * code)
if (p->convert)
mask |= set_string (&block, &post_block, var, IOPARM_open_convert,
p->convert);
+
+ if (p->newunit)
+ mask |= set_parameter_ref (&block, &post_block, var, IOPARM_open_newunit,
+ p->newunit);
set_parameter_const (&block, var, IOPARM_common_flags, mask);
@@ -2149,7 +2148,7 @@ gfc_trans_transfer (gfc_code * code)
gfc_start_block (&block);
gfc_init_block (&body);
- expr = code->expr;
+ expr = code->expr1;
ss = gfc_walk_expr (expr);
ref = NULL;
@@ -2209,7 +2208,7 @@ gfc_trans_transfer (gfc_code * code)
/* Initialize the loop. */
gfc_conv_ss_startstride (&loop);
- gfc_conv_loop_setup (&loop, &code->expr->where);
+ gfc_conv_loop_setup (&loop, &code->expr1->where);
/* The main loop body. */
gfc_mark_ss_chain_used (ss, 1);
diff --git a/gcc/fortran/trans-openmp.c b/gcc/fortran/trans-openmp.c
index 5ad2f9cc669..a476487a0a2 100644
--- a/gcc/fortran/trans-openmp.c
+++ b/gcc/fortran/trans-openmp.c
@@ -150,14 +150,14 @@ gfc_omp_clause_default_ctor (tree clause, tree decl, tree outer)
gfc_add_modify (&cond_block, decl, outer);
rank = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (type) - 1];
- size = gfc_conv_descriptor_ubound (decl, rank);
+ size = gfc_conv_descriptor_ubound_get (decl, rank);
size = fold_build2 (MINUS_EXPR, gfc_array_index_type, size,
- gfc_conv_descriptor_lbound (decl, rank));
+ gfc_conv_descriptor_lbound_get (decl, rank));
size = fold_build2 (PLUS_EXPR, gfc_array_index_type, size,
gfc_index_one_node);
if (GFC_TYPE_ARRAY_RANK (type) > 1)
size = fold_build2 (MULT_EXPR, gfc_array_index_type, size,
- gfc_conv_descriptor_stride (decl, rank));
+ gfc_conv_descriptor_stride_get (decl, rank));
esize = fold_convert (gfc_array_index_type,
TYPE_SIZE_UNIT (gfc_get_element_type (type)));
size = fold_build2 (MULT_EXPR, gfc_array_index_type, size, esize);
@@ -202,14 +202,14 @@ gfc_omp_clause_copy_ctor (tree clause, tree dest, tree src)
gfc_add_modify (&block, dest, src);
rank = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (type) - 1];
- size = gfc_conv_descriptor_ubound (dest, rank);
+ size = gfc_conv_descriptor_ubound_get (dest, rank);
size = fold_build2 (MINUS_EXPR, gfc_array_index_type, size,
- gfc_conv_descriptor_lbound (dest, rank));
+ gfc_conv_descriptor_lbound_get (dest, rank));
size = fold_build2 (PLUS_EXPR, gfc_array_index_type, size,
gfc_index_one_node);
if (GFC_TYPE_ARRAY_RANK (type) > 1)
size = fold_build2 (MULT_EXPR, gfc_array_index_type, size,
- gfc_conv_descriptor_stride (dest, rank));
+ gfc_conv_descriptor_stride_get (dest, rank));
esize = fold_convert (gfc_array_index_type,
TYPE_SIZE_UNIT (gfc_get_element_type (type)));
size = fold_build2 (MULT_EXPR, gfc_array_index_type, size, esize);
@@ -243,14 +243,14 @@ gfc_omp_clause_assign_op (tree clause ATTRIBUTE_UNUSED, tree dest, tree src)
gfc_start_block (&block);
rank = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (type) - 1];
- size = gfc_conv_descriptor_ubound (dest, rank);
+ size = gfc_conv_descriptor_ubound_get (dest, rank);
size = fold_build2 (MINUS_EXPR, gfc_array_index_type, size,
- gfc_conv_descriptor_lbound (dest, rank));
+ gfc_conv_descriptor_lbound_get (dest, rank));
size = fold_build2 (PLUS_EXPR, gfc_array_index_type, size,
gfc_index_one_node);
if (GFC_TYPE_ARRAY_RANK (type) > 1)
size = fold_build2 (MULT_EXPR, gfc_array_index_type, size,
- gfc_conv_descriptor_stride (dest, rank));
+ gfc_conv_descriptor_stride_get (dest, rank));
esize = fold_convert (gfc_array_index_type,
TYPE_SIZE_UNIT (gfc_get_element_type (type)));
size = fold_build2 (MULT_EXPR, gfc_array_index_type, size, esize);
@@ -436,7 +436,7 @@ gfc_trans_omp_variable_list (enum omp_clause_code code, gfc_namelist *namelist,
tree t = gfc_trans_omp_variable (namelist->sym);
if (t != error_mark_node)
{
- tree node = build_omp_clause (code);
+ tree node = build_omp_clause (input_location, code);
OMP_CLAUSE_DECL (node) = t;
list = gfc_trans_add_clause (node, list);
}
@@ -606,14 +606,14 @@ gfc_trans_omp_array_reduction (tree c, gfc_symbol *sym, locus where)
gfc_add_modify (&block, decl, outer_sym.backend_decl);
rank = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (type) - 1];
- size = gfc_conv_descriptor_ubound (decl, rank);
+ size = gfc_conv_descriptor_ubound_get (decl, rank);
size = fold_build2 (MINUS_EXPR, gfc_array_index_type, size,
- gfc_conv_descriptor_lbound (decl, rank));
+ gfc_conv_descriptor_lbound_get (decl, rank));
size = fold_build2 (PLUS_EXPR, gfc_array_index_type, size,
gfc_index_one_node);
if (GFC_TYPE_ARRAY_RANK (type) > 1)
size = fold_build2 (MULT_EXPR, gfc_array_index_type, size,
- gfc_conv_descriptor_stride (decl, rank));
+ gfc_conv_descriptor_stride_get (decl, rank));
esize = fold_convert (gfc_array_index_type,
TYPE_SIZE_UNIT (gfc_get_element_type (type)));
size = fold_build2 (MULT_EXPR, gfc_array_index_type, size, esize);
@@ -682,7 +682,8 @@ gfc_trans_omp_reduction_list (gfc_namelist *namelist, tree list,
tree t = gfc_trans_omp_variable (namelist->sym);
if (t != error_mark_node)
{
- tree node = build_omp_clause (OMP_CLAUSE_REDUCTION);
+ tree node = build_omp_clause (where.lb->location,
+ OMP_CLAUSE_REDUCTION);
OMP_CLAUSE_DECL (node) = t;
OMP_CLAUSE_REDUCTION_CODE (node) = reduction_code;
if (namelist->sym->attr.dimension)
@@ -801,7 +802,7 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
if_var = gfc_evaluate_now (se.expr, block);
gfc_add_block_to_block (block, &se.post);
- c = build_omp_clause (OMP_CLAUSE_IF);
+ c = build_omp_clause (where.lb->location, OMP_CLAUSE_IF);
OMP_CLAUSE_IF_EXPR (c) = if_var;
omp_clauses = gfc_trans_add_clause (c, omp_clauses);
}
@@ -816,7 +817,7 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
num_threads = gfc_evaluate_now (se.expr, block);
gfc_add_block_to_block (block, &se.post);
- c = build_omp_clause (OMP_CLAUSE_NUM_THREADS);
+ c = build_omp_clause (where.lb->location, OMP_CLAUSE_NUM_THREADS);
OMP_CLAUSE_NUM_THREADS_EXPR (c) = num_threads;
omp_clauses = gfc_trans_add_clause (c, omp_clauses);
}
@@ -833,7 +834,7 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
if (clauses->sched_kind != OMP_SCHED_NONE)
{
- c = build_omp_clause (OMP_CLAUSE_SCHEDULE);
+ c = build_omp_clause (where.lb->location, OMP_CLAUSE_SCHEDULE);
OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = chunk_size;
switch (clauses->sched_kind)
{
@@ -860,7 +861,7 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
if (clauses->default_sharing != OMP_DEFAULT_UNKNOWN)
{
- c = build_omp_clause (OMP_CLAUSE_DEFAULT);
+ c = build_omp_clause (where.lb->location, OMP_CLAUSE_DEFAULT);
switch (clauses->default_sharing)
{
case OMP_DEFAULT_NONE:
@@ -883,25 +884,25 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
if (clauses->nowait)
{
- c = build_omp_clause (OMP_CLAUSE_NOWAIT);
+ c = build_omp_clause (where.lb->location, OMP_CLAUSE_NOWAIT);
omp_clauses = gfc_trans_add_clause (c, omp_clauses);
}
if (clauses->ordered)
{
- c = build_omp_clause (OMP_CLAUSE_ORDERED);
+ c = build_omp_clause (where.lb->location, OMP_CLAUSE_ORDERED);
omp_clauses = gfc_trans_add_clause (c, omp_clauses);
}
if (clauses->untied)
{
- c = build_omp_clause (OMP_CLAUSE_UNTIED);
+ c = build_omp_clause (where.lb->location, OMP_CLAUSE_UNTIED);
omp_clauses = gfc_trans_add_clause (c, omp_clauses);
}
if (clauses->collapse)
{
- c = build_omp_clause (OMP_CLAUSE_COLLAPSE);
+ c = build_omp_clause (where.lb->location, OMP_CLAUSE_COLLAPSE);
OMP_CLAUSE_COLLAPSE_EXPR (c) = build_int_cst (NULL, clauses->collapse);
omp_clauses = gfc_trans_add_clause (c, omp_clauses);
}
@@ -952,13 +953,13 @@ gfc_trans_omp_atomic (gfc_code *code)
code = code->block->next;
gcc_assert (code->op == EXEC_ASSIGN);
gcc_assert (code->next == NULL);
- var = code->expr->symtree->n.sym;
+ var = code->expr1->symtree->n.sym;
gfc_init_se (&lse, NULL);
gfc_init_se (&rse, NULL);
gfc_start_block (&block);
- gfc_conv_expr (&lse, code->expr);
+ gfc_conv_expr (&lse, code->expr1);
gfc_add_block_to_block (&block, &lse.pre);
type = TREE_TYPE (lse.expr);
lhsaddr = gfc_build_addr_expr (NULL, lse.expr);
@@ -1244,7 +1245,7 @@ gfc_trans_omp_do (gfc_code *code, stmtblock_t *pblock,
if (!dovar_found)
{
- tmp = build_omp_clause (OMP_CLAUSE_PRIVATE);
+ tmp = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
OMP_CLAUSE_DECL (tmp) = dovar;
omp_clauses = gfc_trans_add_clause (tmp, omp_clauses);
}
@@ -1277,7 +1278,8 @@ gfc_trans_omp_do (gfc_code *code, stmtblock_t *pblock,
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
&& OMP_CLAUSE_DECL (c) == dovar)
{
- tree l = build_omp_clause (OMP_CLAUSE_LASTPRIVATE);
+ tree l = build_omp_clause (input_location,
+ OMP_CLAUSE_LASTPRIVATE);
OMP_CLAUSE_DECL (l) = dovar;
OMP_CLAUSE_CHAIN (l) = omp_clauses;
OMP_CLAUSE_LASTPRIVATE_STMT (l) = tmp;
@@ -1290,7 +1292,7 @@ gfc_trans_omp_do (gfc_code *code, stmtblock_t *pblock,
}
if (!simple)
{
- tmp = build_omp_clause (OMP_CLAUSE_PRIVATE);
+ tmp = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
OMP_CLAUSE_DECL (tmp) = count;
omp_clauses = gfc_trans_add_clause (tmp, omp_clauses);
}
@@ -1558,7 +1560,7 @@ gfc_trans_omp_workshare (gfc_code *code, gfc_omp_clauses *clauses)
pushlevel (0);
if (!code)
- return build_empty_stmt ();
+ return build_empty_stmt (input_location);
gfc_start_block (&block);
pblock = &block;
@@ -1681,7 +1683,8 @@ gfc_trans_omp_workshare (gfc_code *code, gfc_omp_clauses *clauses)
tmp = gfc_finish_block (&singleblock);
tmp = build2 (OMP_SINGLE, void_type_node, tmp,
clauses->nowait
- ? build_omp_clause (OMP_CLAUSE_NOWAIT) : NULL_TREE);
+ ? build_omp_clause (input_location, OMP_CLAUSE_NOWAIT)
+ : NULL_TREE);
gfc_add_expr_to_block (pblock, tmp);
}
diff --git a/gcc/fortran/trans-stmt.c b/gcc/fortran/trans-stmt.c
index 9bad071cd37..0e8ce67c443 100644
--- a/gcc/fortran/trans-stmt.c
+++ b/gcc/fortran/trans-stmt.c
@@ -104,21 +104,21 @@ gfc_trans_label_assign (gfc_code * code)
/* Start a new block. */
gfc_init_se (&se, NULL);
gfc_start_block (&se.pre);
- gfc_conv_label_variable (&se, code->expr);
+ gfc_conv_label_variable (&se, code->expr1);
len = GFC_DECL_STRING_LEN (se.expr);
addr = GFC_DECL_ASSIGN_ADDR (se.expr);
- label_tree = gfc_get_label_decl (code->label);
+ label_tree = gfc_get_label_decl (code->label1);
- if (code->label->defined == ST_LABEL_TARGET)
+ if (code->label1->defined == ST_LABEL_TARGET)
{
label_tree = gfc_build_addr_expr (pvoid_type_node, label_tree);
len_tree = integer_minus_one_node;
}
else
{
- gfc_expr *format = code->label->format;
+ gfc_expr *format = code->label1->format;
label_len = format->value.character.length;
len_tree = build_int_cst (NULL_TREE, label_len);
@@ -144,13 +144,13 @@ gfc_trans_goto (gfc_code * code)
tree tmp;
gfc_se se;
- if (code->label != NULL)
- return build1_v (GOTO_EXPR, gfc_get_label_decl (code->label));
+ if (code->label1 != NULL)
+ return build1_v (GOTO_EXPR, gfc_get_label_decl (code->label1));
/* ASSIGNED GOTO. */
gfc_init_se (&se, NULL);
gfc_start_block (&se.pre);
- gfc_conv_label_variable (&se, code->expr);
+ gfc_conv_label_variable (&se, code->expr1);
tmp = GFC_DECL_STRING_LEN (se.expr);
tmp = fold_build2 (NE_EXPR, boolean_type_node, tmp,
build_int_cst (TREE_TYPE (tmp), -1));
@@ -170,12 +170,12 @@ gfc_trans_goto (gfc_code * code)
/* Check the label list. */
do
{
- target = gfc_get_label_decl (code->label);
+ target = gfc_get_label_decl (code->label1);
tmp = gfc_build_addr_expr (pvoid_type_node, target);
tmp = fold_build2 (EQ_EXPR, boolean_type_node, tmp, assigned_goto);
tmp = build3_v (COND_EXPR, tmp,
fold_build1 (GOTO_EXPR, void_type_node, target),
- build_empty_stmt ());
+ build_empty_stmt (input_location));
gfc_add_expr_to_block (&se.pre, tmp);
code = code->block;
}
@@ -309,8 +309,8 @@ gfc_conv_elemental_dependencies (gfc_se * se, gfc_se * loopse,
offset = gfc_index_zero_node;
for (n = 0; n < info->dimen; n++)
{
- tmp = gfc_conv_descriptor_stride (info->descriptor,
- gfc_rank_cst[n]);
+ tmp = gfc_conv_descriptor_stride_get (info->descriptor,
+ gfc_rank_cst[n]);
tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
loopse->loop->from[n], tmp);
offset = fold_build2 (MINUS_EXPR, gfc_array_index_type,
@@ -363,7 +363,7 @@ gfc_trans_call (gfc_code * code, bool dependency_check,
/* Translate the call. */
has_alternate_specifier
= gfc_conv_procedure_call (&se, code->resolved_sym, code->ext.actual,
- code->expr, NULL_TREE);
+ code->expr1, NULL_TREE);
/* A subroutine without side-effect, by definition, does nothing! */
TREE_SIDE_EFFECTS (se.expr) = 1;
@@ -375,7 +375,7 @@ gfc_trans_call (gfc_code * code, bool dependency_check,
gfc_symbol *sym;
select_code = code->next;
gcc_assert(select_code->op == EXEC_SELECT);
- sym = select_code->expr->symtree->n.sym;
+ sym = select_code->expr1->symtree->n.sym;
se.expr = convert (gfc_typenode_for_spec (&sym->ts), se.expr);
if (sym->backend_decl == NULL)
sym->backend_decl = gfc_get_symbol_decl (sym);
@@ -411,7 +411,7 @@ gfc_trans_call (gfc_code * code, bool dependency_check,
subscripts. This could be prevented in the elemental case
as temporaries are handled separatedly
(below in gfc_conv_elemental_dependencies). */
- gfc_conv_loop_setup (&loop, &code->expr->where);
+ gfc_conv_loop_setup (&loop, &code->expr1->where);
gfc_mark_ss_chain_used (ss, 1);
/* Convert the arguments, checking for dependencies. */
@@ -447,13 +447,13 @@ gfc_trans_call (gfc_code * code, bool dependency_check,
/* Add the subroutine call to the block. */
gfc_conv_procedure_call (&loopse, code->resolved_sym,
- code->ext.actual, code->expr,
+ code->ext.actual, code->expr1,
NULL_TREE);
if (mask && count1)
{
tmp = build3_v (COND_EXPR, maskexpr, loopse.expr,
- build_empty_stmt ());
+ build_empty_stmt (input_location));
gfc_add_expr_to_block (&loopse.pre, tmp);
tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
count1, gfc_index_one_node);
@@ -483,7 +483,7 @@ gfc_trans_call (gfc_code * code, bool dependency_check,
tree
gfc_trans_return (gfc_code * code ATTRIBUTE_UNUSED)
{
- if (code->expr)
+ if (code->expr1)
{
gfc_se se;
tree tmp;
@@ -497,7 +497,7 @@ gfc_trans_return (gfc_code * code ATTRIBUTE_UNUSED)
if (!result)
{
gfc_warning ("An alternate return at %L without a * dummy argument",
- &code->expr->where);
+ &code->expr1->where);
return build1_v (GOTO_EXPR, gfc_get_return_label ());
}
@@ -505,7 +505,7 @@ gfc_trans_return (gfc_code * code ATTRIBUTE_UNUSED)
gfc_init_se (&se, NULL);
gfc_start_block (&se.pre);
- gfc_conv_expr (&se, code->expr);
+ gfc_conv_expr (&se, code->expr1);
tmp = fold_build2 (MODIFY_EXPR, TREE_TYPE (result), result,
fold_convert (TREE_TYPE (result), se.expr));
@@ -536,14 +536,14 @@ gfc_trans_pause (gfc_code * code)
gfc_start_block (&se.pre);
- if (code->expr == NULL)
+ if (code->expr1 == NULL)
{
tmp = build_int_cst (gfc_int4_type_node, code->ext.stop_code);
tmp = build_call_expr (gfor_fndecl_pause_numeric, 1, tmp);
}
else
{
- gfc_conv_expr_reference (&se, code->expr);
+ gfc_conv_expr_reference (&se, code->expr1);
tmp = build_call_expr (gfor_fndecl_pause_string, 2,
se.expr, se.string_length);
}
@@ -571,14 +571,14 @@ gfc_trans_stop (gfc_code * code)
gfc_start_block (&se.pre);
- if (code->expr == NULL)
+ if (code->expr1 == NULL)
{
tmp = build_int_cst (gfc_int4_type_node, code->ext.stop_code);
tmp = build_call_expr (gfor_fndecl_stop_numeric, 1, tmp);
}
else
{
- gfc_conv_expr_reference (&se, code->expr);
+ gfc_conv_expr_reference (&se, code->expr1);
tmp = build_call_expr (gfor_fndecl_stop_string, 2,
se.expr, se.string_length);
}
@@ -638,7 +638,7 @@ gfc_trans_if_1 (gfc_code * code)
tree stmt, elsestmt;
/* Check for an unconditional ELSE clause. */
- if (!code->expr)
+ if (!code->expr1)
return gfc_trans_code (code->next);
/* Initialize a statement builder for each block. Puts in NULL_TREEs. */
@@ -646,7 +646,7 @@ gfc_trans_if_1 (gfc_code * code)
gfc_start_block (&if_se.pre);
/* Calculate the IF condition expression. */
- gfc_conv_expr_val (&if_se, code->expr);
+ gfc_conv_expr_val (&if_se, code->expr1);
/* Translate the THEN clause. */
stmt = gfc_trans_code (code->next);
@@ -655,7 +655,7 @@ gfc_trans_if_1 (gfc_code * code)
if (code->block)
elsestmt = gfc_trans_if_1 (code->block);
else
- elsestmt = build_empty_stmt ();
+ elsestmt = build_empty_stmt (input_location);
/* Build the condition expression and add it to the condition block. */
stmt = fold_build3 (COND_EXPR, void_type_node, if_se.expr, stmt, elsestmt);
@@ -713,20 +713,20 @@ gfc_trans_arithmetic_if (gfc_code * code)
gfc_start_block (&se.pre);
/* Pre-evaluate COND. */
- gfc_conv_expr_val (&se, code->expr);
+ gfc_conv_expr_val (&se, code->expr1);
se.expr = gfc_evaluate_now (se.expr, &se.pre);
/* Build something to compare with. */
zero = gfc_build_const (TREE_TYPE (se.expr), integer_zero_node);
- if (code->label->value != code->label2->value)
+ if (code->label1->value != code->label2->value)
{
/* If (cond < 0) take branch1 else take branch2.
First build jumps to the COND .LT. 0 and the COND .EQ. 0 cases. */
- branch1 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label));
+ branch1 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label1));
branch2 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label2));
- if (code->label->value != code->label3->value)
+ if (code->label1->value != code->label3->value)
tmp = fold_build2 (LT_EXPR, boolean_type_node, se.expr, zero);
else
tmp = fold_build2 (NE_EXPR, boolean_type_node, se.expr, zero);
@@ -734,9 +734,9 @@ gfc_trans_arithmetic_if (gfc_code * code)
branch1 = fold_build3 (COND_EXPR, void_type_node, tmp, branch1, branch2);
}
else
- branch1 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label));
+ branch1 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label1));
- if (code->label->value != code->label3->value
+ if (code->label1->value != code->label3->value
&& code->label2->value != code->label3->value)
{
/* if (cond <= 0) take branch1 else take branch2. */
@@ -849,7 +849,7 @@ gfc_trans_simple_do (gfc_code * code, stmtblock_t *pblock, tree dovar,
tmp = build1_v (GOTO_EXPR, exit_label);
TREE_USED (exit_label) = 1;
tmp = fold_build3 (COND_EXPR, void_type_node,
- cond, tmp, build_empty_stmt ());
+ cond, tmp, build_empty_stmt (input_location));
gfc_add_expr_to_block (&body, tmp);
/* Finish the loop body. */
@@ -862,7 +862,7 @@ gfc_trans_simple_do (gfc_code * code, stmtblock_t *pblock, tree dovar,
else
cond = fold_build2 (GE_EXPR, boolean_type_node, dovar, to);
tmp = fold_build3 (COND_EXPR, void_type_node,
- cond, tmp, build_empty_stmt ());
+ cond, tmp, build_empty_stmt (input_location));
gfc_add_expr_to_block (pblock, tmp);
/* Add the exit label. */
@@ -1007,7 +1007,7 @@ gfc_trans_do (gfc_code * code)
tmp = fold_build2 (LT_EXPR, boolean_type_node, to, from);
pos = fold_build3 (COND_EXPR, void_type_node, tmp,
build1_v (GOTO_EXPR, exit_label),
- build_empty_stmt ());
+ build_empty_stmt (input_location));
tmp = fold_build2 (MINUS_EXPR, type, to, from);
tmp = fold_convert (utype, tmp);
tmp = fold_build2 (TRUNC_DIV_EXPR, utype, tmp,
@@ -1018,7 +1018,7 @@ gfc_trans_do (gfc_code * code)
tmp = fold_build2 (GT_EXPR, boolean_type_node, to, from);
neg = fold_build3 (COND_EXPR, void_type_node, tmp,
build1_v (GOTO_EXPR, exit_label),
- build_empty_stmt ());
+ build_empty_stmt (input_location));
tmp = fold_build2 (MINUS_EXPR, type, from, to);
tmp = fold_convert (utype, tmp);
tmp = fold_build2 (TRUNC_DIV_EXPR, utype, tmp,
@@ -1049,7 +1049,7 @@ gfc_trans_do (gfc_code * code)
/* If the loop is empty, go directly to the exit label. */
tmp = fold_build3 (COND_EXPR, void_type_node, tmp,
build1_v (GOTO_EXPR, exit_label),
- build_empty_stmt ());
+ build_empty_stmt (input_location));
gfc_add_expr_to_block (&block, tmp);
}
@@ -1094,7 +1094,7 @@ gfc_trans_do (gfc_code * code)
build_int_cst (utype, 0));
tmp = build1_v (GOTO_EXPR, exit_label);
tmp = fold_build3 (COND_EXPR, void_type_node,
- cond, tmp, build_empty_stmt ());
+ cond, tmp, build_empty_stmt (input_location));
gfc_add_expr_to_block (&body, tmp);
/* Decrement the loop count. */
@@ -1160,7 +1160,7 @@ gfc_trans_do_while (gfc_code * code)
/* Create a GIMPLE version of the exit condition. */
gfc_init_se (&cond, NULL);
- gfc_conv_expr_val (&cond, code->expr);
+ gfc_conv_expr_val (&cond, code->expr1);
gfc_add_block_to_block (&block, &cond.pre);
cond.expr = fold_build1 (TRUTH_NOT_EXPR, boolean_type_node, cond.expr);
@@ -1168,7 +1168,7 @@ gfc_trans_do_while (gfc_code * code)
tmp = build1_v (GOTO_EXPR, exit_label);
TREE_USED (exit_label) = 1;
tmp = fold_build3 (COND_EXPR, void_type_node,
- cond.expr, tmp, build_empty_stmt ());
+ cond.expr, tmp, build_empty_stmt (input_location));
gfc_add_expr_to_block (&block, tmp);
/* The main body of the loop. */
@@ -1258,7 +1258,7 @@ gfc_trans_integer_select (gfc_code * code)
/* Calculate the switch expression. */
gfc_init_se (&se, NULL);
- gfc_conv_expr_val (&se, code->expr);
+ gfc_conv_expr_val (&se, code->expr1);
gfc_add_block_to_block (&block, &se.pre);
end_label = gfc_build_label_decl (NULL_TREE);
@@ -1399,7 +1399,7 @@ gfc_trans_logical_select (gfc_code * code)
/* Calculate the switch expression. We always need to do this
because it may have side effects. */
gfc_init_se (&se, NULL);
- gfc_conv_expr_val (&se, code->expr);
+ gfc_conv_expr_val (&se, code->expr1);
gfc_add_block_to_block (&block, &se.pre);
if (t == f && t != NULL)
@@ -1413,8 +1413,8 @@ gfc_trans_logical_select (gfc_code * code)
{
tree true_tree, false_tree, stmt;
- true_tree = build_empty_stmt ();
- false_tree = build_empty_stmt ();
+ true_tree = build_empty_stmt (input_location);
+ false_tree = build_empty_stmt (input_location);
/* If we have a case for .TRUE. and for .FALSE., discard the default case.
Otherwise, if .TRUE. or .FALSE. is missing and there is a default case,
@@ -1472,11 +1472,11 @@ gfc_trans_character_select (gfc_code *code)
static tree ss_string2[2], ss_string2_len[2];
static tree ss_target[2];
- tree pchartype = gfc_get_pchar_type (code->expr->ts.kind);
+ tree pchartype = gfc_get_pchar_type (code->expr1->ts.kind);
- if (code->expr->ts.kind == 1)
+ if (code->expr1->ts.kind == 1)
k = 0;
- else if (code->expr->ts.kind == 4)
+ else if (code->expr1->ts.kind == 4)
k = 1;
else
gcc_unreachable ();
@@ -1485,9 +1485,9 @@ gfc_trans_character_select (gfc_code *code)
{
select_struct[k] = make_node (RECORD_TYPE);
- if (code->expr->ts.kind == 1)
+ if (code->expr1->ts.kind == 1)
TYPE_NAME (select_struct[k]) = get_identifier ("_jump_struct_char1");
- else if (code->expr->ts.kind == 4)
+ else if (code->expr1->ts.kind == 4)
TYPE_NAME (select_struct[k]) = get_identifier ("_jump_struct_char4");
else
gcc_unreachable ();
@@ -1603,13 +1603,13 @@ gfc_trans_character_select (gfc_code *code)
init = gfc_build_addr_expr (pvoid_type_node, init);
gfc_init_se (&se, NULL);
- gfc_conv_expr_reference (&se, code->expr);
+ gfc_conv_expr_reference (&se, code->expr1);
gfc_add_block_to_block (&block, &se.pre);
- if (code->expr->ts.kind == 1)
+ if (code->expr1->ts.kind == 1)
fndecl = gfor_fndecl_select_string;
- else if (code->expr->ts.kind == 4)
+ else if (code->expr1->ts.kind == 4)
fndecl = gfor_fndecl_select_string_char4;
else
gcc_unreachable ();
@@ -1649,14 +1649,14 @@ gfc_trans_character_select (gfc_code *code)
tree
gfc_trans_select (gfc_code * code)
{
- gcc_assert (code && code->expr);
+ gcc_assert (code && code->expr1);
/* Empty SELECT constructs are legal. */
if (code->block == NULL)
- return build_empty_stmt ();
+ return build_empty_stmt (input_location);
/* Select the correct translation function. */
- switch (code->expr->ts.type)
+ switch (code->expr1->ts.type)
{
case BT_LOGICAL: return gfc_trans_logical_select (code);
case BT_INTEGER: return gfc_trans_integer_select (code);
@@ -1732,7 +1732,7 @@ forall_make_variable_temp (gfc_code *c, stmtblock_t *pre, stmtblock_t *post)
tree tmp;
/* Build a copy of the lvalue. */
- old_symtree = c->expr->symtree;
+ old_symtree = c->expr1->symtree;
old_sym = old_symtree->n.sym;
e = gfc_lval_expr_from_sym (old_sym);
if (old_sym->attr.dimension)
@@ -1746,9 +1746,8 @@ forall_make_variable_temp (gfc_code *c, stmtblock_t *pre, stmtblock_t *post)
if (e->ts.type != BT_CHARACTER)
{
/* Use the variable offset for the temporary. */
- tmp = gfc_conv_descriptor_offset (tse.expr);
- gfc_add_modify (pre, tmp,
- gfc_conv_array_offset (old_sym->backend_decl));
+ tmp = gfc_conv_array_offset (old_sym->backend_decl);
+ gfc_conv_descriptor_offset_set (pre, tse.expr, tmp);
}
}
else
@@ -1797,7 +1796,7 @@ forall_make_variable_temp (gfc_code *c, stmtblock_t *pre, stmtblock_t *post)
/* Go through the expression reference replacing the old_symtree
with the new. */
- forall_replace_symtree (c->expr, old_sym, 2);
+ forall_replace_symtree (c->expr1, old_sym, 2);
/* Now we have made this temporary, we might as well use it for
the right hand side. */
@@ -1814,8 +1813,8 @@ check_forall_dependencies (gfc_code *c, stmtblock_t *pre, stmtblock_t *post)
int need_temp;
gfc_symbol *lsym;
- lsym = c->expr->symtree->n.sym;
- need_temp = gfc_check_dependency (c->expr, c->expr2, 0);
+ lsym = c->expr1->symtree->n.sym;
+ need_temp = gfc_check_dependency (c->expr1, c->expr2, 0);
/* Now check for dependencies within the 'variable'
expression itself. These are treated by making a complete
@@ -1829,7 +1828,7 @@ check_forall_dependencies (gfc_code *c, stmtblock_t *pre, stmtblock_t *post)
return need_temp;
new_symtree = NULL;
- if (find_forall_index (c->expr, lsym, 2) == SUCCESS)
+ if (find_forall_index (c->expr1, lsym, 2) == SUCCESS)
{
forall_make_variable_temp (c, pre, post);
need_temp = 0;
@@ -1837,12 +1836,12 @@ check_forall_dependencies (gfc_code *c, stmtblock_t *pre, stmtblock_t *post)
/* Substrings with dependencies are treated in the same
way. */
- if (c->expr->ts.type == BT_CHARACTER
- && c->expr->ref
+ if (c->expr1->ts.type == BT_CHARACTER
+ && c->expr1->ref
&& c->expr2->expr_type == EXPR_VARIABLE
&& lsym == c->expr2->symtree->n.sym)
{
- for (lref = c->expr->ref; lref; lref = lref->next)
+ for (lref = c->expr1->ref; lref; lref = lref->next)
if (lref->type == REF_SUBSTRING)
break;
for (rref = c->expr2->ref; rref; rref = rref->next)
@@ -1863,7 +1862,7 @@ check_forall_dependencies (gfc_code *c, stmtblock_t *pre, stmtblock_t *post)
static void
cleanup_forall_symtrees (gfc_code *c)
{
- forall_restore_symtree (c->expr);
+ forall_restore_symtree (c->expr1);
forall_restore_symtree (c->expr2);
gfc_free (new_symtree->n.sym);
gfc_free (new_symtree);
@@ -1929,7 +1928,7 @@ gfc_trans_forall_loop (forall_info *forall_tmp, tree body,
count, build_int_cst (TREE_TYPE (count), 0));
tmp = build1_v (GOTO_EXPR, exit_label);
tmp = fold_build3 (COND_EXPR, void_type_node,
- cond, tmp, build_empty_stmt ());
+ cond, tmp, build_empty_stmt (input_location));
gfc_add_expr_to_block (&block, tmp);
/* The main loop body. */
@@ -2011,7 +2010,8 @@ gfc_trans_nested_forall_loop (forall_info * nested_forall_info, tree body,
if (mask)
{
tmp = gfc_build_array_ref (mask, maskindex, NULL);
- body = build3_v (COND_EXPR, tmp, body, build_empty_stmt ());
+ body = build3_v (COND_EXPR, tmp, body,
+ build_empty_stmt (input_location));
}
}
body = gfc_trans_forall_loop (forall_tmp, body, mask_flag, &header);
@@ -2147,7 +2147,8 @@ generate_loop_for_temp_to_lhs (gfc_expr *expr, tree tmp1, tree count3,
TREE_TYPE (wheremaskexpr),
wheremaskexpr);
tmp = fold_build3 (COND_EXPR, void_type_node,
- wheremaskexpr, tmp, build_empty_stmt ());
+ wheremaskexpr, tmp,
+ build_empty_stmt (input_location));
}
gfc_add_expr_to_block (&body, tmp);
@@ -2244,7 +2245,7 @@ generate_loop_for_rhs_to_temp (gfc_expr *expr2, tree tmp1, tree count3,
TREE_TYPE (wheremaskexpr),
wheremaskexpr);
tmp = fold_build3 (COND_EXPR, void_type_node,
- wheremaskexpr, tmp, build_empty_stmt ());
+ wheremaskexpr, tmp, build_empty_stmt (input_location));
}
gfc_add_expr_to_block (&body1, tmp);
@@ -2813,10 +2814,10 @@ gfc_trans_forall_1 (gfc_code * code, forall_info * nested_forall_info)
bool need_mask;
/* Do nothing if the mask is false. */
- if (code->expr
- && code->expr->expr_type == EXPR_CONSTANT
- && !code->expr->value.logical)
- return build_empty_stmt ();
+ if (code->expr1
+ && code->expr1->expr_type == EXPR_CONSTANT
+ && !code->expr1->value.logical)
+ return build_empty_stmt (input_location);
n = 0;
/* Count the FORALL index number. */
@@ -2918,11 +2919,11 @@ gfc_trans_forall_1 (gfc_code * code, forall_info * nested_forall_info)
info->nvar = nvar;
info->size = size;
- if (code->expr)
+ if (code->expr1)
{
/* If the mask is .true., consider the FORALL unconditional. */
- if (code->expr->expr_type == EXPR_CONSTANT
- && code->expr->value.logical)
+ if (code->expr1->expr_type == EXPR_CONSTANT
+ && code->expr1->value.logical)
need_mask = false;
else
need_mask = true;
@@ -2968,7 +2969,7 @@ gfc_trans_forall_1 (gfc_code * code, forall_info * nested_forall_info)
/* Evaluate the mask expression. */
gfc_init_se (&se, NULL);
- gfc_conv_expr_val (&se, code->expr);
+ gfc_conv_expr_val (&se, code->expr1);
gfc_add_block_to_block (&body, &se.pre);
/* Store the mask. */
@@ -3005,12 +3006,12 @@ gfc_trans_forall_1 (gfc_code * code, forall_info * nested_forall_info)
/* Temporaries due to array assignment data dependencies introduce
no end of problems. */
if (need_temp)
- gfc_trans_assign_need_temp (c->expr, c->expr2, NULL, false,
+ gfc_trans_assign_need_temp (c->expr1, c->expr2, NULL, false,
nested_forall_info, &block);
else
{
/* Use the normal assignment copying routines. */
- assign = gfc_trans_assignment (c->expr, c->expr2, false);
+ assign = gfc_trans_assignment (c->expr1, c->expr2, false);
/* Generate body and loops. */
tmp = gfc_trans_nested_forall_loop (nested_forall_info,
@@ -3032,14 +3033,14 @@ gfc_trans_forall_1 (gfc_code * code, forall_info * nested_forall_info)
/* Pointer assignment inside FORALL. */
case EXEC_POINTER_ASSIGN:
- need_temp = gfc_check_dependency (c->expr, c->expr2, 0);
+ need_temp = gfc_check_dependency (c->expr1, c->expr2, 0);
if (need_temp)
- gfc_trans_pointer_assign_need_temp (c->expr, c->expr2,
+ gfc_trans_pointer_assign_need_temp (c->expr1, c->expr2,
nested_forall_info, &block);
else
{
/* Use the normal assignment copying routines. */
- assign = gfc_trans_pointer_assignment (c->expr, c->expr2);
+ assign = gfc_trans_pointer_assignment (c->expr1, c->expr2);
/* Generate body and loops. */
tmp = gfc_trans_nested_forall_loop (nested_forall_info,
@@ -3373,7 +3374,7 @@ gfc_trans_where_assign (gfc_expr *expr1, gfc_expr *expr2,
tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
loop.temp_ss != NULL, false);
- tmp = build3_v (COND_EXPR, maskexpr, tmp, build_empty_stmt ());
+ tmp = build3_v (COND_EXPR, maskexpr, tmp, build_empty_stmt (input_location));
gfc_add_expr_to_block (&body, tmp);
@@ -3426,7 +3427,8 @@ gfc_trans_where_assign (gfc_expr *expr1, gfc_expr *expr2,
/* Use the scalar assignment as is. */
tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts, false, false);
- tmp = build3_v (COND_EXPR, maskexpr, tmp, build_empty_stmt ());
+ tmp = build3_v (COND_EXPR, maskexpr, tmp,
+ build_empty_stmt (input_location));
gfc_add_expr_to_block (&body, tmp);
/* Increment count2. */
@@ -3519,7 +3521,7 @@ gfc_trans_where_2 (gfc_code * code, tree mask, bool invert,
/* Two clauses, the first empty, the second non-empty. */
else if (mask)
{
- need_cmask = (cblock->block->expr != 0);
+ need_cmask = (cblock->block->expr1 != 0);
need_pmask = true;
}
else
@@ -3532,7 +3534,7 @@ gfc_trans_where_2 (gfc_code * code, tree mask, bool invert,
{
/* Calculate the size of temporary needed by the mask-expr. */
gfc_init_block (&inner_size_body);
- inner_size = compute_inner_temp_size (cblock->expr, cblock->expr,
+ inner_size = compute_inner_temp_size (cblock->expr1, cblock->expr1,
&inner_size_body, &lss, &rss);
/* Calculate the total size of temporary needed. */
@@ -3564,7 +3566,7 @@ gfc_trans_where_2 (gfc_code * code, tree mask, bool invert,
bottom of the loop. */
/* Has mask-expr. */
- if (cblock->expr)
+ if (cblock->expr1)
{
/* Ensure that the WHERE mask will be evaluated exactly once.
If there are no statements in this WHERE/ELSEWHERE clause,
@@ -3572,13 +3574,13 @@ gfc_trans_where_2 (gfc_code * code, tree mask, bool invert,
If this is the last clause of the WHERE construct, then
we don't need to update the pending control mask (pmask). */
if (mask)
- gfc_evaluate_where_mask (cblock->expr, nested_forall_info,
+ gfc_evaluate_where_mask (cblock->expr1, nested_forall_info,
mask, invert,
cblock->next ? cmask : NULL_TREE,
cblock->block ? pmask : NULL_TREE,
mask_type, block);
else
- gfc_evaluate_where_mask (cblock->expr, nested_forall_info,
+ gfc_evaluate_where_mask (cblock->expr1, nested_forall_info,
NULL_TREE, false,
(cblock->next || cblock->block)
? cmask : NULL_TREE,
@@ -3617,7 +3619,7 @@ gfc_trans_where_2 (gfc_code * code, tree mask, bool invert,
goto evaluate;
case EXEC_ASSIGN:
- expr1 = cnext->expr;
+ expr1 = cnext->expr1;
expr2 = cnext->expr2;
evaluate:
if (nested_forall_info != NULL)
@@ -3729,10 +3731,10 @@ gfc_trans_where_3 (gfc_code * cblock, gfc_code * eblock)
if (ompws_flags & OMPWS_WORKSHARE_FLAG)
ompws_flags |= OMPWS_SCALARIZER_WS;
- cond = cblock->expr;
- tdst = cblock->next->expr;
+ cond = cblock->expr1;
+ tdst = cblock->next->expr1;
tsrc = cblock->next->expr2;
- edst = eblock ? eblock->next->expr : NULL;
+ edst = eblock ? eblock->next->expr1 : NULL;
esrc = eblock ? eblock->next->expr2 : NULL;
gfc_start_block (&block);
@@ -3833,7 +3835,7 @@ gfc_trans_where_3 (gfc_code * cblock, gfc_code * eblock)
tstmt = gfc_trans_scalar_assign (&tdse, &tsse, tdst->ts, false, false);
estmt = eblock ? gfc_trans_scalar_assign (&edse, &esse, edst->ts, false, false)
- : build_empty_stmt ();
+ : build_empty_stmt (input_location);
tmp = build3_v (COND_EXPR, cexpr, tstmt, estmt);
gfc_add_expr_to_block (&body, tmp);
gfc_add_block_to_block (&body, &cse.post);
@@ -3868,13 +3870,13 @@ gfc_trans_where (gfc_code * code)
/* A simple "WHERE (cond) x = y" statement or block is
dependence free if cond is not dependent upon writing x,
and the source y is unaffected by the destination x. */
- if (!gfc_check_dependency (cblock->next->expr,
- cblock->expr, 0)
- && !gfc_check_dependency (cblock->next->expr,
+ if (!gfc_check_dependency (cblock->next->expr1,
+ cblock->expr1, 0)
+ && !gfc_check_dependency (cblock->next->expr1,
cblock->next->expr2, 0))
return gfc_trans_where_3 (cblock, NULL);
}
- else if (!eblock->expr
+ else if (!eblock->expr1
&& !eblock->block
&& eblock->next
&& eblock->next->op == EXEC_ASSIGN
@@ -3890,22 +3892,22 @@ gfc_trans_where (gfc_code * code)
are the same. In short, this is VERY conservative and this
is needed because the two loops, required by the standard
are coalesced in gfc_trans_where_3. */
- if (!gfc_check_dependency(cblock->next->expr,
- cblock->expr, 0)
- && !gfc_check_dependency(eblock->next->expr,
- cblock->expr, 0)
- && !gfc_check_dependency(cblock->next->expr,
+ if (!gfc_check_dependency(cblock->next->expr1,
+ cblock->expr1, 0)
+ && !gfc_check_dependency(eblock->next->expr1,
+ cblock->expr1, 0)
+ && !gfc_check_dependency(cblock->next->expr1,
eblock->next->expr2, 1)
- && !gfc_check_dependency(eblock->next->expr,
+ && !gfc_check_dependency(eblock->next->expr1,
cblock->next->expr2, 1)
- && !gfc_check_dependency(cblock->next->expr,
+ && !gfc_check_dependency(cblock->next->expr1,
cblock->next->expr2, 1)
- && !gfc_check_dependency(eblock->next->expr,
+ && !gfc_check_dependency(eblock->next->expr1,
eblock->next->expr2, 1)
- && !gfc_check_dependency(cblock->next->expr,
- eblock->next->expr, 0)
- && !gfc_check_dependency(eblock->next->expr,
- cblock->next->expr, 0))
+ && !gfc_check_dependency(cblock->next->expr1,
+ eblock->next->expr1, 0)
+ && !gfc_check_dependency(eblock->next->expr1,
+ cblock->next->expr1, 0))
return gfc_trans_where_3 (cblock, eblock);
}
}
@@ -3971,7 +3973,7 @@ gfc_trans_allocate (gfc_code * code)
gfc_start_block (&block);
/* Either STAT= and/or ERRMSG is present. */
- if (code->expr || code->expr2)
+ if (code->expr1 || code->expr2)
{
tree gfc_int4_type_node = gfc_get_int_type (4);
@@ -4006,13 +4008,13 @@ gfc_trans_allocate (gfc_code * code)
fold_convert (TREE_TYPE (se.expr), tmp));
gfc_add_expr_to_block (&se.pre, tmp);
- if (code->expr || code->expr2)
+ if (code->expr1 || code->expr2)
{
tmp = build1_v (GOTO_EXPR, error_label);
parm = fold_build2 (NE_EXPR, boolean_type_node,
stat, build_int_cst (TREE_TYPE (stat), 0));
tmp = fold_build3 (COND_EXPR, void_type_node,
- parm, tmp, build_empty_stmt ());
+ parm, tmp, build_empty_stmt (input_location));
gfc_add_expr_to_block (&se.pre, tmp);
}
@@ -4030,13 +4032,13 @@ gfc_trans_allocate (gfc_code * code)
}
/* STAT block. */
- if (code->expr)
+ if (code->expr1)
{
tmp = build1_v (LABEL_EXPR, error_label);
gfc_add_expr_to_block (&block, tmp);
gfc_init_se (&se, NULL);
- gfc_conv_expr_lhs (&se, code->expr);
+ gfc_conv_expr_lhs (&se, code->expr1);
tmp = convert (TREE_TYPE (se.expr), stat);
gfc_add_modify (&block, se.expr, tmp);
}
@@ -4067,7 +4069,7 @@ gfc_trans_allocate (gfc_code * code)
tmp = fold_build2 (NE_EXPR, boolean_type_node, stat,
build_int_cst (TREE_TYPE (stat), 0));
- tmp = build3_v (COND_EXPR, tmp, dlen, build_empty_stmt ());
+ tmp = build3_v (COND_EXPR, tmp, dlen, build_empty_stmt (input_location));
gfc_add_expr_to_block (&block, tmp);
}
@@ -4094,7 +4096,7 @@ gfc_trans_deallocate (gfc_code *code)
/* Count the number of failed deallocations. If deallocate() was
called with STAT= , then set STAT to the count. If deallocate
was called with ERRMSG, then set ERRMG to a string. */
- if (code->expr || code->expr2)
+ if (code->expr1 || code->expr2)
{
tree gfc_int4_type_node = gfc_get_int_type (4);
@@ -4155,7 +4157,7 @@ gfc_trans_deallocate (gfc_code *code)
/* Keep track of the number of failed deallocations by adding stat
of the last deallocation to the running total. */
- if (code->expr || code->expr2)
+ if (code->expr1 || code->expr2)
{
apstat = fold_build2 (PLUS_EXPR, TREE_TYPE (stat), astat, stat);
gfc_add_modify (&se.pre, astat, apstat);
@@ -4167,10 +4169,10 @@ gfc_trans_deallocate (gfc_code *code)
}
/* Set STAT. */
- if (code->expr)
+ if (code->expr1)
{
gfc_init_se (&se, NULL);
- gfc_conv_expr_lhs (&se, code->expr);
+ gfc_conv_expr_lhs (&se, code->expr1);
tmp = convert (TREE_TYPE (se.expr), astat);
gfc_add_modify (&block, se.expr, tmp);
}
@@ -4201,7 +4203,7 @@ gfc_trans_deallocate (gfc_code *code)
tmp = fold_build2 (NE_EXPR, boolean_type_node, astat,
build_int_cst (TREE_TYPE (astat), 0));
- tmp = build3_v (COND_EXPR, tmp, dlen, build_empty_stmt ());
+ tmp = build3_v (COND_EXPR, tmp, dlen, build_empty_stmt (input_location));
gfc_add_expr_to_block (&block, tmp);
}
diff --git a/gcc/fortran/trans-types.c b/gcc/fortran/trans-types.c
index 5f089009be0..1785908f811 100644
--- a/gcc/fortran/trans-types.c
+++ b/gcc/fortran/trans-types.c
@@ -163,6 +163,96 @@ get_int_kind_from_node (tree type)
return -1;
}
+/* Return a typenode for the "standard" C type with a given name. */
+static tree
+get_typenode_from_name (const char *name)
+{
+ if (name == NULL || *name == '\0')
+ return NULL_TREE;
+
+ if (strcmp (name, "char") == 0)
+ return char_type_node;
+ if (strcmp (name, "unsigned char") == 0)
+ return unsigned_char_type_node;
+ if (strcmp (name, "signed char") == 0)
+ return signed_char_type_node;
+
+ if (strcmp (name, "short int") == 0)
+ return short_integer_type_node;
+ if (strcmp (name, "short unsigned int") == 0)
+ return short_unsigned_type_node;
+
+ if (strcmp (name, "int") == 0)
+ return integer_type_node;
+ if (strcmp (name, "unsigned int") == 0)
+ return unsigned_type_node;
+
+ if (strcmp (name, "long int") == 0)
+ return long_integer_type_node;
+ if (strcmp (name, "long unsigned int") == 0)
+ return long_unsigned_type_node;
+
+ if (strcmp (name, "long long int") == 0)
+ return long_long_integer_type_node;
+ if (strcmp (name, "long long unsigned int") == 0)
+ return long_long_unsigned_type_node;
+
+ gcc_unreachable ();
+}
+
+static int
+get_int_kind_from_name (const char *name)
+{
+ return get_int_kind_from_node (get_typenode_from_name (name));
+}
+
+
+/* Get the kind number corresponding to an integer of given size,
+ following the required return values for ISO_FORTRAN_ENV INT* constants:
+ -2 is returned if we support a kind of larger size, -1 otherwise. */
+int
+gfc_get_int_kind_from_width_isofortranenv (int size)
+{
+ int i;
+
+ /* Look for a kind with matching storage size. */
+ for (i = 0; gfc_integer_kinds[i].kind != 0; i++)
+ if (gfc_integer_kinds[i].bit_size == size)
+ return gfc_integer_kinds[i].kind;
+
+ /* Look for a kind with larger storage size. */
+ for (i = 0; gfc_integer_kinds[i].kind != 0; i++)
+ if (gfc_integer_kinds[i].bit_size > size)
+ return -2;
+
+ return -1;
+}
+
+/* Get the kind number corresponding to a real of given storage size,
+ following the required return values for ISO_FORTRAN_ENV REAL* constants:
+ -2 is returned if we support a kind of larger size, -1 otherwise. */
+int
+gfc_get_real_kind_from_width_isofortranenv (int size)
+{
+ int i;
+
+ size /= 8;
+
+ /* Look for a kind with matching storage size. */
+ for (i = 0; gfc_real_kinds[i].kind != 0; i++)
+ if (int_size_in_bytes (gfc_get_real_type (gfc_real_kinds[i].kind)) == size)
+ return gfc_real_kinds[i].kind;
+
+ /* Look for a kind with larger storage size. */
+ for (i = 0; gfc_real_kinds[i].kind != 0; i++)
+ if (int_size_in_bytes (gfc_get_real_type (gfc_real_kinds[i].kind)) > size)
+ return -2;
+
+ return -1;
+}
+
+
+
static int
get_int_kind_from_width (int size)
{
@@ -195,11 +285,6 @@ static
void init_c_interop_kinds (void)
{
int i;
- tree intmax_type_node = INT_TYPE_SIZE == LONG_LONG_TYPE_SIZE ?
- integer_type_node :
- (LONG_TYPE_SIZE == LONG_LONG_TYPE_SIZE ?
- long_integer_type_node :
- long_long_integer_type_node);
/* init all pointers in the list to NULL */
for (i = 0; i < ISOCBINDING_NUMBER; i++)
@@ -252,7 +337,7 @@ void init_c_interop_kinds (void)
void
gfc_init_kinds (void)
{
- enum machine_mode mode;
+ unsigned int mode;
int i_index, r_index, kind;
bool saw_i4 = false, saw_i8 = false;
bool saw_r4 = false, saw_r8 = false, saw_r16 = false;
@@ -261,7 +346,7 @@ gfc_init_kinds (void)
{
int kind, bitsize;
- if (!targetm.scalar_mode_supported_p (mode))
+ if (!targetm.scalar_mode_supported_p ((enum machine_mode) mode))
continue;
/* The middle end doesn't support constants larger than 2*HWI.
@@ -309,12 +394,13 @@ gfc_init_kinds (void)
for (r_index = 0, mode = MIN_MODE_FLOAT; mode <= MAX_MODE_FLOAT; mode++)
{
- const struct real_format *fmt = REAL_MODE_FORMAT (mode);
+ const struct real_format *fmt =
+ REAL_MODE_FORMAT ((enum machine_mode) mode);
int kind;
if (fmt == NULL)
continue;
- if (!targetm.scalar_mode_supported_p (mode))
+ if (!targetm.scalar_mode_supported_p ((enum machine_mode) mode))
continue;
/* Only let float/double/long double go through because the fortran
@@ -595,7 +681,7 @@ gfc_build_int_type (gfc_integer_info *info)
return make_signed_type (mode_precision);
}
-static tree
+tree
gfc_build_uint_type (int size)
{
if (size == CHAR_TYPE_SIZE)
@@ -679,6 +765,7 @@ gfc_build_logical_type (gfc_logical_info *info)
return new_type;
}
+
#if 0
/* Return the bit size of the C "size_t". */
@@ -716,7 +803,8 @@ gfc_init_types (void)
/* Create and name the types. */
#define PUSH_TYPE(name, node) \
- pushdecl (build_decl (TYPE_DECL, get_identifier (name), node))
+ pushdecl (build_decl (input_location, \
+ TYPE_DECL, get_identifier (name), node))
for (index = 0; gfc_integer_kinds[index].kind != 0; ++index)
{
@@ -1154,19 +1242,22 @@ gfc_get_desc_dim_type (void)
TYPE_PACKED (type) = 1;
/* Consists of the stride, lbound and ubound members. */
- decl = build_decl (FIELD_DECL,
+ decl = build_decl (input_location,
+ FIELD_DECL,
get_identifier ("stride"), gfc_array_index_type);
DECL_CONTEXT (decl) = type;
TREE_NO_WARNING (decl) = 1;
fieldlist = decl;
- decl = build_decl (FIELD_DECL,
+ decl = build_decl (input_location,
+ FIELD_DECL,
get_identifier ("lbound"), gfc_array_index_type);
DECL_CONTEXT (decl) = type;
TREE_NO_WARNING (decl) = 1;
fieldlist = chainon (fieldlist, decl);
- decl = build_decl (FIELD_DECL,
+ decl = build_decl (input_location,
+ FIELD_DECL,
get_identifier ("ubound"), gfc_array_index_type);
DECL_CONTEXT (decl) = type;
TREE_NO_WARNING (decl) = 1;
@@ -1418,7 +1509,8 @@ gfc_get_nodesc_array_type (tree etype, gfc_array_spec * as, gfc_packed packed)
GFC_TYPE_ARRAY_UBOUND (type, n));
gtype = build_array_type (gtype, rtype);
}
- TYPE_NAME (type) = type_decl = build_decl (TYPE_DECL, NULL, gtype);
+ TYPE_NAME (type) = type_decl = build_decl (input_location,
+ TYPE_DECL, NULL, gtype);
DECL_ORIGINAL_TYPE (type_decl) = gtype;
}
@@ -1452,20 +1544,23 @@ gfc_get_array_descriptor_base (int dimen)
TYPE_NAME (fat_type) = get_identifier (name);
/* Add the data member as the first element of the descriptor. */
- decl = build_decl (FIELD_DECL, get_identifier ("data"), ptr_type_node);
+ decl = build_decl (input_location,
+ FIELD_DECL, get_identifier ("data"), ptr_type_node);
DECL_CONTEXT (decl) = fat_type;
fieldlist = decl;
/* Add the base component. */
- decl = build_decl (FIELD_DECL, get_identifier ("offset"),
+ decl = build_decl (input_location,
+ FIELD_DECL, get_identifier ("offset"),
gfc_array_index_type);
DECL_CONTEXT (decl) = fat_type;
TREE_NO_WARNING (decl) = 1;
fieldlist = chainon (fieldlist, decl);
/* Add the dtype component. */
- decl = build_decl (FIELD_DECL, get_identifier ("dtype"),
+ decl = build_decl (input_location,
+ FIELD_DECL, get_identifier ("dtype"),
gfc_array_index_type);
DECL_CONTEXT (decl) = fat_type;
TREE_NO_WARNING (decl) = 1;
@@ -1478,7 +1573,8 @@ gfc_get_array_descriptor_base (int dimen)
gfc_index_zero_node,
gfc_rank_cst[dimen - 1]));
- decl = build_decl (FIELD_DECL, get_identifier ("dim"), arraytype);
+ decl = build_decl (input_location,
+ FIELD_DECL, get_identifier ("dim"), arraytype);
DECL_CONTEXT (decl) = fat_type;
TREE_NO_WARNING (decl) = 1;
fieldlist = chainon (fieldlist, decl);
@@ -1716,7 +1812,8 @@ gfc_finish_type (tree type)
{
tree decl;
- decl = build_decl (TYPE_DECL, NULL_TREE, type);
+ decl = build_decl (input_location,
+ TYPE_DECL, NULL_TREE, type);
TYPE_STUB_DECL (type) = decl;
layout_type (type);
rest_of_type_compilation (type, 1);
@@ -1735,7 +1832,8 @@ gfc_add_field_to_struct (tree *fieldlist, tree context,
{
tree decl;
- decl = build_decl (FIELD_DECL, name, type);
+ decl = build_decl (input_location,
+ FIELD_DECL, name, type);
DECL_CONTEXT (decl) = context;
DECL_INITIAL (decl) = 0;
@@ -1793,7 +1891,7 @@ tree
gfc_get_ppc_type (gfc_component* c)
{
tree t;
- if (c->attr.function)
+ if (c->attr.function && !c->attr.dimension)
t = gfc_typenode_for_spec (&c->ts);
else
t = void_type_node;
@@ -1915,7 +2013,7 @@ gfc_get_derived_type (gfc_symbol * derived)
/* This returns an array descriptor type. Initialization may be
required. */
- if (c->attr.dimension)
+ if (c->attr.dimension && !c->attr.proc_pointer)
{
if (c->attr.pointer || c->attr.allocatable)
{
@@ -2037,7 +2135,8 @@ gfc_get_mixed_entry_union (gfc_namespace *ns)
if (el == el2)
{
- decl = build_decl (FIELD_DECL,
+ decl = build_decl (input_location,
+ FIELD_DECL,
get_identifier (el->sym->result->name),
gfc_sym_type (el->sym->result));
DECL_CONTEXT (decl) = type;
@@ -2324,7 +2423,7 @@ gfc_get_array_descr_info (const_tree type, struct array_descr_info *info)
base_decl = GFC_TYPE_ARRAY_BASE_DECL (type, indirect);
if (!base_decl)
{
- base_decl = build_decl (VAR_DECL, NULL_TREE,
+ base_decl = build_decl (input_location, VAR_DECL, NULL_TREE,
indirect ? build_pointer_type (ptype) : ptype);
GFC_TYPE_ARRAY_BASE_DECL (type, indirect) = base_decl;
}
diff --git a/gcc/fortran/trans-types.h b/gcc/fortran/trans-types.h
index c3e51a11c8e..283d57772a0 100644
--- a/gcc/fortran/trans-types.h
+++ b/gcc/fortran/trans-types.h
@@ -68,6 +68,7 @@ tree gfc_get_function_type (gfc_symbol *);
tree gfc_type_for_size (unsigned, int);
tree gfc_type_for_mode (enum machine_mode, int);
+tree gfc_build_uint_type (int);
tree gfc_get_element_type (tree);
tree gfc_get_array_type_bounds (tree, int, tree *, tree *, int,
diff --git a/gcc/fortran/trans.c b/gcc/fortran/trans.c
index 28cb60ab2ef..319ae69edcc 100644
--- a/gcc/fortran/trans.c
+++ b/gcc/fortran/trans.c
@@ -238,7 +238,7 @@ gfc_finish_block (stmtblock_t * stmtblock)
expr = stmtblock->head;
if (!expr)
- expr = build_empty_stmt ();
+ expr = build_empty_stmt (input_location);
stmtblock->head = NULL_TREE;
@@ -485,7 +485,7 @@ gfc_trans_runtime_check (bool error, bool once, tree cond, stmtblock_t * pblock,
cond = build_call_expr (built_in_decls[BUILT_IN_EXPECT], 2, cond, tmp);
cond = fold_convert (boolean_type_node, cond);
- tmp = build3_v (COND_EXPR, cond, body, build_empty_stmt ());
+ tmp = build3_v (COND_EXPR, cond, body, build_empty_stmt (input_location));
gfc_add_expr_to_block (pblock, tmp);
}
}
@@ -516,7 +516,7 @@ gfc_call_malloc (stmtblock_t * block, tree type, tree size)
("Attempt to allocate a negative amount of memory."));
tmp = fold_build3 (COND_EXPR, void_type_node, negative,
build_call_expr (gfor_fndecl_runtime_error, 1, msg),
- build_empty_stmt ());
+ build_empty_stmt (input_location));
gfc_add_expr_to_block (block, tmp);
/* Call malloc and check the result. */
@@ -534,7 +534,7 @@ gfc_call_malloc (stmtblock_t * block, tree type, tree size)
("Memory allocation failed"));
tmp = fold_build3 (COND_EXPR, void_type_node, null_result,
build_call_expr (gfor_fndecl_os_error, 1, msg),
- build_empty_stmt ());
+ build_empty_stmt (input_location));
gfc_add_expr_to_block (&block2, tmp);
malloc_result = gfc_finish_block (&block2);
@@ -607,7 +607,7 @@ gfc_allocate_with_status (stmtblock_t * block, tree size, tree status)
tmp = fold_build3 (COND_EXPR, void_type_node,
fold_build2 (NE_EXPR, boolean_type_node, status,
build_int_cst (TREE_TYPE (status), 0)),
- tmp, build_empty_stmt ());
+ tmp, build_empty_stmt (input_location));
gfc_add_expr_to_block (block, tmp);
}
@@ -664,7 +664,7 @@ gfc_allocate_with_status (stmtblock_t * block, tree size, tree status)
tmp = fold_build3 (COND_EXPR, void_type_node,
fold_build2 (EQ_EXPR, boolean_type_node, res,
build_int_cst (pvoid_type_node, 0)),
- tmp, build_empty_stmt ());
+ tmp, build_empty_stmt (input_location));
gfc_add_expr_to_block (&alloc_block, tmp);
cond = fold_build2 (LT_EXPR, boolean_type_node, size,
@@ -790,7 +790,7 @@ gfc_call_free (tree var)
build_int_cst (pvoid_type_node, 0));
call = build_call_expr (built_in_decls[BUILT_IN_FREE], 1, var);
tmp = fold_build3 (COND_EXPR, void_type_node, cond, call,
- build_empty_stmt ());
+ build_empty_stmt (input_location));
gfc_add_expr_to_block (&block, tmp);
return gfc_finish_block (&block);
@@ -854,7 +854,7 @@ gfc_deallocate_with_status (tree pointer, tree status, bool can_fail,
varname);
}
else
- error = build_empty_stmt ();
+ error = build_empty_stmt (input_location);
if (status != NULL_TREE && !integer_zerop (status))
{
@@ -889,7 +889,7 @@ gfc_deallocate_with_status (tree pointer, tree status, bool can_fail,
fold_build1 (INDIRECT_REF, status_type, status),
build_int_cst (status_type, 0));
tmp = fold_build3 (COND_EXPR, void_type_node, cond2, tmp,
- build_empty_stmt ());
+ build_empty_stmt (input_location));
gfc_add_expr_to_block (&non_null, tmp);
}
@@ -936,7 +936,7 @@ gfc_call_realloc (stmtblock_t * block, tree mem, tree size)
("Attempt to allocate a negative amount of memory."));
tmp = fold_build3 (COND_EXPR, void_type_node, negative,
build_call_expr (gfor_fndecl_runtime_error, 1, msg),
- build_empty_stmt ());
+ build_empty_stmt (input_location));
gfc_add_expr_to_block (block, tmp);
/* Call realloc and check the result. */
@@ -953,14 +953,14 @@ gfc_call_realloc (stmtblock_t * block, tree mem, tree size)
("Out of memory"));
tmp = fold_build3 (COND_EXPR, void_type_node, null_result,
build_call_expr (gfor_fndecl_os_error, 1, msg),
- build_empty_stmt ());
+ build_empty_stmt (input_location));
gfc_add_expr_to_block (block, tmp);
/* if (size == 0) then the result is NULL. */
tmp = fold_build2 (MODIFY_EXPR, type, res, build_int_cst (type, 0));
zero = fold_build1 (TRUTH_NOT_EXPR, boolean_type_node, nonzero);
tmp = fold_build3 (COND_EXPR, void_type_node, zero, tmp,
- build_empty_stmt ());
+ build_empty_stmt (input_location));
gfc_add_expr_to_block (block, tmp);
return res;
@@ -1038,7 +1038,7 @@ gfc_trans_code (gfc_code * code)
tree res;
if (!code)
- return build_empty_stmt ();
+ return build_empty_stmt (input_location);
gfc_start_block (&block);
@@ -1056,6 +1056,7 @@ gfc_trans_code (gfc_code * code)
{
case EXEC_NOP:
case EXEC_END_BLOCK:
+ case EXEC_END_PROCEDURE:
res = NULL_TREE;
break;
@@ -1288,10 +1289,9 @@ gfc_generate_module_code (gfc_namespace * ns)
gcc_assert (ns->proc_name->backend_decl == NULL);
ns->proc_name->backend_decl
- = build_decl (NAMESPACE_DECL, get_identifier (ns->proc_name->name),
+ = build_decl (ns->proc_name->declared_at.lb->location,
+ NAMESPACE_DECL, get_identifier (ns->proc_name->name),
void_type_node);
- gfc_set_decl_location (ns->proc_name->backend_decl,
- &ns->proc_name->declared_at);
entry = gfc_find_module (ns->proc_name->name);
if (entry->namespace_decl)
/* Buggy sourcecode, using a module before defining it? */
diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h
index 41e6f2774b8..5152b95f5e8 100644
--- a/gcc/fortran/trans.h
+++ b/gcc/fortran/trans.h
@@ -590,6 +590,8 @@ extern GTY(()) tree gfor_fndecl_convert_char4_to_char1;
extern GTY(()) tree gfor_fndecl_size0;
extern GTY(()) tree gfor_fndecl_size1;
extern GTY(()) tree gfor_fndecl_iargc;
+extern GTY(()) tree gfor_fndecl_clz128;
+extern GTY(()) tree gfor_fndecl_ctz128;
/* Implemented in Fortran. */
extern GTY(()) tree gfor_fndecl_sc_kind;
diff --git a/gcc/function.c b/gcc/function.c
index f4f69c18051..3ec5ea8ae7b 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -124,13 +124,11 @@ struct machine_function * (*init_machine_status) (void);
/* The currently compiled function. */
struct function *cfun = 0;
-/* These arrays record the INSN_UIDs of the prologue and epilogue insns. */
-static VEC(int,heap) *prologue;
-static VEC(int,heap) *epilogue;
-
-/* Array of INSN_UIDs to hold the INSN_UIDs for each sibcall epilogue
- in this function. */
-static VEC(int,heap) *sibcall_epilogue;
+/* These hashes record the prologue and epilogue insns. */
+static GTY((if_marked ("ggc_marked_p"), param_is (struct rtx_def)))
+ htab_t prologue_insn_hash;
+static GTY((if_marked ("ggc_marked_p"), param_is (struct rtx_def)))
+ htab_t epilogue_insn_hash;
/* Forward declarations. */
@@ -143,8 +141,8 @@ static tree *get_block_vector (tree, int *);
extern tree debug_find_var_in_block_tree (tree, tree);
/* We always define `record_insns' even if it's not used so that we
can always export `prologue_epilogue_contains'. */
-static void record_insns (rtx, VEC(int,heap) **) ATTRIBUTE_UNUSED;
-static int contains (const_rtx, VEC(int,heap) **);
+static void record_insns (rtx, rtx, htab_t *) ATTRIBUTE_UNUSED;
+static bool contains (const_rtx, htab_t);
#ifdef HAVE_return
static void emit_return_into_block (basic_block);
#endif
@@ -207,9 +205,9 @@ free_after_parsing (struct function *f)
void
free_after_compilation (struct function *f)
{
- VEC_free (int, heap, prologue);
- VEC_free (int, heap, epilogue);
- VEC_free (int, heap, sibcall_epilogue);
+ prologue_insn_hash = NULL;
+ epilogue_insn_hash = NULL;
+
if (crtl->emit.regno_pointer_align)
free (crtl->emit.regno_pointer_align);
@@ -357,8 +355,8 @@ assign_stack_local_1 (enum machine_mode mode, HOST_WIDE_INT size,
if (crtl->stack_alignment_needed < alignment_in_bits)
crtl->stack_alignment_needed = alignment_in_bits;
- if (crtl->max_used_stack_slot_alignment < crtl->stack_alignment_needed)
- crtl->max_used_stack_slot_alignment = crtl->stack_alignment_needed;
+ if (crtl->max_used_stack_slot_alignment < alignment_in_bits)
+ crtl->max_used_stack_slot_alignment = alignment_in_bits;
/* Calculate how many bytes the start of local variables is off from
stack alignment. */
@@ -2105,7 +2103,8 @@ split_complex_args (tree args)
layout_decl (p, 0);
/* Build a second synthetic decl. */
- decl = build_decl (PARM_DECL, NULL_TREE, subtype);
+ decl = build_decl (EXPR_LOCATION (p),
+ PARM_DECL, NULL_TREE, subtype);
DECL_ARG_TYPE (decl) = DECL_ARG_TYPE (p);
DECL_ARTIFICIAL (decl) = addressable;
DECL_IGNORED_P (decl) = addressable;
@@ -2140,7 +2139,8 @@ assign_parms_augmented_arg_list (struct assign_parm_data_all *all)
tree type = build_pointer_type (TREE_TYPE (fntype));
tree decl;
- decl = build_decl (PARM_DECL, NULL_TREE, type);
+ decl = build_decl (DECL_SOURCE_LOCATION (fndecl),
+ PARM_DECL, NULL_TREE, type);
DECL_ARG_TYPE (decl) = type;
DECL_ARTIFICIAL (decl) = 1;
DECL_IGNORED_P (decl) = 1;
@@ -3525,8 +3525,6 @@ locate_and_pad_parm (enum machine_mode passed_mode, tree type, int in_regs,
calling function side. */
if (crtl->stack_alignment_needed < boundary)
crtl->stack_alignment_needed = boundary;
- if (crtl->max_used_stack_slot_alignment < crtl->stack_alignment_needed)
- crtl->max_used_stack_slot_alignment = crtl->stack_alignment_needed;
if (crtl->preferred_stack_boundary < boundary)
crtl->preferred_stack_boundary = boundary;
@@ -4199,18 +4197,11 @@ init_function_start (tree subr)
warning (OPT_Waggregate_return, "function returns an aggregate");
}
-/* Make sure all values used by the optimization passes have sane
- defaults. */
+/* Make sure all values used by the optimization passes have sane defaults. */
unsigned int
init_function_for_compilation (void)
{
reg_renumber = 0;
-
- /* No prologue/epilogue insns yet. Make sure that these vectors are
- empty. */
- gcc_assert (VEC_length (int, prologue) == 0);
- gcc_assert (VEC_length (int, epilogue) == 0);
- gcc_assert (VEC_length (int, sibcall_epilogue) == 0);
return 0;
}
@@ -4876,16 +4867,42 @@ get_arg_pointer_save_area (void)
return ret;
}
-/* Extend a vector that records the INSN_UIDs of INSNS
- (a list of one or more insns). */
+/* Add a list of INSNS to the hash HASHP, possibly allocating HASHP
+ for the first time. */
static void
-record_insns (rtx insns, VEC(int,heap) **vecp)
+record_insns (rtx insns, rtx end, htab_t *hashp)
{
rtx tmp;
+ htab_t hash = *hashp;
+
+ if (hash == NULL)
+ *hashp = hash
+ = htab_create_ggc (17, htab_hash_pointer, htab_eq_pointer, NULL);
+
+ for (tmp = insns; tmp != end; tmp = NEXT_INSN (tmp))
+ {
+ void **slot = htab_find_slot (hash, tmp, INSERT);
+ gcc_assert (*slot == NULL);
+ *slot = tmp;
+ }
+}
+
+/* INSN has been duplicated as COPY, as part of duping a basic block.
+ If INSN is an epilogue insn, then record COPY as epilogue as well. */
- for (tmp = insns; tmp != NULL_RTX; tmp = NEXT_INSN (tmp))
- VEC_safe_push (int, heap, *vecp, INSN_UID (tmp));
+void
+maybe_copy_epilogue_insn (rtx insn, rtx copy)
+{
+ void **slot;
+
+ if (epilogue_insn_hash == NULL
+ || htab_find (epilogue_insn_hash, insn) == NULL)
+ return;
+
+ slot = htab_find_slot (epilogue_insn_hash, copy, INSERT);
+ gcc_assert (*slot == NULL);
+ *slot = copy;
}
/* Set the locator of the insn chain starting at INSN to LOC. */
@@ -4900,52 +4917,37 @@ set_insn_locators (rtx insn, int loc)
}
}
-/* Determine how many INSN_UIDs in VEC are part of INSN. Because we can
- be running after reorg, SEQUENCE rtl is possible. */
+/* Determine if any INSNs in HASH are, or are part of, INSN. Because
+ we can be running after reorg, SEQUENCE rtl is possible. */
-static int
-contains (const_rtx insn, VEC(int,heap) **vec)
+static bool
+contains (const_rtx insn, htab_t hash)
{
- int i, j;
+ if (hash == NULL)
+ return false;
- if (NONJUMP_INSN_P (insn)
- && GET_CODE (PATTERN (insn)) == SEQUENCE)
+ if (NONJUMP_INSN_P (insn) && GET_CODE (PATTERN (insn)) == SEQUENCE)
{
- int count = 0;
+ int i;
for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--)
- for (j = VEC_length (int, *vec) - 1; j >= 0; --j)
- if (INSN_UID (XVECEXP (PATTERN (insn), 0, i))
- == VEC_index (int, *vec, j))
- count++;
- return count;
+ if (htab_find (hash, XVECEXP (PATTERN (insn), 0, i)))
+ return true;
+ return false;
}
- else
- {
- for (j = VEC_length (int, *vec) - 1; j >= 0; --j)
- if (INSN_UID (insn) == VEC_index (int, *vec, j))
- return 1;
- }
- return 0;
+
+ return htab_find (hash, insn) != NULL;
}
int
prologue_epilogue_contains (const_rtx insn)
{
- if (contains (insn, &prologue))
+ if (contains (insn, prologue_insn_hash))
return 1;
- if (contains (insn, &epilogue))
+ if (contains (insn, epilogue_insn_hash))
return 1;
return 0;
}
-int
-sibcall_epilogue_contains (const_rtx insn)
-{
- if (sibcall_epilogue)
- return contains (insn, &sibcall_epilogue);
- return 0;
-}
-
#ifdef HAVE_return
/* Insert gen_return at the end of block BB. This also means updating
block_for_insn appropriately. */
@@ -4988,7 +4990,7 @@ thread_prologue_and_epilogue_insns (void)
emit_use (hard_frame_pointer_rtx);
/* Retain a map of the prologue insns. */
- record_insns (seq, &prologue);
+ record_insns (seq, NULL, &prologue_insn_hash);
emit_note (NOTE_INSN_PROLOGUE_END);
#ifndef PROFILE_BEFORE_PROLOGUE
@@ -5120,6 +5122,38 @@ thread_prologue_and_epilogue_insns (void)
}
}
#endif
+
+ /* A small fib -- epilogue is not yet completed, but we wish to re-use
+ this marker for the splits of EH_RETURN patterns, and nothing else
+ uses the flag in the meantime. */
+ epilogue_completed = 1;
+
+#ifdef HAVE_eh_return
+ /* Find non-fallthru edges that end with EH_RETURN instructions. On
+ some targets, these get split to a special version of the epilogue
+ code. In order to be able to properly annotate these with unwind
+ info, try to split them now. If we get a valid split, drop an
+ EPILOGUE_BEG note and mark the insns as epilogue insns. */
+ FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds)
+ {
+ rtx prev, last, trial;
+
+ if (e->flags & EDGE_FALLTHRU)
+ continue;
+ last = BB_END (e->src);
+ if (!eh_returnjump_p (last))
+ continue;
+
+ prev = PREV_INSN (last);
+ trial = try_split (PATTERN (last), last, 1);
+ if (trial == last)
+ continue;
+
+ record_insns (NEXT_INSN (prev), NEXT_INSN (trial), &epilogue_insn_hash);
+ emit_note_after (NOTE_INSN_EPILOGUE_BEG, prev);
+ }
+#endif
+
/* Find the edge that falls through to EXIT. Other edges may exist
due to RETURN instructions, but those don't need epilogues.
There really shouldn't be a mixture -- either all should have
@@ -5140,7 +5174,7 @@ thread_prologue_and_epilogue_insns (void)
emit_jump_insn (seq);
/* Retain a map of the epilogue insns. */
- record_insns (seq, &epilogue);
+ record_insns (seq, NULL, &epilogue_insn_hash);
set_insn_locators (seq, epilogue_locator);
seq = get_insns ();
@@ -5202,6 +5236,7 @@ epilogue_done:
}
start_sequence ();
+ emit_note (NOTE_INSN_EPILOGUE_BEG);
emit_insn (gen_sibcall_epilogue ());
seq = get_insns ();
end_sequence ();
@@ -5209,7 +5244,7 @@ epilogue_done:
/* Retain a map of the epilogue insns. Used in life analysis to
avoid getting rid of sibcall epilogue insns. Do this before we
actually emit the sequence. */
- record_insns (seq, &sibcall_epilogue);
+ record_insns (seq, NULL, &epilogue_insn_hash);
set_insn_locators (seq, epilogue_locator);
emit_insn_before (seq, insn);
@@ -5243,23 +5278,29 @@ epilogue_done:
df_update_entry_exit_and_calls ();
}
-/* Reposition the prologue-end and epilogue-begin notes after instruction
- scheduling and delayed branch scheduling. */
+/* Reposition the prologue-end and epilogue-begin notes after
+ instruction scheduling. */
void
reposition_prologue_and_epilogue_notes (void)
{
-#if defined (HAVE_prologue) || defined (HAVE_epilogue)
+#if defined (HAVE_prologue) || defined (HAVE_epilogue) \
+ || defined (HAVE_sibcall_epilogue)
rtx insn, last, note;
- int len;
+ basic_block bb;
- if ((len = VEC_length (int, prologue)) > 0)
+ /* Since the hash table is created on demand, the fact that it is
+ non-null is a signal that it is non-empty. */
+ if (prologue_insn_hash != NULL)
{
+ size_t len = htab_elements (prologue_insn_hash);
last = 0, note = 0;
- /* Scan from the beginning until we reach the last prologue insn.
- We apparently can't depend on basic_block_{head,end} after
- reorg has run. */
+ /* Scan from the beginning until we reach the last prologue insn. */
+ /* ??? While we do have the CFG intact, there are two problems:
+ (1) The prologue can contain loops (typically probing the stack),
+ which means that the end of the prologue isn't in the first bb.
+ (2) Sometimes the PROLOGUE_END note gets pushed into the next bb. */
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
{
if (NOTE_P (insn))
@@ -5267,7 +5308,7 @@ reposition_prologue_and_epilogue_notes (void)
if (NOTE_KIND (insn) == NOTE_INSN_PROLOGUE_END)
note = insn;
}
- else if (contains (insn, &prologue))
+ else if (contains (insn, prologue_insn_hash))
{
last = insn;
if (--len == 0)
@@ -5277,14 +5318,17 @@ reposition_prologue_and_epilogue_notes (void)
if (last)
{
- /* Find the prologue-end note if we haven't already, and
- move it to just after the last prologue insn. */
- if (note == 0)
+ if (note == NULL)
{
- for (note = last; (note = NEXT_INSN (note));)
- if (NOTE_P (note)
- && NOTE_KIND (note) == NOTE_INSN_PROLOGUE_END)
- break;
+ /* Scan forward looking for the PROLOGUE_END note. It should
+ be right at the beginning of the block, possibly with other
+ insn notes that got moved there. */
+ for (note = NEXT_INSN (last); ; note = NEXT_INSN (note))
+ {
+ if (NOTE_P (note)
+ && NOTE_KIND (note) == NOTE_INSN_PROLOGUE_END)
+ break;
+ }
}
/* Avoid placing note between CODE_LABEL and BASIC_BLOCK note. */
@@ -5294,41 +5338,39 @@ reposition_prologue_and_epilogue_notes (void)
}
}
- if ((len = VEC_length (int, epilogue)) > 0)
+ if (epilogue_insn_hash != NULL)
{
- last = 0, note = 0;
+ edge_iterator ei;
+ edge e;
- /* Scan from the end until we reach the first epilogue insn.
- We apparently can't depend on basic_block_{head,end} after
- reorg has run. */
- for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
+ FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds)
{
- if (NOTE_P (insn))
- {
- if (NOTE_KIND (insn) == NOTE_INSN_EPILOGUE_BEG)
- note = insn;
- }
- else if (contains (insn, &epilogue))
- {
- last = insn;
- if (--len == 0)
- break;
- }
- }
+ last = 0, note = 0;
+ bb = e->src;
- if (last)
- {
- /* Find the epilogue-begin note if we haven't already, and
- move it to just before the first epilogue insn. */
- if (note == 0)
+ /* Scan from the beginning until we reach the first epilogue insn.
+ Take the cue for whether this is a plain or sibcall epilogue
+ from the kind of note we find first. */
+ FOR_BB_INSNS (bb, insn)
{
- for (note = insn; (note = PREV_INSN (note));)
- if (NOTE_P (note)
- && NOTE_KIND (note) == NOTE_INSN_EPILOGUE_BEG)
- break;
+ if (NOTE_P (insn))
+ {
+ if (NOTE_KIND (insn) == NOTE_INSN_EPILOGUE_BEG)
+ {
+ note = insn;
+ if (last)
+ break;
+ }
+ }
+ else if (contains (insn, epilogue_insn_hash))
+ {
+ last = insn;
+ if (note != NULL)
+ break;
+ }
}
-
- if (PREV_INSN (last) != note)
+
+ if (last && note && PREV_INSN (last) != note)
reorder_insns (note, note, PREV_INSN (last));
}
}
diff --git a/gcc/function.h b/gcc/function.h
index db1d266e383..c53d719f8bd 100644
--- a/gcc/function.h
+++ b/gcc/function.h
@@ -138,7 +138,7 @@ struct GTY(()) expr_status {
rtx x_forced_labels;
};
-typedef struct call_site_record *call_site_record;
+typedef struct call_site_record_d *call_site_record;
DEF_VEC_P(call_site_record);
DEF_VEC_ALLOC_P(call_site_record, gc);
@@ -173,12 +173,12 @@ struct GTY(()) rtl_eh {
struct gimple_df;
struct temp_slot;
typedef struct temp_slot *temp_slot_p;
-struct call_site_record;
+struct call_site_record_d;
DEF_VEC_P(temp_slot_p);
DEF_VEC_ALLOC_P(temp_slot_p,gc);
-struct ipa_opt_pass;
-typedef struct ipa_opt_pass *ipa_opt_pass;
+struct ipa_opt_pass_d;
+typedef struct ipa_opt_pass_d *ipa_opt_pass;
DEF_VEC_P(ipa_opt_pass);
DEF_VEC_ALLOC_P(ipa_opt_pass,heap);
diff --git a/gcc/gbl-ctors.h b/gcc/gbl-ctors.h
index 67d57405226..ac4faae1292 100644
--- a/gcc/gbl-ctors.h
+++ b/gcc/gbl-ctors.h
@@ -35,6 +35,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
Note that this file should only be compiled with GCC.
*/
+#ifndef GCC_GBL_CTORS_H
+#define GCC_GBL_CTORS_H
+
/* Declare a pointer to void function type. */
typedef void (*func_ptr) (void);
@@ -81,3 +84,4 @@ do { \
} while (0)
#endif
+#endif /* GCC_GBL_CTORS_H */
diff --git a/gcc/gcc-plugin.h b/gcc/gcc-plugin.h
index 96c867d4bc6..1588bca372c 100644
--- a/gcc/gcc-plugin.h
+++ b/gcc/gcc-plugin.h
@@ -20,6 +20,13 @@ along with GCC; see the file COPYING3. If not see
#ifndef GCC_PLUGIN_H
#define GCC_PLUGIN_H
+#ifndef IN_GCC
+#define IN_GCC
+#endif
+
+#include "config.h"
+#include "system.h"
+
/* Event names. Keep in sync with plugin_event_name[]. */
enum plugin_event
{
@@ -28,7 +35,12 @@ enum plugin_event
PLUGIN_FINISH_UNIT, /* Useful for summary processing. */
PLUGIN_CXX_CP_PRE_GENERICIZE, /* Allows to see low level AST in C++ FE. */
PLUGIN_FINISH, /* Called before GCC exits. */
- PLUGIN_INFO, /* Information about the plugin */
+ PLUGIN_INFO, /* Information about the plugin. */
+ PLUGIN_GGC_START, /* Called at start of GCC Garbage Collection. */
+ PLUGIN_GGC_MARKING, /* Extend the GGC marking. */
+ PLUGIN_GGC_END, /* Called at end of GGC. */
+ PLUGIN_REGISTER_GGC_ROOTS, /* Register an extra GGC root table. */
+ PLUGIN_ATTRIBUTES, /* Called during attribute registration. */
PLUGIN_EVENT_LAST /* Dummy event used for indexing callback
array. */
};
@@ -78,6 +90,20 @@ struct plugin_gcc_version
const char *configuration_arguments;
};
+/* Object that keeps track of the plugin name and its arguments. */
+struct plugin_name_args
+{
+ char *base_name; /* Short name of the plugin (filename without
+ .so suffix). */
+ const char *full_name; /* Path to the plugin as specified with
+ -fplugin=. */
+ int argc; /* Number of arguments specified with
+ -fplugin-arg-... */
+ struct plugin_argument *argv; /* Array of ARGC key-value pairs. */
+ const char *version; /* Version string provided by plugin. */
+ const char *help; /* Help string provided by plugin. */
+};
+
/* The default version check. Compares every field in VERSION. */
extern bool plugin_default_version_check (struct plugin_gcc_version *,
@@ -87,21 +113,18 @@ extern bool plugin_default_version_check (struct plugin_gcc_version *,
should define this as an externally-visible function with name
"plugin_init."
- PLUGIN_NAME - name of the plugin (useful for error reporting)
- VERSION - the plugin_gcc_version symbol of the plugin itself.
- ARGC - the size of the ARGV array
- ARGV - an array of key-value argument pair
+ PLUGIN_INFO - plugin invocation information.
+ VERSION - the plugin_gcc_version symbol of GCC.
Returns 0 if initialization finishes successfully. */
-typedef int (*plugin_init_func) (const char *plugin_name,
- struct plugin_gcc_version *version,
- int argc, struct plugin_argument *argv);
+typedef int (*plugin_init_func) (struct plugin_name_args *plugin_info,
+ struct plugin_gcc_version *version);
/* Declaration for "plugin_init" function so that it doesn't need to be
duplicated in every plugin. */
-extern int plugin_init (const char *, struct plugin_gcc_version *version,
- int, struct plugin_argument *);
+extern int plugin_init (struct plugin_name_args *plugin_info,
+ struct plugin_gcc_version *version);
/* Function type for a plugin callback routine.
@@ -116,7 +139,13 @@ typedef void (*plugin_callback_func) (void *gcc_data, void *user_data);
PLUGIN_NAME - display name for this plugin
EVENT - which event the callback is for
CALLBACK - the callback to be called at the event
- USER_DATA - plugin-provided data */
+ USER_DATA - plugin-provided data.
+*/
+
+/* This is also called without a callback routine for the
+ PLUGIN_PASS_MANAGER_SETUP, PLUGIN_INFO, PLUGIN_REGISTER_GGC_ROOTS
+ pseudo-events, with a specific user_data.
+ */
extern void register_callback (const char *plugin_name,
enum plugin_event event,
diff --git a/gcc/gcc.c b/gcc/gcc.c
index d296a9eaa86..f65cf24132a 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -3722,10 +3722,15 @@ process_command (int argc, const char **argv)
}
/* Convert new-style -- options to old-style. */
- translate_options (&argc, (const char *const **) &argv);
+ translate_options (&argc,
+ CONST_CAST2 (const char *const **, const char ***,
+ &argv));
/* Do language-specific adjustment/addition of flags. */
- lang_specific_driver (&argc, (const char *const **) &argv, &added_libraries);
+ lang_specific_driver (&argc,
+ CONST_CAST2 (const char *const **, const char ***,
+ &argv),
+ &added_libraries);
/* Scan argv twice. Here, the first time, just count how many switches
there will be in their vector, and how many input files in theirs.
@@ -4591,6 +4596,11 @@ set_collect_gcc_options (void)
if ((switches[i].live_cond & SWITCH_IGNORE) != 0)
continue;
+ /* Don't use -fwhole-program when compiling the init and fini routines,
+ since we'd wrongly assume that the routines aren't needed. */
+ if (strcmp (switches[i].part1, "fwhole-program") == 0)
+ continue;
+
obstack_grow (&collect_obstack, "'-", 2);
q = switches[i].part1;
while ((p = strchr (q, '\'')))
@@ -6799,7 +6809,7 @@ main (int argc, char **argv)
Make a table of specified input files (infiles, n_infiles).
Decode switches that are handled locally. */
- process_command (argc, (const char **) argv);
+ process_command (argc, CONST_CAST2 (const char **, char **, argv));
/* Initialize the vector of specs to just the default.
This means one element containing 0s, as a terminator. */
diff --git a/gcc/gcov.c b/gcc/gcov.c
index 61ac7ed6974..4f5c3d4ebba 100644
--- a/gcc/gcov.c
+++ b/gcc/gcov.c
@@ -1065,27 +1065,29 @@ read_count_file (void)
program_count++;
else if (tag == GCOV_TAG_FUNCTION)
{
- unsigned ident = gcov_read_unsigned ();
- struct function_info *fn_n = functions;
+ {
+ unsigned ident = gcov_read_unsigned ();
+ struct function_info *fn_n = functions;
- /* Try to find the function in the list.
- To speed up the search, first start from the last function
- found. */
- for (fn = fn ? fn->next : NULL; ; fn = fn->next)
- {
- if (fn)
- ;
- else if ((fn = fn_n))
- fn_n = NULL;
- else
- {
- fnotice (stderr, "%s:unknown function '%u'\n",
- da_file_name, ident);
+ /* Try to find the function in the list.
+ To speed up the search, first start from the last function
+ found. */
+ for (fn = fn ? fn->next : NULL; ; fn = fn->next)
+ {
+ if (fn)
+ ;
+ else if ((fn = fn_n))
+ fn_n = NULL;
+ else
+ {
+ fnotice (stderr, "%s:unknown function '%u'\n",
+ da_file_name, ident);
+ break;
+ }
+ if (fn->ident == ident)
break;
- }
- if (fn->ident == ident)
- break;
- }
+ }
+ }
if (!fn)
;
diff --git a/gcc/gcse.c b/gcc/gcse.c
index d167b0bb194..0b22bb85056 100644
--- a/gcc/gcse.c
+++ b/gcc/gcse.c
@@ -169,6 +169,7 @@ along with GCC; see the file COPYING3. If not see
#include "hashtab.h"
#include "df.h"
#include "dbgcnt.h"
+#include "target.h"
/* Propagate flow information through back edges and thus enable PRE's
moving loop invariant calculations out of loops.
@@ -343,7 +344,7 @@ struct occr
[one could build a mapping table without holes afterwards though].
Someday I'll perform the computation and figure it out. */
-struct hash_table
+struct hash_table_d
{
/* The table itself.
This is an array of `expr_hash_table_size' elements. */
@@ -360,10 +361,10 @@ struct hash_table
};
/* Expression hash table. */
-static struct hash_table expr_hash_table;
+static struct hash_table_d expr_hash_table;
/* Copy propagation hash table. */
-static struct hash_table set_hash_table;
+static struct hash_table_d set_hash_table;
/* This is a list of expressions which are MEMs and will be used by load
or store motion.
@@ -445,30 +446,30 @@ static void *gcalloc (size_t, size_t) ATTRIBUTE_MALLOC;
static void *gcse_alloc (unsigned long);
static void alloc_gcse_mem (void);
static void free_gcse_mem (void);
-static void hash_scan_insn (rtx, struct hash_table *);
-static void hash_scan_set (rtx, rtx, struct hash_table *);
-static void hash_scan_clobber (rtx, rtx, struct hash_table *);
-static void hash_scan_call (rtx, rtx, struct hash_table *);
+static void hash_scan_insn (rtx, struct hash_table_d *);
+static void hash_scan_set (rtx, rtx, struct hash_table_d *);
+static void hash_scan_clobber (rtx, rtx, struct hash_table_d *);
+static void hash_scan_call (rtx, rtx, struct hash_table_d *);
static int want_to_gcse_p (rtx);
static bool gcse_constant_p (const_rtx);
static int oprs_unchanged_p (const_rtx, const_rtx, int);
static int oprs_anticipatable_p (const_rtx, const_rtx);
static int oprs_available_p (const_rtx, const_rtx);
static void insert_expr_in_table (rtx, enum machine_mode, rtx, int, int,
- struct hash_table *);
-static void insert_set_in_table (rtx, rtx, struct hash_table *);
+ struct hash_table_d *);
+static void insert_set_in_table (rtx, rtx, struct hash_table_d *);
static unsigned int hash_expr (const_rtx, enum machine_mode, int *, int);
static unsigned int hash_set (int, int);
static int expr_equiv_p (const_rtx, const_rtx);
static void record_last_reg_set_info (rtx, int);
static void record_last_mem_set_info (rtx);
static void record_last_set_info (rtx, const_rtx, void *);
-static void compute_hash_table (struct hash_table *);
-static void alloc_hash_table (struct hash_table *, int);
-static void free_hash_table (struct hash_table *);
-static void compute_hash_table_work (struct hash_table *);
-static void dump_hash_table (FILE *, const char *, struct hash_table *);
-static struct expr *lookup_set (unsigned int, struct hash_table *);
+static void compute_hash_table (struct hash_table_d *);
+static void alloc_hash_table (struct hash_table_d *, int);
+static void free_hash_table (struct hash_table_d *);
+static void compute_hash_table_work (struct hash_table_d *);
+static void dump_hash_table (FILE *, const char *, struct hash_table_d *);
+static struct expr *lookup_set (unsigned int, struct hash_table_d *);
static struct expr *next_set (unsigned int, struct expr *);
static void reset_opr_set_tables (void);
static int oprs_not_set_p (const_rtx, const_rtx);
@@ -481,7 +482,7 @@ static void free_cprop_mem (void);
static void compute_transp (const_rtx, int, sbitmap *, int);
static void compute_transpout (void);
static void compute_local_properties (sbitmap *, sbitmap *, sbitmap *,
- struct hash_table *);
+ struct hash_table_d *);
static void compute_cprop_data (void);
static void find_used_regs (rtx *, void *);
static int try_replace_reg (rtx, rtx, rtx);
@@ -691,7 +692,7 @@ free_gcse_mem (void)
static void
compute_local_properties (sbitmap *transp, sbitmap *comp, sbitmap *antloc,
- struct hash_table *table)
+ struct hash_table_d *table)
{
unsigned int i;
@@ -805,6 +806,11 @@ static GTY(()) rtx test_insn;
/* Return true if we can assign X to a pseudo register such that the
resulting insn does not result in clobbering a hard register as a
side-effect.
+
+ Additionally, if the target requires it, check that the resulting insn
+ can be copied. If it cannot, this means that X is special and probably
+ has hidden side-effects we don't want to mess with.
+
This function is typically used by code motion passes, to verify
that it is safe to insert an insn without worrying about clobbering
maybe live hard regs. */
@@ -837,8 +843,18 @@ can_assign_to_reg_without_clobbers_p (rtx x)
valid. */
PUT_MODE (SET_DEST (PATTERN (test_insn)), GET_MODE (x));
SET_SRC (PATTERN (test_insn)) = x;
- return ((icode = recog (PATTERN (test_insn), test_insn, &num_clobbers)) >= 0
- && (num_clobbers == 0 || ! added_clobbers_hard_reg_p (icode)));
+
+ icode = recog (PATTERN (test_insn), test_insn, &num_clobbers);
+ if (icode < 0)
+ return false;
+
+ if (num_clobbers > 0 && added_clobbers_hard_reg_p (icode))
+ return false;
+
+ if (targetm.cannot_copy_insn_p && targetm.cannot_copy_insn_p (test_insn))
+ return false;
+
+ return true;
}
/* Return nonzero if the operands of expression X are unchanged from the
@@ -1096,7 +1112,7 @@ expr_equiv_p (const_rtx x, const_rtx y)
static void
insert_expr_in_table (rtx x, enum machine_mode mode, rtx insn, int antic_p,
- int avail_p, struct hash_table *table)
+ int avail_p, struct hash_table_d *table)
{
int found, do_not_record_p;
unsigned int hash;
@@ -1197,7 +1213,7 @@ insert_expr_in_table (rtx x, enum machine_mode mode, rtx insn, int antic_p,
basic block. */
static void
-insert_set_in_table (rtx x, rtx insn, struct hash_table *table)
+insert_set_in_table (rtx x, rtx insn, struct hash_table_d *table)
{
int found;
unsigned int hash;
@@ -1293,7 +1309,7 @@ gcse_constant_p (const_rtx x)
expression one). */
static void
-hash_scan_set (rtx pat, rtx insn, struct hash_table *table)
+hash_scan_set (rtx pat, rtx insn, struct hash_table_d *table)
{
rtx src = SET_SRC (pat);
rtx dest = SET_DEST (pat);
@@ -1432,14 +1448,14 @@ hash_scan_set (rtx pat, rtx insn, struct hash_table *table)
static void
hash_scan_clobber (rtx x ATTRIBUTE_UNUSED, rtx insn ATTRIBUTE_UNUSED,
- struct hash_table *table ATTRIBUTE_UNUSED)
+ struct hash_table_d *table ATTRIBUTE_UNUSED)
{
/* Currently nothing to do. */
}
static void
hash_scan_call (rtx x ATTRIBUTE_UNUSED, rtx insn ATTRIBUTE_UNUSED,
- struct hash_table *table ATTRIBUTE_UNUSED)
+ struct hash_table_d *table ATTRIBUTE_UNUSED)
{
/* Currently nothing to do. */
}
@@ -1456,7 +1472,7 @@ hash_scan_call (rtx x ATTRIBUTE_UNUSED, rtx insn ATTRIBUTE_UNUSED,
otherwise it is for the expression hash table. */
static void
-hash_scan_insn (rtx insn, struct hash_table *table)
+hash_scan_insn (rtx insn, struct hash_table_d *table)
{
rtx pat = PATTERN (insn);
int i;
@@ -1486,7 +1502,7 @@ hash_scan_insn (rtx insn, struct hash_table *table)
}
static void
-dump_hash_table (FILE *file, const char *name, struct hash_table *table)
+dump_hash_table (FILE *file, const char *name, struct hash_table_d *table)
{
int i;
/* Flattened out table, so it's printed in proper order. */
@@ -1647,7 +1663,7 @@ record_last_set_info (rtx dest, const_rtx setter ATTRIBUTE_UNUSED, void *data)
TABLE is the table computed. */
static void
-compute_hash_table_work (struct hash_table *table)
+compute_hash_table_work (struct hash_table_d *table)
{
int i;
@@ -1705,7 +1721,7 @@ compute_hash_table_work (struct hash_table *table)
be created. */
static void
-alloc_hash_table (struct hash_table *table, int set_p)
+alloc_hash_table (struct hash_table_d *table, int set_p)
{
int n;
@@ -1727,7 +1743,7 @@ alloc_hash_table (struct hash_table *table, int set_p)
/* Free things allocated by alloc_hash_table. */
static void
-free_hash_table (struct hash_table *table)
+free_hash_table (struct hash_table_d *table)
{
free (table->table);
}
@@ -1736,7 +1752,7 @@ free_hash_table (struct hash_table *table)
expression hash table. */
static void
-compute_hash_table (struct hash_table *table)
+compute_hash_table (struct hash_table_d *table)
{
/* Initialize count of number of entries in hash table. */
table->n_elems = 0;
@@ -1751,7 +1767,7 @@ compute_hash_table (struct hash_table *table)
table entry, or NULL if not found. */
static struct expr *
-lookup_set (unsigned int regno, struct hash_table *table)
+lookup_set (unsigned int regno, struct hash_table_d *table)
{
unsigned int hash = hash_set (regno, table->size);
struct expr *expr;
diff --git a/gcc/genattrtab.c b/gcc/genattrtab.c
index 794a8db1bb1..def9a694a0e 100644
--- a/gcc/genattrtab.c
+++ b/gcc/genattrtab.c
@@ -1,6 +1,7 @@
/* Generate code from machine description to compute values of attributes.
Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+ 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+ Free Software Foundation, Inc.
Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
This file is part of GCC.
@@ -1637,7 +1638,7 @@ write_length_unit_log (void)
for (length_unit_log = 0; length_or & 1; length_or >>= 1)
length_unit_log++;
}
- printf ("const int length_unit_log = %u;\n", length_unit_log);
+ printf ("EXPORTED_CONST int length_unit_log = %u;\n", length_unit_log);
}
/* Take a COND expression and see if any of the conditions in it can be
diff --git a/gcc/genchecksum.c b/gcc/genchecksum.c
index ebcd34a29d3..fa00d0e3225 100644
--- a/gcc/genchecksum.c
+++ b/gcc/genchecksum.c
@@ -1,5 +1,5 @@
/* Generate checksums of executables for PCH validation
- Copyright (C) 2005, 2007
+ Copyright (C) 2005, 2007, 2009
Free Software Foundation, Inc.
This file is part of GCC.
@@ -56,7 +56,9 @@ dosum (const char *file)
exit (1);
}
- fputs ("const unsigned char executable_checksum[16] = { ", stdout);
+ puts ("#include \"config.h\"");
+ puts ("#include \"system.h\"");
+ fputs ("EXPORTED_CONST unsigned char executable_checksum[16] = { ", stdout);
for (i = 0; i < 16; i++)
printf ("%#02x%s", result[i], i == 15 ? " };\n" : ", ");
}
diff --git a/gcc/gengtype.c b/gcc/gengtype.c
index c7d59fd0019..1b1e6fa7078 100644
--- a/gcc/gengtype.c
+++ b/gcc/gengtype.c
@@ -1,5 +1,5 @@
/* Process source files and output type information.
- Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008
+ Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
Free Software Foundation, Inc.
This file is part of GCC.
@@ -128,18 +128,24 @@ typedef struct outf * outf_p;
/* An output file, suitable for definitions, that can see declarations
made in INPUT_FILE and is linked into every language that uses
- INPUT_FILE. */
+ INPUT_FILE. May return NULL in plugin mode. */
extern outf_p get_output_file_with_visibility
(const char *input_file);
const char *get_output_file_name (const char *);
-/* Print, like fprintf, to O. */
+/* Print, like fprintf, to O. No-op if O is NULL. */
static void oprintf (outf_p o, const char *S, ...)
ATTRIBUTE_PRINTF_2;
/* The list of output files. */
static outf_p output_files;
+/* The plugin input files and their number; in that case only
+ corresponding gt-<plugin>.h are generated in the current
+ directory. */
+static char** plugin_files;
+static int nb_plugin_files;
+
/* The output header file that is included into pretty much every
source file. */
static outf_p header_file;
@@ -274,7 +280,7 @@ measure_input_list (FILE *list)
int c;
bool atbol = true;
num_lang_dirs = 0;
- num_gt_files = 0;
+ num_gt_files = plugin_files ? nb_plugin_files : 0;
while ((c = getc (list)) != EOF)
{
n++;
@@ -455,6 +461,13 @@ read_input_list (const char *listname)
/* Update the global counts now that we know accurately how many
things there are. (We do not bother resizing the arrays down.) */
num_lang_dirs = langno;
+ /* Add the plugin files if provided. */
+ if (plugin_files)
+ {
+ int i;
+ for (i = 0; i < nb_plugin_files; i++)
+ gt_files[nfiles++] = plugin_files[i];
+ }
num_gt_files = nfiles;
}
@@ -962,9 +975,11 @@ write_rtx_next (void)
{
outf_p f = get_output_file_with_visibility (NULL);
int i;
+ if (!f)
+ return;
oprintf (f, "\n/* Used to implement the RTX_NEXT macro. */\n");
- oprintf (f, "const unsigned char rtx_next[NUM_RTX_CODE] = {\n");
+ oprintf (f, "EXPORTED_CONST unsigned char rtx_next[NUM_RTX_CODE] = {\n");
for (i = 0; i < NUM_RTX_CODE; i++)
if (rtx_next_new[i] == -1)
oprintf (f, " 0,\n");
@@ -1449,7 +1464,7 @@ static outf_p
create_file (const char *name, const char *oname)
{
static const char *const hdr[] = {
- " Copyright (C) 2004, 2007 Free Software Foundation, Inc.\n",
+ " Copyright (C) 2004, 2007, 2009 Free Software Foundation, Inc.\n",
"\n",
"This file is part of GCC.\n",
"\n",
@@ -1472,6 +1487,8 @@ create_file (const char *name, const char *oname)
outf_p f;
size_t i;
+ gcc_assert (name != NULL);
+ gcc_assert (oname != NULL);
f = XCNEW (struct outf);
f->next = output_files;
f->name = oname;
@@ -1495,6 +1512,11 @@ oprintf (outf_p o, const char *format, ...)
size_t slength;
va_list ap;
+ /* In plugin mode, the O could be a NULL pointer, so avoid crashing
+ in that case. */
+ if (!o)
+ return;
+
va_start (ap, format);
slength = vasprintf (&s, format, ap);
if (s == NULL || (int)slength < 0)
@@ -1524,6 +1546,9 @@ open_base_files (void)
{
size_t i;
+ if (nb_plugin_files > 0 && plugin_files)
+ return;
+
header_file = create_file ("GCC", "gtype-desc.h");
base_files = XNEWVEC (outf_p, num_lang_dirs);
@@ -1686,6 +1711,18 @@ get_output_file_with_visibility (const char *input_file)
if (input_file == NULL)
input_file = "system.h";
+ /* In plugin mode, return NULL unless the input_file is one of the
+ plugin_files. */
+ if (plugin_files && nb_plugin_files > 0)
+ {
+ int ix= -1, i;
+ for (i = 0; i < nb_plugin_files && ix < 0; i++)
+ if (strcmp (input_file, plugin_files[i]) == 0)
+ ix = i;
+ if (ix < 0)
+ return NULL;
+ }
+
/* Determine the output file name. */
basename = get_file_basename (input_file);
@@ -1737,6 +1774,7 @@ get_output_file_with_visibility (const char *input_file)
/* If not, create it. */
r = create_file (for_name, output_name);
+ gcc_assert (r && r->name);
return r;
}
@@ -1747,7 +1785,10 @@ get_output_file_with_visibility (const char *input_file)
const char *
get_output_file_name (const char *input_file)
{
- return get_output_file_with_visibility (input_file)->name;
+ outf_p o = get_output_file_with_visibility (input_file);
+ if (o)
+ return o->name;
+ return NULL;
}
/* Copy the output to its final destination,
@@ -2812,7 +2853,6 @@ write_local_func_for_structure (type_p orig_s, type_p s, type_p *param)
memset (&d, 0, sizeof (d));
d.of = get_output_file_with_visibility (fn);
-
d.process_field = write_types_local_process_field;
d.opt = s->u.s.opt;
d.line = &s->u.s.line;
@@ -2848,6 +2888,8 @@ write_local (type_p structures, type_p param_structs)
{
type_p s;
+ if (!header_file)
+ return;
oprintf (header_file, "\n/* Local pointer-walking routines. */\n");
for (s = structures; s; s = s->next)
if (s->gc_used == GC_POINTED_TO
@@ -2933,6 +2975,8 @@ write_enum_defn (type_p structures, type_p param_structs)
{
type_p s;
+ if (!header_file)
+ return;
oprintf (header_file, "\n/* Enumeration of types known. */\n");
oprintf (header_file, "enum gt_types_enum {\n");
for (s = structures; s; s = s->next)
@@ -2983,6 +3027,8 @@ static void
put_mangled_filename (outf_p f, const char *fn)
{
const char *name = get_output_file_name (fn);
+ if (!f || !name)
+ return;
for (; *name != 0; name++)
if (ISALNUM (*name))
oprintf (f, "%c", *name);
@@ -3007,7 +3053,7 @@ finish_root_table (struct flist *flp, const char *pfx, const char *lastname,
oprintf (fli2->f, "};\n\n");
}
- for (fli2 = flp; fli2; fli2 = fli2->next)
+ for (fli2 = flp; fli2 && base_files; fli2 = fli2->next)
if (fli2->started_p)
{
lang_bitmap bitmap = get_lang_bitmap (fli2->name);
@@ -3026,9 +3072,9 @@ finish_root_table (struct flist *flp, const char *pfx, const char *lastname,
{
size_t fnum;
- for (fnum = 0; fnum < num_lang_dirs; fnum++)
+ for (fnum = 0; base_files && fnum < num_lang_dirs; fnum++)
oprintf (base_files [fnum],
- "const struct %s * const %s[] = {\n",
+ "EXPORTED_CONST struct %s * const %s[] = {\n",
tname, name);
}
@@ -3041,7 +3087,7 @@ finish_root_table (struct flist *flp, const char *pfx, const char *lastname,
fli2->started_p = 0;
- for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
+ for (fnum = 0; base_files && bitmap != 0; fnum++, bitmap >>= 1)
if (bitmap & 1)
{
oprintf (base_files[fnum], " gt_%s_", pfx);
@@ -3052,7 +3098,7 @@ finish_root_table (struct flist *flp, const char *pfx, const char *lastname,
{
size_t fnum;
- for (fnum = 0; fnum < num_lang_dirs; fnum++)
+ for (fnum = 0; base_files && fnum < num_lang_dirs; fnum++)
{
oprintf (base_files[fnum], " NULL\n");
oprintf (base_files[fnum], "};\n");
@@ -3309,7 +3355,7 @@ write_roots (pair_p variables)
v->name, o->name);
for (fli = flp; fli; fli = fli->next)
- if (fli->f == f)
+ if (fli->f == f && f)
break;
if (fli == NULL)
{
@@ -3318,6 +3364,7 @@ write_roots (pair_p variables)
fli->next = flp;
fli->started_p = 0;
fli->name = v->line.file;
+ gcc_assert(fli->name);
flp = fli;
oprintf (f, "\n/* GC roots. */\n\n");
@@ -3359,7 +3406,7 @@ write_roots (pair_p variables)
{
fli->started_p = 1;
- oprintf (f, "const struct ggc_root_tab gt_ggc_r_");
+ oprintf (f, "EXPORTED_CONST struct ggc_root_tab gt_ggc_r_");
put_mangled_filename (f, v->line.file);
oprintf (f, "[] = {\n");
}
@@ -3393,7 +3440,7 @@ write_roots (pair_p variables)
{
fli->started_p = 1;
- oprintf (f, "const struct ggc_root_tab gt_ggc_rd_");
+ oprintf (f, "EXPORTED_CONST struct ggc_root_tab gt_ggc_rd_");
put_mangled_filename (f, v->line.file);
oprintf (f, "[] = {\n");
}
@@ -3437,7 +3484,7 @@ write_roots (pair_p variables)
{
fli->started_p = 1;
- oprintf (f, "const struct ggc_cache_tab gt_ggc_rc_");
+ oprintf (f, "EXPORTED_CONST struct ggc_cache_tab gt_ggc_rc_");
put_mangled_filename (f, v->line.file);
oprintf (f, "[] = {\n");
}
@@ -3473,7 +3520,7 @@ write_roots (pair_p variables)
{
fli->started_p = 1;
- oprintf (f, "const struct ggc_root_tab gt_pch_rc_");
+ oprintf (f, "EXPORTED_CONST struct ggc_root_tab gt_pch_rc_");
put_mangled_filename (f, v->line.file);
oprintf (f, "[] = {\n");
}
@@ -3509,7 +3556,7 @@ write_roots (pair_p variables)
{
fli->started_p = 1;
- oprintf (f, "const struct ggc_root_tab gt_pch_rs_");
+ oprintf (f, "EXPORTED_CONST struct ggc_root_tab gt_pch_rs_");
put_mangled_filename (f, v->line.file);
oprintf (f, "[] = {\n");
}
@@ -3586,17 +3633,28 @@ main (int argc, char **argv)
{
size_t i;
static struct fileloc pos = { this_file, 0 };
-
+ char* inputlist = 0;
/* fatal uses this */
progname = "gengtype";
- if (argc != 3)
- fatal ("usage: gengtype srcdir input-list");
+ if (argc >= 5 && !strcmp (argv[1], "-p"))
+ {
+ srcdir = argv[2];
+ inputlist = argv[3];
+ plugin_files = argv+4;
+ nb_plugin_files = argc-4;
+ }
+ else if (argc == 3)
+ {
+ srcdir = argv[1];
+ inputlist = argv[2];
+ }
+ else
+ fatal ("usage: gengtype [-p] srcdir input-list [file1 file2 ... fileN]");
- srcdir = argv[1];
srcdir_len = strlen (srcdir);
- read_input_list (argv[2]);
+ read_input_list (inputlist);
if (hit_error)
return 1;
diff --git a/gcc/genopinit.c b/gcc/genopinit.c
index 8e13d1ccdf4..f8cbf9549f8 100644
--- a/gcc/genopinit.c
+++ b/gcc/genopinit.c
@@ -198,15 +198,12 @@ static const char * const optabs[] =
"optab_handler (movstrict_optab, $A)->insn_code = CODE_FOR_$(movstrict$a$)",
"optab_handler (movmisalign_optab, $A)->insn_code = CODE_FOR_$(movmisalign$a$)",
"optab_handler (storent_optab, $A)->insn_code = CODE_FOR_$(storent$a$)",
- "optab_handler (cmp_optab, $A)->insn_code = CODE_FOR_$(cmp$a$)",
- "optab_handler (tst_optab, $A)->insn_code = CODE_FOR_$(tst$a$)",
"optab_handler (addcc_optab, $A)->insn_code = CODE_FOR_$(add$acc$)",
- "bcc_gen_fctn[$C] = gen_$(b$c$)",
- "setcc_gen_code[$C] = CODE_FOR_$(s$c$)",
"movcc_gen_code[$A] = CODE_FOR_$(mov$acc$)",
"optab_handler (cbranch_optab, $A)->insn_code = CODE_FOR_$(cbranch$a4$)",
"optab_handler (cmov_optab, $A)->insn_code = CODE_FOR_$(cmov$a6$)",
"optab_handler (cstore_optab, $A)->insn_code = CODE_FOR_$(cstore$a4$)",
+ "optab_handler (ctrap_optab, $A)->insn_code = CODE_FOR_$(ctrap$a4$)",
"optab_handler (push_optab, $A)->insn_code = CODE_FOR_$(push$a1$)",
"reload_in_optab[$A] = CODE_FOR_$(reload_in$a$)",
"reload_out_optab[$A] = CODE_FOR_$(reload_out$a$)",
diff --git a/gcc/ggc-common.c b/gcc/ggc-common.c
index b6b9e1e3400..2499ff51cd7 100644
--- a/gcc/ggc-common.c
+++ b/gcc/ggc-common.c
@@ -30,6 +30,8 @@ along with GCC; see the file COPYING3. If not see
#include "params.h"
#include "hosthooks.h"
#include "hosthooks-def.h"
+#include "plugin.h"
+#include "vec.h"
#ifdef HAVE_SYS_RESOURCE_H
# include <sys/resource.h>
@@ -86,6 +88,34 @@ ggc_htab_delete (void **slot, void *info)
return 1;
}
+
+/* This extra vector of dynamically registered root_tab-s is used by
+ ggc_mark_roots and gives the ability to dynamically add new GGC root
+ tables, for instance from some plugins; this vector is a heap one
+ [since it is used by GGC internally!] */
+typedef const struct ggc_root_tab* const_ggc_root_tab_t;
+DEF_VEC_P(const_ggc_root_tab_t);
+DEF_VEC_ALLOC_P(const_ggc_root_tab_t, heap);
+static VEC(const_ggc_root_tab_t, heap) *extra_root_vec;
+
+
+/* Dynamically register a new GGC root table RT. This is useful for
+ plugins. */
+
+void
+ggc_register_root_tab (const struct ggc_root_tab* rt)
+{
+ if (!rt)
+ return;
+ if (!extra_root_vec)
+ {
+ int vlen = 32;
+ extra_root_vec = VEC_alloc (const_ggc_root_tab_t, heap, vlen);
+ }
+ VEC_safe_push (const_ggc_root_tab_t, heap, extra_root_vec, rt);
+}
+
+
/* Iterate through all registered roots and mark each element. */
void
@@ -104,7 +134,21 @@ ggc_mark_roots (void)
for (rt = gt_ggc_rtab; *rt; rt++)
for (rti = *rt; rti->base != NULL; rti++)
for (i = 0; i < rti->nelt; i++)
- (*rti->cb)(*(void **)((char *)rti->base + rti->stride * i));
+ (*rti->cb) (*(void **)((char *)rti->base + rti->stride * i));
+
+ if (extra_root_vec
+ && VEC_length(const_ggc_root_tab_t,extra_root_vec) > 0)
+ {
+ const_ggc_root_tab_t rtp = NULL;
+ for (i=0;
+ VEC_iterate(const_ggc_root_tab_t, extra_root_vec, i, rtp);
+ i++)
+ {
+ for (rti = rtp; rti->base != NULL; rti++)
+ for (i = 0; i < rti->nelt; i++)
+ (*rti->cb) (*(void **) ((char *)rti->base + rti->stride * i));
+ }
+ }
if (ggc_protect_identifiers)
ggc_mark_stringpool ();
@@ -123,6 +167,9 @@ ggc_mark_roots (void)
if (! ggc_protect_identifiers)
ggc_purge_stringpool ();
+
+ /* Some plugins may call ggc_set_mark from here. */
+ invoke_plugin_callbacks (PLUGIN_GGC_MARKING, NULL);
}
/* Allocate a block of memory, then clear it. */
diff --git a/gcc/ggc-page.c b/gcc/ggc-page.c
index 41cbd44c585..4f872b294f1 100644
--- a/gcc/ggc-page.c
+++ b/gcc/ggc-page.c
@@ -31,6 +31,7 @@ along with GCC; see the file COPYING3. If not see
#include "timevar.h"
#include "params.h"
#include "tree-flow.h"
+#include "plugin.h"
/* Prefer MAP_ANON(YMOUS) to /dev/zero, since we don't need to keep a
file open. Prefer either to valloc. */
@@ -1937,6 +1938,8 @@ ggc_collect (void)
/* Indicate that we've seen collections at this context depth. */
G.context_depth_collections = ((unsigned long)1 << (G.context_depth + 1)) - 1;
+ invoke_plugin_callbacks (PLUGIN_GGC_START, NULL);
+
clear_marks ();
ggc_mark_roots ();
#ifdef GATHER_STATISTICS
@@ -1948,6 +1951,8 @@ ggc_collect (void)
G.allocated_last_gc = G.allocated;
+ invoke_plugin_callbacks (PLUGIN_GGC_END, NULL);
+
timevar_pop (TV_GC);
if (!quiet_flag)
diff --git a/gcc/ggc-zone.c b/gcc/ggc-zone.c
index 5031a01b404..442c80e6713 100644
--- a/gcc/ggc-zone.c
+++ b/gcc/ggc-zone.c
@@ -36,6 +36,7 @@ along with GCC; see the file COPYING3. If not see
#include "timevar.h"
#include "params.h"
#include "bitmap.h"
+#include "plugin.h"
/* Prefer MAP_ANON(YMOUS) to /dev/zero, since we don't need to keep a
file open. Prefer either to valloc. */
@@ -2029,6 +2030,8 @@ ggc_collect (void)
}
}
+ invoke_plugin_callbacks (PLUGIN_GGC_START, NULL);
+
/* Start by possibly collecting the main zone. */
main_zone.was_collected = false;
marked |= ggc_collect_1 (&main_zone, true);
@@ -2093,6 +2096,8 @@ ggc_collect (void)
}
}
+ invoke_plugin_callbacks (PLUGIN_GGC_END, NULL);
+
timevar_pop (TV_GC);
}
diff --git a/gcc/ggc.h b/gcc/ggc.h
index 5b2743b3386..e3471e45353 100644
--- a/gcc/ggc.h
+++ b/gcc/ggc.h
@@ -1,6 +1,7 @@
/* Garbage collection for the GNU compiler.
- Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008
- Free Software Foundation, Inc.
+
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007,
+ 2008, 2009 Free Software Foundation, Inc.
This file is part of GCC.
@@ -270,6 +271,10 @@ extern const char *ggc_alloc_string (const char *contents, int length);
function is called, not during allocations. */
extern void ggc_collect (void);
+/* Register an additional root table. This can be useful for some
+ plugins. Does nothing if the passed pointer is null. */
+extern void ggc_register_root_tab (const struct ggc_root_tab *);
+
/* Return the number of bytes allocated at the indicated address. */
extern size_t ggc_get_size (const void *);
diff --git a/gcc/gimple-iterator.c b/gcc/gimple-iterator.c
index a52c83072b4..666b47b47a8 100644
--- a/gcc/gimple-iterator.c
+++ b/gcc/gimple-iterator.c
@@ -604,7 +604,7 @@ gsi_insert_seq_on_edge (edge e, gimple_seq seq)
In all cases, the returned *GSI points to the correct location. The
return value is true if insertion should be done after the location,
- or false if it should be done before the location. If new basic block
+ or false if it should be done before the location. If a new basic block
has to be created, it is stored in *NEW_BB. */
static bool
diff --git a/gcc/gimple-low.c b/gcc/gimple-low.c
index 02a1ce63549..e096c00dd21 100644
--- a/gcc/gimple-low.c
+++ b/gcc/gimple-low.c
@@ -169,7 +169,7 @@ lower_function_body (void)
tree disp_label, disp_var, arg;
/* Build 'DISP_LABEL:' and insert. */
- disp_label = create_artificial_label ();
+ disp_label = create_artificial_label (cfun->function_end_locus);
/* This mark will create forward edges from every call site. */
DECL_NONLOCAL (disp_label) = 1;
cfun->has_nonlocal_label = 1;
@@ -368,7 +368,6 @@ lower_stmt (gimple_stmt_iterator *gsi, struct lower_data *data)
case GIMPLE_PREDICT:
case GIMPLE_LABEL:
case GIMPLE_SWITCH:
- case GIMPLE_CHANGE_DYNAMIC_TYPE:
case GIMPLE_OMP_FOR:
case GIMPLE_OMP_SECTIONS:
case GIMPLE_OMP_SECTIONS_SWITCH:
@@ -728,7 +727,7 @@ lower_gimple_return (gimple_stmt_iterator *gsi, struct lower_data *data)
}
/* Not found. Create a new label and record the return statement. */
- tmp_rs.label = create_artificial_label ();
+ tmp_rs.label = create_artificial_label (cfun->function_end_locus);
tmp_rs.stmt = stmt;
VEC_safe_push (return_statements_t, heap, data->return_statements, &tmp_rs);
@@ -798,8 +797,9 @@ static void
lower_builtin_setjmp (gimple_stmt_iterator *gsi)
{
gimple stmt = gsi_stmt (*gsi);
- tree cont_label = create_artificial_label ();
- tree next_label = create_artificial_label ();
+ location_t loc = gimple_location (stmt);
+ tree cont_label = create_artificial_label (loc);
+ tree next_label = create_artificial_label (loc);
tree dest, t, arg;
gimple g;
diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index 70acba6672b..681f77cbc30 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -508,7 +508,7 @@ dump_gimple_call (pretty_printer *buffer, gimple gs, int spc, int flags)
pp_space (buffer);
}
- dump_generic_node (buffer, gimple_call_fn (gs), spc, flags, false);
+ print_call_name (buffer, gimple_call_fn (gs));
pp_string (buffer, " (");
dump_gimple_call_args (buffer, gs, flags);
pp_character (buffer, ')');
@@ -1349,27 +1349,6 @@ dump_gimple_omp_atomic_store (pretty_printer *buffer, gimple gs, int spc,
}
}
-/* Dump a GIMPLE_CHANGE_DYNAMIC_TYPE statement GS. BUFFER, SPC and
- FLAGS are as in dump_gimple_stmt. */
-
-static void
-dump_gimple_cdt (pretty_printer *buffer, gimple gs, int spc, int flags)
-{
- if (flags & TDF_RAW)
- dump_gimple_fmt (buffer, spc, flags, "%G <%T, %T>", gs,
- gimple_cdt_new_type (gs), gimple_cdt_location (gs));
- else
- {
- pp_string (buffer, "<<<change_dynamic_type (");
- dump_generic_node (buffer, gimple_cdt_new_type (gs), spc + 2, flags,
- false);
- pp_string (buffer, ") ");
- dump_generic_node (buffer, gimple_cdt_location (gs), spc + 2, flags,
- false);
- pp_string (buffer, ")>>>");
- }
-}
-
/* Dump all the memory operands for statement GS. BUFFER, SPC and
FLAGS are as in dump_gimple_stmt. */
@@ -1425,6 +1404,8 @@ dump_gimple_stmt (pretty_printer *buffer, gimple gs, int spc, int flags)
pp_string (buffer, " : ");
}
pp_decimal_int (buffer, xloc.line);
+ pp_string (buffer, ":");
+ pp_decimal_int (buffer, xloc.column);
pp_string (buffer, "] ");
}
@@ -1533,10 +1514,6 @@ dump_gimple_stmt (pretty_printer *buffer, gimple gs, int spc, int flags)
dump_gimple_omp_critical (buffer, gs, spc, flags);
break;
- case GIMPLE_CHANGE_DYNAMIC_TYPE:
- dump_gimple_cdt (buffer, gs, spc, flags);
- break;
-
case GIMPLE_CATCH:
dump_gimple_catch (buffer, gs, spc, flags);
break;
@@ -1613,6 +1590,12 @@ dump_bb_header (pretty_printer *buffer, basic_block bb, int indent, int flags)
pp_decimal_int (buffer, get_lineno (gsi_stmt (gsi)));
break;
}
+
+ if (bb->discriminator)
+ {
+ pp_string (buffer, ", discriminator ");
+ pp_decimal_int (buffer, bb->discriminator);
+ }
}
newline_and_indent (buffer, indent);
@@ -1779,6 +1762,8 @@ dump_implicit_edges (pretty_printer *buffer, basic_block bb, int indent,
pp_string (buffer, " : ");
}
pp_decimal_int (buffer, goto_xloc.line);
+ pp_string (buffer, " : ");
+ pp_decimal_int (buffer, goto_xloc.column);
pp_string (buffer, "] ");
}
diff --git a/gcc/gimple.c b/gcc/gimple.c
index e2b4fdc6cc8..44044fc7e55 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -45,7 +45,7 @@ const char *const gimple_code_name[] = {
operands vector the size of the structure minus the size of the 1
element tree array at the end (see gimple_ops). */
#define DEFGSCODE(SYM, NAME, STRUCT) (sizeof (STRUCT) - sizeof (tree)),
-const size_t gimple_ops_offset_[] = {
+EXPORTED_CONST size_t gimple_ops_offset_[] = {
#include "gimple.def"
};
#undef DEFGSCODE
@@ -102,7 +102,6 @@ gss_for_code (enum gimple_code code)
case GIMPLE_COND:
case GIMPLE_GOTO:
case GIMPLE_LABEL:
- case GIMPLE_CHANGE_DYNAMIC_TYPE:
case GIMPLE_DEBUG:
case GIMPLE_SWITCH: return GSS_WITH_OPS;
case GIMPLE_ASM: return GSS_ASM;
@@ -191,8 +190,6 @@ gimple_size (enum gimple_code code)
return sizeof (struct gimple_statement_omp_atomic_store);
case GIMPLE_WITH_CLEANUP_EXPR:
return sizeof (struct gimple_statement_wce);
- case GIMPLE_CHANGE_DYNAMIC_TYPE:
- return sizeof (struct gimple_statement_with_ops);
case GIMPLE_PREDICT:
return sizeof (struct gimple_statement_base);
default:
@@ -452,7 +449,7 @@ gimple_build_assign_with_ops_stat (enum tree_code subcode, tree lhs, tree op1,
This function returns the newly created GIMPLE_ASSIGN tuple. */
-inline gimple
+gimple
gimplify_assign (tree dst, tree src, gimple_seq *seq_p)
{
tree t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
@@ -1065,20 +1062,6 @@ gimple_build_omp_single (gimple_seq body, tree clauses)
}
-/* Build a GIMPLE_CHANGE_DYNAMIC_TYPE statement. TYPE is the new type
- for the location PTR. */
-
-gimple
-gimple_build_cdt (tree type, tree ptr)
-{
- gimple p = gimple_build_with_ops (GIMPLE_CHANGE_DYNAMIC_TYPE, ERROR_MARK, 2);
- gimple_cdt_set_new_type (p, type);
- gimple_cdt_set_location (p, ptr);
-
- return p;
-}
-
-
/* Build a GIMPLE_OMP_ATOMIC_LOAD statement. */
gimple
@@ -1483,16 +1466,6 @@ walk_gimple_op (gimple stmt, walk_tree_fn callback_op,
return ret;
break;
- case GIMPLE_CHANGE_DYNAMIC_TYPE:
- ret = walk_tree (gimple_cdt_location_ptr (stmt), callback_op, wi, pset);
- if (ret)
- return ret;
-
- ret = walk_tree (gimple_cdt_new_type_ptr (stmt), callback_op, wi, pset);
- if (ret)
- return ret;
- break;
-
case GIMPLE_ASM:
ret = walk_gimple_asm (stmt, callback_op, wi);
if (ret)
@@ -2777,7 +2750,6 @@ is_gimple_stmt (tree t)
case TRY_FINALLY_EXPR:
case EH_FILTER_EXPR:
case CATCH_EXPR:
- case CHANGE_DYNAMIC_TYPE_EXPR:
case ASM_EXPR:
case RESX_EXPR:
case STATEMENT_LIST:
@@ -3282,8 +3254,7 @@ walk_stmt_load_store_addr_ops (gimple stmt, void *data,
}
else if (visit_addr
&& (is_gimple_assign (stmt)
- || gimple_code (stmt) == GIMPLE_COND
- || gimple_code (stmt) == GIMPLE_CHANGE_DYNAMIC_TYPE))
+ || gimple_code (stmt) == GIMPLE_COND))
{
for (i = 0; i < gimple_num_ops (stmt); ++i)
if (gimple_op (stmt, i)
@@ -3321,6 +3292,11 @@ walk_stmt_load_store_addr_ops (gimple stmt, void *data,
&& 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 (gimple_call_lhs (stmt)))
+ ret |= visit_addr (stmt, gimple_call_lhs (stmt), data);
}
else if (gimple_code (stmt) == GIMPLE_ASM)
{
diff --git a/gcc/gimple.def b/gcc/gimple.def
index f4c41eca514..716f6e2acbb 100644
--- a/gcc/gimple.def
+++ b/gcc/gimple.def
@@ -81,17 +81,6 @@ DEFGSCODE(GIMPLE_LABEL, "gimple_label", struct gimple_statement_with_ops)
They must be CASE_LABEL_EXPR nodes. */
DEFGSCODE(GIMPLE_SWITCH, "gimple_switch", struct gimple_statement_with_ops)
-/* GIMPLE_CHANGE_DYNAMIC_TYPE indicates a change in the dynamic type
- of a memory location. This has no value and generates no
- executable code. It is only used for type based alias analysis.
- This is generated by C++ placement new and it's a direct
- translation from CHANGE_DYNAMIC_TYPE_EXPR. The first operand
- (gimple_cdt_new_type) is the new type. The second operand
- (gimple_cdt_location) is the location (pointer) whose type is being
- changed. */
-DEFGSCODE(GIMPLE_CHANGE_DYNAMIC_TYPE, "gimple_change_dynamic_type",
- struct gimple_statement_with_ops)
-
/* IMPORTANT.
Do not rearrange the codes between GIMPLE_ASSIGN and GIMPLE_RETURN.
diff --git a/gcc/gimple.h b/gcc/gimple.h
index 914552a76ee..c233b0314bc 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -1364,35 +1364,6 @@ gimple_modified_p (const_gimple g)
return (gimple_has_ops (g)) ? (bool) g->gsbase.modified : false;
}
-/* Return the type of the main expression computed by STMT. Return
- void_type_node if the statement computes nothing. */
-
-static inline tree
-gimple_expr_type (const_gimple stmt)
-{
- enum gimple_code code = gimple_code (stmt);
-
- if (code == GIMPLE_ASSIGN || code == GIMPLE_CALL)
- {
- tree type = TREE_TYPE (gimple_get_lhs (stmt));
- /* Integral sub-types are never the type of the expression,
- but they still can be the type of the result as the base
- type (in which expressions are computed) is trivially
- convertible to one of its sub-types. So always return
- the base type here. */
- if (INTEGRAL_TYPE_P (type)
- && TREE_TYPE (type)
- /* But only if they are trivially convertible. */
- && useless_type_conversion_p (type, TREE_TYPE (type)))
- type = TREE_TYPE (type);
- return type;
- }
- else if (code == GIMPLE_COND)
- return boolean_type_node;
- else
- return void_type_node;
-}
-
/* Return the tree code for the expression computed by STMT. This is
only valid for GIMPLE_COND, GIMPLE_CALL and GIMPLE_ASSIGN. For
@@ -4210,69 +4181,6 @@ gimple_nop_p (const_gimple g)
}
-/* Return the new type set by GIMPLE_CHANGE_DYNAMIC_TYPE statement GS. */
-
-static inline tree
-gimple_cdt_new_type (gimple gs)
-{
- GIMPLE_CHECK (gs, GIMPLE_CHANGE_DYNAMIC_TYPE);
- return gimple_op (gs, 1);
-}
-
-/* Return a pointer to the new type set by GIMPLE_CHANGE_DYNAMIC_TYPE
- statement GS. */
-
-static inline tree *
-gimple_cdt_new_type_ptr (gimple gs)
-{
- GIMPLE_CHECK (gs, GIMPLE_CHANGE_DYNAMIC_TYPE);
- return gimple_op_ptr (gs, 1);
-}
-
-/* Set NEW_TYPE to be the type returned by GIMPLE_CHANGE_DYNAMIC_TYPE
- statement GS. */
-
-static inline void
-gimple_cdt_set_new_type (gimple gs, tree new_type)
-{
- GIMPLE_CHECK (gs, GIMPLE_CHANGE_DYNAMIC_TYPE);
- gcc_assert (TREE_CODE_CLASS (TREE_CODE (new_type)) == tcc_type);
- gimple_set_op (gs, 1, new_type);
-}
-
-
-/* Return the location affected by GIMPLE_CHANGE_DYNAMIC_TYPE statement GS. */
-
-static inline tree
-gimple_cdt_location (gimple gs)
-{
- GIMPLE_CHECK (gs, GIMPLE_CHANGE_DYNAMIC_TYPE);
- return gimple_op (gs, 0);
-}
-
-
-/* Return a pointer to the location affected by GIMPLE_CHANGE_DYNAMIC_TYPE
- statement GS. */
-
-static inline tree *
-gimple_cdt_location_ptr (gimple gs)
-{
- GIMPLE_CHECK (gs, GIMPLE_CHANGE_DYNAMIC_TYPE);
- return gimple_op_ptr (gs, 0);
-}
-
-
-/* Set PTR to be the location affected by GIMPLE_CHANGE_DYNAMIC_TYPE
- statement GS. */
-
-static inline void
-gimple_cdt_set_location (gimple gs, tree ptr)
-{
- GIMPLE_CHECK (gs, GIMPLE_CHANGE_DYNAMIC_TYPE);
- gimple_set_op (gs, 0, ptr);
-}
-
-
/* Return the predictor of GIMPLE_PREDICT statement GS. */
static inline enum br_predictor
@@ -4317,6 +4225,44 @@ gimple_predict_set_outcome (gimple gs, enum prediction outcome)
}
+/* Return the type of the main expression computed by STMT. Return
+ void_type_node if the statement computes nothing. */
+
+static inline tree
+gimple_expr_type (const_gimple stmt)
+{
+ enum gimple_code code = gimple_code (stmt);
+
+ if (code == GIMPLE_ASSIGN || code == GIMPLE_CALL)
+ {
+ tree type;
+ /* In general we want to pass out a type that can be substituted
+ for both the RHS and the LHS types if there is a possibly
+ useless conversion involved. That means returning the
+ original RHS type as far as we can reconstruct it. */
+ if (code == GIMPLE_CALL)
+ type = gimple_call_return_type (stmt);
+ else
+ switch (gimple_assign_rhs_code (stmt))
+ {
+ case POINTER_PLUS_EXPR:
+ type = TREE_TYPE (gimple_assign_rhs1 (stmt));
+ break;
+
+ default:
+ /* As fallback use the type of the LHS. */
+ type = TREE_TYPE (gimple_get_lhs (stmt));
+ break;
+ }
+ return type;
+ }
+ else if (code == GIMPLE_COND)
+ return boolean_type_node;
+ else
+ return void_type_node;
+}
+
+
/* Return a new iterator pointing to GIMPLE_SEQ's first statement. */
static inline gimple_stmt_iterator
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index bff7cdd4b6f..15005c379bd 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -516,7 +516,8 @@ create_tmp_var_raw (tree type, const char *prefix)
new_type = build_type_variant (type, 0, 0);
TYPE_ATTRIBUTES (new_type) = TYPE_ATTRIBUTES (type);
- tmp_var = build_decl (VAR_DECL, prefix ? create_tmp_var_name (prefix) : NULL,
+ tmp_var = build_decl (input_location,
+ VAR_DECL, prefix ? create_tmp_var_name (prefix) : NULL,
type);
/* The variable was declared by the compiler. */
@@ -1464,7 +1465,7 @@ static enum gimplify_status
gimplify_loop_expr (tree *expr_p, gimple_seq *pre_p)
{
tree saved_label = gimplify_ctxp->exit_label;
- tree start_label = create_artificial_label ();
+ tree start_label = create_artificial_label (UNKNOWN_LOCATION);
gimplify_seq_add_stmt (pre_p, gimple_build_label (start_label));
@@ -1654,9 +1655,10 @@ gimplify_switch_expr (tree *expr_p, gimple_seq *pre_p)
{
gimple new_default;
- default_case = build3 (CASE_LABEL_EXPR, void_type_node,
- NULL_TREE, NULL_TREE,
- create_artificial_label ());
+ default_case
+ = build3 (CASE_LABEL_EXPR, void_type_node,
+ NULL_TREE, NULL_TREE,
+ create_artificial_label (UNKNOWN_LOCATION));
new_default = gimple_build_label (CASE_LABEL (default_case));
gimplify_seq_add_stmt (&switch_body_seq, new_default);
}
@@ -1707,7 +1709,7 @@ build_and_jump (tree *label_p)
if (*label_p == NULL_TREE)
{
- tree label = create_artificial_label ();
+ tree label = create_artificial_label (UNKNOWN_LOCATION);
*label_p = label;
}
@@ -1853,7 +1855,7 @@ gimplify_conversion (tree *expr_p)
{
tree tem;
gcc_assert (CONVERT_EXPR_P (*expr_p));
-
+
/* Then strip away all but the outermost conversion. */
STRIP_SIGN_NOPS (TREE_OPERAND (*expr_p, 0));
@@ -1868,8 +1870,8 @@ gimplify_conversion (tree *expr_p)
&& POINTER_TYPE_P (TREE_TYPE (*expr_p))
&& POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (*expr_p, 0)))
&& (tem = maybe_fold_offset_to_address
- (TREE_OPERAND (*expr_p, 0),
- integer_zero_node, TREE_TYPE (*expr_p))) != NULL_TREE)
+ (EXPR_LOCATION (*expr_p), TREE_OPERAND (*expr_p, 0),
+ integer_zero_node, TREE_TYPE (*expr_p))) != NULL_TREE)
*expr_p = tem;
/* If we still have a conversion at the toplevel,
@@ -2310,6 +2312,7 @@ gimplify_arg (tree *arg_p, gimple_seq *pre_p, location_t call_location)
/* If this is a variable sized type, we must remember the size. */
maybe_with_size_expr (arg_p);
+ /* FIXME diagnostics: This will mess up gcc.dg/Warray-bounds.c. */
/* Make sure arguments have the same location as the function call
itself. */
protected_set_expr_location (*arg_p, call_location);
@@ -2374,13 +2377,13 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
if (call_expr_nargs (*expr_p) < 2)
{
error ("too few arguments to function %<va_start%>");
- *expr_p = build_empty_stmt ();
+ *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
return GS_OK;
}
if (fold_builtin_next_arg (*expr_p, true))
{
- *expr_p = build_empty_stmt ();
+ *expr_p = build_empty_stmt (EXPR_LOCATION (*expr_p));
return GS_OK;
}
}
@@ -3048,7 +3051,7 @@ gimplify_cond_expr (tree *expr_p, gimple_seq *pre_p, fallback_t fallback)
have_then_clause_p = true;
}
else
- label_true = create_artificial_label ();
+ label_true = create_artificial_label (UNKNOWN_LOCATION);
if (TREE_OPERAND (expr, 2) != NULL
&& TREE_CODE (TREE_OPERAND (expr, 2)) == GOTO_EXPR
&& TREE_CODE (GOTO_DESTINATION (TREE_OPERAND (expr, 2))) == LABEL_DECL
@@ -3066,7 +3069,7 @@ gimplify_cond_expr (tree *expr_p, gimple_seq *pre_p, fallback_t fallback)
have_else_clause_p = true;
}
else
- label_false = create_artificial_label ();
+ label_false = create_artificial_label (UNKNOWN_LOCATION);
gimple_cond_get_ops_from_tree (COND_EXPR_COND (expr), &pred_code, &arm1,
&arm2);
@@ -3097,7 +3100,7 @@ gimplify_cond_expr (tree *expr_p, gimple_seq *pre_p, fallback_t fallback)
&& gimple_seq_may_fallthru (seq))
{
gimple g;
- label_cont = create_artificial_label ();
+ label_cont = create_artificial_label (UNKNOWN_LOCATION);
g = gimple_build_goto (label_cont);
@@ -3380,9 +3383,9 @@ gimplify_init_ctor_eval_range (tree object, tree lower, tree upper,
tree loop_entry_label, loop_exit_label, fall_thru_label;
tree var, var_type, cref, tmp;
- loop_entry_label = create_artificial_label ();
- loop_exit_label = create_artificial_label ();
- fall_thru_label = create_artificial_label ();
+ loop_entry_label = create_artificial_label (UNKNOWN_LOCATION);
+ loop_exit_label = create_artificial_label (UNKNOWN_LOCATION);
+ fall_thru_label = create_artificial_label (UNKNOWN_LOCATION);
/* Create and initialize the index variable. */
var_type = TREE_TYPE (upper);
@@ -4479,7 +4482,10 @@ gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
gimple_call_set_lhs (assign, *to_p);
}
else
- assign = gimple_build_assign (*to_p, *from_p);
+ {
+ assign = gimple_build_assign (*to_p, *from_p);
+ gimple_set_location (assign, EXPR_LOCATION (*expr_p));
+ }
gimplify_seq_add_stmt (pre_p, assign);
@@ -5819,7 +5825,7 @@ gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data)
else
gcc_unreachable ();
- clause = build_omp_clause (code);
+ clause = build_omp_clause (input_location, code);
OMP_CLAUSE_DECL (clause) = decl;
OMP_CLAUSE_CHAIN (clause) = *list_p;
if (private_debug)
@@ -6769,6 +6775,24 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
}
break;
+ case TARGET_MEM_REF:
+ {
+ enum gimplify_status r0 = GS_ALL_DONE, r1 = GS_ALL_DONE;
+
+ if (TMR_SYMBOL (*expr_p))
+ r0 = gimplify_expr (&TMR_SYMBOL (*expr_p), pre_p,
+ post_p, is_gimple_lvalue, fb_either);
+ else if (TMR_BASE (*expr_p))
+ r0 = gimplify_expr (&TMR_BASE (*expr_p), pre_p,
+ post_p, is_gimple_val, fb_either);
+ if (TMR_INDEX (*expr_p))
+ r1 = gimplify_expr (&TMR_INDEX (*expr_p), pre_p,
+ post_p, is_gimple_val, fb_rvalue);
+ /* TMR_STEP and TMR_OFFSET are always integer constants. */
+ ret = MIN (r0, r1);
+ }
+ break;
+
case NON_LVALUE_EXPR:
/* This should have been stripped above. */
gcc_unreachable ();
@@ -6838,19 +6862,6 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
break;
}
- case CHANGE_DYNAMIC_TYPE_EXPR:
- {
- gimple cdt;
-
- ret = gimplify_expr (&CHANGE_DYNAMIC_TYPE_LOCATION (*expr_p),
- pre_p, post_p, is_gimple_reg, fb_lvalue);
- cdt = gimple_build_cdt (CHANGE_DYNAMIC_TYPE_NEW_TYPE (*expr_p),
- CHANGE_DYNAMIC_TYPE_LOCATION (*expr_p));
- gimplify_seq_add_stmt (pre_p, cdt);
- ret = GS_ALL_DONE;
- }
- break;
-
case OBJ_TYPE_REF:
{
enum gimplify_status r0, r1;
@@ -6964,8 +6975,9 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
*/
if (TREE_CODE (TREE_OPERAND (*expr_p, 1)) == INTEGER_CST
&& (tmp = maybe_fold_offset_to_address
- (TREE_OPERAND (*expr_p, 0), TREE_OPERAND (*expr_p, 1),
- TREE_TYPE (*expr_p))))
+ (EXPR_LOCATION (*expr_p),
+ TREE_OPERAND (*expr_p, 0), TREE_OPERAND (*expr_p, 1),
+ TREE_TYPE (*expr_p))))
{
*expr_p = tmp;
break;
@@ -6976,10 +6988,11 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
&& POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (*expr_p,
0),0)))
&& (tmp = maybe_fold_offset_to_address
- (TREE_OPERAND (TREE_OPERAND (*expr_p, 0), 0),
- TREE_OPERAND (*expr_p, 1),
- TREE_TYPE (TREE_OPERAND (TREE_OPERAND (*expr_p, 0),
- 0)))))
+ (EXPR_LOCATION (*expr_p),
+ TREE_OPERAND (TREE_OPERAND (*expr_p, 0), 0),
+ TREE_OPERAND (*expr_p, 1),
+ TREE_TYPE (TREE_OPERAND (TREE_OPERAND (*expr_p, 0),
+ 0)))))
{
*expr_p = fold_convert (TREE_TYPE (*expr_p), tmp);
break;
diff --git a/gcc/graphite.c b/gcc/graphite.c
index 6b497a808f7..90e11acb3cc 100644
--- a/gcc/graphite.c
+++ b/gcc/graphite.c
@@ -181,7 +181,7 @@ register_bb_in_sese (basic_block entry_bb, basic_block exit_bb, sese region)
sese
new_sese (edge entry, edge exit)
{
- sese res = XNEW (struct sese);
+ sese res = XNEW (struct sese_d);
SESE_ENTRY (res) = entry;
SESE_EXIT (res) = exit;
@@ -274,7 +274,7 @@ static void
loop_iv_stack_push_iv (loop_iv_stack stack, tree iv, const char *name)
{
iv_stack_entry *entry = XNEW (iv_stack_entry);
- name_tree named_iv = XNEW (struct name_tree);
+ name_tree named_iv = XNEW (struct name_tree_d);
named_iv->t = iv;
named_iv->name = name;
@@ -396,7 +396,7 @@ free_loop_iv_stack (loop_iv_stack stack)
/* Structure containing the mapping between the CLooG's induction
variable and the type of the old induction variable. */
-typedef struct ivtype_map_elt
+typedef struct ivtype_map_elt_d
{
tree type;
const char *cloog_iv;
@@ -417,7 +417,7 @@ debug_ivtype_elt (ivtype_map_elt elt)
static int
debug_ivtype_map_1 (void **slot, void *s ATTRIBUTE_UNUSED)
{
- struct ivtype_map_elt *entry = (struct ivtype_map_elt *) *slot;
+ struct ivtype_map_elt_d *entry = (struct ivtype_map_elt_d *) *slot;
debug_ivtype_elt (entry);
return 1;
}
@@ -437,7 +437,7 @@ new_ivtype_map_elt (const char *cloog_iv, tree type)
{
ivtype_map_elt res;
- res = XNEW (struct ivtype_map_elt);
+ res = XNEW (struct ivtype_map_elt_d);
res->cloog_iv = cloog_iv;
res->type = type;
@@ -449,7 +449,7 @@ new_ivtype_map_elt (const char *cloog_iv, tree type)
static hashval_t
ivtype_map_elt_info (const void *elt)
{
- return htab_hash_pointer (((const struct ivtype_map_elt *) elt)->cloog_iv);
+ return htab_hash_pointer (((const struct ivtype_map_elt_d *) elt)->cloog_iv);
}
/* Compares database elements E1 and E2. */
@@ -457,8 +457,8 @@ ivtype_map_elt_info (const void *elt)
static int
eq_ivtype_map_elts (const void *e1, const void *e2)
{
- const struct ivtype_map_elt *elt1 = (const struct ivtype_map_elt *) e1;
- const struct ivtype_map_elt *elt2 = (const struct ivtype_map_elt *) e2;
+ const struct ivtype_map_elt_d *elt1 = (const struct ivtype_map_elt_d *) e1;
+ const struct ivtype_map_elt_d *elt2 = (const struct ivtype_map_elt_d *) e2;
return (elt1->cloog_iv == elt2->cloog_iv);
}
@@ -472,7 +472,7 @@ eq_ivtype_map_elts (const void *e1, const void *e2)
static tree
gcc_type_for_cloog_iv (const char *cloog_iv, graphite_bb_p gbb)
{
- struct ivtype_map_elt tmp;
+ struct ivtype_map_elt_d tmp;
PTR *slot;
tmp.cloog_iv = cloog_iv;
@@ -1339,7 +1339,7 @@ free_graphite_bb (struct graphite_bb *gbb)
/* Structure containing the mapping between the old names and the new
names used after block copy in the new loop context. */
-typedef struct rename_map_elt
+typedef struct rename_map_elt_d
{
tree old_name, new_name;
} *rename_map_elt;
@@ -1362,7 +1362,7 @@ debug_rename_elt (rename_map_elt elt)
static int
debug_rename_map_1 (void **slot, void *s ATTRIBUTE_UNUSED)
{
- struct rename_map_elt *entry = (struct rename_map_elt *) *slot;
+ struct rename_map_elt_d *entry = (struct rename_map_elt_d *) *slot;
debug_rename_elt (entry);
return 1;
}
@@ -1382,7 +1382,7 @@ new_rename_map_elt (tree old_name, tree new_name)
{
rename_map_elt res;
- res = XNEW (struct rename_map_elt);
+ res = XNEW (struct rename_map_elt_d);
res->old_name = old_name;
res->new_name = new_name;
@@ -1394,7 +1394,7 @@ new_rename_map_elt (tree old_name, tree new_name)
static hashval_t
rename_map_elt_info (const void *elt)
{
- return htab_hash_pointer (((const struct rename_map_elt *) elt)->old_name);
+ return htab_hash_pointer (((const struct rename_map_elt_d *) elt)->old_name);
}
/* Compares database elements E1 and E2. */
@@ -1402,8 +1402,8 @@ rename_map_elt_info (const void *elt)
static int
eq_rename_map_elts (const void *e1, const void *e2)
{
- const struct rename_map_elt *elt1 = (const struct rename_map_elt *) e1;
- const struct rename_map_elt *elt2 = (const struct rename_map_elt *) e2;
+ const struct rename_map_elt_d *elt1 = (const struct rename_map_elt_d *) e1;
+ const struct rename_map_elt_d *elt2 = (const struct rename_map_elt_d *) e2;
return (elt1->old_name == elt2->old_name);
}
@@ -1413,7 +1413,7 @@ eq_rename_map_elts (const void *e1, const void *e2)
static tree
get_new_name_from_old_name (htab_t map, tree old_name)
{
- struct rename_map_elt tmp;
+ struct rename_map_elt_d tmp;
PTR *slot;
tmp.old_name = old_name;
@@ -2419,7 +2419,7 @@ scop_record_loop (scop_p scop, loop_p loop)
if (!induction_var)
return false;
- oldiv = XNEW (struct name_tree);
+ oldiv = XNEW (struct name_tree_d);
oldiv->t = induction_var;
oldiv->name = get_name (SSA_NAME_VAR (oldiv->t));
oldiv->loop = loop;
@@ -2664,7 +2664,7 @@ param_index (tree var, scop_p scop)
gcc_assert (SCOP_ADD_PARAMS (scop));
- nvar = XNEW (struct name_tree);
+ nvar = XNEW (struct name_tree_d);
nvar->t = var;
nvar->name = NULL;
VEC_safe_push (name_tree, heap, SCOP_PARAMS (scop), nvar);
@@ -3224,7 +3224,7 @@ add_conditions_to_domain (graphite_bb_p gb)
}
break;
}
- case SWITCH_EXPR:
+ case GIMPLE_SWITCH:
/* Switch statements are not supported right know. */
gcc_unreachable ();
break;
@@ -4428,7 +4428,7 @@ build_iv_mapping (loop_iv_stack ivstack, htab_t map, gbb_p gbb, scop_p scop)
for (i = 0; VEC_iterate (name_tree, SCOP_OLDIVS (scop), i, iv); i++)
{
- struct rename_map_elt tmp;
+ struct rename_map_elt_d tmp;
if (!flow_bb_inside_loop_p (iv->loop, GBB_BB (gbb)))
continue;
@@ -4450,7 +4450,7 @@ build_iv_mapping (loop_iv_stack ivstack, htab_t map, gbb_p gbb, scop_p scop)
static void
register_old_and_new_names (htab_t map, tree old_name, tree new_name)
{
- struct rename_map_elt tmp;
+ struct rename_map_elt_d tmp;
PTR *slot;
tmp.old_name = old_name;
@@ -4549,7 +4549,7 @@ copy_bb_and_scalar_dependences (basic_block bb, scop_p scop,
static int
add_loop_exit_phis (void **slot, void *s)
{
- struct rename_map_elt *entry = (struct rename_map_elt *) *slot;
+ struct rename_map_elt_d *entry = (struct rename_map_elt_d *) *slot;
tree new_name = entry->new_name;
basic_block bb = (basic_block) s;
gimple phi = create_phi_node (new_name, bb);
@@ -4606,7 +4606,7 @@ default_liveout_before_guard (htab_t liveout_before_guard, tree old_name)
static int
add_guard_exit_phis (void **slot, void *s)
{
- struct rename_map_elt *entry = (struct rename_map_elt *) *slot;
+ struct rename_map_elt_d *entry = (struct rename_map_elt_d *) *slot;
struct igp *i = (struct igp *) s;
basic_block bb = i->bb;
edge true_edge = i->true_edge;
@@ -4661,11 +4661,11 @@ insert_guard_phis (scop_p scop, basic_block bb, edge true_edge,
static int
copy_renames (void **slot, void *s)
{
- struct rename_map_elt *entry = (struct rename_map_elt *) *slot;
+ struct rename_map_elt_d *entry = (struct rename_map_elt_d *) *slot;
htab_t res = (htab_t) s;
tree old_name = entry->old_name;
tree new_name = entry->new_name;
- struct rename_map_elt tmp;
+ struct rename_map_elt_d tmp;
PTR *x;
tmp.old_name = old_name;
@@ -5009,7 +5009,8 @@ remove_sese_region (sese region)
VEC_free (basic_block, heap, bbs);
}
-typedef struct ifsese {
+typedef struct ifsese_d
+{
sese region;
sese true_region;
sese false_region;
@@ -5083,10 +5084,10 @@ create_if_region_on_edge (edge entry, tree condition)
{
edge e;
edge_iterator ei;
- sese sese_region = GGC_NEW (struct sese);
- sese true_region = GGC_NEW (struct sese);
- sese false_region = GGC_NEW (struct sese);
- ifsese if_region = GGC_NEW (struct ifsese);
+ sese sese_region = GGC_NEW (struct sese_d);
+ sese true_region = GGC_NEW (struct sese_d);
+ sese false_region = GGC_NEW (struct sese_d);
+ ifsese if_region = GGC_NEW (struct ifsese_d);
edge exit = create_empty_if_region_on_edge (entry, condition);
if_region->region = sese_region;
@@ -5369,7 +5370,7 @@ compute_cloog_iv_types_1 (graphite_bb_p gbb,
for (t = user_stmt->substitutions; t; t = t->next, index++)
{
PTR *slot;
- struct ivtype_map_elt tmp;
+ struct ivtype_map_elt_d tmp;
struct clast_expr *expr = (struct clast_expr *)
((struct clast_assignment *)t)->RHS;
diff --git a/gcc/graphite.h b/gcc/graphite.h
index a2700655ea4..e663c2d0fe5 100644
--- a/gcc/graphite.h
+++ b/gcc/graphite.h
@@ -265,7 +265,7 @@ struct loop_to_cloog_loop_str
CloogLoop *cloog_loop;
};
-typedef struct name_tree
+typedef struct name_tree_d
{
tree t;
const char *name;
@@ -277,7 +277,7 @@ DEF_VEC_ALLOC_P (name_tree, heap);
/* A Single Entry, Single Exit region is a part of the CFG delimited
by two edges. */
-typedef struct sese
+typedef struct sese_d
{
/* Single ENTRY and single EXIT from the SESE region. */
edge entry, exit;
diff --git a/gcc/gstab.h b/gcc/gstab.h
index 7f82b55ec10..fccb296cd9a 100644
--- a/gcc/gstab.h
+++ b/gcc/gstab.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998, 2001 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 1998, 2001, 2009 Free Software Foundation, Inc.
This file is part of GCC.
@@ -21,12 +21,15 @@ along with GCC; see the file COPYING3. If not see
#define __define_stab(NAME, CODE, STRING) NAME=CODE,
-enum __stab_debug_code
+enum
{
#include "stab.def"
LAST_UNUSED_STAB_CODE
};
+/* stabs debug codes really are integers with expressive names. */
+typedef int stab_code_type;
+
#undef __define_stab
#endif /* ! GCC_GSTAB_H */
diff --git a/gcc/gthr-win32.h b/gcc/gthr-win32.h
index a4fd32b6a34..74ac6179c2c 100644
--- a/gcc/gthr-win32.h
+++ b/gcc/gthr-win32.h
@@ -361,15 +361,14 @@ typedef struct {
__gthread_recursive_mutex_init_function
#define __GTHREAD_RECURSIVE_MUTEX_INIT_DEFAULT {-1, 0, 0, 0}
-#if __MINGW32_MAJOR_VERSION >= 1 || \
- (__MINGW32_MAJOR_VERSION == 0 && __MINGW32_MINOR_VERSION > 2)
+#if defined (_WIN32) && !defined(__CYGWIN__)
#define MINGW32_SUPPORTS_MT_EH 1
/* Mingw runtime >= v0.3 provides a magic variable that is set to nonzero
if -mthreads option was specified, or 0 otherwise. This is to get around
the lack of weak symbols in PE-COFF. */
extern int _CRT_MT;
extern int __mingwthr_key_dtor (unsigned long, void (*) (void *));
-#endif /* __MINGW32__ version */
+#endif /* _WIN32 && !__CYGWIN__ */
/* The Windows95 kernel does not export InterlockedCompareExchange.
This provides a substitute. When building apps that reference
diff --git a/gcc/haifa-sched.c b/gcc/haifa-sched.c
index e4b24e150f5..84f48490557 100644
--- a/gcc/haifa-sched.c
+++ b/gcc/haifa-sched.c
@@ -601,7 +601,7 @@ static rtx last_scheduled_insn;
/* Compute cost of executing INSN.
This is the number of cycles between instruction issue and
instruction results. */
-HAIFA_INLINE int
+int
insn_cost (rtx insn)
{
int cost;
@@ -4899,8 +4899,6 @@ check_cfg (rtx head, rtx tail)
#endif /* ENABLE_CHECKING */
-const struct sched_scan_info_def *sched_scan_info;
-
/* Extend per basic block data structures. */
static void
extend_bb (void)
diff --git a/gcc/hooks.c b/gcc/hooks.c
index 796d915e1c6..5af3cd1c411 100644
--- a/gcc/hooks.c
+++ b/gcc/hooks.c
@@ -328,3 +328,10 @@ hook_constcharptr_int_const_tree_const_tree_null (int i ATTRIBUTE_UNUSED,
{
return NULL;
}
+
+/* Generic hook that takes a const_tree and returns NULL_TREE. */
+tree
+hook_tree_const_tree_null (const_tree t ATTRIBUTE_UNUSED)
+{
+ return NULL;
+}
diff --git a/gcc/hooks.h b/gcc/hooks.h
index 89e7f6dbf43..b057d5d6118 100644
--- a/gcc/hooks.h
+++ b/gcc/hooks.h
@@ -63,6 +63,8 @@ extern int hook_int_rtx_0 (rtx);
extern int hook_int_rtx_bool_0 (rtx, bool);
extern int hook_int_size_t_constcharptr_int_0 (size_t, const char *, int);
+extern tree hook_tree_const_tree_null (const_tree);
+
extern tree hook_tree_tree_tree_null (tree, tree);
extern tree hook_tree_tree_tree_tree_null (tree, tree, tree);
extern tree hook_tree_tree_tree_tree_3rd_identity (tree, tree, tree);
diff --git a/gcc/hwint.h b/gcc/hwint.h
index 4e0679c77b6..18085156ac2 100644
--- a/gcc/hwint.h
+++ b/gcc/hwint.h
@@ -99,6 +99,7 @@ extern char sizeof_long_long_must_be_8[sizeof(long long) == 8 ? 1 : -1];
|| (HOST_BITS_PER_LONGLONG < 64 && HOST_BITS_PER___INT64 < 64)
# define HOST_WIDEST_INT HOST_WIDE_INT
# define HOST_BITS_PER_WIDEST_INT HOST_BITS_PER_WIDE_INT
+# define HOST_WIDEST_INT_PRINT HOST_WIDE_INT_PRINT
# define HOST_WIDEST_INT_PRINT_DEC HOST_WIDE_INT_PRINT_DEC
# define HOST_WIDEST_INT_PRINT_DEC_C HOST_WIDE_INT_PRINT_DEC_C
# define HOST_WIDEST_INT_PRINT_UNSIGNED HOST_WIDE_INT_PRINT_UNSIGNED
@@ -116,6 +117,7 @@ extern char sizeof_long_long_must_be_8[sizeof(long long) == 8 ? 1 : -1];
#error "This line should be impossible to reach"
# endif
# endif
+# define HOST_WIDEST_INT_PRINT HOST_LONG_LONG_FORMAT
# define HOST_WIDEST_INT_PRINT_DEC "%" HOST_LONG_LONG_FORMAT "d"
# define HOST_WIDEST_INT_PRINT_DEC_C "%" HOST_LONG_LONG_FORMAT "dLL"
# define HOST_WIDEST_INT_PRINT_UNSIGNED "%" HOST_LONG_LONG_FORMAT "u"
diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c
index 2214c711852..faff1671c7f 100644
--- a/gcc/ifcvt.c
+++ b/gcc/ifcvt.c
@@ -62,9 +62,6 @@
#ifndef HAVE_trap
#define HAVE_trap 0
#endif
-#ifndef HAVE_conditional_trap
-#define HAVE_conditional_trap 0
-#endif
#ifndef MAX_CONDITIONAL_EXECUTE
#define MAX_CONDITIONAL_EXECUTE \
@@ -3048,7 +3045,8 @@ find_if_header (basic_block test_bb, int pass)
&& cond_exec_find_if_block (&ce_info))
goto success;
- if (HAVE_trap && HAVE_conditional_trap
+ if (HAVE_trap
+ && optab_handler (ctrap_optab, word_mode)->insn_code != CODE_FOR_nothing
&& find_cond_trap (test_bb, then_edge, else_edge))
goto success;
diff --git a/gcc/insn-notes.def b/gcc/insn-notes.def
index 16b4a275477..83161ec14b6 100644
--- a/gcc/insn-notes.def
+++ b/gcc/insn-notes.def
@@ -70,4 +70,8 @@ INSN_NOTE (BASIC_BLOCK)
between hot and cold text sections. */
INSN_NOTE (SWITCH_TEXT_SECTIONS)
+/* Mark the restore point after an epilogue changed CFI data. Used only
+ when an epilogue appears in the middle of a function. */
+INSN_NOTE (CFA_RESTORE_STATE)
+
#undef INSN_NOTE
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index 7761aab92d6..581a88a1b6c 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -1,5 +1,5 @@
/* Interprocedural constant propagation
- Copyright (C) 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+ Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
Contributed by Razya Ladelsky <RAZYA@il.ibm.com>
This file is part of GCC.
@@ -396,7 +396,7 @@ ipcp_cloning_candidate_p (struct cgraph_node *node)
cgraph_node_name (node));
return false;
}
- if (node->local.inline_summary.self_insns < n_calls)
+ if (node->local.inline_summary.self_size < n_calls)
{
if (dump_file)
fprintf (dump_file, "Considering %s for cloning; code would shrink.\n",
@@ -837,10 +837,7 @@ ipcp_update_callgraph (void)
{
next = cs->next_caller;
if (!ipcp_node_is_clone (cs->caller) && ipcp_need_redirect_p (cs))
- {
- cgraph_redirect_edge_callee (cs, orig_node);
- gimple_call_set_fndecl (cs->call_stmt, orig_node->decl);
- }
+ cgraph_redirect_edge_callee (cs, orig_node);
}
}
}
@@ -916,7 +913,7 @@ ipcp_estimate_growth (struct cgraph_node *node)
call site. Precise cost is dificult to get, as our size metric counts
constants and moves as free. Generally we are looking for cases that
small function is called very many times. */
- growth = node->local.inline_summary.self_insns
+ growth = node->local.inline_summary.self_size
- removable_args * redirectable_node_callers;
if (growth < 0)
return 0;
@@ -956,7 +953,7 @@ ipcp_estimate_cloning_cost (struct cgraph_node *node)
cost /= freq_sum * 1000 / REG_BR_PROB_BASE + 1;
if (dump_file)
fprintf (dump_file, "Cost of versioning %s is %i, (size: %i, freq: %i)\n",
- cgraph_node_name (node), cost, node->local.inline_summary.self_insns,
+ cgraph_node_name (node), cost, node->local.inline_summary.self_size,
freq_sum);
return cost + 1;
}
@@ -1012,7 +1009,7 @@ ipcp_insert_stage (void)
{
if (node->count > max_count)
max_count = node->count;
- overall_size += node->local.inline_summary.self_insns;
+ overall_size += node->local.inline_summary.self_size;
}
max_new_size = overall_size;
@@ -1201,7 +1198,7 @@ cgraph_gate_cp (void)
return flag_ipa_cp;
}
-struct ipa_opt_pass pass_ipa_cp =
+struct ipa_opt_pass_d pass_ipa_cp =
{
{
IPA_PASS,
diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
index 99640bfdb55..28f0ec9862d 100644
--- a/gcc/ipa-inline.c
+++ b/gcc/ipa-inline.c
@@ -138,6 +138,9 @@ along with GCC; see the file COPYING3. If not see
#include "tree-flow.h"
#include "rtl.h"
#include "ipa-prop.h"
+#include "except.h"
+
+#define MAX_TIME 1000000000
/* Mode incremental inliner operate on:
@@ -152,6 +155,7 @@ along with GCC; see the file COPYING3. If not see
enum inlining_mode {
INLINE_NONE = 0,
INLINE_ALWAYS_INLINE,
+ INLINE_SIZE_NORECURSIVE,
INLINE_SIZE,
INLINE_ALL
};
@@ -163,8 +167,8 @@ cgraph_decide_inlining_incrementally (struct cgraph_node *, enum inlining_mode,
/* Statistics we collect about inlining algorithm. */
static int ncalls_inlined;
static int nfunctions_inlined;
-static int overall_insns;
-static gcov_type max_count;
+static int overall_size;
+static gcov_type max_count, max_benefit;
/* Holders of ipa cgraph hooks: */
static struct cgraph_node_hook_list *function_insertion_hook_holder;
@@ -175,19 +179,30 @@ inline_summary (struct cgraph_node *node)
return &node->local.inline_summary;
}
-/* Estimate size of the function after inlining WHAT into TO. */
+/* Estimate self time of the function after inlining WHAT into TO. */
static int
-cgraph_estimate_size_after_inlining (int times, struct cgraph_node *to,
+cgraph_estimate_time_after_inlining (int frequency, struct cgraph_node *to,
struct cgraph_node *what)
{
- int size;
- tree fndecl = what->decl, arg;
- int call_insns = PARAM_VALUE (PARAM_INLINE_CALL_COST);
+ gcov_type time = (((gcov_type)what->global.time
+ - inline_summary (what)->time_inlining_benefit)
+ * frequency + CGRAPH_FREQ_BASE / 2) / CGRAPH_FREQ_BASE
+ + to->global.time;
+ if (time < 0)
+ time = 0;
+ if (time > MAX_TIME)
+ time = MAX_TIME;
+ return time;
+}
- for (arg = DECL_ARGUMENTS (fndecl); arg; arg = TREE_CHAIN (arg))
- call_insns += estimate_move_cost (TREE_TYPE (arg));
- size = (what->global.insns - call_insns) * times + to->global.insns;
+/* Estimate self time of the function after inlining WHAT into TO. */
+
+static int
+cgraph_estimate_size_after_inlining (int times, struct cgraph_node *to,
+ struct cgraph_node *what)
+{
+ int size = (what->global.size - inline_summary (what)->size_inlining_benefit) * times + to->global.size;
gcc_assert (size >= 0);
return size;
}
@@ -213,7 +228,10 @@ cgraph_clone_inlined_nodes (struct cgraph_edge *e, bool duplicate,
{
gcc_assert (!e->callee->global.inlined_to);
if (e->callee->analyzed)
- overall_insns -= e->callee->global.insns, nfunctions_inlined++;
+ {
+ overall_size -= e->callee->global.size;
+ nfunctions_inlined++;
+ }
duplicate = false;
}
else
@@ -253,12 +271,12 @@ static bool
cgraph_mark_inline_edge (struct cgraph_edge *e, bool update_original,
VEC (cgraph_edge_p, heap) **new_edges)
{
- int old_insns = 0, new_insns = 0;
+ int old_size = 0, new_size = 0;
struct cgraph_node *to = NULL, *what;
struct cgraph_edge *curr = e;
-
- if (e->callee->inline_decl)
- cgraph_redirect_edge_callee (e, cgraph_node (e->callee->inline_decl));
+ int freq;
+ bool duplicate = false;
+ int orig_size = e->callee->global.size;
gcc_assert (e->inline_failed);
e->inline_failed = CIF_OK;
@@ -267,23 +285,28 @@ cgraph_mark_inline_edge (struct cgraph_edge *e, bool update_original,
DECL_POSSIBLY_INLINED (e->callee->decl) = true;
e->callee->global.inlined = true;
+ if (e->callee->callers->next_caller
+ || e->callee->needed)
+ duplicate = true;
cgraph_clone_inlined_nodes (e, true, update_original);
what = e->callee;
+ freq = e->frequency;
/* Now update size of caller and all functions caller is inlined into. */
for (;e && !e->inline_failed; e = e->caller->callers)
{
- old_insns = e->caller->global.insns;
- new_insns = cgraph_estimate_size_after_inlining (1, e->caller,
- what);
- gcc_assert (new_insns >= 0);
to = e->caller;
- to->global.insns = new_insns;
+ old_size = e->caller->global.size;
+ new_size = cgraph_estimate_size_after_inlining (1, to, what);
+ to->global.size = new_size;
+ to->global.time = cgraph_estimate_time_after_inlining (freq, to, what);
}
gcc_assert (what->global.inlined_to == to);
- if (new_insns > old_insns)
- overall_insns += new_insns - old_insns;
+ if (new_size > old_size)
+ overall_size += new_size - old_size;
+ if (!duplicate)
+ overall_size -= orig_size;
ncalls_inlined++;
if (flag_indirect_inlining)
@@ -338,7 +361,7 @@ cgraph_estimate_growth (struct cgraph_node *node)
self_recursive = true;
if (e->inline_failed)
growth += (cgraph_estimate_size_after_inlining (1, e->caller, node)
- - e->caller->global.insns);
+ - e->caller->global.size);
}
/* ??? Wrong for non-trivially self recursive functions or cases where
@@ -346,7 +369,7 @@ cgraph_estimate_growth (struct cgraph_node *node)
as in that case we will keep the body around, but we will also avoid
some inlining. */
if (!node->needed && !DECL_EXTERNAL (node->decl) && !self_recursive)
- growth -= node->global.insns;
+ growth -= node->global.size;
node->global.estimated_growth = growth;
return growth;
@@ -381,17 +404,17 @@ cgraph_check_inline_limits (struct cgraph_node *to, struct cgraph_node *what,
/* When inlining large function body called once into small function,
take the inlined function as base for limiting the growth. */
- if (inline_summary (to)->self_insns > inline_summary(what)->self_insns)
- limit = inline_summary (to)->self_insns;
+ if (inline_summary (to)->self_size > inline_summary(what)->self_size)
+ limit = inline_summary (to)->self_size;
else
- limit = inline_summary (what)->self_insns;
+ limit = inline_summary (what)->self_size;
limit += limit * PARAM_VALUE (PARAM_LARGE_FUNCTION_GROWTH) / 100;
/* Check the size after inlining against the function limits. But allow
the function to shrink if it went over the limits by forced inlining. */
newsize = cgraph_estimate_size_after_inlining (times, to, what);
- if (newsize >= to->global.insns
+ if (newsize >= to->global.size
&& newsize > PARAM_VALUE (PARAM_LARGE_FUNCTION_INSNS)
&& newsize > limit)
{
@@ -424,8 +447,6 @@ cgraph_default_inline_p (struct cgraph_node *n, cgraph_inline_failed_t *reason)
{
tree decl = n->decl;
- if (n->inline_decl)
- decl = n->inline_decl;
if (!flag_inline_small_functions && !DECL_DECLARED_INLINE_P (decl))
{
if (reason)
@@ -442,7 +463,7 @@ cgraph_default_inline_p (struct cgraph_node *n, cgraph_inline_failed_t *reason)
if (DECL_DECLARED_INLINE_P (decl))
{
- if (n->global.insns >= MAX_INLINE_INSNS_SINGLE)
+ if (n->global.size >= MAX_INLINE_INSNS_SINGLE)
{
if (reason)
*reason = CIF_MAX_INLINE_INSNS_SINGLE_LIMIT;
@@ -451,7 +472,7 @@ cgraph_default_inline_p (struct cgraph_node *n, cgraph_inline_failed_t *reason)
}
else
{
- if (n->global.insns >= MAX_INLINE_INSNS_AUTO)
+ if (n->global.size >= MAX_INLINE_INSNS_AUTO)
{
if (reason)
*reason = CIF_MAX_INLINE_INSNS_AUTO_LIMIT;
@@ -493,11 +514,11 @@ cgraph_recursive_inlining_p (struct cgraph_node *to,
static int
cgraph_edge_badness (struct cgraph_edge *edge)
{
- int badness;
+ gcov_type badness;
int growth =
cgraph_estimate_size_after_inlining (1, edge->caller, edge->callee);
- growth -= edge->caller->global.insns;
+ growth -= edge->caller->global.size;
/* Always prefer inlining saving code size. */
if (growth <= 0)
@@ -506,7 +527,8 @@ cgraph_edge_badness (struct cgraph_edge *edge)
/* When profiling is available, base priorities -(#calls / growth).
So we optimize for overall number of "executed" inlined calls. */
else if (max_count)
- badness = ((int)((double)edge->count * INT_MIN / max_count)) / growth;
+ badness = ((int)((double)edge->count * INT_MIN / max_count / (max_benefit + 1))
+ * (inline_summary (edge->callee)->time_inlining_benefit + 1)) / growth;
/* When function local profile is available, base priorities on
growth / frequency, so we optimize for overall frequency of inlined
@@ -519,21 +541,23 @@ cgraph_edge_badness (struct cgraph_edge *edge)
of the same size gets priority). */
else if (flag_guess_branch_prob)
{
- int div = edge->frequency * 100 / CGRAPH_FREQ_BASE;
- int growth =
- cgraph_estimate_size_after_inlining (1, edge->caller, edge->callee);
- growth -= edge->caller->global.insns;
- badness = growth * 256;
+ int div = edge->frequency * 100 / CGRAPH_FREQ_BASE + 1;
+ badness = growth * 10000;
+ div *= MIN (100 * inline_summary (edge->callee)->time_inlining_benefit
+ / (edge->callee->global.time + 1) + 1, 100);
+
/* Decrease badness if call is nested. */
/* Compress the range so we don't overflow. */
- if (div > 256)
- div = 256 + ceil_log2 (div) - 8;
+ if (div > 10000)
+ div = 10000 + ceil_log2 (div) - 8;
if (div < 1)
div = 1;
if (badness > 0)
badness /= div;
badness += cgraph_estimate_growth (edge->callee);
+ if (badness > INT_MAX)
+ badness = INT_MAX;
}
/* When function local profile is not available or it does not give
useful information (ie frequency is zero), base the cost on
@@ -766,8 +790,9 @@ cgraph_decide_recursive_inlining (struct cgraph_node *node,
fibheap_delete (heap);
if (dump_file)
fprintf (dump_file,
- "\n Inlined %i times, body grown from %i to %i insns\n", n,
- master_clone->global.insns, node->global.insns);
+ "\n Inlined %i times, body grown from size %i to %i, time %i to %i\n", n,
+ master_clone->global.size, node->global.size,
+ master_clone->global.time, node->global.time);
/* Remove master clone we used for inlining. We rely that clones inlined
into master clone gets queued just before master clone so we don't
@@ -845,7 +870,7 @@ cgraph_decide_inlining_of_small_functions (void)
cgraph_inline_failed_t failed_reason;
fibheap_t heap = fibheap_new ();
bitmap updated_nodes = BITMAP_ALLOC (NULL);
- int min_insns, max_insns;
+ int min_size, max_size;
VEC (cgraph_edge_p, heap) *new_indirect_edges = NULL;
if (flag_indirect_inlining)
@@ -879,26 +904,26 @@ cgraph_decide_inlining_of_small_functions (void)
}
}
- max_insns = compute_max_insns (overall_insns);
- min_insns = overall_insns;
+ max_size = compute_max_insns (overall_size);
+ min_size = overall_size;
- while (overall_insns <= max_insns
+ while (overall_size <= max_size
&& (edge = (struct cgraph_edge *) fibheap_extract_min (heap)))
{
- int old_insns = overall_insns;
+ int old_size = overall_size;
struct cgraph_node *where;
int growth =
cgraph_estimate_size_after_inlining (1, edge->caller, edge->callee);
cgraph_inline_failed_t not_good = CIF_OK;
- growth -= edge->caller->global.insns;
+ growth -= edge->caller->global.size;
if (dump_file)
{
fprintf (dump_file,
- "\nConsidering %s with %i insns\n",
+ "\nConsidering %s with %i size\n",
cgraph_node_name (edge->callee),
- edge->callee->global.insns);
+ edge->callee->global.size);
fprintf (dump_file,
" to be inlined into %s in %s:%i\n"
" Estimated growth after inlined into all callees is %+i insns.\n"
@@ -1040,19 +1065,20 @@ cgraph_decide_inlining_of_small_functions (void)
if (dump_file)
{
fprintf (dump_file,
- " Inlined into %s which now has %i insns,"
- "net change of %+i insns.\n",
+ " Inlined into %s which now has size %i and self time %i,"
+ "net change of %+i.\n",
cgraph_node_name (edge->caller),
- edge->caller->global.insns,
- overall_insns - old_insns);
+ edge->caller->global.time,
+ edge->caller->global.size,
+ overall_size - old_size);
}
- if (min_insns > overall_insns)
+ if (min_size > overall_size)
{
- min_insns = overall_insns;
- max_insns = compute_max_insns (min_insns);
+ min_size = overall_size;
+ max_size = compute_max_insns (min_size);
if (dump_file)
- fprintf (dump_file, "New minimal insns reached: %i\n", min_insns);
+ fprintf (dump_file, "New minimal size reached: %i\n", min_size);
}
}
while ((edge = (struct cgraph_edge *) fibheap_extract_min (heap)) != NULL)
@@ -1081,34 +1107,38 @@ cgraph_decide_inlining (void)
int nnodes;
struct cgraph_node **order =
XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
- int old_insns = 0;
+ int old_size = 0;
int i;
- int initial_insns = 0;
bool redo_always_inline = true;
+ int initial_size = 0;
cgraph_remove_function_insertion_hook (function_insertion_hook_holder);
max_count = 0;
+ max_benefit = 0;
for (node = cgraph_nodes; node; node = node->next)
- if (node->analyzed && (node->needed || node->reachable))
+ if (node->analyzed)
{
struct cgraph_edge *e;
- initial_insns += inline_summary (node)->self_insns;
- gcc_assert (inline_summary (node)->self_insns == node->global.insns);
+ gcc_assert (inline_summary (node)->self_size == node->global.size);
+ gcc_assert (node->needed || node->reachable);
+ initial_size += node->global.size;
for (e = node->callees; e; e = e->next_callee)
if (max_count < e->count)
max_count = e->count;
+ if (max_benefit < inline_summary (node)->time_inlining_benefit)
+ max_benefit = inline_summary (node)->time_inlining_benefit;
}
- overall_insns = initial_insns;
gcc_assert (!max_count || (profile_info && flag_branch_probabilities));
+ overall_size = initial_size;
nnodes = cgraph_postorder (order);
if (dump_file)
fprintf (dump_file,
- "\nDeciding on inlining. Starting with %i insns.\n",
- initial_insns);
+ "\nDeciding on inlining. Starting with size %i.\n",
+ initial_size);
for (node = cgraph_nodes; node; node = node->next)
node->aux = 0;
@@ -1142,9 +1172,9 @@ cgraph_decide_inlining (void)
continue;
if (dump_file)
fprintf (dump_file,
- "\nConsidering %s %i insns (always inline)\n",
- cgraph_node_name (node), node->global.insns);
- old_insns = overall_insns;
+ "\nConsidering %s size:%i (always inline)\n",
+ cgraph_node_name (node), node->global.size);
+ old_size = overall_size;
for (e = node->callers; e; e = next)
{
next = e->next_caller;
@@ -1163,9 +1193,9 @@ cgraph_decide_inlining (void)
redo_always_inline = true;
if (dump_file)
fprintf (dump_file,
- " Inlined into %s which now has %i insns.\n",
+ " Inlined into %s which now has size %i.\n",
cgraph_node_name (e->caller),
- e->caller->global.insns);
+ e->caller->global.size);
}
/* Inlining self recursive function might introduce new calls to
themselves we didn't see in the loop above. Fill in the proper
@@ -1175,8 +1205,8 @@ cgraph_decide_inlining (void)
e->inline_failed = CIF_RECURSIVE_INLINING;
if (dump_file)
fprintf (dump_file,
- " Inlined for a net change of %+i insns.\n",
- overall_insns - old_insns);
+ " Inlined for a net change of %+i size.\n",
+ overall_size - old_size);
}
}
@@ -1201,30 +1231,29 @@ cgraph_decide_inlining (void)
&& !DECL_EXTERNAL (node->decl)
&& !DECL_COMDAT (node->decl))
{
+ old_size = overall_size;
if (dump_file)
{
fprintf (dump_file,
- "\nConsidering %s %i insns.\n",
- cgraph_node_name (node), node->global.insns);
+ "\nConsidering %s size %i.\n",
+ cgraph_node_name (node), node->global.size);
fprintf (dump_file,
" Called once from %s %i insns.\n",
cgraph_node_name (node->callers->caller),
- node->callers->caller->global.insns);
+ node->callers->caller->global.size);
}
- old_insns = overall_insns;
-
if (cgraph_check_inline_limits (node->callers->caller, node,
NULL, false))
{
cgraph_mark_inline (node->callers);
if (dump_file)
fprintf (dump_file,
- " Inlined into %s which now has %i insns"
- " for a net change of %+i insns.\n",
+ " Inlined into %s which now has %i size"
+ " for a net change of %+i size.\n",
cgraph_node_name (node->callers->caller),
- node->callers->caller->global.insns,
- overall_insns - old_insns);
+ node->callers->caller->global.size,
+ overall_size - old_size);
}
else
{
@@ -1243,9 +1272,9 @@ cgraph_decide_inlining (void)
if (dump_file)
fprintf (dump_file,
"\nInlined %i calls, eliminated %i functions, "
- "%i insns turned to %i insns.\n\n",
- ncalls_inlined, nfunctions_inlined, initial_insns,
- overall_insns);
+ "size %i turned to %i size.\n\n",
+ ncalls_inlined, nfunctions_inlined, initial_size,
+ overall_size);
free (order);
return 0;
}
@@ -1269,6 +1298,7 @@ try_inline (struct cgraph_edge *e, enum inlining_mode mode, int depth)
struct cgraph_node *callee = e->callee;
enum inlining_mode callee_mode = (enum inlining_mode) (size_t) callee->aux;
bool always_inline = e->callee->local.disregard_inline_limits;
+ bool inlined = false;
/* We've hit cycle? */
if (callee_mode)
@@ -1323,8 +1353,23 @@ try_inline (struct cgraph_edge *e, enum inlining_mode mode, int depth)
if (mode == INLINE_ALL || always_inline)
cgraph_decide_inlining_incrementally (e->callee, mode, depth + 1);
+ inlined = true;
}
callee->aux = (void *)(size_t) callee_mode;
+ return inlined;
+}
+
+/* Return true when N is leaf function. Accept cheap (pure&const) builtins
+ in leaf functions. */
+static bool
+leaf_node_p (struct cgraph_node *n)
+{
+ struct cgraph_edge *e;
+ for (e = n->callees; e; e = e->next_callee)
+ if (!DECL_BUILT_IN (e->callee->decl)
+ || (!TREE_READONLY (e->callee->decl)
+ || DECL_PURE_P (e->callee->decl)))
+ return false;
return true;
}
@@ -1348,7 +1393,7 @@ cgraph_decide_inlining_incrementally (struct cgraph_node *node,
old_mode = (enum inlining_mode) (size_t)node->aux;
- if (mode != INLINE_ALWAYS_INLINE
+ if (mode != INLINE_ALWAYS_INLINE && mode != INLINE_SIZE_NORECURSIVE
&& lookup_attribute ("flatten", DECL_ATTRIBUTES (node->decl)) != NULL)
{
if (dump_file)
@@ -1362,74 +1407,76 @@ cgraph_decide_inlining_incrementally (struct cgraph_node *node,
node->aux = (void *)(size_t) mode;
/* First of all look for always inline functions. */
- for (e = node->callees; e; e = e->next_callee)
- {
- if (!e->callee->local.disregard_inline_limits
- && (mode != INLINE_ALL || !e->callee->local.inlinable))
- continue;
- if (gimple_call_cannot_inline_p (e->call_stmt))
- continue;
- /* When the edge is already inlined, we just need to recurse into
- it in order to fully flatten the leaves. */
- if (!e->inline_failed && mode == INLINE_ALL)
- {
- inlined |= try_inline (e, mode, depth);
- continue;
- }
- if (dump_file)
- {
- indent_to (dump_file, depth);
- fprintf (dump_file,
- "Considering to always inline inline candidate %s.\n",
- cgraph_node_name (e->callee));
- }
- if (cgraph_recursive_inlining_p (node, e->callee, &e->inline_failed))
- {
- if (dump_file)
- {
- indent_to (dump_file, depth);
- fprintf (dump_file, "Not inlining: recursive call.\n");
- }
+ if (mode != INLINE_SIZE_NORECURSIVE)
+ for (e = node->callees; e; e = e->next_callee)
+ {
+ if (!e->callee->local.disregard_inline_limits
+ && (mode != INLINE_ALL || !e->callee->local.inlinable))
continue;
- }
- if (!tree_can_inline_p (node->decl, e->callee->decl))
- {
- gimple_call_set_cannot_inline (e->call_stmt, true);
- if (dump_file)
- {
- indent_to (dump_file, depth);
- fprintf (dump_file,
- "Not inlining: Target specific option mismatch.\n");
- }
+ if (gimple_call_cannot_inline_p (e->call_stmt))
continue;
- }
- if (gimple_in_ssa_p (DECL_STRUCT_FUNCTION (node->decl))
- != gimple_in_ssa_p (DECL_STRUCT_FUNCTION (e->callee->decl)))
- {
- if (dump_file)
- {
- indent_to (dump_file, depth);
- fprintf (dump_file, "Not inlining: SSA form does not match.\n");
- }
- continue;
- }
- if (!e->callee->analyzed && !e->callee->inline_decl)
- {
- if (dump_file)
- {
- indent_to (dump_file, depth);
- fprintf (dump_file,
- "Not inlining: Function body no longer available.\n");
- }
- continue;
- }
- inlined |= try_inline (e, mode, depth);
- }
+ /* When the edge is already inlined, we just need to recurse into
+ it in order to fully flatten the leaves. */
+ if (!e->inline_failed && mode == INLINE_ALL)
+ {
+ inlined |= try_inline (e, mode, depth);
+ continue;
+ }
+ if (dump_file)
+ {
+ indent_to (dump_file, depth);
+ fprintf (dump_file,
+ "Considering to always inline inline candidate %s.\n",
+ cgraph_node_name (e->callee));
+ }
+ if (cgraph_recursive_inlining_p (node, e->callee, &e->inline_failed))
+ {
+ if (dump_file)
+ {
+ indent_to (dump_file, depth);
+ fprintf (dump_file, "Not inlining: recursive call.\n");
+ }
+ continue;
+ }
+ if (!tree_can_inline_p (node->decl, e->callee->decl))
+ {
+ gimple_call_set_cannot_inline (e->call_stmt, true);
+ if (dump_file)
+ {
+ indent_to (dump_file, depth);
+ fprintf (dump_file,
+ "Not inlining: Target specific option mismatch.\n");
+ }
+ continue;
+ }
+ if (gimple_in_ssa_p (DECL_STRUCT_FUNCTION (node->decl))
+ != gimple_in_ssa_p (DECL_STRUCT_FUNCTION (e->callee->decl)))
+ {
+ if (dump_file)
+ {
+ indent_to (dump_file, depth);
+ fprintf (dump_file, "Not inlining: SSA form does not match.\n");
+ }
+ continue;
+ }
+ if (!e->callee->analyzed)
+ {
+ if (dump_file)
+ {
+ indent_to (dump_file, depth);
+ fprintf (dump_file,
+ "Not inlining: Function body no longer available.\n");
+ }
+ continue;
+ }
+ inlined |= try_inline (e, mode, depth);
+ }
/* Now do the automatic inlining. */
if (mode != INLINE_ALL && mode != INLINE_ALWAYS_INLINE)
for (e = node->callees; e; e = e->next_callee)
{
+ int allowed_growth = 0;
if (!e->callee->local.inlinable
|| !e->inline_failed
|| e->callee->local.disregard_inline_limits)
@@ -1456,29 +1503,33 @@ cgraph_decide_inlining_incrementally (struct cgraph_node *node,
}
continue;
}
+
+ if (cgraph_maybe_hot_edge_p (e) && leaf_node_p (e->callee))
+ allowed_growth = PARAM_VALUE (PARAM_EARLY_INLINING_INSNS);
+
/* When the function body would grow and inlining the function won't
eliminate the need for offline copy of the function, don't inline.
*/
- if ((mode == INLINE_SIZE
+ if (((mode == INLINE_SIZE || mode == INLINE_SIZE_NORECURSIVE)
|| (!flag_inline_functions
&& !DECL_DECLARED_INLINE_P (e->callee->decl)))
&& (cgraph_estimate_size_after_inlining (1, e->caller, e->callee)
- > e->caller->global.insns)
- && cgraph_estimate_growth (e->callee) > 0)
+ > e->caller->global.size + allowed_growth)
+ && cgraph_estimate_growth (e->callee) > allowed_growth)
{
if (dump_file)
{
indent_to (dump_file, depth);
fprintf (dump_file,
- "Not inlining: code size would grow by %i insns.\n",
+ "Not inlining: code size would grow by %i.\n",
cgraph_estimate_size_after_inlining (1, e->caller,
e->callee)
- - e->caller->global.insns);
+ - e->caller->global.size);
}
continue;
}
if (!cgraph_check_inline_limits (node, e->callee, &e->inline_failed,
- false)
+ false)
|| gimple_call_cannot_inline_p (e->call_stmt))
{
if (dump_file)
@@ -1489,7 +1540,7 @@ cgraph_decide_inlining_incrementally (struct cgraph_node *node,
}
continue;
}
- if (!e->callee->analyzed && !e->callee->inline_decl)
+ if (!e->callee->analyzed)
{
if (dump_file)
{
@@ -1531,15 +1582,22 @@ cgraph_early_inlining (void)
{
struct cgraph_node *node = cgraph_node (current_function_decl);
unsigned int todo = 0;
+ int iterations = 0;
if (sorrycount || errorcount)
return 0;
- if (cgraph_decide_inlining_incrementally (node, INLINE_SIZE, 0))
+ while (cgraph_decide_inlining_incrementally (node,
+ iterations
+ ? INLINE_SIZE_NORECURSIVE : INLINE_SIZE, 0)
+ && iterations < PARAM_VALUE (PARAM_EARLY_INLINER_MAX_ITERATIONS))
{
timevar_push (TV_INTEGRATION);
- todo = optimize_inline_calls (current_function_decl);
+ todo |= optimize_inline_calls (current_function_decl);
+ iterations++;
timevar_pop (TV_INTEGRATION);
}
+ if (dump_file)
+ fprintf (dump_file, "Iterations: %i\n", iterations);
cfun->always_inline_functions_inlined = true;
return todo;
}
@@ -1600,6 +1658,178 @@ struct simple_ipa_opt_pass pass_ipa_early_inline =
}
};
+/* See if statement might disappear after inlining. We are not terribly
+ sophisficated, basically looking for simple abstraction penalty wrappers. */
+
+static bool
+likely_eliminated_by_inlining_p (gimple stmt)
+{
+ enum gimple_code code = gimple_code (stmt);
+ switch (code)
+ {
+ case GIMPLE_RETURN:
+ return true;
+ case GIMPLE_ASSIGN:
+ if (gimple_num_ops (stmt) != 2)
+ return false;
+
+ /* Casts of parameters, loads from parameters passed by reference
+ and stores to return value or parameters are probably free after
+ inlining. */
+ if (gimple_assign_rhs_code (stmt) == CONVERT_EXPR
+ || gimple_assign_rhs_code (stmt) == NOP_EXPR
+ || gimple_assign_rhs_code (stmt) == VIEW_CONVERT_EXPR
+ || gimple_assign_rhs_class (stmt) == GIMPLE_SINGLE_RHS)
+ {
+ tree rhs = gimple_assign_rhs1 (stmt);
+ tree lhs = gimple_assign_lhs (stmt);
+ tree inner_rhs = rhs;
+ tree inner_lhs = lhs;
+ bool rhs_free = false;
+ bool lhs_free = false;
+
+ while (handled_component_p (inner_lhs) || TREE_CODE (inner_lhs) == INDIRECT_REF)
+ inner_lhs = TREE_OPERAND (inner_lhs, 0);
+ while (handled_component_p (inner_rhs)
+ || TREE_CODE (inner_rhs) == ADDR_EXPR || TREE_CODE (inner_rhs) == INDIRECT_REF)
+ inner_rhs = TREE_OPERAND (inner_rhs, 0);
+
+
+ if (TREE_CODE (inner_rhs) == PARM_DECL
+ || (TREE_CODE (inner_rhs) == SSA_NAME
+ && SSA_NAME_IS_DEFAULT_DEF (inner_rhs)
+ && TREE_CODE (SSA_NAME_VAR (inner_rhs)) == PARM_DECL))
+ rhs_free = true;
+ if (rhs_free && is_gimple_reg (lhs))
+ lhs_free = true;
+ if (((TREE_CODE (inner_lhs) == PARM_DECL
+ || (TREE_CODE (inner_lhs) == SSA_NAME
+ && SSA_NAME_IS_DEFAULT_DEF (inner_lhs)
+ && TREE_CODE (SSA_NAME_VAR (inner_lhs)) == PARM_DECL))
+ && inner_lhs != lhs)
+ || TREE_CODE (inner_lhs) == RESULT_DECL
+ || (TREE_CODE (inner_lhs) == SSA_NAME
+ && TREE_CODE (SSA_NAME_VAR (inner_lhs)) == RESULT_DECL))
+ lhs_free = true;
+ if (lhs_free && (is_gimple_reg (rhs) || is_gimple_min_invariant (rhs)))
+ rhs_free = true;
+ if (lhs_free && rhs_free)
+ return true;
+ }
+ return false;
+ default:
+ return false;
+ }
+}
+
+/* Compute function body size parameters for NODE. */
+
+static void
+estimate_function_body_sizes (struct cgraph_node *node)
+{
+ gcov_type time = 0;
+ gcov_type time_inlining_benefit = 0;
+ int size = 0;
+ int size_inlining_benefit = 0;
+ basic_block bb;
+ gimple_stmt_iterator bsi;
+ struct function *my_function = DECL_STRUCT_FUNCTION (node->decl);
+ tree arg;
+ int freq;
+ tree funtype = TREE_TYPE (node->decl);
+ bitmap must_not_throw = must_not_throw_labels ();
+
+ if (dump_file)
+ {
+ fprintf (dump_file, "Analyzing function body size: %s\n", cgraph_node_name (node));
+ }
+
+ gcc_assert (my_function && my_function->cfg);
+ FOR_EACH_BB_FN (bb, my_function)
+ {
+ freq = compute_call_stmt_bb_frequency (node->decl, bb);
+ for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
+ {
+ int this_size = estimate_num_insns (gsi_stmt (bsi), &eni_size_weights);
+ int this_time = estimate_num_insns (gsi_stmt (bsi), &eni_time_weights);
+
+ /* MUST_NOT_THROW is usually handled by runtime calling terminate and stopping
+ stacking unwinding. However when there is local cleanup that can resume
+ to MUST_NOT_THROW then we generate explicit handler containing
+ std::terminate () call.
+
+ Because inlining of function can introduce new cleanup region, prior
+ inlining we keep std::terinate () calls for every MUST_NOT_THROW containing
+ function call. Wast majority of these will be eliminated after inlining
+ and crossjumping will inify possible duplicated calls. So ignore
+ the handlers for function body estimates. */
+ if (gimple_code (gsi_stmt (bsi)) == GIMPLE_LABEL
+ && bitmap_bit_p (must_not_throw,
+ LABEL_DECL_UID (gimple_label_label (gsi_stmt (bsi)))))
+ {
+ if (dump_file)
+ fprintf (dump_file, " MUST_NOT_THROW landing pad. Ignoring whole BB.\n");
+ }
+ if (dump_file)
+ {
+ fprintf (dump_file, " freq:%6i size:%3i time:%3i ", freq, this_size, this_time);
+ print_gimple_stmt (dump_file, gsi_stmt (bsi), 0, 0);
+ }
+ this_time *= freq;
+ time += this_time;
+ size += this_size;
+ if (likely_eliminated_by_inlining_p (gsi_stmt (bsi)))
+ {
+ size_inlining_benefit += this_size;
+ time_inlining_benefit += this_time;
+ if (dump_file)
+ fprintf (dump_file, " Likely eliminated\n");
+ }
+ gcc_assert (time >= 0);
+ gcc_assert (size >= 0);
+ }
+ }
+ time = (time + CGRAPH_FREQ_BASE / 2) / CGRAPH_FREQ_BASE;
+ time_inlining_benefit = ((time_inlining_benefit + CGRAPH_FREQ_BASE / 2)
+ / CGRAPH_FREQ_BASE);
+ if (dump_file)
+ {
+ fprintf (dump_file, "Overall function body time: %i-%i size: %i-%i\n",
+ (int)time, (int)time_inlining_benefit,
+ size, size_inlining_benefit);
+ }
+ time_inlining_benefit += eni_time_weights.call_cost;
+ size_inlining_benefit += eni_size_weights.call_cost;
+ if (!VOID_TYPE_P (TREE_TYPE (funtype)))
+ {
+ int cost = estimate_move_cost (TREE_TYPE (funtype));
+ time_inlining_benefit += cost;
+ size_inlining_benefit += cost;
+ }
+ for (arg = DECL_ARGUMENTS (node->decl); arg; arg = TREE_CHAIN (arg))
+ if (!VOID_TYPE_P (TREE_TYPE (arg)))
+ {
+ int cost = estimate_move_cost (TREE_TYPE (arg));
+ time_inlining_benefit += cost;
+ size_inlining_benefit += cost;
+ }
+ if (time_inlining_benefit > MAX_TIME)
+ time_inlining_benefit = MAX_TIME;
+ if (time > MAX_TIME)
+ time = MAX_TIME;
+ inline_summary (node)->self_time = time;
+ inline_summary (node)->self_size = size;
+ if (dump_file)
+ {
+ fprintf (dump_file, "With function call overhead time: %i-%i size: %i-%i\n",
+ (int)time, (int)time_inlining_benefit,
+ size, size_inlining_benefit);
+ }
+ inline_summary (node)->time_inlining_benefit = time_inlining_benefit;
+ inline_summary (node)->size_inlining_benefit = size_inlining_benefit;
+ BITMAP_FREE (must_not_throw);
+}
+
/* Compute parameters of functions used by inliner. */
unsigned int
compute_inline_parameters (struct cgraph_node *node)
@@ -1617,19 +1847,13 @@ compute_inline_parameters (struct cgraph_node *node)
/* Can this function be inlined at all? */
node->local.inlinable = tree_inlinable_function_p (current_function_decl);
-
- /* Estimate the number of instructions for this function.
- ??? At -O0 we don't use this information except for the dumps, and
- even then only for always_inline functions. But disabling this
- causes ICEs in the inline heuristics... */
- inline_summary (node)->self_insns
- = estimate_num_insns_fn (current_function_decl, &eni_inlining_weights);
if (node->local.inlinable && !node->local.disregard_inline_limits)
node->local.disregard_inline_limits
= DECL_DISREGARD_INLINE_LIMITS (current_function_decl);
-
+ estimate_function_body_sizes (node);
/* Inlining characteristics are maintained by the cgraph_mark_inline. */
- node->global.insns = inline_summary (node)->self_insns;
+ node->global.time = inline_summary (node)->self_time;
+ node->global.size = inline_summary (node)->self_size;
return 0;
}
@@ -1647,7 +1871,7 @@ struct gimple_opt_pass pass_inline_parameters =
{
{
GIMPLE_PASS,
- NULL, /* name */
+ "inline_param", /* name */
NULL, /* gate */
compute_inline_parameters_for_current,/* execute */
NULL, /* sub */
@@ -1762,7 +1986,7 @@ inline_transform (struct cgraph_node *node)
return todo | execute_fixup_cfg ();
}
-struct ipa_opt_pass pass_ipa_inline =
+struct ipa_opt_pass_d pass_ipa_inline =
{
{
IPA_PASS,
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index f4fa37d5a05..a376f45c7b3 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -172,48 +172,30 @@ ipa_initialize_node_params (struct cgraph_node *node)
}
}
-/* Check STMT to detect whether a formal parameter is directly modified within
- STMT, the appropriate entry is updated in the modified flags of INFO.
- Directly means that this function does not check for modifications through
- pointers or escaping addresses because all TREE_ADDRESSABLE parameters are
- considered modified anyway. */
+/* Callback of walk_stmt_load_store_addr_ops for the visit_store and visit_addr
+ parameters. If OP is a parameter declaration, mark it as modified in the
+ info structure passed in DATA. */
-static void
-ipa_check_stmt_modifications (struct ipa_node_params *info, gimple stmt)
+static bool
+visit_store_addr_for_mod_analysis (gimple stmt ATTRIBUTE_UNUSED,
+ tree op, void *data)
{
- int j;
- int index;
- tree lhs;
+ struct ipa_node_params *info = (struct ipa_node_params *) data;
- switch (gimple_code (stmt))
+ if (TREE_CODE (op) == PARM_DECL)
{
- case GIMPLE_ASSIGN:
- lhs = gimple_assign_lhs (stmt);
-
- while (handled_component_p (lhs))
- lhs = TREE_OPERAND (lhs, 0);
- if (TREE_CODE (lhs) == SSA_NAME)
- lhs = SSA_NAME_VAR (lhs);
- index = ipa_get_param_decl_index (info, lhs);
- if (index >= 0)
- info->params[index].modified = true;
- break;
-
- case GIMPLE_ASM:
- /* Asm code could modify any of the parameters. */
- for (j = 0; j < ipa_get_param_count (info); j++)
- info->params[j].modified = true;
- break;
-
- default:
- break;
+ int index = ipa_get_param_decl_index (info, op);
+ gcc_assert (index >= 0);
+ info->params[index].modified = true;
}
+
+ return false;
}
/* Compute which formal parameters of function associated with NODE are locally
- modified. Parameters may be modified in NODE if they are TREE_ADDRESSABLE,
- if they appear on the left hand side of an assignment or if there is an
- ASM_EXPR in the function. */
+ modified or their address is taken. Note that this does not apply on
+ parameters with SSA names but those can and should be analyzed
+ differently. */
void
ipa_detect_param_modifications (struct cgraph_node *node)
@@ -222,27 +204,17 @@ ipa_detect_param_modifications (struct cgraph_node *node)
basic_block bb;
struct function *func;
gimple_stmt_iterator gsi;
- gimple stmt;
struct ipa_node_params *info = IPA_NODE_REF (node);
- int i, count;
if (ipa_get_param_count (info) == 0 || info->modification_analysis_done)
return;
func = DECL_STRUCT_FUNCTION (decl);
FOR_EACH_BB_FN (bb, func)
- {
- for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
- {
- stmt = gsi_stmt (gsi);
- ipa_check_stmt_modifications (info, stmt);
- }
- }
-
- count = ipa_get_param_count (info);
- for (i = 0; i < count; i++)
- if (TREE_ADDRESSABLE (ipa_get_param (info, i)))
- info->params[i].modified = true;
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ walk_stmt_load_store_addr_ops (gsi_stmt (gsi), info, NULL,
+ visit_store_addr_for_mod_analysis,
+ visit_store_addr_for_mod_analysis);
info->modification_analysis_done = 1;
}
@@ -456,6 +428,24 @@ fill_member_ptr_cst_jump_function (struct ipa_jump_func *jfunc,
jfunc->value.member_cst.delta = delta;
}
+/* If RHS is an SSA_NAMe and it is defined by a simple copy assign statement,
+ return the rhs of its defining statement. */
+
+static inline tree
+get_ssa_def_if_simple_copy (tree rhs)
+{
+ while (TREE_CODE (rhs) == SSA_NAME && !SSA_NAME_IS_DEFAULT_DEF (rhs))
+ {
+ gimple def_stmt = SSA_NAME_DEF_STMT (rhs);
+
+ if (gimple_assign_single_p (def_stmt))
+ rhs = gimple_assign_rhs1 (def_stmt);
+ else
+ break;
+ }
+ return rhs;
+}
+
/* Traverse statements from CALL backwards, scanning whether the argument ARG
which is a member pointer is filled in with constant values. If it is, fill
the jump function JFUNC in appropriately. METHOD_FIELD and DELTA_FIELD are
@@ -482,7 +472,7 @@ determine_cst_member_ptr (gimple call, tree arg, tree method_field,
gimple stmt = gsi_stmt (gsi);
tree lhs, rhs, fld;
- if (!is_gimple_assign (stmt) || gimple_num_ops (stmt) != 2)
+ if (!gimple_assign_single_p (stmt))
return;
lhs = gimple_assign_lhs (stmt);
@@ -495,6 +485,7 @@ determine_cst_member_ptr (gimple call, tree arg, tree method_field,
fld = TREE_OPERAND (lhs, 1);
if (!method && fld == method_field)
{
+ rhs = get_ssa_def_if_simple_copy (rhs);
if (TREE_CODE (rhs) == ADDR_EXPR
&& TREE_CODE (TREE_OPERAND (rhs, 0)) == FUNCTION_DECL
&& TREE_CODE (TREE_TYPE (TREE_OPERAND (rhs, 0))) == METHOD_TYPE)
@@ -512,6 +503,7 @@ determine_cst_member_ptr (gimple call, tree arg, tree method_field,
if (!delta && fld == delta_field)
{
+ rhs = get_ssa_def_if_simple_copy (rhs);
if (TREE_CODE (rhs) == INTEGER_CST)
{
delta = rhs;
@@ -617,7 +609,7 @@ ipa_get_stmt_member_ptr_load_param (gimple stmt)
{
tree rhs;
- if (!is_gimple_assign (stmt) || gimple_num_ops (stmt) != 2)
+ if (!gimple_assign_single_p (stmt))
return NULL_TREE;
rhs = gimple_assign_rhs1 (stmt);
@@ -797,7 +789,7 @@ ipa_analyze_call_uses (struct ipa_node_params *info, gimple call)
return;
def = SSA_NAME_DEF_STMT (cond);
- if (!is_gimple_assign (def) || gimple_num_ops (def) != 3
+ if (!is_gimple_assign (def)
|| gimple_assign_rhs_code (def) != BIT_AND_EXPR
|| !integer_onep (gimple_assign_rhs2 (def)))
return;
@@ -808,8 +800,8 @@ ipa_analyze_call_uses (struct ipa_node_params *info, gimple call)
def = SSA_NAME_DEF_STMT (cond);
- if (is_gimple_assign (def) && gimple_num_ops (def) == 2
- && gimple_assign_rhs_code (def) == NOP_EXPR)
+ if (is_gimple_assign (def)
+ && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def)))
{
cond = gimple_assign_rhs1 (def);
if (!ipa_is_ssa_with_stmt_def (cond))
diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c
index e6fa76add5b..1fe7fd2faa8 100644
--- a/gcc/ipa-pure-const.c
+++ b/gcc/ipa-pure-const.c
@@ -880,7 +880,7 @@ gate_pure_const (void)
&& !(errorcount || sorrycount));
}
-struct ipa_opt_pass pass_ipa_pure_const =
+struct ipa_opt_pass_d pass_ipa_pure_const =
{
{
IPA_PASS,
diff --git a/gcc/ipa-reference.c b/gcc/ipa-reference.c
index 0753f2a60fd..10daf56eab6 100644
--- a/gcc/ipa-reference.c
+++ b/gcc/ipa-reference.c
@@ -1,5 +1,5 @@
/* Callgraph based analysis of static variables.
- Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
Contributed by Kenneth Zadeck <zadeck@naturalbridge.com>
This file is part of GCC.
@@ -1253,7 +1253,7 @@ gate_reference (void)
&& !(errorcount || sorrycount));
}
-struct ipa_opt_pass pass_ipa_reference =
+struct ipa_opt_pass_d pass_ipa_reference =
{
{
IPA_PASS,
diff --git a/gcc/ipa-struct-reorg.c b/gcc/ipa-struct-reorg.c
index 6468d77f06a..199c5855e2e 100644
--- a/gcc/ipa-struct-reorg.c
+++ b/gcc/ipa-struct-reorg.c
@@ -2178,7 +2178,8 @@ create_new_var_1 (tree orig_decl, d_str str, new_var node)
type = gen_struct_type (orig_decl, type);
if (is_global_var (orig_decl))
- new_decl = build_decl (VAR_DECL, new_name, type);
+ new_decl = build_decl (DECL_SOURCE_LOCATION (orig_decl),
+ VAR_DECL, new_name, type);
else
{
const char *name = new_name ? IDENTIFIER_POINTER (new_name) : NULL;
@@ -3646,7 +3647,7 @@ do_reorg_1 (void)
push_cfun (DECL_STRUCT_FUNCTION (node->decl));
current_function_decl = node->decl;
if (dump_file)
- fprintf (dump_file, "\nFunction to do reorg is %s: \n",
+ fprintf (dump_file, "\nFunction to do reorg is %s: \n",
(const char *) IDENTIFIER_POINTER (DECL_NAME (node->decl)));
do_reorg_for_func (node);
free_dominance_info (CDI_DOMINATORS);
diff --git a/gcc/ipa-utils.h b/gcc/ipa-utils.h
index 31d78374ff6..e70a01688e2 100644
--- a/gcc/ipa-utils.h
+++ b/gcc/ipa-utils.h
@@ -23,9 +23,6 @@ along with GCC; see the file COPYING3. If not see
#include "tree.h"
#include "cgraph.h"
-/* Used for parsing attributes of asm code. */
-extern tree memory_identifier_string;
-
struct ipa_dfs_info {
int dfn_number;
int low_link;
diff --git a/gcc/ira-build.c b/gcc/ira-build.c
index 4ff969a8f5e..edb761b0d71 100644
--- a/gcc/ira-build.c
+++ b/gcc/ira-build.c
@@ -2394,7 +2394,8 @@ static ira_allocno_t *regno_top_level_allocno_map;
static bool
copy_info_to_removed_store_destinations (int regno)
{
- ira_allocno_t a, parent_a;
+ ira_allocno_t a;
+ ira_allocno_t parent_a = NULL;
ira_loop_tree_node_t parent;
allocno_live_range_t r;
bool merged_p;
diff --git a/gcc/ira-conflicts.c b/gcc/ira-conflicts.c
index e3bfb862e1c..bce5c7f6294 100644
--- a/gcc/ira-conflicts.c
+++ b/gcc/ira-conflicts.c
@@ -248,12 +248,10 @@ get_dup_num (int op_num, bool use_commut_op_p)
break;
case 'p':
- GO_IF_LEGITIMATE_ADDRESS (VOIDmode, op, win_p);
+ if (address_operand (op, VOIDmode))
+ return -1;
break;
-
- win_p:
- return -1;
-
+
case 'g':
return -1;
@@ -491,7 +489,7 @@ add_insn_allocno_copies (rtx insn)
? operand : SUBREG_REG (operand)) != NULL_RTX)
{
str = recog_data.constraints[i];
- while (*str == ' ' && *str == '\t')
+ while (*str == ' ' || *str == '\t')
str++;
bound_p = false;
for (j = 0, commut_p = false; j < 2; j++, commut_p = true)
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog
index 960e1144f91..b3daaa8e189 100644
--- a/gcc/java/ChangeLog
+++ b/gcc/java/ChangeLog
@@ -1,3 +1,44 @@
+2009-06-12 Aldy Hernandez <aldyh@redhat.com>
+
+ * java-gimplify.c (java_gimplify_block): New argument to
+ build_empty_stmt.
+ * expr.c (force_evaluation_order): Same.
+ * typeck.c: Add location to build_decl or PUSH_FIELD calls.
+ * class.c: Same.
+ * decl.c: Same.
+ * jcf-parse.c: Same.
+ * constants.c: Same.
+ * resource.c: Same.
+ * except.c: Same.
+ * builtins.c: Same.
+ * expr.c: Same.
+ * java-tree.h (PUSH_FIELD): Add location field.
+
+2009-06-09 Ian Lance Taylor <iant@google.com>
+
+ * verify.h: Remove extern "C".
+
+2009-06-07 Ian Lance Taylor <iant@google.com>
+
+ * jcf-parse.c (handle_constant): Change local variable 'kind' to
+ unsigned int.
+
+2009-06-01 Ian Lance Taylor <iant@google.com>
+
+ * jcf-io.c (find_class): Use CONST_CAST.
+
+2009-05-27 Ian Lance Taylor <iant@google.com>
+
+ * Make-lang.in ($(XGCJ)$(exeext)): Change $(COMPILER) to
+ $(LINKER).
+ (jc1$(exeext), jcf-dump$(exeext), jvgenmain$(exeext)): Likewise.
+
+2009-05-26 Ian Lance Taylor <iant@google.com>
+
+ * Make-lang.in (jvspec.o): Use $(COMPILER).
+ ($(XGCJ)$(exeext), jc1$(exeext), jcf-dump$(exeext)): Likewise.
+ (jvgenmain$(exeext), java/jcf-io.o, java/jcf-path.o): Likewise.
+
2009-05-12 Alexandre Oliva <aoliva@redhat.com>
* Make-lang.in (GCJ): Renamed to...
diff --git a/gcc/java/Make-lang.in b/gcc/java/Make-lang.in
index fafa94ae766..263ddc39b04 100644
--- a/gcc/java/Make-lang.in
+++ b/gcc/java/Make-lang.in
@@ -1,7 +1,7 @@
# Top level -*- makefile -*- fragment for the GNU compiler for the Java(TM)
# language.
# Copyright (C) 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-# 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
#This file is part of GCC.
@@ -59,14 +59,14 @@ JAVA_TARGET_INDEPENDENT_BIN_TOOLS = jcf-dump
jvspec.o: $(srcdir)/java/jvspec.c $(SYSTEM_H) coretypes.h $(TM_H) \
$(GCC_H) $(CONFIG_H) java/jcf.h java/javaop.h
(SHLIB_LINK='$(SHLIB_LINK)'; \
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(DRIVER_DEFINES) \
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(DRIVER_DEFINES) \
$(INCLUDES) $(srcdir)/java/jvspec.c $(OUTPUT_OPTION))
# Create the compiler driver for $(XGCJ).
$(XGCJ)$(exeext): $(GCC_OBJS) jvspec.o java/jcf-path.o version.o \
prefix.o intl.o $(LIBDEPS) $(EXTRA_GCC_OBJS)
- $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(GCC_OBJS) jvspec.o \
- java/jcf-path.o prefix.o intl.o \
+ $(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ $(GCC_OBJS) \
+ jvspec.o java/jcf-path.o prefix.o intl.o \
version.o $(EXTRA_GCC_OBJS) $(LIBS)
# Create a version of the $(XGCJ) driver which calls the cross-compiler.
@@ -100,17 +100,18 @@ jvspec.o-warn = -Wno-error
jc1$(exeext): $(JAVA_OBJS) $(BACKEND) $(LIBDEPS) attribs.o
rm -f $@
- $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ \
+ $(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
$(JAVA_OBJS) $(BACKEND) $(ZLIB) $(LIBICONV) $(LIBS) attribs.o $(BACKENDLIBS)
jcf-dump$(exeext): $(JCFDUMP_OBJS) $(LIBDEPS)
rm -f $@
- $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(JCFDUMP_OBJS) \
+ $(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ $(JCFDUMP_OBJS) \
$(CPPLIBS) $(ZLIB) $(LDEXP_LIB) $(LIBS)
jvgenmain$(exeext): $(JVGENMAIN_OBJS) $(LIBDEPS)
rm -f $@
- $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(JVGENMAIN_OBJS) $(LIBS)
+ $(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ $(JVGENMAIN_OBJS) \
+ $(LIBS)
#
# Build hooks:
@@ -305,13 +306,13 @@ java/java-gimplify.o: java/java-gimplify.c $(CONFIG_H) $(SYSTEM_H) \
# jcf-io.o needs $(ZLIBINC) added to cflags.
java/jcf-io.o: java/jcf-io.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(JAVA_TREE_H) java/zipfile.h
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(ZLIBINC) \
- $(srcdir)/java/jcf-io.c $(OUTPUT_OPTION)
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $(ZLIBINC) $(srcdir)/java/jcf-io.c $(OUTPUT_OPTION)
# jcf-path.o needs a -D.
java/jcf-path.o: java/jcf-path.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
java/jcf.h
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
-DLIBGCJ_ZIP_FILE='"$(datadir)/java/libgcj-$(version).jar"' \
-DDEFAULT_TARGET_VERSION=\"$(version)\" \
$(srcdir)/java/jcf-path.c $(OUTPUT_OPTION)
diff --git a/gcc/java/builtins.c b/gcc/java/builtins.c
index 39c73a5e7fa..0f7b197f78c 100644
--- a/gcc/java/builtins.c
+++ b/gcc/java/builtins.c
@@ -411,7 +411,7 @@ getVolatile_builtin (tree method_return_type ATTRIBUTE_UNUSED,
stmt = build_call_expr (built_in_decls[BUILT_IN_SYNCHRONIZE], 0);
- tmp = build_decl (VAR_DECL, NULL, method_return_type);
+ tmp = build_decl (BUILTINS_LOCATION, VAR_DECL, NULL, method_return_type);
DECL_IGNORED_P (tmp) = 1;
DECL_ARTIFICIAL (tmp) = 1;
pushdecl (tmp);
@@ -453,7 +453,8 @@ define_builtin (enum built_in_function val,
{
tree decl;
- decl = build_decl (FUNCTION_DECL, get_identifier (name), type);
+ decl = build_decl (BUILTINS_LOCATION,
+ FUNCTION_DECL, get_identifier (name), type);
DECL_EXTERNAL (decl) = 1;
TREE_PUBLIC (decl) = 1;
SET_DECL_ASSEMBLER_NAME (decl, get_identifier (libname));
diff --git a/gcc/java/class.c b/gcc/java/class.c
index edd16f0ad61..1b594e5ca84 100644
--- a/gcc/java/class.c
+++ b/gcc/java/class.c
@@ -420,7 +420,7 @@ do \
\
sprintf (buf, #NAME "_%s", type_name); \
TYPE_## TABLE ##_DECL (type) = decl = \
- build_decl (VAR_DECL, get_identifier (buf), TABLE_TYPE); \
+ build_decl (input_location, VAR_DECL, get_identifier (buf), TABLE_TYPE); \
DECL_EXTERNAL (decl) = 1; \
TREE_STATIC (decl) = 1; \
TREE_READONLY (decl) = 1; \
@@ -432,7 +432,7 @@ do \
DECL_OWNER (decl) = TYPE; \
sprintf (buf, #NAME "_syms_%s", type_name); \
TYPE_## TABLE ##_SYMS_DECL (TYPE) = \
- build_decl (VAR_DECL, get_identifier (buf), symbols_array_type); \
+ build_decl (input_location, VAR_DECL, get_identifier (buf), symbols_array_type); \
TREE_STATIC (TYPE_## TABLE ##_SYMS_DECL (TYPE)) = 1; \
TREE_CONSTANT (TYPE_## TABLE ##_SYMS_DECL (TYPE)) = 1; \
DECL_IGNORED_P (TYPE_## TABLE ##_SYMS_DECL (TYPE)) = 1; \
@@ -452,12 +452,14 @@ gen_indirect_dispatch_tables (tree type)
tree catch_class_type = make_node (RECORD_TYPE);
sprintf (buf, "_catch_classes_%s", type_name);
- PUSH_FIELD (catch_class_type, field, "address", utf8const_ptr_type);
- PUSH_FIELD (catch_class_type, field, "classname", ptr_type_node);
+ PUSH_FIELD (input_location,
+ catch_class_type, field, "address", utf8const_ptr_type);
+ PUSH_FIELD (input_location,
+ catch_class_type, field, "classname", ptr_type_node);
FINISH_RECORD (catch_class_type);
TYPE_CTABLE_DECL (type)
- = build_decl (VAR_DECL, get_identifier (buf),
+ = build_decl (input_location, VAR_DECL, get_identifier (buf),
build_array_type (catch_class_type, 0));
DECL_EXTERNAL (TYPE_CTABLE_DECL (type)) = 1;
TREE_STATIC (TYPE_CTABLE_DECL (type)) = 1;
@@ -483,7 +485,7 @@ push_class (tree class_type, tree class_name)
tree decl, signature;
location_t saved_loc = input_location;
CLASS_P (class_type) = 1;
- decl = build_decl (TYPE_DECL, class_name, class_type);
+ decl = build_decl (input_location, TYPE_DECL, class_name, class_type);
TYPE_DECL_SUPPRESS_DEBUG (decl) = 1;
/* dbxout needs a DECL_SIZE if in gstabs mode */
@@ -758,7 +760,7 @@ add_method_1 (tree this_class, int access_flags, tree name, tree function_type)
method_type = build_java_method_type (function_type,
this_class, access_flags);
- fndecl = build_decl (FUNCTION_DECL, name, method_type);
+ fndecl = build_decl (input_location, FUNCTION_DECL, name, method_type);
DECL_CONTEXT (fndecl) = this_class;
DECL_LANG_SPECIFIC (fndecl)
@@ -844,7 +846,8 @@ add_field (tree klass, tree name, tree field_type, int flags)
{
int is_static = (flags & ACC_STATIC) != 0;
tree field;
- field = build_decl (is_static ? VAR_DECL : FIELD_DECL, name, field_type);
+ field = build_decl (input_location,
+ is_static ? VAR_DECL : FIELD_DECL, name, field_type);
TREE_CHAIN (field) = TYPE_FIELDS (klass);
TYPE_FIELDS (klass) = field;
DECL_CONTEXT (field) = klass;
@@ -948,9 +951,10 @@ build_utf8_ref (tree name)
- (name_len & (TYPE_ALIGN_UNIT (utf8const_type) - 1));
str_type = build_prim_array_type (unsigned_byte_type_node,
name_len + name_pad);
- PUSH_FIELD (ctype, field, "hash", unsigned_short_type_node);
- PUSH_FIELD (ctype, field, "length", unsigned_short_type_node);
- PUSH_FIELD (ctype, field, "data", str_type);
+ PUSH_FIELD (input_location, ctype, field, "hash", unsigned_short_type_node);
+ PUSH_FIELD (input_location,
+ ctype, field, "length", unsigned_short_type_node);
+ PUSH_FIELD (input_location, ctype, field, "data", str_type);
FINISH_RECORD (ctype);
START_RECORD_CONSTRUCTOR (cinit, ctype);
name_hash = hashUtf8String (name_ptr, name_len) & 0xFFFF;
@@ -965,7 +969,8 @@ build_utf8_ref (tree name)
/* Generate a unique-enough identifier. */
sprintf(buf, "_Utf%d", ++utf8_count);
- decl = build_decl (VAR_DECL, get_identifier (buf), utf8const_type);
+ decl = build_decl (input_location,
+ VAR_DECL, get_identifier (buf), utf8const_type);
TREE_STATIC (decl) = 1;
DECL_ARTIFICIAL (decl) = 1;
DECL_IGNORED_P (decl) = 1;
@@ -1027,7 +1032,7 @@ build_static_class_ref (tree type)
decl = IDENTIFIER_GLOBAL_VALUE (decl_name);
if (decl == NULL_TREE)
{
- decl = build_decl (VAR_DECL, decl_name, class_type_node);
+ decl = build_decl (input_location, VAR_DECL, decl_name, class_type_node);
TREE_STATIC (decl) = 1;
if (! flag_indirect_classes)
{
@@ -1062,7 +1067,8 @@ build_classdollar_field (tree type)
if (decl == NULL_TREE)
{
decl
- = build_decl (VAR_DECL, decl_name,
+ = build_decl (input_location,
+ VAR_DECL, decl_name,
(build_type_variant
(build_pointer_type
(build_type_variant (class_type_node,
@@ -1097,7 +1103,8 @@ cache_this_class_ref (tree fndecl)
else
classdollar_field = build_static_class_ref (output_class);
- this_classdollar = build_decl (VAR_DECL, NULL_TREE,
+ this_classdollar = build_decl (input_location,
+ VAR_DECL, NULL_TREE,
TREE_TYPE (classdollar_field));
java_add_local_var (this_classdollar);
@@ -1175,7 +1182,8 @@ build_class_ref (tree type)
decl = IDENTIFIER_GLOBAL_VALUE (decl_name);
if (decl == NULL_TREE)
{
- decl = build_decl (VAR_DECL, decl_name, class_type_node);
+ decl = build_decl (input_location,
+ VAR_DECL, decl_name, class_type_node);
TREE_STATIC (decl) = 1;
TREE_PUBLIC (decl) = 1;
DECL_EXTERNAL (decl) = 1;
@@ -1205,7 +1213,8 @@ build_fieldref_cache_entry (int index, tree fdecl ATTRIBUTE_UNUSED)
decl = IDENTIFIER_GLOBAL_VALUE (decl_name);
if (decl == NULL_TREE)
{
- decl = build_decl (VAR_DECL, decl_name, ptr_type_node);
+ decl = build_decl (input_location,
+ VAR_DECL, decl_name, ptr_type_node);
TREE_STATIC (decl) = 1;
TREE_PUBLIC (decl) = 0;
DECL_EXTERNAL (decl) = 0;
@@ -1386,7 +1395,8 @@ make_local_function_alias (tree method)
strcpy (name + 1, method_name);
ASM_GENERATE_INTERNAL_LABEL (buf, name, alias_labelno++);
- alias = build_decl (FUNCTION_DECL, get_identifier (buf),
+ alias = build_decl (input_location,
+ FUNCTION_DECL, get_identifier (buf),
TREE_TYPE (method));
DECL_CONTEXT (alias) = NULL;
TREE_READONLY (alias) = TREE_READONLY (method);
@@ -1530,7 +1540,8 @@ make_method_value (tree mdecl)
table = build_constructor_from_list (type, table);
/* Compute something unique enough. */
sprintf (buf, "_methods%d", method_name_count++);
- array = build_decl (VAR_DECL, get_identifier (buf), type);
+ array = build_decl (input_location,
+ VAR_DECL, get_identifier (buf), type);
DECL_INITIAL (array) = table;
TREE_STATIC (array) = 1;
DECL_ARTIFICIAL (array) = 1;
@@ -1862,7 +1873,8 @@ make_class_data (tree type)
instance_fields = nreverse (instance_fields);
static_fields = chainon (static_fields, instance_fields);
field_array_type = build_prim_array_type (field_type_node, field_count);
- fields_decl = build_decl (VAR_DECL, mangled_classname ("_FL_", type),
+ fields_decl = build_decl (input_location,
+ VAR_DECL, mangled_classname ("_FL_", type),
field_array_type);
DECL_INITIAL (fields_decl) = build_constructor_from_list
(field_array_type, static_fields);
@@ -1918,7 +1930,8 @@ make_class_data (tree type)
}
}
method_array_type = build_prim_array_type (method_type_node, method_count);
- methods_decl = build_decl (VAR_DECL, mangled_classname ("_MT_", type),
+ methods_decl = build_decl (input_location,
+ VAR_DECL, mangled_classname ("_MT_", type),
method_array_type);
DECL_INITIAL (methods_decl) = build_constructor_from_list
(method_array_type, nreverse (methods));
@@ -1964,7 +1977,8 @@ make_class_data (tree type)
tree interface_array_type, idecl;
interface_array_type
= build_prim_array_type (class_ptr_type, interface_len);
- idecl = build_decl (VAR_DECL, mangled_classname ("_IF_", type),
+ idecl = build_decl (input_location,
+ VAR_DECL, mangled_classname ("_IF_", type),
interface_array_type);
for (i = interface_len; i > 0; i--)
@@ -2168,7 +2182,8 @@ make_class_data (tree type)
static int reflection_data_count;
sprintf (buf, "_reflection_data_%d", reflection_data_count++);
- array = build_decl (VAR_DECL, get_identifier (buf), type);
+ array = build_decl (input_location,
+ VAR_DECL, get_identifier (buf), type);
rewrite_reflection_indexes (field_indexes);
@@ -2298,23 +2313,25 @@ build_dtable_decl (tree type)
dtype = make_node (RECORD_TYPE);
- PUSH_FIELD (dtype, dummy, "top_offset", ptr_type_node);
- PUSH_FIELD (dtype, dummy, "type_info", ptr_type_node);
+ PUSH_FIELD (input_location, dtype, dummy, "top_offset", ptr_type_node);
+ PUSH_FIELD (input_location, dtype, dummy, "type_info", ptr_type_node);
- PUSH_FIELD (dtype, dummy, "class", class_ptr_type);
+ PUSH_FIELD (input_location, dtype, dummy, "class", class_ptr_type);
for (n = 1; n < TARGET_VTABLE_USES_DESCRIPTORS; ++n)
{
- tree tmp_field = build_decl (FIELD_DECL, NULL_TREE, ptr_type_node);
+ tree tmp_field = build_decl (input_location,
+ FIELD_DECL, NULL_TREE, ptr_type_node);
TREE_CHAIN (dummy) = tmp_field;
DECL_CONTEXT (tmp_field) = dtype;
DECL_ARTIFICIAL (tmp_field) = 1;
dummy = tmp_field;
}
- PUSH_FIELD (dtype, dummy, "gc_descr", ptr_type_node);
+ PUSH_FIELD (input_location, dtype, dummy, "gc_descr", ptr_type_node);
for (n = 1; n < TARGET_VTABLE_USES_DESCRIPTORS; ++n)
{
- tree tmp_field = build_decl (FIELD_DECL, NULL_TREE, ptr_type_node);
+ tree tmp_field = build_decl (input_location,
+ FIELD_DECL, NULL_TREE, ptr_type_node);
TREE_CHAIN (dummy) = tmp_field;
DECL_CONTEXT (tmp_field) = dtype;
DECL_ARTIFICIAL (tmp_field) = 1;
@@ -2325,14 +2342,15 @@ build_dtable_decl (tree type)
if (TARGET_VTABLE_USES_DESCRIPTORS)
n *= TARGET_VTABLE_USES_DESCRIPTORS;
- PUSH_FIELD (dtype, dummy, "methods",
+ PUSH_FIELD (input_location, dtype, dummy, "methods",
build_prim_array_type (nativecode_ptr_type_node, n));
layout_type (dtype);
}
else
dtype = dtable_type;
- decl = build_decl (VAR_DECL, get_identifier ("vt$"), dtype);
+ decl = build_decl (input_location,
+ VAR_DECL, get_identifier ("vt$"), dtype);
DECL_CONTEXT (decl) = type;
MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);
DECL_VTABLE_P (decl) = 1;
@@ -2350,7 +2368,8 @@ push_super_field (tree this_class, tree super_class)
/* Don't insert the field if we're just re-laying the class out. */
if (TYPE_FIELDS (this_class) && !DECL_NAME (TYPE_FIELDS (this_class)))
return;
- base_decl = build_decl (FIELD_DECL, NULL_TREE, super_class);
+ base_decl = build_decl (input_location,
+ FIELD_DECL, NULL_TREE, super_class);
DECL_IGNORED_P (base_decl) = 1;
TREE_CHAIN (base_decl) = TYPE_FIELDS (this_class);
TYPE_FIELDS (this_class) = base_decl;
@@ -2719,7 +2738,8 @@ emit_indirect_register_classes (tree *list_p)
int size = VEC_length (tree, registered_class) * 2 + 1;
tree class_array_type
= build_prim_array_type (ptr_type_node, size);
- tree cdecl = build_decl (VAR_DECL, get_identifier ("_Jv_CLS"),
+ tree cdecl = build_decl (input_location,
+ VAR_DECL, get_identifier ("_Jv_CLS"),
class_array_type);
tree reg_class_list;
for (i = 0; VEC_iterate (tree, registered_class, i, klass); ++i)
@@ -2747,7 +2767,8 @@ emit_indirect_register_classes (tree *list_p)
t = build_function_type_list (void_type_node,
build_pointer_type (ptr_type_node), NULL);
- t = build_decl (FUNCTION_DECL,
+ t = build_decl (input_location,
+ FUNCTION_DECL,
get_identifier ("_Jv_RegisterNewClasses"), t);
TREE_PUBLIC (t) = 1;
DECL_EXTERNAL (t) = 1;
@@ -2809,7 +2830,8 @@ emit_register_classes (tree *list_p)
int i;
t = build_function_type_list (void_type_node, class_ptr_type, NULL);
- t = build_decl (FUNCTION_DECL, get_identifier ("_Jv_RegisterClass"), t);
+ t = build_decl (input_location,
+ FUNCTION_DECL, get_identifier ("_Jv_RegisterClass"), t);
TREE_PUBLIC (t) = 1;
DECL_EXTERNAL (t) = 1;
register_class_fn = t;
@@ -2915,7 +2937,8 @@ emit_symbol_table (tree name, tree the_table, tree decl_list,
table_size
= build_index_type (build_int_cst (NULL_TREE, index * element_size + 1));
the_array_type = build_array_type (the_array_element_type, table_size);
- the_table = build_decl (VAR_DECL, name, the_array_type);
+ the_table = build_decl (input_location,
+ VAR_DECL, name, the_array_type);
TREE_STATIC (the_table) = 1;
TREE_READONLY (the_table) = 1;
rest_of_decl_compilation (the_table, 1, 0);
@@ -2959,7 +2982,8 @@ emit_catch_table (tree this_class)
= build_array_type (TREE_TYPE (TREE_TYPE (TYPE_CTABLE_DECL (this_class))),
table_size);
table =
- build_decl (VAR_DECL, DECL_NAME (TYPE_CTABLE_DECL (this_class)), array_type);
+ build_decl (input_location,
+ VAR_DECL, DECL_NAME (TYPE_CTABLE_DECL (this_class)), array_type);
DECL_INITIAL (table) =
build_constructor_from_list (array_type, TYPE_CATCH_CLASSES (this_class));
TREE_STATIC (table) = 1;
@@ -3043,7 +3067,8 @@ emit_assertion_table (tree klass)
list = nreverse (list);
ctor = build_constructor_from_list (assertion_table_type, list);
- table_decl = build_decl (VAR_DECL, mangled_classname ("_type_assert_", klass),
+ table_decl = build_decl (input_location,
+ VAR_DECL, mangled_classname ("_type_assert_", klass),
assertion_table_type);
TREE_STATIC (table_decl) = 1;
diff --git a/gcc/java/constants.c b/gcc/java/constants.c
index 70d628b4c5a..541e78d2cb5 100644
--- a/gcc/java/constants.c
+++ b/gcc/java/constants.c
@@ -463,7 +463,7 @@ build_constant_data_ref (bool indirect)
thinks the type is incomplete. */
layout_type (type);
- decl = build_decl (VAR_DECL, decl_name, type);
+ decl = build_decl (input_location, VAR_DECL, decl_name, type);
TREE_STATIC (decl) = 1;
IDENTIFIER_GLOBAL_VALUE (decl_name) = decl;
}
@@ -581,7 +581,8 @@ build_constants_constructor (void)
data_value = build_address_of (data_decl);
tags_type = build_array_type (unsigned_byte_type_node, index_type);
- tags_decl = build_decl (VAR_DECL, mangled_classname ("_CT_",
+ tags_decl = build_decl (input_location,
+ VAR_DECL, mangled_classname ("_CT_",
current_class),
tags_type);
TREE_STATIC (tags_decl) = 1;
diff --git a/gcc/java/decl.c b/gcc/java/decl.c
index bd0cc8e4de6..3c1e7eaef9c 100644
--- a/gcc/java/decl.c
+++ b/gcc/java/decl.c
@@ -274,7 +274,7 @@ find_local_variable (int index, tree type, int pc ATTRIBUTE_UNUSED)
tree name;
sprintf (buf, "#slot#%d#%d", index, uniq++);
name = get_identifier (buf);
- decl = build_decl (VAR_DECL, name, type);
+ decl = build_decl (input_location, VAR_DECL, name, type);
DECL_IGNORED_P (decl) = 1;
DECL_ARTIFICIAL (decl) = 1;
decl = push_jvm_slot (index, decl);
@@ -297,7 +297,7 @@ find_local_variable (int index, tree type, int pc ATTRIBUTE_UNUSED)
name = get_identifier (buf);
base_decl
= TREE_VEC_ELT (base_decl_map, index)
- = build_decl (VAR_DECL, name, ptr_type_node);
+ = build_decl (input_location, VAR_DECL, name, ptr_type_node);
pushdecl_function_level (base_decl);
DECL_IGNORED_P (base_decl) = 1;
DECL_ARTIFICIAL (base_decl) = 1;
@@ -450,7 +450,8 @@ push_promoted_type (const char *name, tree actual_type)
TYPE_PRECISION (type) = TYPE_PRECISION (int_type_node);
TYPE_STRING_FLAG (type) = TYPE_STRING_FLAG (actual_type);
layout_type (type);
- pushdecl (build_decl (TYPE_DECL, get_identifier (name), type));
+ pushdecl (build_decl (input_location,
+ TYPE_DECL, get_identifier (name), type));
return type;
}
@@ -462,7 +463,8 @@ create_primitive_vtable (const char *name)
char buf[50];
sprintf (buf, "_Jv_%sVTable", name);
- r = build_decl (VAR_DECL, get_identifier (buf), ptr_type_node);
+ r = build_decl (input_location,
+ VAR_DECL, get_identifier (buf), ptr_type_node);
DECL_EXTERNAL (r) = 1;
return r;
}
@@ -545,25 +547,33 @@ java_init_decl_processing (void)
initialize_sizetypes (false);
byte_type_node = make_signed_type (8);
- pushdecl (build_decl (TYPE_DECL, get_identifier ("byte"), byte_type_node));
+ pushdecl (build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier ("byte"), byte_type_node));
short_type_node = make_signed_type (16);
- pushdecl (build_decl (TYPE_DECL, get_identifier ("short"), short_type_node));
+ pushdecl (build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier ("short"), short_type_node));
int_type_node = make_signed_type (32);
- pushdecl (build_decl (TYPE_DECL, get_identifier ("int"), int_type_node));
+ pushdecl (build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier ("int"), int_type_node));
long_type_node = make_signed_type (64);
- pushdecl (build_decl (TYPE_DECL, get_identifier ("long"), long_type_node));
+ pushdecl (build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier ("long"), long_type_node));
unsigned_byte_type_node = make_unsigned_type (8);
- pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned byte"),
+ pushdecl (build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier ("unsigned byte"),
unsigned_byte_type_node));
unsigned_short_type_node = make_unsigned_type (16);
- pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned short"),
+ pushdecl (build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier ("unsigned short"),
unsigned_short_type_node));
unsigned_int_type_node = make_unsigned_type (32);
- pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned int"),
+ pushdecl (build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier ("unsigned int"),
unsigned_int_type_node));
unsigned_long_type_node = make_unsigned_type (64);
- pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned long"),
+ pushdecl (build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier ("unsigned long"),
unsigned_long_type_node));
/* This is not a java type, however tree-dfa requires a definition for
@@ -600,7 +610,8 @@ java_init_decl_processing (void)
long_zero_node = build_int_cst (long_type_node, 0);
void_type_node = make_node (VOID_TYPE);
- pushdecl (build_decl (TYPE_DECL, get_identifier ("void"), void_type_node));
+ pushdecl (build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier ("void"), void_type_node));
layout_type (void_type_node); /* Uses size_zero_node */
ptr_type_node = build_pointer_type (void_type_node);
@@ -617,12 +628,14 @@ java_init_decl_processing (void)
TYPE_STRING_FLAG (char_type_node) = 1;
TYPE_PRECISION (char_type_node) = 16;
fixup_unsigned_type (char_type_node);
- pushdecl (build_decl (TYPE_DECL, get_identifier ("char"), char_type_node));
+ pushdecl (build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier ("char"), char_type_node));
boolean_type_node = make_node (BOOLEAN_TYPE);
TYPE_PRECISION (boolean_type_node) = 1;
fixup_unsigned_type (boolean_type_node);
- pushdecl (build_decl (TYPE_DECL, get_identifier ("boolean"),
+ pushdecl (build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier ("boolean"),
boolean_type_node));
boolean_false_node = TYPE_MIN_VALUE (boolean_type_node);
boolean_true_node = TYPE_MAX_VALUE (boolean_type_node);
@@ -638,13 +651,15 @@ java_init_decl_processing (void)
float_type_node = make_node (REAL_TYPE);
TYPE_PRECISION (float_type_node) = 32;
- pushdecl (build_decl (TYPE_DECL, get_identifier ("float"),
+ pushdecl (build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier ("float"),
float_type_node));
layout_type (float_type_node);
double_type_node = make_node (REAL_TYPE);
TYPE_PRECISION (double_type_node) = 64;
- pushdecl (build_decl (TYPE_DECL, get_identifier ("double"),
+ pushdecl (build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier ("double"),
double_type_node));
layout_type (double_type_node);
@@ -663,8 +678,10 @@ java_init_decl_processing (void)
one_elt_array_domain_type = build_index_type (integer_one_node);
utf8const_type = make_node (RECORD_TYPE);
- PUSH_FIELD (utf8const_type, field, "hash", unsigned_short_type_node);
- PUSH_FIELD (utf8const_type, field, "length", unsigned_short_type_node);
+ PUSH_FIELD (input_location,
+ utf8const_type, field, "hash", unsigned_short_type_node);
+ PUSH_FIELD (input_location,
+ utf8const_type, field, "length", unsigned_short_type_node);
FINISH_RECORD (utf8const_type);
utf8const_ptr_type = build_pointer_type (utf8const_type);
@@ -679,9 +696,11 @@ java_init_decl_processing (void)
itable_ptr_type = build_pointer_type (itable_type);
symbol_type = make_node (RECORD_TYPE);
- PUSH_FIELD (symbol_type, field, "clname", utf8const_ptr_type);
- PUSH_FIELD (symbol_type, field, "name", utf8const_ptr_type);
- PUSH_FIELD (symbol_type, field, "signature", utf8const_ptr_type);
+ PUSH_FIELD (input_location,
+ symbol_type, field, "clname", utf8const_ptr_type);
+ PUSH_FIELD (input_location, symbol_type, field, "name", utf8const_ptr_type);
+ PUSH_FIELD (input_location,
+ symbol_type, field, "signature", utf8const_ptr_type);
FINISH_RECORD (symbol_type);
symbols_array_type = build_array_type (symbol_type,
@@ -689,9 +708,12 @@ java_init_decl_processing (void)
symbols_array_ptr_type = build_pointer_type (symbols_array_type);
assertion_entry_type = make_node (RECORD_TYPE);
- PUSH_FIELD (assertion_entry_type, field, "assertion_code", integer_type_node);
- PUSH_FIELD (assertion_entry_type, field, "op1", utf8const_ptr_type);
- PUSH_FIELD (assertion_entry_type, field, "op2", utf8const_ptr_type);
+ PUSH_FIELD (input_location,
+ assertion_entry_type, field, "assertion_code", integer_type_node);
+ PUSH_FIELD (input_location,
+ assertion_entry_type, field, "op1", utf8const_ptr_type);
+ PUSH_FIELD (input_location,
+ assertion_entry_type, field, "op2", utf8const_ptr_type);
FINISH_RECORD (assertion_entry_type);
assertion_table_type = build_array_type (assertion_entry_type,
@@ -729,7 +751,8 @@ java_init_decl_processing (void)
methodtable_type = make_node (RECORD_TYPE);
layout_type (methodtable_type);
- build_decl (TYPE_DECL, get_identifier ("methodtable"), methodtable_type);
+ build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier ("methodtable"), methodtable_type);
methodtable_ptr_type = build_pointer_type (methodtable_type);
TYPE_identifier_node = get_identifier ("TYPE");
@@ -747,12 +770,16 @@ java_init_decl_processing (void)
init_expr_processing();
constants_type_node = make_node (RECORD_TYPE);
- PUSH_FIELD (constants_type_node, field, "size", unsigned_int_type_node);
- PUSH_FIELD (constants_type_node, field, "tags", ptr_type_node);
- PUSH_FIELD (constants_type_node, field, "data", ptr_type_node);
+ PUSH_FIELD (input_location,
+ constants_type_node, field, "size", unsigned_int_type_node);
+ PUSH_FIELD (input_location,
+ constants_type_node, field, "tags", ptr_type_node);
+ PUSH_FIELD (input_location,
+ constants_type_node, field, "data", ptr_type_node);
constants_data_field_decl_node = field;
FINISH_RECORD (constants_type_node);
- build_decl (TYPE_DECL, get_identifier ("constants"), constants_type_node);
+ build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier ("constants"), constants_type_node);
access_flags_type_node = unsigned_short_type_node;
@@ -764,7 +791,8 @@ java_init_decl_processing (void)
TYPE_NONALIASED_COMPONENT (otable_type) = 1;
otable_ptr_type = build_pointer_type (otable_type);
- PUSH_FIELD (object_type_node, field, "vtable", dtable_ptr_type);
+ PUSH_FIELD (input_location,
+ object_type_node, field, "vtable", dtable_ptr_type);
DECL_FCONTEXT (field) = object_type_node;
TYPE_VFIELD (object_type_node) = field;
@@ -772,7 +800,7 @@ java_init_decl_processing (void)
There is an unresolved issue here, which is whether the vtable
should be marked by the GC. */
if (! flag_hash_synchronization)
- PUSH_FIELD (object_type_node, field, "sync_info",
+ PUSH_FIELD (input_location, object_type_node, field, "sync_info",
build_pointer_type (object_type_node));
for (t = TYPE_FIELDS (object_type_node); t != NULL_TREE; t = TREE_CHAIN (t))
FIELD_PRIVATE (t) = 1;
@@ -787,101 +815,154 @@ java_init_decl_processing (void)
set_super_info (0, string_type_node, object_type_node, 0);
class_ptr_type = build_pointer_type (class_type_node);
- PUSH_FIELD (class_type_node, field, "next_or_version", class_ptr_type);
- PUSH_FIELD (class_type_node, field, "name", utf8const_ptr_type);
- PUSH_FIELD (class_type_node, field, "accflags", access_flags_type_node);
- PUSH_FIELD (class_type_node, field, "superclass", class_ptr_type);
- PUSH_FIELD (class_type_node, field, "constants", constants_type_node);
+ PUSH_FIELD (input_location,
+ class_type_node, field, "next_or_version", class_ptr_type);
+ PUSH_FIELD (input_location,
+ class_type_node, field, "name", utf8const_ptr_type);
+ PUSH_FIELD (input_location,
+ class_type_node, field, "accflags", access_flags_type_node);
+ PUSH_FIELD (input_location,
+ class_type_node, field, "superclass", class_ptr_type);
+ PUSH_FIELD (input_location,
+ class_type_node, field, "constants", constants_type_node);
constants_field_decl_node = field;
- PUSH_FIELD (class_type_node, field, "methods", method_ptr_type_node);
- PUSH_FIELD (class_type_node, field, "method_count", short_type_node);
- PUSH_FIELD (class_type_node, field, "vtable_method_count", short_type_node);
- PUSH_FIELD (class_type_node, field, "fields", field_ptr_type_node);
- PUSH_FIELD (class_type_node, field, "size_in_bytes", int_type_node);
- PUSH_FIELD (class_type_node, field, "field_count", short_type_node);
- PUSH_FIELD (class_type_node, field, "static_field_count", short_type_node);
- PUSH_FIELD (class_type_node, field, "vtable", dtable_ptr_type);
- PUSH_FIELD (class_type_node, field, "otable", otable_ptr_type);
- PUSH_FIELD (class_type_node, field, "otable_syms",
+ PUSH_FIELD (input_location,
+ class_type_node, field, "methods", method_ptr_type_node);
+ PUSH_FIELD (input_location,
+ class_type_node, field, "method_count", short_type_node);
+ PUSH_FIELD (input_location,
+ class_type_node, field, "vtable_method_count", short_type_node);
+ PUSH_FIELD (input_location,
+ class_type_node, field, "fields", field_ptr_type_node);
+ PUSH_FIELD (input_location,
+ class_type_node, field, "size_in_bytes", int_type_node);
+ PUSH_FIELD (input_location,
+ class_type_node, field, "field_count", short_type_node);
+ PUSH_FIELD (input_location,
+ class_type_node, field, "static_field_count", short_type_node);
+ PUSH_FIELD (input_location,
+ class_type_node, field, "vtable", dtable_ptr_type);
+ PUSH_FIELD (input_location,
+ class_type_node, field, "otable", otable_ptr_type);
+ PUSH_FIELD (input_location,
+ class_type_node, field, "otable_syms",
symbols_array_ptr_type);
- PUSH_FIELD (class_type_node, field, "atable", atable_ptr_type);
- PUSH_FIELD (class_type_node, field, "atable_syms",
+ PUSH_FIELD (input_location,
+ class_type_node, field, "atable", atable_ptr_type);
+ PUSH_FIELD (input_location,
+ class_type_node, field, "atable_syms",
symbols_array_ptr_type);
- PUSH_FIELD (class_type_node, field, "itable", itable_ptr_type);
- PUSH_FIELD (class_type_node, field, "itable_syms",
+ PUSH_FIELD (input_location,
+ class_type_node, field, "itable", itable_ptr_type);
+ PUSH_FIELD (input_location, class_type_node, field, "itable_syms",
symbols_array_ptr_type);
- PUSH_FIELD (class_type_node, field, "catch_classes", ptr_type_node);
- PUSH_FIELD (class_type_node, field, "interfaces",
+ PUSH_FIELD (input_location,
+ class_type_node, field, "catch_classes", ptr_type_node);
+ PUSH_FIELD (input_location, class_type_node, field, "interfaces",
build_pointer_type (class_ptr_type));
- PUSH_FIELD (class_type_node, field, "loader", ptr_type_node);
- PUSH_FIELD (class_type_node, field, "interface_count", short_type_node);
- PUSH_FIELD (class_type_node, field, "state", byte_type_node);
- PUSH_FIELD (class_type_node, field, "thread", ptr_type_node);
- PUSH_FIELD (class_type_node, field, "depth", short_type_node);
- PUSH_FIELD (class_type_node, field, "ancestors", ptr_type_node);
- PUSH_FIELD (class_type_node, field, "idt", ptr_type_node);
- PUSH_FIELD (class_type_node, field, "arrayclass", ptr_type_node);
- PUSH_FIELD (class_type_node, field, "protectionDomain", ptr_type_node);
- PUSH_FIELD (class_type_node, field, "assertion_table", ptr_type_node);
- PUSH_FIELD (class_type_node, field, "hack_signers", ptr_type_node);
- PUSH_FIELD (class_type_node, field, "chain", ptr_type_node);
- PUSH_FIELD (class_type_node, field, "aux_info", ptr_type_node);
- PUSH_FIELD (class_type_node, field, "engine", ptr_type_node);
- PUSH_FIELD (class_type_node, field, "reflection_data", ptr_type_node);
+ PUSH_FIELD (input_location, class_type_node, field, "loader", ptr_type_node);
+ PUSH_FIELD (input_location,
+ class_type_node, field, "interface_count", short_type_node);
+ PUSH_FIELD (input_location, class_type_node, field, "state", byte_type_node);
+ PUSH_FIELD (input_location, class_type_node, field, "thread", ptr_type_node);
+ PUSH_FIELD (input_location,
+ class_type_node, field, "depth", short_type_node);
+ PUSH_FIELD (input_location,
+ class_type_node, field, "ancestors", ptr_type_node);
+ PUSH_FIELD (input_location, class_type_node, field, "idt", ptr_type_node);
+ PUSH_FIELD (input_location,
+ class_type_node, field, "arrayclass", ptr_type_node);
+ PUSH_FIELD (input_location,
+ class_type_node, field, "protectionDomain", ptr_type_node);
+ PUSH_FIELD (input_location,
+ class_type_node, field, "assertion_table", ptr_type_node);
+ PUSH_FIELD (input_location,
+ class_type_node, field, "hack_signers", ptr_type_node);
+ PUSH_FIELD (input_location, class_type_node, field, "chain", ptr_type_node);
+ PUSH_FIELD (input_location,
+ class_type_node, field, "aux_info", ptr_type_node);
+ PUSH_FIELD (input_location, class_type_node, field, "engine", ptr_type_node);
+ PUSH_FIELD (input_location,
+ class_type_node, field, "reflection_data", ptr_type_node);
for (t = TYPE_FIELDS (class_type_node); t != NULL_TREE; t = TREE_CHAIN (t))
FIELD_PRIVATE (t) = 1;
push_super_field (class_type_node, object_type_node);
FINISH_RECORD (class_type_node);
- build_decl (TYPE_DECL, get_identifier ("Class"), class_type_node);
+ build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier ("Class"), class_type_node);
field_info_union_node = make_node (UNION_TYPE);
- PUSH_FIELD (field_info_union_node, field, "boffset", int_type_node);
- PUSH_FIELD (field_info_union_node, field, "addr", ptr_type_node);
+ PUSH_FIELD (input_location,
+ field_info_union_node, field, "boffset", int_type_node);
+ PUSH_FIELD (input_location,
+ field_info_union_node, field, "addr", ptr_type_node);
layout_type (field_info_union_node);
- PUSH_FIELD (field_type_node, field, "name", utf8const_ptr_type);
- PUSH_FIELD (field_type_node, field, "type", class_ptr_type);
- PUSH_FIELD (field_type_node, field, "accflags", access_flags_type_node);
- PUSH_FIELD (field_type_node, field, "bsize", unsigned_short_type_node);
- PUSH_FIELD (field_type_node, field, "info", field_info_union_node);
+ PUSH_FIELD (input_location,
+ field_type_node, field, "name", utf8const_ptr_type);
+ PUSH_FIELD (input_location, field_type_node, field, "type", class_ptr_type);
+ PUSH_FIELD (input_location,
+ field_type_node, field, "accflags", access_flags_type_node);
+ PUSH_FIELD (input_location,
+ field_type_node, field, "bsize", unsigned_short_type_node);
+ PUSH_FIELD (input_location,
+ field_type_node, field, "info", field_info_union_node);
FINISH_RECORD (field_type_node);
- build_decl (TYPE_DECL, get_identifier ("Field"), field_type_node);
+ build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier ("Field"), field_type_node);
nativecode_ptr_array_type_node
= build_array_type (nativecode_ptr_type_node, one_elt_array_domain_type);
- PUSH_FIELD (dtable_type, field, "class", class_ptr_type);
- PUSH_FIELD (dtable_type, field, "methods", nativecode_ptr_array_type_node);
+ PUSH_FIELD (input_location,
+ dtable_type, field, "class", class_ptr_type);
+ PUSH_FIELD (input_location,
+ dtable_type, field, "methods", nativecode_ptr_array_type_node);
FINISH_RECORD (dtable_type);
- build_decl (TYPE_DECL, get_identifier ("dispatchTable"), dtable_type);
+ build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier ("dispatchTable"), dtable_type);
jexception_type = make_node (RECORD_TYPE);
- PUSH_FIELD (jexception_type, field, "start_pc", ptr_type_node);
- PUSH_FIELD (jexception_type, field, "end_pc", ptr_type_node);
- PUSH_FIELD (jexception_type, field, "handler_pc", ptr_type_node);
- PUSH_FIELD (jexception_type, field, "catch_type", class_ptr_type);
+ PUSH_FIELD (input_location,
+ jexception_type, field, "start_pc", ptr_type_node);
+ PUSH_FIELD (input_location, jexception_type, field, "end_pc", ptr_type_node);
+ PUSH_FIELD (input_location,
+ jexception_type, field, "handler_pc", ptr_type_node);
+ PUSH_FIELD (input_location,
+ jexception_type, field, "catch_type", class_ptr_type);
FINISH_RECORD (jexception_type);
- build_decl (TYPE_DECL, get_identifier ("jexception"), field_type_node);
+ build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier ("jexception"), field_type_node);
jexception_ptr_type = build_pointer_type (jexception_type);
lineNumberEntry_type = make_node (RECORD_TYPE);
- PUSH_FIELD (lineNumberEntry_type, field, "line_nr", unsigned_short_type_node);
- PUSH_FIELD (lineNumberEntry_type, field, "start_pc", ptr_type_node);
+ PUSH_FIELD (input_location,
+ lineNumberEntry_type, field, "line_nr", unsigned_short_type_node);
+ PUSH_FIELD (input_location,
+ lineNumberEntry_type, field, "start_pc", ptr_type_node);
FINISH_RECORD (lineNumberEntry_type);
lineNumbers_type = make_node (RECORD_TYPE);
- PUSH_FIELD (lineNumbers_type, field, "length", unsigned_int_type_node);
+ PUSH_FIELD (input_location,
+ lineNumbers_type, field, "length", unsigned_int_type_node);
FINISH_RECORD (lineNumbers_type);
- PUSH_FIELD (method_type_node, field, "name", utf8const_ptr_type);
- PUSH_FIELD (method_type_node, field, "signature", utf8const_ptr_type);
- PUSH_FIELD (method_type_node, field, "accflags", access_flags_type_node);
- PUSH_FIELD (method_type_node, field, "index", unsigned_short_type_node);
- PUSH_FIELD (method_type_node, field, "ncode", nativecode_ptr_type_node);
- PUSH_FIELD (method_type_node, field, "throws", ptr_type_node);
+ PUSH_FIELD (input_location,
+ method_type_node, field, "name", utf8const_ptr_type);
+ PUSH_FIELD (input_location,
+ method_type_node, field, "signature", utf8const_ptr_type);
+ PUSH_FIELD (input_location,
+ method_type_node, field, "accflags", access_flags_type_node);
+ PUSH_FIELD (input_location,
+ method_type_node, field, "index", unsigned_short_type_node);
+ PUSH_FIELD (input_location,
+ method_type_node, field, "ncode", nativecode_ptr_type_node);
+ PUSH_FIELD (input_location,
+ method_type_node, field, "throws", ptr_type_node);
FINISH_RECORD (method_type_node);
- build_decl (TYPE_DECL, get_identifier ("Method"), method_type_node);
+ build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier ("Method"), method_type_node);
endlink = end_params_node = tree_cons (NULL_TREE, void_type_node, NULL_TREE);
@@ -1632,7 +1713,7 @@ give_name_to_locals (JCF *jcf)
{
tree *ptr;
int end_pc = start_pc + length;
- tree decl = build_decl (VAR_DECL, name, type);
+ tree decl = build_decl (input_location, VAR_DECL, name, type);
if (end_pc > DECL_CODE_LENGTH (current_function_decl))
{
warning (0, "bad PC range for debug info for local %q+D",
@@ -1694,7 +1775,8 @@ build_result_decl (tree fndecl)
tree result = DECL_RESULT (fndecl);
if (! result)
{
- result = build_decl (RESULT_DECL, NULL_TREE, restype);
+ result = build_decl (DECL_SOURCE_LOCATION (fndecl),
+ RESULT_DECL, NULL_TREE, restype);
DECL_ARTIFICIAL (result) = 1;
DECL_IGNORED_P (result) = 1;
DECL_CONTEXT (result) = fndecl;
@@ -1733,7 +1815,7 @@ start_java_method (tree fndecl)
tree parm_type = TREE_VALUE (tem);
gcc_assert (i < DECL_MAX_LOCALS (fndecl));
- parm_decl = build_decl (PARM_DECL, parm_name, parm_type);
+ parm_decl = build_decl (input_location, PARM_DECL, parm_name, parm_type);
DECL_CONTEXT (parm_decl) = fndecl;
if (targetm.calls.promote_prototypes (parm_type)
&& TYPE_PRECISION (parm_type) < TYPE_PRECISION (integer_type_node)
diff --git a/gcc/java/except.c b/gcc/java/except.c
index d163ba0e1b7..e97ed7755d9 100644
--- a/gcc/java/except.c
+++ b/gcc/java/except.c
@@ -393,7 +393,8 @@ prepare_eh_table_type (tree type)
name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
buf = (char *) alloca (strlen (name) + 5);
sprintf (buf, "%s_ref", name);
- decl = build_decl (VAR_DECL, get_identifier (buf), ptr_type_node);
+ decl = build_decl (input_location,
+ VAR_DECL, get_identifier (buf), ptr_type_node);
TREE_STATIC (decl) = 1;
DECL_ARTIFICIAL (decl) = 1;
DECL_IGNORED_P (decl) = 1;
@@ -410,7 +411,8 @@ prepare_eh_table_type (tree type)
name = IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (utf8_ref, 0)));
buf = (char *) alloca (strlen (name) + 5);
sprintf (buf, "%s_ref", name);
- decl = build_decl (VAR_DECL, get_identifier (buf), utf8const_ptr_type);
+ decl = build_decl (input_location,
+ VAR_DECL, get_identifier (buf), utf8const_ptr_type);
TREE_STATIC (decl) = 1;
DECL_ARTIFICIAL (decl) = 1;
DECL_IGNORED_P (decl) = 1;
diff --git a/gcc/java/expr.c b/gcc/java/expr.c
index 858bc937d93..72ca77303ec 100644
--- a/gcc/java/expr.c
+++ b/gcc/java/expr.c
@@ -669,7 +669,7 @@ java_stack_swap (void)
flush_quick_stack ();
decl1 = find_stack_slot (stack_pointer - 1, type1);
decl2 = find_stack_slot (stack_pointer - 2, type2);
- temp = build_decl (VAR_DECL, NULL_TREE, type1);
+ temp = build_decl (input_location, VAR_DECL, NULL_TREE, type1);
java_add_local_var (temp);
java_add_stmt (build2 (MODIFY_EXPR, type1, temp, decl1));
java_add_stmt (build2 (MODIFY_EXPR, type2,
@@ -1192,7 +1192,7 @@ expand_java_arraystore (tree rhs_type_node)
MODIFY_EXPR to set the array element. */
access = build_java_arrayaccess (array, rhs_type_node, index);
- temp = build_decl (VAR_DECL, NULL_TREE,
+ temp = build_decl (input_location, VAR_DECL, NULL_TREE,
build_pointer_type (TREE_TYPE (access)));
java_add_local_var (temp);
java_add_stmt (build2 (MODIFY_EXPR, TREE_TYPE (temp),
@@ -1332,7 +1332,7 @@ expand_load_internal (int index, tree type, int pc)
generated. To avoid this we create a new local and copy our
value into it. Then we push this new local on the stack.
Hopefully this all gets optimized out. */
- copy = build_decl (VAR_DECL, NULL_TREE, type);
+ copy = build_decl (input_location, VAR_DECL, NULL_TREE, type);
if ((INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type))
&& TREE_TYPE (copy) != TREE_TYPE (var))
var = convert (type, var);
@@ -1824,7 +1824,7 @@ tree
create_label_decl (tree name)
{
tree decl;
- decl = build_decl (LABEL_DECL, name,
+ decl = build_decl (input_location, LABEL_DECL, name,
TREE_TYPE (return_address_type_node));
DECL_CONTEXT (decl) = current_function_decl;
DECL_IGNORED_P (decl) = 1;
@@ -1907,7 +1907,7 @@ expand_java_switch (tree selector, int default_pc)
java_add_stmt (switch_expr);
x = build3 (CASE_LABEL_EXPR, void_type_node, NULL_TREE, NULL_TREE,
- create_artificial_label ());
+ create_artificial_label (input_location));
append_to_statement_list (x, &SWITCH_BODY (switch_expr));
x = build1 (GOTO_EXPR, void_type_node, lookup_label (default_pc));
@@ -1924,7 +1924,7 @@ expand_java_add_case (tree switch_expr, int match, int target_pc)
value = build_int_cst (TREE_TYPE (switch_expr), match);
x = build3 (CASE_LABEL_EXPR, void_type_node, value, NULL_TREE,
- create_artificial_label ());
+ create_artificial_label (input_location));
append_to_statement_list (x, &SWITCH_BODY (switch_expr));
x = build1 (GOTO_EXPR, void_type_node, lookup_label (target_pc));
@@ -2026,7 +2026,7 @@ build_class_init (tree clas, tree expr)
{
/* Build a declaration and mark it as a flag used to track
static class initializations. */
- decl = build_decl (VAR_DECL, NULL_TREE,
+ decl = build_decl (input_location, VAR_DECL, NULL_TREE,
boolean_type_node);
MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);
DECL_CONTEXT (decl) = current_function_decl;
@@ -2666,12 +2666,13 @@ build_jni_stub (tree method)
DECL_ARTIFICIAL (method) = 1;
DECL_EXTERNAL (method) = 0;
- env_var = build_decl (VAR_DECL, get_identifier ("env"), ptr_type_node);
+ env_var = build_decl (input_location,
+ VAR_DECL, get_identifier ("env"), ptr_type_node);
DECL_CONTEXT (env_var) = method;
if (TREE_TYPE (TREE_TYPE (method)) != void_type_node)
{
- res_var = build_decl (VAR_DECL, get_identifier ("res"),
+ res_var = build_decl (input_location, VAR_DECL, get_identifier ("res"),
TREE_TYPE (TREE_TYPE (method)));
DECL_CONTEXT (res_var) = method;
TREE_CHAIN (env_var) = res_var;
@@ -2745,7 +2746,8 @@ build_jni_stub (tree method)
garbage-collected. If it is, we end up using canonical types
with different uids for equivalent function types, and this in
turn causes utf8 identifiers and output order to vary. */
- meth_var = build_decl (VAR_DECL, get_identifier ("meth"), jni_func_type);
+ meth_var = build_decl (input_location,
+ VAR_DECL, get_identifier ("meth"), jni_func_type);
TREE_STATIC (meth_var) = 1;
TREE_PUBLIC (meth_var) = 0;
DECL_EXTERNAL (meth_var) = 0;
@@ -2971,7 +2973,8 @@ expand_java_field_op (int is_static, int is_putting, int field_ref_index)
}
else
{
- tree temp = build_decl (VAR_DECL, NULL_TREE, TREE_TYPE (field_ref));
+ tree temp = build_decl (input_location,
+ VAR_DECL, NULL_TREE, TREE_TYPE (field_ref));
java_add_local_var (temp);
if (TREE_THIS_VOLATILE (field_decl))
@@ -3795,7 +3798,7 @@ force_evaluation_order (tree node)
tree
build_java_empty_stmt (void)
{
- tree t = build_empty_stmt ();
+ tree t = build_empty_stmt (input_location);
return t;
}
@@ -3832,7 +3835,7 @@ cache_cpool_data_ref (void)
{
tree cpool;
tree d = build_constant_data_ref (flag_indirect_classes);
- tree cpool_ptr = build_decl (VAR_DECL, NULL_TREE,
+ tree cpool_ptr = build_decl (input_location, VAR_DECL, NULL_TREE,
build_pointer_type (TREE_TYPE (d)));
java_add_local_var (cpool_ptr);
TREE_CONSTANT (cpool_ptr) = 1;
diff --git a/gcc/java/java-gimplify.c b/gcc/java/java-gimplify.c
index e2ad02b697a..c460e5b0941 100644
--- a/gcc/java/java-gimplify.c
+++ b/gcc/java/java-gimplify.c
@@ -163,7 +163,7 @@ java_gimplify_block (tree java_block)
/* Don't bother with empty blocks. */
if (! body)
- return build_empty_stmt ();
+ return build_empty_stmt (input_location);
if (IS_EMPTY_STMT (body))
return body;
diff --git a/gcc/java/java-tree.h b/gcc/java/java-tree.h
index 9ab76606b46..98352a2eaf2 100644
--- a/gcc/java/java-tree.h
+++ b/gcc/java/java-tree.h
@@ -1435,15 +1435,15 @@ extern tree *type_map;
#define DECL_INNER_CLASS_LIST(NODE) DECL_INITIAL (TYPE_DECL_CHECK (NODE))
/* Add a FIELD_DECL to RECORD_TYPE RTYPE.
- The field has name NAME (a char*), and type FTYPE.
+ The field has name NAME (a char*), a type FTYPE, and a location of LOC.
Unless this is the first field, FIELD most hold the previous field.
FIELD is set to the newly created FIELD_DECL.
We set DECL_ARTIFICIAL so these fields get skipped by make_class_data
if compiling java.lang.Object or java.lang.Class. */
-#define PUSH_FIELD(RTYPE, FIELD, NAME, FTYPE) \
-{ tree _field = build_decl (FIELD_DECL, get_identifier ((NAME)), (FTYPE)); \
+#define PUSH_FIELD(LOC, RTYPE, FIELD, NAME, FTYPE) \
+{ tree _field = build_decl (LOC, FIELD_DECL, get_identifier ((NAME)), (FTYPE)); \
if (TYPE_FIELDS (RTYPE) == NULL_TREE) \
TYPE_FIELDS (RTYPE) = _field; \
else \
diff --git a/gcc/java/jcf-io.c b/gcc/java/jcf-io.c
index b968214e509..28a48bb4504 100644
--- a/gcc/java/jcf-io.c
+++ b/gcc/java/jcf-io.c
@@ -1,6 +1,6 @@
/* Utility routines for finding and reading Java(TM) .class files.
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005,
- 2006, 2007, 2008 Free Software Foundation, Inc.
+ 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
This file is part of GCC.
@@ -399,9 +399,8 @@ find_class (const char *classname, int classname_length, JCF *jcf)
/* Remember that this class could not be found so that we do not
have to look again. */
- *(const void **)htab_find_slot_with_hash (memoized_class_lookups,
- classname, hash, INSERT)
- = classname;
+ *htab_find_slot_with_hash (memoized_class_lookups, classname, hash, INSERT)
+ = (void *) CONST_CAST (char *, classname);
return NULL;
found:
diff --git a/gcc/java/jcf-parse.c b/gcc/java/jcf-parse.c
index e3b933182a9..98c98c8bd90 100644
--- a/gcc/java/jcf-parse.c
+++ b/gcc/java/jcf-parse.c
@@ -498,7 +498,7 @@ handle_long_constant (JCF *jcf, CPool *cpool, enum cpool_tag kind,
static uint16
handle_constant (JCF *jcf, int index, enum cpool_tag purpose)
{
- enum cpool_tag kind;
+ unsigned int kind;
CPool *cpool = cpool_for_class (output_class);
if (index == 0)
@@ -507,7 +507,7 @@ handle_constant (JCF *jcf, int index, enum cpool_tag purpose)
if (! CPOOL_INDEX_IN_RANGE (&jcf->cpool, index))
error ("<constant pool index %d not in range>", index);
- kind = (enum cpool_tag) JPOOL_TAG (jcf, index);
+ kind = JPOOL_TAG (jcf, index);
if ((kind & ~CONSTANT_ResolvedFlag) != purpose)
{
@@ -555,12 +555,12 @@ handle_constant (JCF *jcf, int index, enum cpool_tag purpose)
break;
case CONSTANT_Long:
- index = handle_long_constant (jcf, cpool, kind, index,
+ index = handle_long_constant (jcf, cpool, CONSTANT_Long, index,
WORDS_BIG_ENDIAN);
break;
case CONSTANT_Double:
- index = handle_long_constant (jcf, cpool, kind, index,
+ index = handle_long_constant (jcf, cpool, CONSTANT_Double, index,
FLOAT_WORDS_BIG_ENDIAN);
break;
@@ -1703,10 +1703,11 @@ java_emit_static_constructor (void)
tree name = get_identifier ("_Jv_global_static_constructor");
tree decl
- = build_decl (FUNCTION_DECL, name,
+ = build_decl (input_location, FUNCTION_DECL, name,
build_function_type (void_type_node, void_list_node));
- tree resdecl = build_decl (RESULT_DECL, NULL_TREE, void_type_node);
+ tree resdecl = build_decl (input_location,
+ RESULT_DECL, NULL_TREE, void_type_node);
DECL_ARTIFICIAL (resdecl) = 1;
DECL_RESULT (decl) = resdecl;
current_function_decl = decl;
@@ -1835,7 +1836,8 @@ java_parse_file (int set_yydebug ATTRIBUTE_UNUSED)
duplicate_class_warning (IDENTIFIER_POINTER (node));
else
{
- tree file_decl = build_decl (TRANSLATION_UNIT_DECL, node, NULL);
+ tree file_decl = build_decl (input_location,
+ TRANSLATION_UNIT_DECL, node, NULL);
TREE_CHAIN (file_decl) = current_file_list;
current_file_list = file_decl;
IS_A_COMMAND_LINE_FILENAME_P (node) = 1;
diff --git a/gcc/java/resource.c b/gcc/java/resource.c
index e6e50bab94a..550e1d505d8 100644
--- a/gcc/java/resource.c
+++ b/gcc/java/resource.c
@@ -59,9 +59,11 @@ compile_resource_data (const char *name, const char *buffer, int length)
data_type = build_prim_array_type (unsigned_byte_type_node,
strlen (name) + length);
rtype = make_node (RECORD_TYPE);
- PUSH_FIELD (rtype, field, "name_length", unsigned_int_type_node);
- PUSH_FIELD (rtype, field, "resource_length", unsigned_int_type_node);
- PUSH_FIELD (rtype, field, "data", data_type);
+ PUSH_FIELD (input_location,
+ rtype, field, "name_length", unsigned_int_type_node);
+ PUSH_FIELD (input_location,
+ rtype, field, "resource_length", unsigned_int_type_node);
+ PUSH_FIELD (input_location, rtype, field, "data", data_type);
FINISH_RECORD (rtype);
START_RECORD_CONSTRUCTOR (rinit, rtype);
PUSH_FIELD_VALUE (rinit, "name_length",
@@ -74,7 +76,8 @@ compile_resource_data (const char *name, const char *buffer, int length)
FINISH_RECORD_CONSTRUCTOR (rinit);
TREE_CONSTANT (rinit) = 1;
- decl = build_decl (VAR_DECL, java_mangle_resource_name (name), rtype);
+ decl = build_decl (input_location,
+ VAR_DECL, java_mangle_resource_name (name), rtype);
TREE_STATIC (decl) = 1;
TREE_PUBLIC (decl) = 1;
java_hide_decl (decl);
@@ -100,7 +103,8 @@ write_resource_constructor (tree *list_p)
return;
t = build_function_type_list (void_type_node, ptr_type_node, NULL);
- t = build_decl (FUNCTION_DECL, get_identifier ("_Jv_RegisterResource"), t);
+ t = build_decl (input_location,
+ FUNCTION_DECL, get_identifier ("_Jv_RegisterResource"), t);
TREE_PUBLIC (t) = 1;
DECL_EXTERNAL (t) = 1;
register_resource_fn = t;
diff --git a/gcc/java/typeck.c b/gcc/java/typeck.c
index e812f31b829..c16976ca3b0 100644
--- a/gcc/java/typeck.c
+++ b/gcc/java/typeck.c
@@ -347,7 +347,7 @@ build_java_array_type (tree element_type, HOST_WIDE_INT length)
strcpy (suffix, "[]");
TYPE_NAME (t)
= TYPE_STUB_DECL (t)
- = build_decl (TYPE_DECL,
+ = build_decl (input_location, TYPE_DECL,
identifier_subst (el_name, "", '.', '.', suffix),
t);
TYPE_DECL_SUPPRESS_DEBUG (TYPE_STUB_DECL (t)) = true;
@@ -360,7 +360,8 @@ build_java_array_type (tree element_type, HOST_WIDE_INT length)
TYPE_ARRAY_ELEMENT (t) = element_type;
/* Add length pseudo-field. */
- fld = build_decl (FIELD_DECL, get_identifier ("length"), int_type_node);
+ fld = build_decl (input_location,
+ FIELD_DECL, get_identifier ("length"), int_type_node);
TYPE_FIELDS (t) = fld;
DECL_CONTEXT (fld) = t;
FIELD_PUBLIC (fld) = 1;
@@ -368,7 +369,8 @@ build_java_array_type (tree element_type, HOST_WIDE_INT length)
TREE_READONLY (fld) = 1;
atype = build_prim_array_type (element_type, length);
- arfld = build_decl (FIELD_DECL, get_identifier ("data"), atype);
+ arfld = build_decl (input_location,
+ FIELD_DECL, get_identifier ("data"), atype);
DECL_CONTEXT (arfld) = t;
TREE_CHAIN (fld) = arfld;
DECL_ALIGN (arfld) = TYPE_ALIGN (element_type);
diff --git a/gcc/java/verify.h b/gcc/java/verify.h
index 21fe67254fb..8c3184447eb 100644
--- a/gcc/java/verify.h
+++ b/gcc/java/verify.h
@@ -1,5 +1,6 @@
/* Declarations to interface gcj with bytecode verifier.
- Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2004, 2005, 2006, 2007, 2009
+ Free Software Foundation, Inc.
This file is part of GCC.
@@ -26,11 +27,6 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#ifndef GCC_VERIFY_H
#define GCC_VERIFY_H
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
#include "system.h"
#include "coretypes.h"
#include "jcf.h"
@@ -155,8 +151,4 @@ typedef enum
int verify_method (vfy_method *meth);
-#ifdef __cplusplus
-}
-#endif
-
#endif /* ! GCC_VERIFY_H */
diff --git a/gcc/jump.c b/gcc/jump.c
index 90359f8f997..350de16f07c 100644
--- a/gcc/jump.c
+++ b/gcc/jump.c
@@ -869,18 +869,54 @@ returnjump_p_1 (rtx *loc, void *data ATTRIBUTE_UNUSED)
{
rtx x = *loc;
- return x && (GET_CODE (x) == RETURN
- || (GET_CODE (x) == SET && SET_IS_RETURN_P (x)));
+ if (x == NULL)
+ return false;
+
+ switch (GET_CODE (x))
+ {
+ case RETURN:
+ case EH_RETURN:
+ return true;
+
+ case SET:
+ return SET_IS_RETURN_P (x);
+
+ default:
+ return false;
+ }
}
+/* Return TRUE if INSN is a return jump. */
+
int
returnjump_p (rtx insn)
{
+ /* Handle delayed branches. */
+ if (NONJUMP_INSN_P (insn) && GET_CODE (PATTERN (insn)) == SEQUENCE)
+ insn = XVECEXP (PATTERN (insn), 0, 0);
+
if (!JUMP_P (insn))
return 0;
+
return for_each_rtx (&PATTERN (insn), returnjump_p_1, NULL);
}
+/* Return true if INSN is a (possibly conditional) return insn. */
+
+static int
+eh_returnjump_p_1 (rtx *loc, void *data ATTRIBUTE_UNUSED)
+{
+ return *loc && GET_CODE (*loc) == EH_RETURN;
+}
+
+int
+eh_returnjump_p (rtx insn)
+{
+ if (!JUMP_P (insn))
+ return 0;
+ return for_each_rtx (&PATTERN (insn), eh_returnjump_p_1, NULL);
+}
+
/* Return true if INSN is a jump that only transfers control and
nothing more. */
diff --git a/gcc/langhooks-def.h b/gcc/langhooks-def.h
index 4b6ce274c00..2631ff8db7f 100644
--- a/gcc/langhooks-def.h
+++ b/gcc/langhooks-def.h
@@ -58,7 +58,6 @@ extern void lhd_incomplete_type_error (const_tree, const_tree);
extern tree lhd_type_promotes_to (tree);
extern void lhd_register_builtin_type (tree, const char *);
extern bool lhd_decl_ok_for_sibcall (const_tree);
-extern const char *lhd_comdat_group (tree);
extern tree lhd_expr_size (const_tree);
extern size_t lhd_tree_size (enum tree_code);
extern HOST_WIDE_INT lhd_to_target_charset (HOST_WIDE_INT);
@@ -161,6 +160,7 @@ extern tree lhd_make_node (enum tree_code);
lhd_omp_firstprivatize_type_sizes
#define LANG_HOOKS_TYPE_HASH_EQ NULL
#define LANG_HOOKS_GET_ARRAY_DESCR_INFO NULL
+#define LANG_HOOKS_GET_SUBRANGE_BOUNDS NULL
#define LANG_HOOKS_RECONSTRUCT_COMPLEX_TYPE reconstruct_complex_type
#define LANG_HOOKS_HASH_TYPES true
@@ -177,6 +177,7 @@ extern tree lhd_make_node (enum tree_code);
LANG_HOOKS_OMP_FIRSTPRIVATIZE_TYPE_SIZES, \
LANG_HOOKS_TYPE_HASH_EQ, \
LANG_HOOKS_GET_ARRAY_DESCR_INFO, \
+ LANG_HOOKS_GET_SUBRANGE_BOUNDS, \
LANG_HOOKS_RECONSTRUCT_COMPLEX_TYPE, \
LANG_HOOKS_HASH_TYPES \
}
@@ -189,7 +190,6 @@ extern tree lhd_make_node (enum tree_code);
#define LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL lhd_warn_unused_global_decl
#define LANG_HOOKS_WRITE_GLOBALS write_global_declarations
#define LANG_HOOKS_DECL_OK_FOR_SIBCALL lhd_decl_ok_for_sibcall
-#define LANG_HOOKS_COMDAT_GROUP lhd_comdat_group
#define LANG_HOOKS_OMP_PRIVATIZE_BY_REFERENCE hook_bool_const_tree_false
#define LANG_HOOKS_OMP_PREDETERMINED_SHARING lhd_omp_predetermined_sharing
#define LANG_HOOKS_OMP_DISREGARD_VALUE_EXPR hook_bool_tree_bool_false
@@ -209,7 +209,6 @@ extern tree lhd_make_node (enum tree_code);
LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL, \
LANG_HOOKS_WRITE_GLOBALS, \
LANG_HOOKS_DECL_OK_FOR_SIBCALL, \
- LANG_HOOKS_COMDAT_GROUP, \
LANG_HOOKS_OMP_PRIVATIZE_BY_REFERENCE, \
LANG_HOOKS_OMP_PREDETERMINED_SHARING, \
LANG_HOOKS_OMP_DISREGARD_VALUE_EXPR, \
diff --git a/gcc/langhooks.c b/gcc/langhooks.c
index 8579062e715..ff20dd16600 100644
--- a/gcc/langhooks.c
+++ b/gcc/langhooks.c
@@ -300,14 +300,6 @@ lhd_decl_ok_for_sibcall (const_tree decl ATTRIBUTE_UNUSED)
return true;
}
-/* Return the COMDAT group into which DECL should be placed. */
-
-const char *
-lhd_comdat_group (tree decl)
-{
- return IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
-}
-
/* lang_hooks.decls.final_write_globals: perform final processing on
global variables. */
void
@@ -432,7 +424,7 @@ lhd_print_error_function (diagnostic_context *context, const char *file,
pp_newline (context->printer);
if (s.file != NULL)
{
- if (flag_show_column && s.column != 0)
+ if (flag_show_column)
pp_printf (context->printer,
_(" inlined from %qs at %s:%d:%d"),
identifier_to_locale (lang_hooks.decl_printable_name (fndecl, 2)),
@@ -524,7 +516,7 @@ add_builtin_function_common (const char *name,
tree (*hook) (tree))
{
tree id = get_identifier (name);
- tree decl = build_decl (FUNCTION_DECL, id, type);
+ tree decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL, id, type);
TREE_PUBLIC (decl) = 1;
DECL_EXTERNAL (decl) = 1;
diff --git a/gcc/langhooks.h b/gcc/langhooks.h
index 0694189d730..ed3e7e72919 100644
--- a/gcc/langhooks.h
+++ b/gcc/langhooks.h
@@ -130,6 +130,9 @@ struct lang_hooks_for_types
for the debugger about the array bounds, strides, etc. */
bool (*get_array_descr_info) (const_tree, struct array_descr_info *);
+ /* Fill in information for the debugger about the bounds of TYPE. */
+ void (*get_subrange_bounds) (const_tree, tree *, tree *);
+
/* If we requested a pointer to a vector, build up the pointers that
we stripped off while looking for the inner type. Similarly for
return values from functions. The argument TYPE is the top of the
@@ -173,15 +176,6 @@ struct lang_hooks_for_decls
/* True if this decl may be called via a sibcall. */
bool (*ok_for_sibcall) (const_tree);
- /* Return the COMDAT group into which this DECL should be placed.
- It is known that the DECL belongs in *some* COMDAT group when
- this hook is called. The return value will be used immediately,
- but not explicitly deallocated, so implementations should not use
- xmalloc to allocate the string returned. (Typically, the return
- value will be the string already stored in an
- IDENTIFIER_NODE.) */
- const char * (*comdat_group) (tree);
-
/* True if OpenMP should privatize what this DECL points to rather
than the DECL itself. */
bool (*omp_privatize_by_reference) (const_tree);
diff --git a/gcc/matrix-reorg.c b/gcc/matrix-reorg.c
index 7b8de0b8909..d2687b86e47 100644
--- a/gcc/matrix-reorg.c
+++ b/gcc/matrix-reorg.c
@@ -140,6 +140,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-data-ref.h"
#include "tree-chrec.h"
#include "tree-scalar-evolution.h"
+#include "tree-ssa-sccvn.h"
/* We need to collect a lot of data from the original malloc,
particularly as the gimplifier has converted:
diff --git a/gcc/mips-tdump.c b/gcc/mips-tdump.c
index df902a6deb4..240e9e8b887 100644
--- a/gcc/mips-tdump.c
+++ b/gcc/mips-tdump.c
@@ -1116,7 +1116,7 @@ print_file_desc (FDR *fdp, int number)
(fdp->fBigendian) ? "BIG" : "LITTLE");
printf (" Debug level = %-10s Language = %s\n",
- glevel_to_string (fdp->glevel),
+ glevel_to_string ((glevel_t) fdp->glevel),
lang_to_string((lang_t) fdp->lang));
printf (" Adr = 0x%08lx\n\n", (long) fdp->adr);
diff --git a/gcc/mips-tfile.c b/gcc/mips-tfile.c
index f8bb492b381..07d229e672c 100644
--- a/gcc/mips-tfile.c
+++ b/gcc/mips-tfile.c
@@ -675,8 +675,6 @@ main (void)
#include "gstab.h"
-#define STAB_CODE_TYPE enum __stab_debug_code
-
#ifndef MALLOC_CHECK
#ifdef __SABER__
#define MALLOC_CHECK
@@ -1939,8 +1937,8 @@ add_ext_symbol (EXTR *esym, int ifd)
if (debug > 1)
{
long value = esym->asym.value;
- const char *sc_str = sc_to_string (esym->asym.sc);
- const char *st_str = st_to_string (esym->asym.st);
+ const char *sc_str = sc_to_string ((sc_t) esym->asym.sc);
+ const char *st_str = st_to_string ((st_t) esym->asym.st);
fprintf (stderr,
"\tesym\tv= %10ld, ifd= %2d, sc= %-12s",
@@ -3475,7 +3473,8 @@ mark_stabs (const char *start ATTRIBUTE_UNUSED)
stabs_seen = 1;
(void) add_local_symbol (stabs_symbol,
stabs_symbol + sizeof (stabs_symbol),
- stNil, scInfo, -1, MIPS_MARK_STAB (0));
+ (st_t) stNil, (sc_t) scInfo, -1,
+ MIPS_MARK_STAB (0));
}
}
@@ -3668,8 +3667,8 @@ parse_stabs_common (const char *string_start, /* start of string or NULL */
/* Traditionally, N_LBRAC and N_RBRAC are *not* relocated. */
if (code == (int) N_LBRAC || code == (int) N_RBRAC)
{
- sc = scNil;
- st = stNil;
+ sc = (sc_t) scNil;
+ st = (st_t) stNil;
}
else
{
diff --git a/gcc/objc/ChangeLog b/gcc/objc/ChangeLog
index a1f0f242b4c..2fe4b25be8c 100644
--- a/gcc/objc/ChangeLog
+++ b/gcc/objc/ChangeLog
@@ -1,3 +1,67 @@
+2009-06-15 Ian Lance Taylor <iant@google.com>
+
+ * objc-act.c (objc_start_function): Don't set
+ label_context_stack_se or label_context_stack_vm.
+
+2009-06-12 Aldy Hernandez <aldyh@redhat.com>
+
+ * objc-act.c (finish_var_decl): Pass location to finish_decl.
+ (objc_get_parm_info): Same.
+ (get_super_receiver): Same.
+ * objc-act.c (objc_build_component_ref): Pass location to
+ build_compound_ref.
+ (build_module_initializer_routine): Pass location to
+ c_end_compound_stmt.
+ (objc_generate_static_init_call): Pass location to build_stmt.
+ (build_typed_selector_reference): New location argument.
+ (build_selector_reference): Same.
+ (objc_substitute_decl): Pass location to build_array_ref.
+ (next_sjlj_build_try_catch_finally): Pass location to build_stmt.
+ (objc_begin_catch_clause): Same.
+ (objc_finish_try_stmt): Same.
+ (objc_finish_catch_clause): Pass location to c_end_compound_stmt.
+ (objc_build_throw_stmt): New argument.
+ (generate_shared_structures): Pass location to build_c_cast.
+ (objc_build_message_expr): Use local location.
+ (objc_finish_message_expr): Use input_location.
+ (build_objc_method_call): New argument.
+ (objc_build_selector_expr): Same.
+ (get_super_receiver): Pass location to build_c_cast,
+ build_modify_expr, build_compound_expr.
+ * objc-act.c: Add location to all calls to start_struct, build_decl,
+ finish_struct.
+
+2009-06-09 Ian Lance Taylor <iant@google.com>
+
+ * objc-act.c (objc_gimplify_expr): Change return type to int.
+ * objc-act.h: Update declaration.
+
+2009-06-08 Alexandre Oliva <aoliva@redhat.com>
+
+ * objc-act.c (objc_init): Skip print_struct_values during
+ -fcompare-debug-second.
+
+2009-06-03 Ian Lance Taylor <iant@google.com>
+
+ * Make-lang.in (cc1obj-checksum.o): Depend upon $(CONFIG_H) and
+ $(SYSTEM_H).
+
+2009-05-27 Ian Lance Taylor <iant@google.com>
+
+ * Make-lang.in (cc1obj-dummy$(exeext)): Change $(COMPILER) to
+ $(LINKER).
+ (cc1obj$(exeext)): Likewise.
+
+2009-05-26 Ian Lance Taylor <iant@google.com>
+
+ * Make-lang.in (cc1obj-dummy$(exeext)): Use $(COMPILER).
+ (cc1obj$(exeext)): Likewise.
+
+2009-05-20 Ian Lance Taylor <iant@google.com>
+
+ * objc-act.c (objc_generate_cxx_ctor_or_dtor): Pass NULL rather
+ than NULL_TREE to build_special_member_call.
+
2009-05-10 Ian Lance Taylor <iant@google.com>
* objc-act.c (objc_building_struct): New static variable.
diff --git a/gcc/objc/Make-lang.in b/gcc/objc/Make-lang.in
index 4f854ea78ae..bfe8a849091 100644
--- a/gcc/objc/Make-lang.in
+++ b/gcc/objc/Make-lang.in
@@ -1,6 +1,6 @@
# Top level -*- makefile -*- fragment for GNU Objective-C
# Copyright (C) 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2007,
-# 2008 Free Software Foundation, Inc.
+# 2008, 2009 Free Software Foundation, Inc.
#This file is part of GCC.
@@ -52,17 +52,17 @@ OBJC_OBJS = objc/objc-lang.o objc/objc-act.o
objc_OBJS = $(OBJC_OBJS) cc1obj-checksum.o
cc1obj-dummy$(exeext): $(OBJC_OBJS) $(C_AND_OBJC_OBJS) dummy-checksum.o $(BACKEND) $(LIBDEPS)
- $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ \
+ $(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
$(OBJC_OBJS) $(C_AND_OBJC_OBJS) dummy-checksum.o \
$(BACKEND) $(LIBS) $(BACKENDLIBS)
cc1obj-checksum.c : cc1obj-dummy$(exeext) build/genchecksum$(build_exeext)
build/genchecksum$(build_exeext) cc1obj-dummy$(exeext) > $@
-cc1obj-checksum.o : cc1obj-checksum.c
+cc1obj-checksum.o : cc1obj-checksum.c $(CONFIG_H) $(SYSTEM_H)
cc1obj$(exeext): $(OBJC_OBJS) $(C_AND_OBJC_OBJS) cc1obj-checksum.o $(BACKEND) $(LIBDEPS)
- $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ \
+ $(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
$(OBJC_OBJS) $(C_AND_OBJC_OBJS) cc1obj-checksum.o \
$(BACKEND) $(LIBS) $(BACKENDLIBS)
diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c
index a9e1608042a..f114b65ef4a 100644
--- a/gcc/objc/objc-act.c
+++ b/gcc/objc/objc-act.c
@@ -151,7 +151,7 @@ static void finish_objc (void);
/* Code generation. */
static tree objc_build_constructor (tree, tree);
-static tree build_objc_method_call (int, tree, tree, tree, tree);
+static tree build_objc_method_call (location_t, int, tree, tree, tree, tree);
static tree get_proto_encoding (tree);
static tree lookup_interface (tree);
static tree objc_add_static_instance (tree, tree);
@@ -430,8 +430,8 @@ objc_start_struct (tree name)
{
gcc_assert (!objc_building_struct);
objc_building_struct = true;
- return start_struct (RECORD_TYPE, name, &objc_in_struct, &objc_struct_types,
- UNKNOWN_LOCATION);
+ return start_struct (input_location, RECORD_TYPE,
+ name, &objc_in_struct, &objc_struct_types);
}
/* Finish building a struct for objc. */
@@ -441,8 +441,8 @@ objc_finish_struct (tree type, tree fieldlist)
{
gcc_assert (objc_building_struct);
objc_building_struct = false;
- return finish_struct (type, fieldlist, NULL_TREE, objc_in_struct,
- objc_struct_types);
+ return finish_struct (input_location, type, fieldlist, NULL_TREE,
+ objc_in_struct, objc_struct_types);
}
/* Some platforms pass small structures through registers versus
@@ -826,7 +826,8 @@ objc_build_struct (tree klass, tree fields, tree super_name)
{
/* Prepend a packed variant of the base class into the layout. This
is necessary to preserve ObjC ABI compatibility. */
- tree base = build_decl (FIELD_DECL, NULL_TREE, super);
+ tree base = build_decl (input_location,
+ FIELD_DECL, NULL_TREE, super);
tree field = TYPE_FIELDS (super);
while (field && TREE_CHAIN (field)
@@ -1287,7 +1288,7 @@ objc_build_component_ref (tree datum, tree component)
return finish_class_member_access_expr (datum, component, false,
tf_warning_or_error);
#else
- return build_component_ref (datum, component);
+ return build_component_ref (input_location, datum, component);
#endif
}
@@ -1482,7 +1483,8 @@ lookup_and_install_protocols (tree protocols)
static tree
create_field_decl (tree type, const char *name)
{
- return build_decl (FIELD_DECL, get_identifier (name), type);
+ return build_decl (input_location,
+ FIELD_DECL, get_identifier (name), type);
}
/* Create a global, static declaration for variable NAME of a given TYPE. The
@@ -1491,7 +1493,8 @@ create_field_decl (tree type, const char *name)
static tree
start_var_decl (tree type, const char *name)
{
- tree var = build_decl (VAR_DECL, get_identifier (name), type);
+ tree var = build_decl (input_location,
+ VAR_DECL, get_identifier (name), type);
TREE_STATIC (var) = 1;
DECL_INITIAL (var) = error_mark_node; /* A real initializer is coming... */
@@ -1510,7 +1513,7 @@ start_var_decl (tree type, const char *name)
static void
finish_var_decl (tree var, tree initializer)
{
- finish_decl (var, initializer, NULL_TREE, NULL_TREE);
+ finish_decl (var, input_location, initializer, NULL_TREE, NULL_TREE);
/* Ensure that the variable actually gets output. */
mark_decl_referenced (var);
/* Mark the decl to avoid "defined but not used" warning. */
@@ -1581,11 +1584,13 @@ synth_module_prologue (void)
/* Declare the 'id' and 'Class' typedefs. */
- type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
+ type = lang_hooks.decls.pushdecl (build_decl (input_location,
+ TYPE_DECL,
objc_object_name,
objc_object_type));
TREE_NO_WARNING (type) = 1;
- type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
+ type = lang_hooks.decls.pushdecl (build_decl (input_location,
+ TYPE_DECL,
objc_class_name,
objc_class_type));
TREE_NO_WARNING (type) = 1;
@@ -1843,11 +1848,14 @@ static tree
objc_build_internal_const_str_type (void)
{
tree type = (*lang_hooks.types.make_type) (RECORD_TYPE);
- tree fields = build_decl (FIELD_DECL, NULL_TREE, ptr_type_node);
- tree field = build_decl (FIELD_DECL, NULL_TREE, ptr_type_node);
+ tree fields = build_decl (input_location,
+ FIELD_DECL, NULL_TREE, ptr_type_node);
+ tree field = build_decl (input_location,
+ FIELD_DECL, NULL_TREE, ptr_type_node);
TREE_CHAIN (field) = fields; fields = field;
- field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
+ field = build_decl (input_location,
+ FIELD_DECL, NULL_TREE, unsigned_type_node);
TREE_CHAIN (field) = fields; fields = field;
/* NB: The finish_builtin_struct() routine expects FIELD_DECLs in
reverse order! */
@@ -1990,7 +1998,8 @@ objc_build_string_object (tree string)
= objc_add_static_instance (constructor, constant_string_type);
else
{
- var = build_decl (CONST_DECL, NULL, TREE_TYPE (constructor));
+ var = build_decl (input_location,
+ CONST_DECL, NULL, TREE_TYPE (constructor));
DECL_INITIAL (var) = constructor;
TREE_STATIC (var) = 1;
pushdecl_top_level (var);
@@ -2028,7 +2037,8 @@ objc_add_static_instance (tree constructor, tree class_decl)
}
sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
- decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
+ decl = build_decl (input_location,
+ VAR_DECL, get_identifier (buf), class_decl);
DECL_COMMON (decl) = 1;
TREE_STATIC (decl) = 1;
DECL_ARTIFICIAL (decl) = 1;
@@ -2371,7 +2381,8 @@ build_module_initializer_routine (void)
push_lang_context (lang_name_c); /* extern "C" */
#endif
- objc_push_parm (build_decl (PARM_DECL, NULL_TREE, void_type_node));
+ objc_push_parm (build_decl (input_location,
+ PARM_DECL, NULL_TREE, void_type_node));
objc_start_function (get_identifier (TAG_GNUINIT),
build_function_type (void_type_node,
OBJC_VOID_AT_END),
@@ -2379,12 +2390,13 @@ build_module_initializer_routine (void)
body = c_begin_compound_stmt (true);
add_stmt (build_function_call
- (execclass_decl,
+ (input_location,
+ execclass_decl,
build_tree_list
(NULL_TREE,
build_unary_op (input_location, ADDR_EXPR,
UOBJC_MODULES_decl, 0))));
- add_stmt (c_end_compound_stmt (body, true));
+ add_stmt (c_end_compound_stmt (input_location, body, true));
TREE_PUBLIC (current_function_decl) = 0;
@@ -2417,8 +2429,9 @@ objc_static_init_needed_p (void)
tree
objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED)
{
- add_stmt (build_stmt (EXPR_STMT,
- build_function_call (GNU_INIT_decl, NULL_TREE)));
+ add_stmt (build_stmt (input_location, EXPR_STMT,
+ build_function_call (input_location,
+ GNU_INIT_decl, NULL_TREE)));
return ctors;
}
@@ -2647,10 +2660,11 @@ get_proto_encoding (tree proto)
}
/* sel_ref_chain is a list whose "value" fields will be instances of
- identifier_node that represent the selector. */
+ identifier_node that represent the selector. LOC is the location of
+ the @selector. */
static tree
-build_typed_selector_reference (tree ident, tree prototype)
+build_typed_selector_reference (location_t loc, tree ident, tree prototype)
{
tree *chain = &sel_ref_chain;
tree expr;
@@ -2668,16 +2682,15 @@ build_typed_selector_reference (tree ident, tree prototype)
*chain = tree_cons (prototype, ident, NULL_TREE);
return_at_index:
- expr = build_unary_op (input_location, ADDR_EXPR,
- build_array_ref (UOBJC_SELECTOR_TABLE_decl,
- build_int_cst (NULL_TREE, index),
- input_location),
+ expr = build_unary_op (loc, ADDR_EXPR,
+ build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl,
+ build_int_cst (NULL_TREE, index)),
1);
return convert (objc_selector_type, expr);
}
static tree
-build_selector_reference (tree ident)
+build_selector_reference (location_t loc, tree ident)
{
tree *chain = &sel_ref_chain;
tree expr;
@@ -2688,9 +2701,8 @@ build_selector_reference (tree ident)
if (TREE_VALUE (*chain) == ident)
return (flag_next_runtime
? TREE_PURPOSE (*chain)
- : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
- build_int_cst (NULL_TREE, index),
- input_location));
+ : build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl,
+ build_int_cst (NULL_TREE, index)));
index++;
chain = &TREE_CHAIN (*chain);
@@ -2702,9 +2714,8 @@ build_selector_reference (tree ident)
return (flag_next_runtime
? expr
- : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
- build_int_cst (NULL_TREE, index),
- input_location));
+ : build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl,
+ build_int_cst (NULL_TREE, index)));
}
static GTY(()) int class_reference_idx;
@@ -2816,7 +2827,7 @@ objc_get_class_reference (tree ident)
IDENTIFIER_POINTER (ident)));
assemble_external (objc_get_class_decl);
- return build_function_call (objc_get_class_decl, params);
+ return build_function_call (input_location, objc_get_class_decl, params);
}
}
@@ -2884,7 +2895,8 @@ build_objc_string_decl (enum string_section section)
ident = get_identifier (buf);
- decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
+ decl = build_decl (input_location,
+ VAR_DECL, ident, build_array_type (char_type_node, 0));
DECL_EXTERNAL (decl) = 1;
TREE_PUBLIC (decl) = 0;
TREE_USED (decl) = 1;
@@ -2924,7 +2936,8 @@ objc_declare_alias (tree alias_ident, tree class_ident)
push_lang_context (lang_name_c); /* extern "C" */
#endif
lang_hooks.decls.pushdecl (build_decl
- (TYPE_DECL,
+ (input_location,
+ TYPE_DECL,
alias_ident,
xref_tag (RECORD_TYPE, underlying_class)));
#ifdef OBJCPLUS
@@ -3088,11 +3101,11 @@ objc_substitute_decl (tree expr, tree oldexpr, tree newexpr)
newexpr),
DECL_NAME (TREE_OPERAND (expr, 1)));
case ARRAY_REF:
- return build_array_ref (objc_substitute_decl (TREE_OPERAND (expr, 0),
+ return build_array_ref (input_location,
+ objc_substitute_decl (TREE_OPERAND (expr, 0),
oldexpr,
newexpr),
- TREE_OPERAND (expr, 1),
- input_location);
+ TREE_OPERAND (expr, 1));
case INDIRECT_REF:
return build_indirect_ref (input_location,
objc_substitute_decl (TREE_OPERAND (expr, 0),
@@ -3129,7 +3142,7 @@ objc_build_ivar_assignment (tree outervar, tree lhs, tree rhs)
NULL_TREE)));
assemble_external (func);
- return build_function_call (func, func_params);
+ return build_function_call (input_location, func, func_params);
}
static tree
@@ -3142,7 +3155,8 @@ objc_build_global_assignment (tree lhs, tree rhs)
NULL_TREE));
assemble_external (objc_assign_global_decl);
- return build_function_call (objc_assign_global_decl, func_params);
+ return build_function_call (input_location,
+ objc_assign_global_decl, func_params);
}
static tree
@@ -3155,7 +3169,8 @@ objc_build_strong_cast_assignment (tree lhs, tree rhs)
NULL_TREE));
assemble_external (objc_assign_strong_cast_decl);
- return build_function_call (objc_assign_strong_cast_decl, func_params);
+ return build_function_call (input_location,
+ objc_assign_strong_cast_decl, func_params);
}
static int
@@ -3422,7 +3437,8 @@ objc_create_temporary_var (tree type)
{
tree decl;
- decl = build_decl (VAR_DECL, NULL_TREE, type);
+ decl = build_decl (input_location,
+ VAR_DECL, NULL_TREE, type);
TREE_USED (decl) = 1;
DECL_ARTIFICIAL (decl) = 1;
DECL_IGNORED_P (decl) = 1;
@@ -3542,7 +3558,8 @@ next_sjlj_build_try_exit (void)
tree t;
t = build_fold_addr_expr (cur_try_context->stack_decl);
t = tree_cons (NULL, t, NULL);
- t = build_function_call (objc_exception_try_exit_decl, t);
+ t = build_function_call (input_location,
+ objc_exception_try_exit_decl, t);
return t;
}
@@ -3562,7 +3579,8 @@ next_sjlj_build_enter_and_setjmp (void)
t = build_fold_addr_expr (cur_try_context->stack_decl);
t = tree_cons (NULL, t, NULL);
- enter = build_function_call (objc_exception_try_enter_decl, t);
+ enter = build_function_call (input_location,
+ objc_exception_try_enter_decl, t);
t = objc_build_component_ref (cur_try_context->stack_decl,
get_identifier ("buf"));
@@ -3577,7 +3595,8 @@ next_sjlj_build_enter_and_setjmp (void)
t = convert (ptr_type_node, t);
#endif
t = tree_cons (NULL, t, NULL);
- sj = build_function_call (objc_setjmp_decl, t);
+ sj = build_function_call (input_location,
+ objc_setjmp_decl, t);
cond = build2 (COMPOUND_EXPR, TREE_TYPE (sj), enter, sj);
cond = c_common_truthvalue_conversion (input_location, cond);
@@ -3596,7 +3615,8 @@ next_sjlj_build_exc_extract (tree decl)
t = build_fold_addr_expr (cur_try_context->stack_decl);
t = tree_cons (NULL, t, NULL);
- t = build_function_call (objc_exception_extract_decl, t);
+ t = build_function_call (input_location,
+ objc_exception_extract_decl, t);
t = convert (TREE_TYPE (decl), t);
t = build2 (MODIFY_EXPR, void_type_node, decl, t);
@@ -3646,7 +3666,8 @@ next_sjlj_build_catch_list (void)
args = tree_cons (NULL, cur_try_context->caught_decl, NULL);
t = objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type)));
args = tree_cons (NULL, t, args);
- t = build_function_call (objc_exception_match_decl, args);
+ t = build_function_call (input_location,
+ objc_exception_match_decl, args);
cond = c_common_truthvalue_conversion (input_location, t);
}
t = build3 (COND_EXPR, void_type_node, cond, body, NULL);
@@ -3744,7 +3765,7 @@ next_sjlj_build_try_catch_finally (void)
if (cur_try_context->catch_list)
{
tree caught_decl = objc_build_exc_ptr ();
- catch_seq = build_stmt (BIND_EXPR, caught_decl, NULL, NULL);
+ catch_seq = build_stmt (input_location, BIND_EXPR, caught_decl, NULL, NULL);
TREE_SIDE_EFFECTS (catch_seq) = 1;
t = next_sjlj_build_exc_extract (caught_decl);
@@ -3768,7 +3789,7 @@ next_sjlj_build_try_catch_finally (void)
/* Build the complete FINALLY statement list. */
t = next_sjlj_build_try_exit ();
- t = build_stmt (COND_EXPR,
+ t = build_stmt (input_location, COND_EXPR,
c_common_truthvalue_conversion
(input_location, rethrow_decl),
NULL, t);
@@ -3779,8 +3800,9 @@ next_sjlj_build_try_catch_finally (void)
&TREE_OPERAND (try_fin, 1));
t = tree_cons (NULL, rethrow_decl, NULL);
- t = build_function_call (objc_exception_throw_decl, t);
- t = build_stmt (COND_EXPR,
+ t = build_function_call (input_location,
+ objc_exception_throw_decl, t);
+ t = build_stmt (input_location, COND_EXPR,
c_common_truthvalue_conversion (input_location,
rethrow_decl),
t, NULL);
@@ -3822,7 +3844,8 @@ objc_begin_catch_clause (tree decl)
compound = c_begin_compound_stmt (true);
/* The parser passed in a PARM_DECL, but what we really want is a VAR_DECL. */
- decl = build_decl (VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
+ decl = build_decl (input_location,
+ VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
lang_hooks.decls.pushdecl (decl);
/* Since a decl is required here by syntax, don't warn if its unused. */
@@ -3865,7 +3888,7 @@ objc_begin_catch_clause (tree decl)
/* Record the data for the catch in the try context so that we can
finalize it later. */
- t = build_stmt (CATCH_EXPR, type, compound);
+ t = build_stmt (input_location, CATCH_EXPR, type, compound);
cur_try_context->current_catch = t;
/* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
@@ -3885,7 +3908,7 @@ objc_finish_catch_clause (void)
cur_try_context->current_catch = NULL;
cur_try_context->end_catch_locus = input_location;
- CATCH_BODY (c) = c_end_compound_stmt (CATCH_BODY (c), 1);
+ CATCH_BODY (c) = c_end_compound_stmt (input_location, CATCH_BODY (c), 1);
append_to_statement_list (c, &cur_try_context->catch_list);
}
@@ -3930,12 +3953,12 @@ objc_finish_try_stmt (void)
stmt = c->try_body;
if (c->catch_list)
{
- stmt = build_stmt (TRY_CATCH_EXPR, stmt, c->catch_list);
+ stmt = build_stmt (input_location, TRY_CATCH_EXPR, stmt, c->catch_list);
SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
}
if (c->finally_body)
{
- stmt = build_stmt (TRY_FINALLY_EXPR, stmt, c->finally_body);
+ stmt = build_stmt (input_location, TRY_FINALLY_EXPR, stmt, c->finally_body);
SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
}
}
@@ -3947,7 +3970,7 @@ objc_finish_try_stmt (void)
}
tree
-objc_build_throw_stmt (tree throw_expr)
+objc_build_throw_stmt (location_t loc, tree throw_expr)
{
tree args;
@@ -3960,7 +3983,7 @@ objc_build_throw_stmt (tree throw_expr)
if (cur_try_context == NULL
|| cur_try_context->current_catch == NULL)
{
- error ("%<@throw%> (rethrow) used outside of a @catch block");
+ error_at (loc, "%<@throw%> (rethrow) used outside of a @catch block");
return NULL_TREE;
}
@@ -3972,7 +3995,8 @@ objc_build_throw_stmt (tree throw_expr)
/* A throw is just a call to the runtime throw function with the
object as a parameter. */
args = tree_cons (NULL, throw_expr, NULL);
- return add_stmt (build_function_call (objc_exception_throw_decl, args));
+ return add_stmt (build_function_call (loc,
+ objc_exception_throw_decl, args));
}
tree
@@ -3983,13 +4007,15 @@ objc_build_synchronized (location_t start_locus, tree mutex, tree body)
/* First lock the mutex. */
mutex = save_expr (mutex);
args = tree_cons (NULL, mutex, NULL);
- call = build_function_call (objc_sync_enter_decl, args);
+ call = build_function_call (input_location,
+ objc_sync_enter_decl, args);
SET_EXPR_LOCATION (call, start_locus);
add_stmt (call);
/* Build the mutex unlock. */
args = tree_cons (NULL, mutex, NULL);
- call = build_function_call (objc_sync_exit_decl, args);
+ call = build_function_call (input_location,
+ objc_sync_exit_decl, args);
SET_EXPR_LOCATION (call, input_location);
/* Put the that and the body in a TRY_FINALLY. */
@@ -4538,7 +4564,7 @@ objc_generate_cxx_ctor_or_dtor (bool dtor)
(build_special_member_call
(build_ivar_reference (DECL_NAME (ivar)),
dtor ? complete_dtor_identifier : complete_ctor_identifier,
- NULL_TREE, type, LOOKUP_NORMAL, tf_warning_or_error));
+ NULL, type, LOOKUP_NORMAL, tf_warning_or_error));
}
}
@@ -5792,13 +5818,14 @@ generate_shared_structures (int cls_flags)
if (my_super_id)
{
super_expr = add_objc_string (my_super_id, class_names);
- super_expr = build_c_cast (cast_type, super_expr); /* cast! */
+ super_expr = build_c_cast (input_location,
+ cast_type, super_expr); /* cast! */
}
else
super_expr = build_int_cst (NULL_TREE, 0);
root_expr = add_objc_string (my_root_id, class_names);
- root_expr = build_c_cast (cast_type, root_expr); /* cast! */
+ root_expr = build_c_cast (input_location, cast_type, root_expr); /* cast! */
if (CLASS_PROTOCOL_LIST (implementation_template))
{
@@ -6234,6 +6261,7 @@ tree
objc_build_message_expr (tree mess)
{
tree receiver = TREE_PURPOSE (mess);
+ location_t loc;
tree sel_name;
#ifdef OBJCPLUS
tree args = TREE_PURPOSE (TREE_VALUE (mess));
@@ -6245,6 +6273,11 @@ objc_build_message_expr (tree mess)
if (TREE_CODE (receiver) == ERROR_MARK)
return error_mark_node;
+ if (CAN_HAVE_LOCATION_P (receiver))
+ loc = EXPR_LOCATION (receiver);
+ else
+ loc = input_location;
+
/* Obtain the full selector name. */
if (TREE_CODE (args) == IDENTIFIER_NODE)
/* A unary selector. */
@@ -6501,9 +6534,12 @@ objc_finish_message_expr (tree receiver, tree sel_name, tree method_params)
if (!warn_missing_methods)
{
- warning (0, "(Messages without a matching method signature");
- warning (0, "will be assumed to return %<id%> and accept");
- warning (0, "%<...%> as arguments.)");
+ warning_at (input_location,
+ 0, "(Messages without a matching method signature");
+ warning_at (input_location,
+ 0, "will be assumed to return %<id%> and accept");
+ warning_at (input_location,
+ 0, "%<...%> as arguments.)");
warn_missing_methods = true;
}
}
@@ -6515,11 +6551,12 @@ objc_finish_message_expr (tree receiver, tree sel_name, tree method_params)
These are the object itself and the selector. */
if (flag_typed_selectors)
- selector = build_typed_selector_reference (sel_name, method_prototype);
+ selector = build_typed_selector_reference (input_location,
+ sel_name, method_prototype);
else
- selector = build_selector_reference (sel_name);
+ selector = build_selector_reference (input_location, sel_name);
- retval = build_objc_method_call (super, method_prototype,
+ retval = build_objc_method_call (input_location, super, method_prototype,
receiver,
selector, method_params);
@@ -6532,11 +6569,12 @@ objc_finish_message_expr (tree receiver, tree sel_name, tree method_params)
looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
assuming the method has prototype METHOD_PROTOTYPE.
(That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
+ LOC is the location of the expression to build.
Use METHOD_PARAMS as list of args to pass to the method.
If SUPER_FLAG is nonzero, we look up the superclass's method. */
static tree
-build_objc_method_call (int super_flag, tree method_prototype,
+build_objc_method_call (location_t loc, int super_flag, tree method_prototype,
tree lookup_object, tree selector,
tree method_params)
{
@@ -6563,7 +6601,7 @@ build_objc_method_call (int super_flag, tree method_prototype,
(method_prototype, METHOD_REF, super_flag)));
tree method, t;
- lookup_object = build_c_cast (rcv_p, lookup_object);
+ lookup_object = build_c_cast (loc, rcv_p, lookup_object);
/* Use SAVE_EXPR to avoid evaluating the receiver twice. */
lookup_object = save_expr (lookup_object);
@@ -6599,7 +6637,8 @@ build_objc_method_call (int super_flag, tree method_prototype,
t = tree_cons (NULL_TREE, selector, NULL_TREE);
t = tree_cons (NULL_TREE, lookup_object, t);
- method = build_function_call (sender, t);
+ method = build_function_call (loc,
+ sender, t);
/* Pass the object to the method. */
method_params = tree_cons (NULL_TREE, object,
@@ -6610,7 +6649,8 @@ build_objc_method_call (int super_flag, tree method_prototype,
/* ??? Selector is not at this point something we can use inside
the compiler itself. Set it to garbage for the nonce. */
t = build3 (OBJ_TYPE_REF, sender_cast, method, lookup_object, size_zero_node);
- return build_function_call (t, method_params);
+ return build_function_call (loc,
+ t, method_params);
}
static void
@@ -6701,9 +6741,10 @@ objc_build_protocol_expr (tree protoname)
/* This function is called by the parser when a @selector() expression
is found, in order to compile it. It is only called by the parser
- and only to compile a @selector(). */
+ and only to compile a @selector(). LOC is the location of the
+ @selector. */
tree
-objc_build_selector_expr (tree selnamelist)
+objc_build_selector_expr (location_t loc, tree selnamelist)
{
tree selname;
@@ -6743,9 +6784,9 @@ objc_build_selector_expr (tree selnamelist)
if (flag_typed_selectors)
- return build_typed_selector_reference (selname, 0);
+ return build_typed_selector_reference (loc, selname, 0);
else
- return build_selector_reference (selname);
+ return build_selector_reference (loc, selname);
}
tree
@@ -8363,7 +8404,7 @@ objc_get_parm_info (int have_ellipsis)
TREE_CHAIN (parm_info) = NULL_TREE;
parm_info = pushdecl (parm_info);
- finish_decl (parm_info, NULL_TREE, NULL_TREE, NULL_TREE);
+ finish_decl (parm_info, input_location, NULL_TREE, NULL_TREE, NULL_TREE);
parm_info = next;
}
arg_info = get_parm_info (have_ellipsis);
@@ -8391,10 +8432,12 @@ synth_self_and_ucmd_args (void)
self_type = objc_object_type;
/* id self; */
- objc_push_parm (build_decl (PARM_DECL, self_id, self_type));
+ objc_push_parm (build_decl (input_location,
+ PARM_DECL, self_id, self_type));
/* SEL _cmd; */
- objc_push_parm (build_decl (PARM_DECL, ucmd_id, objc_selector_type));
+ objc_push_parm (build_decl (input_location,
+ PARM_DECL, ucmd_id, objc_selector_type));
}
/* Transform an Objective-C method definition into a static C function
@@ -8434,7 +8477,8 @@ start_method_def (tree method)
{
tree type = TREE_VALUE (TREE_TYPE (parmlist)), parm;
- parm = build_decl (PARM_DECL, KEYWORD_ARG_NAME (parmlist), type);
+ parm = build_decl (input_location,
+ PARM_DECL, KEYWORD_ARG_NAME (parmlist), type);
objc_push_parm (parm);
parmlist = TREE_CHAIN (parmlist);
}
@@ -8576,7 +8620,8 @@ objc_start_function (tree name, tree type, tree attrs,
#endif
)
{
- tree fndecl = build_decl (FUNCTION_DECL, name, type);
+ tree fndecl = build_decl (input_location,
+ FUNCTION_DECL, name, type);
#ifdef OBJCPLUS
DECL_ARGUMENTS (fndecl) = params;
@@ -8587,19 +8632,6 @@ objc_start_function (tree name, tree type, tree attrs,
cplus_decl_attributes (&fndecl, attrs, 0);
start_preparsed_function (fndecl, attrs, /*flags=*/SF_DEFAULT);
#else
- struct c_label_context_se *nstack_se;
- struct c_label_context_vm *nstack_vm;
- nstack_se = XOBNEW (&parser_obstack, struct c_label_context_se);
- nstack_se->labels_def = NULL;
- nstack_se->labels_used = NULL;
- nstack_se->next = label_context_stack_se;
- label_context_stack_se = nstack_se;
- nstack_vm = XOBNEW (&parser_obstack, struct c_label_context_vm);
- nstack_vm->labels_def = NULL;
- nstack_vm->labels_used = NULL;
- nstack_vm->scope = 0;
- nstack_vm->next = label_context_stack_vm;
- label_context_stack_vm = nstack_vm;
current_function_returns_value = 0; /* Assume, until we see it does. */
current_function_returns_null = 0;
@@ -8612,7 +8644,8 @@ objc_start_function (tree name, tree type, tree attrs,
push_scope ();
declare_parm_level ();
DECL_RESULT (current_function_decl)
- = build_decl (RESULT_DECL, NULL_TREE,
+ = build_decl (input_location,
+ RESULT_DECL, NULL_TREE,
TREE_TYPE (TREE_TYPE (current_function_decl)));
DECL_ARTIFICIAL (DECL_RESULT (current_function_decl)) = 1;
DECL_IGNORED_P (DECL_RESULT (current_function_decl)) = 1;
@@ -8749,19 +8782,22 @@ get_super_receiver (void)
if (!UOBJC_SUPER_decl)
{
- UOBJC_SUPER_decl = build_decl (VAR_DECL, get_identifier (TAG_SUPER),
+ UOBJC_SUPER_decl = build_decl (input_location,
+ VAR_DECL, get_identifier (TAG_SUPER),
objc_super_template);
/* This prevents `unused variable' warnings when compiling with -Wall. */
TREE_USED (UOBJC_SUPER_decl) = 1;
lang_hooks.decls.pushdecl (UOBJC_SUPER_decl);
- finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE, NULL_TREE);
+ finish_decl (UOBJC_SUPER_decl, input_location, NULL_TREE, NULL_TREE,
+ NULL_TREE);
UOBJC_SUPER_scope = objc_get_current_scope ();
}
/* Set receiver to self. */
super_expr = objc_build_component_ref (UOBJC_SUPER_decl, self_id);
super_expr = build_modify_expr (input_location, super_expr, NULL_TREE,
- NOP_EXPR, self_decl, NULL_TREE);
+ NOP_EXPR, input_location, self_decl,
+ NULL_TREE);
super_expr_list = super_expr;
/* Set class to begin searching. */
@@ -8775,6 +8811,7 @@ get_super_receiver (void)
super_expr = build_modify_expr (input_location, super_expr,
NULL_TREE, NOP_EXPR,
+ input_location,
((TREE_CODE (objc_method_context)
== INSTANCE_METHOD_DECL)
? ucls_super_ref
@@ -8807,7 +8844,8 @@ get_super_receiver (void)
super_class
= build_indirect_ref
(input_location,
- build_c_cast (build_pointer_type (objc_class_type),
+ build_c_cast (input_location,
+ build_pointer_type (objc_class_type),
super_class), "unary *");
}
else
@@ -8818,7 +8856,8 @@ get_super_receiver (void)
assemble_external (super_class);
super_class
= build_function_call
- (super_class,
+ (input_location,
+ super_class,
build_tree_list
(NULL_TREE,
my_build_string_pointer
@@ -8829,16 +8868,20 @@ get_super_receiver (void)
super_expr
= build_modify_expr (input_location, super_expr, NULL_TREE,
NOP_EXPR,
- build_c_cast (TREE_TYPE (super_expr),
+ input_location,
+ build_c_cast (input_location,
+ TREE_TYPE (super_expr),
super_class),
NULL_TREE);
}
- super_expr_list = build_compound_expr (super_expr_list, super_expr);
+ super_expr_list = build_compound_expr (input_location,
+ super_expr_list, super_expr);
super_expr = build_unary_op (input_location,
ADDR_EXPR, UOBJC_SUPER_decl, 0);
- super_expr_list = build_compound_expr (super_expr_list, super_expr);
+ super_expr_list = build_compound_expr (input_location,
+ super_expr_list, super_expr);
return super_expr_list;
}
@@ -9350,7 +9393,8 @@ handle_class_ref (tree chain)
#endif
/* Make a decl for this name, so we can use its address in a tree. */
- decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
+ decl = build_decl (input_location,
+ VAR_DECL, get_identifier (string), char_type_node);
DECL_EXTERNAL (decl) = 1;
TREE_PUBLIC (decl) = 1;
@@ -9361,7 +9405,8 @@ handle_class_ref (tree chain)
sprintf (string, "%sobjc_class_ref_%s",
(flag_next_runtime ? "." : "__"), name);
exp = build1 (ADDR_EXPR, string_type_node, decl);
- decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
+ decl = build_decl (input_location,
+ VAR_DECL, get_identifier (string), string_type_node);
DECL_INITIAL (decl) = exp;
TREE_STATIC (decl) = 1;
TREE_USED (decl) = 1;
@@ -9421,7 +9466,8 @@ handle_impent (struct imp_entry *impent)
tree decl, init;
init = build_int_cst (c_common_type_for_size (BITS_PER_WORD, 1), 0);
- decl = build_decl (VAR_DECL, get_identifier (string), TREE_TYPE (init));
+ decl = build_decl (input_location,
+ VAR_DECL, get_identifier (string), TREE_TYPE (init));
TREE_PUBLIC (decl) = 1;
TREE_READONLY (decl) = 1;
TREE_USED (decl) = 1;
@@ -9532,7 +9578,7 @@ objc_rewrite_function_call (tree function, tree first_param)
a function in OBJ_TYPE_REF_EXPR (presumably objc_msgSend or one
of its cousins). */
-enum gimplify_status
+int
objc_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
{
enum gimplify_status r0, r1;
diff --git a/gcc/objc/objc-act.h b/gcc/objc/objc-act.h
index f81559643c3..fb929342b99 100644
--- a/gcc/objc/objc-act.h
+++ b/gcc/objc/objc-act.h
@@ -1,5 +1,5 @@
/* Declarations for objc-act.c.
- Copyright (C) 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008
+ Copyright (C) 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009
Free Software Foundation, Inc.
This file is part of GCC.
@@ -31,7 +31,7 @@ bool objc_init (void);
const char *objc_printable_name (tree, int);
void objc_finish_file (void);
tree objc_fold_obj_type_ref (tree, tree);
-enum gimplify_status objc_gimplify_expr (tree *, gimple_seq *, gimple_seq *);
+int objc_gimplify_expr (tree *, gimple_seq *, gimple_seq *);
/* NB: The remaining public functions are prototyped in c-common.h, for the
benefit of stub-objc.c and objc-act.c. */
diff --git a/gcc/objcp/ChangeLog b/gcc/objcp/ChangeLog
index 4a4067d3bd7..45985f8db0b 100644
--- a/gcc/objcp/ChangeLog
+++ b/gcc/objcp/ChangeLog
@@ -1,3 +1,31 @@
+2009-06-13 Aldy Hernandez <aldyh@redhat.com>
+
+ * objcp-decl.h (start_struct): Add location argument.
+ (finish_struct): Same.
+ (finish_decl): New.
+
+2009-06-12 Aldy Hernandez <aldyh@redhat.com>
+
+ * objcp-decl.h (c_end_compound_stmt): New argument.
+ * objcp-decl.c (objcp_start_struct): Add argument.
+ (objcp_finish_struct): Same.
+
+2009-06-03 Ian Lance Taylor <iant@google.com>
+
+ * Make-lang.in (cc1objplus-checksum.o): Depend upon $(CONFIG_H)
+ and $(SYSTEM_H).
+
+2009-05-27 Ian Lance Taylor <iant@google.com>
+
+ * Make-lang.in (cc1objplus-dummy$(exeext)): Change $(COMPILER) to
+ $(LINKER).
+ (cc1objplus$(exeext)): Likewise.
+
+2009-05-26 Ian Lance Taylor <iant@google.com>
+
+ * Make-lang.in (cc1objplus-dummy$(exeext)): Use $(COMPILER).
+ (cc1objplus$(exeext), objcp/objcp-act.o): Likwise.
+
2009-05-10 Ian Lance Taylor <iant@google.com>
* objcp-decl.h (start_struct): Add three new, ignored, macro
diff --git a/gcc/objcp/Make-lang.in b/gcc/objcp/Make-lang.in
index 6e3290cf6de..2b1b8098429 100644
--- a/gcc/objcp/Make-lang.in
+++ b/gcc/objcp/Make-lang.in
@@ -1,5 +1,5 @@
# Top level -*- makefile -*- fragment for GNU Objective-C++
-# Copyright (C) 2005, 2007, 2008 Free Software Foundation, Inc.
+# Copyright (C) 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
# Contributed by Ziemowit Laski <zlaski@apple.com>
#This file is part of GCC.
@@ -55,16 +55,16 @@ obj-c++_OBJS = $(OBJCXX_OBJS) cc1objplus-checksum.o
cc1objplus-dummy$(exeext): $(OBJCXX_OBJS) dummy-checksum.o $(BACKEND) \
$(LIBDEPS)
- $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ \
+ $(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
$(OBJCXX_OBJS) dummy-checksum.o $(BACKEND) $(LIBS) $(BACKENDLIBS)
cc1objplus-checksum.c : cc1objplus-dummy$(exeext) build/genchecksum$(build_exeext)
build/genchecksum$(build_exeext) cc1objplus-dummy$(exeext) > $@
-cc1objplus-checksum.o : cc1objplus-checksum.c
+cc1objplus-checksum.o : cc1objplus-checksum.c $(CONFIG_H) $(SYSTEM_H)
cc1objplus$(exeext): $(OBJCXX_OBJS) cc1objplus-checksum.o $(BACKEND) $(LIBDEPS)
- $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ \
+ $(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
$(OBJCXX_OBJS) cc1objplus-checksum.o $(BACKEND) $(LIBS) $(BACKENDLIBS)
# Objective C++ language specific files.
@@ -87,7 +87,8 @@ objcp/objcp-act.o : objc/objc-act.c \
objc/objc-act.h input.h $(FUNCTION_H) output.h debug.h langhooks.h \
objcp/objcp-decl.h $(LANGHOOKS_DEF_H) $(HASHTAB_H) gt-objc-objc-act.h \
$(GIMPLE_H)
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< \
+ $(OUTPUT_OPTION)
po-generated:
diff --git a/gcc/objcp/objcp-decl.c b/gcc/objcp/objcp-decl.c
index 12a73c1272a..379a69c2bb4 100644
--- a/gcc/objcp/objcp-decl.c
+++ b/gcc/objcp/objcp-decl.c
@@ -44,7 +44,8 @@ along with GCC; see the file COPYING3. If not see
/* Hacks to simulate start_struct() and finish_struct(). */
tree
-objcp_start_struct (enum tree_code code ATTRIBUTE_UNUSED, tree name)
+objcp_start_struct (location_t loc ATTRIBUTE_UNUSED,
+ enum tree_code code ATTRIBUTE_UNUSED, tree name)
{
tree s;
/* The idea here is to mimic the actions that the C++ parser takes when
@@ -62,7 +63,8 @@ objcp_start_struct (enum tree_code code ATTRIBUTE_UNUSED, tree name)
}
tree
-objcp_finish_struct (tree t, tree fieldlist, tree attributes)
+objcp_finish_struct (location_t loc ATTRIBUTE_UNUSED,
+ tree t, tree fieldlist, tree attributes)
{
tree field, next_field;
diff --git a/gcc/objcp/objcp-decl.h b/gcc/objcp/objcp-decl.h
index 3f6c4321e7f..07d39abaf8f 100644
--- a/gcc/objcp/objcp-decl.h
+++ b/gcc/objcp/objcp-decl.h
@@ -23,8 +23,8 @@ along with GCC; see the file COPYING3. If not see
#ifndef GCC_OBJCP_DECL_H
#define GCC_OBJCP_DECL_H
-extern tree objcp_start_struct (enum tree_code, tree);
-extern tree objcp_finish_struct (tree, tree, tree);
+extern tree objcp_start_struct (location_t, enum tree_code, tree);
+extern tree objcp_finish_struct (location_t, tree, tree, tree);
extern void objcp_finish_function (void);
extern tree objcp_build_function_call (tree, tree);
extern tree objcp_xref_tag (enum tree_code, tree);
@@ -37,19 +37,21 @@ extern tree objcp_end_compound_stmt (tree, int);
invoke the original C++ functions if needed). */
#ifdef OBJCP_REMAP_FUNCTIONS
-#define start_struct(code, name, in_struct, struct_types, loc) \
- objcp_start_struct (code, name)
-#define finish_struct(t, fieldlist, attributes, in_struct, struct_types) \
- objcp_finish_struct (t, fieldlist, attributes)
+#define start_struct(loc, code, name, in_struct, struct_types) \
+ objcp_start_struct (loc, code, name)
+#define finish_struct(loc, t, fieldlist, attributes, in_struct, struct_types) \
+ objcp_finish_struct (loc, t, fieldlist, attributes)
#define finish_function() \
objcp_finish_function ()
+#define finish_decl(decl, loc, init, origtype, asmspec) \
+ cp_finish_decl (decl, init, false, asmspec, 0)
#define xref_tag(code, name) \
objcp_xref_tag (code, name)
#define comptypes(type1, type2) \
objcp_comptypes (type1, type2)
#define c_begin_compound_stmt(flags) \
objcp_begin_compound_stmt (flags)
-#define c_end_compound_stmt(stmt, flags) \
+#define c_end_compound_stmt(loc, stmt, flags) \
objcp_end_compound_stmt (stmt, flags)
#undef OBJC_TYPE_NAME
diff --git a/gcc/omega.c b/gcc/omega.c
index af3bd84d39c..e307ba29057 100644
--- a/gcc/omega.c
+++ b/gcc/omega.c
@@ -1305,7 +1305,7 @@ verify_omega_pb (omega_pb pb)
enum omega_result result;
int e;
bool any_color = false;
- omega_pb tmp_problem = XNEW (struct omega_pb);
+ omega_pb tmp_problem = XNEW (struct omega_pb_d);
omega_copy_problem (tmp_problem, pb);
tmp_problem->safe_vars = 0;
@@ -2286,7 +2286,7 @@ omega_eliminate_redundant (omega_pb pb, bool expensive)
if (!expensive)
goto eliminate_redundant_done;
- tmp_problem = XNEW (struct omega_pb);
+ tmp_problem = XNEW (struct omega_pb_d);
conservative++;
for (e = pb->num_geqs - 1; e >= 0; e--)
@@ -2648,7 +2648,7 @@ omega_eliminate_red (omega_pb pb, bool eliminate_all)
return;
conservative++;
- tmp_problem = XNEW (struct omega_pb);
+ tmp_problem = XNEW (struct omega_pb_d);
for (e = pb->num_geqs - 1; e >= 0; e--)
if (pb->geqs[e].color == omega_red)
@@ -3491,7 +3491,7 @@ parallel_splinter (omega_pb pb, int e, int diff,
omega_print_problem (dump_file, pb);
}
- tmp_problem = XNEW (struct omega_pb);
+ tmp_problem = XNEW (struct omega_pb_d);
omega_copy_eqn (&pb->eqs[0], &pb->geqs[e], pb->num_vars);
pb->num_eqs = 1;
@@ -5499,7 +5499,7 @@ omega_alloc_problem (int nvars, int nprot)
omega_initialize ();
/* Allocate and initialize PB. */
- pb = XCNEW (struct omega_pb);
+ pb = XCNEW (struct omega_pb_d);
pb->var = XCNEWVEC (int, OMEGA_MAX_VARS + 2);
pb->forwarding_address = XCNEWVEC (int, OMEGA_MAX_VARS + 2);
pb->geqs = omega_alloc_eqns (0, OMEGA_MAX_GEQS);
diff --git a/gcc/omega.h b/gcc/omega.h
index b97bfc50f21..02c17987dee 100644
--- a/gcc/omega.h
+++ b/gcc/omega.h
@@ -5,7 +5,7 @@
This code has no license restrictions, and is considered public
domain.
- Changes copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
+ Changes copyright (C) 2005, 2006, 2007, 2009 Free Software Foundation, Inc.
Contributed by Sebastian Pop <sebastian.pop@inria.fr>
This file is part of GCC.
@@ -58,7 +58,7 @@ enum omega_eqn_color {
};
/* Structure for equations. */
-typedef struct eqn
+typedef struct eqn_d
{
int key;
int touched;
@@ -72,7 +72,7 @@ typedef struct eqn
int *coef;
} *eqn;
-typedef struct omega_pb
+typedef struct omega_pb_d
{
/* The number of variables in the system of equations. */
int num_vars;
@@ -215,7 +215,7 @@ static inline eqn
omega_alloc_eqns (int s, int n)
{
int i;
- eqn res = (eqn) (xcalloc (n, sizeof (struct eqn)));
+ eqn res = (eqn) (xcalloc (n, sizeof (struct eqn_d)));
for (i = n - 1; i >= 0; i--)
{
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index 5a25e95c33a..e8b2b4dd52e 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -807,16 +807,14 @@ use_pointer_for_field (tree decl, omp_context *shared_ctx)
tree
copy_var_decl (tree var, tree name, tree type)
{
- tree copy = build_decl (VAR_DECL, name, type);
+ tree copy = build_decl (DECL_SOURCE_LOCATION (var), VAR_DECL, name, type);
TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (var);
TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (var);
DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (var);
- DECL_NO_TBAA_P (copy) = DECL_NO_TBAA_P (var);
DECL_ARTIFICIAL (copy) = DECL_ARTIFICIAL (var);
DECL_IGNORED_P (copy) = DECL_IGNORED_P (var);
DECL_CONTEXT (copy) = DECL_CONTEXT (var);
- DECL_SOURCE_LOCATION (copy) = DECL_SOURCE_LOCATION (var);
TREE_USED (copy) = 1;
DECL_SEEN_IN_BIND_EXPR_P (copy) = 1;
@@ -929,7 +927,8 @@ install_var_field (tree var, bool by_ref, int mask, omp_context *ctx)
else if ((mask & 3) == 1 && is_reference (var))
type = TREE_TYPE (type);
- field = build_decl (FIELD_DECL, DECL_NAME (var), type);
+ field = build_decl (DECL_SOURCE_LOCATION (var),
+ FIELD_DECL, DECL_NAME (var), type);
/* Remember what variable this field was created for. This does have a
side effect of making dwarf2out ignore this member, so for helpful
@@ -949,7 +948,8 @@ install_var_field (tree var, bool by_ref, int mask, omp_context *ctx)
insert_field_into_struct (ctx->record_type, field);
if (ctx->srecord_type)
{
- sfield = build_decl (FIELD_DECL, DECL_NAME (var), type);
+ sfield = build_decl (DECL_SOURCE_LOCATION (var),
+ FIELD_DECL, DECL_NAME (var), type);
DECL_ABSTRACT_ORIGIN (sfield) = var;
DECL_ALIGN (sfield) = DECL_ALIGN (field);
DECL_USER_ALIGN (sfield) = DECL_USER_ALIGN (field);
@@ -967,7 +967,8 @@ install_var_field (tree var, bool by_ref, int mask, omp_context *ctx)
ctx->sfield_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
for (t = TYPE_FIELDS (ctx->record_type); t ; t = TREE_CHAIN (t))
{
- sfield = build_decl (FIELD_DECL, DECL_NAME (t), TREE_TYPE (t));
+ sfield = build_decl (DECL_SOURCE_LOCATION (var),
+ FIELD_DECL, DECL_NAME (t), TREE_TYPE (t));
DECL_ABSTRACT_ORIGIN (sfield) = DECL_ABSTRACT_ORIGIN (t);
insert_field_into_struct (ctx->srecord_type, sfield);
splay_tree_insert (ctx->sfield_map,
@@ -1044,7 +1045,7 @@ omp_copy_decl (tree var, copy_body_data *cb)
if (TREE_CODE (var) == LABEL_DECL)
{
- new_var = create_artificial_label ();
+ new_var = create_artificial_label (DECL_SOURCE_LOCATION (var));
DECL_CONTEXT (new_var) = current_function_decl;
insert_decl_map (&ctx->cb, var, new_var);
return new_var;
@@ -1310,7 +1311,8 @@ fixup_child_record_type (omp_context *ctx)
type = lang_hooks.types.make_type (RECORD_TYPE);
name = DECL_NAME (TYPE_NAME (ctx->record_type));
- name = build_decl (TYPE_DECL, name, type);
+ name = build_decl (DECL_SOURCE_LOCATION (ctx->receiver_decl),
+ TYPE_DECL, name, type);
TYPE_NAME (type) = name;
for (f = TYPE_FIELDS (ctx->record_type); f ; f = TREE_CHAIN (f))
@@ -1556,7 +1558,8 @@ create_omp_child_function (omp_context *ctx, bool task_copy)
else
type = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
- decl = build_decl (FUNCTION_DECL, name, type);
+ decl = build_decl (gimple_location (ctx->stmt),
+ FUNCTION_DECL, name, type);
decl = lang_hooks.decls.pushdecl (decl);
if (!task_copy)
@@ -1574,13 +1577,15 @@ create_omp_child_function (omp_context *ctx, bool task_copy)
DECL_CONTEXT (decl) = NULL_TREE;
DECL_INITIAL (decl) = make_node (BLOCK);
- t = build_decl (RESULT_DECL, NULL_TREE, void_type_node);
+ t = build_decl (DECL_SOURCE_LOCATION (decl),
+ RESULT_DECL, NULL_TREE, void_type_node);
DECL_ARTIFICIAL (t) = 1;
DECL_IGNORED_P (t) = 1;
DECL_CONTEXT (t) = decl;
DECL_RESULT (decl) = t;
- t = build_decl (PARM_DECL, get_identifier (".omp_data_i"), ptr_type_node);
+ t = build_decl (DECL_SOURCE_LOCATION (decl),
+ PARM_DECL, get_identifier (".omp_data_i"), ptr_type_node);
DECL_ARTIFICIAL (t) = 1;
DECL_ARG_TYPE (t) = ptr_type_node;
DECL_CONTEXT (t) = current_function_decl;
@@ -1590,7 +1595,8 @@ create_omp_child_function (omp_context *ctx, bool task_copy)
ctx->receiver_decl = t;
else
{
- t = build_decl (PARM_DECL, get_identifier (".omp_data_o"),
+ t = build_decl (DECL_SOURCE_LOCATION (decl),
+ PARM_DECL, get_identifier (".omp_data_o"),
ptr_type_node);
DECL_ARTIFICIAL (t) = 1;
DECL_ARG_TYPE (t) = ptr_type_node;
@@ -1605,7 +1611,6 @@ create_omp_child_function (omp_context *ctx, bool task_copy)
allocate_struct_function clobbers CFUN, so we need to restore
it afterward. */
push_struct_function (decl);
- DECL_SOURCE_LOCATION (decl) = gimple_location (ctx->stmt);
cfun->function_end_locus = gimple_location (ctx->stmt);
pop_cfun ();
}
@@ -1638,7 +1643,8 @@ scan_omp_parallel (gimple_stmt_iterator *gsi, omp_context *outer_ctx)
ctx->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
name = create_tmp_var_name (".omp_data_s");
- name = build_decl (TYPE_DECL, name, ctx->record_type);
+ name = build_decl (gimple_location (stmt),
+ TYPE_DECL, name, ctx->record_type);
TYPE_NAME (ctx->record_type) = name;
create_omp_child_function (ctx, false);
gimple_omp_parallel_set_child_fn (stmt, ctx->cb.dst_fn);
@@ -1679,7 +1685,8 @@ scan_omp_task (gimple_stmt_iterator *gsi, omp_context *outer_ctx)
ctx->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
name = create_tmp_var_name (".omp_data_s");
- name = build_decl (TYPE_DECL, name, ctx->record_type);
+ name = build_decl (gimple_location (stmt),
+ TYPE_DECL, name, ctx->record_type);
TYPE_NAME (ctx->record_type) = name;
create_omp_child_function (ctx, false);
gimple_omp_task_set_child_fn (stmt, ctx->cb.dst_fn);
@@ -1689,7 +1696,8 @@ scan_omp_task (gimple_stmt_iterator *gsi, omp_context *outer_ctx)
if (ctx->srecord_type)
{
name = create_tmp_var_name (".omp_data_a");
- name = build_decl (TYPE_DECL, name, ctx->srecord_type);
+ name = build_decl (gimple_location (stmt),
+ TYPE_DECL, name, ctx->srecord_type);
TYPE_NAME (ctx->srecord_type) = name;
create_omp_child_function (ctx, true);
}
@@ -1782,7 +1790,8 @@ scan_omp_single (gimple stmt, omp_context *outer_ctx)
ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
name = create_tmp_var_name (".omp_copy_s");
- name = build_decl (TYPE_DECL, name, ctx->record_type);
+ name = build_decl (gimple_location (stmt),
+ TYPE_DECL, name, ctx->record_type);
TYPE_NAME (ctx->record_type) = name;
scan_sharing_clauses (gimple_omp_single_clauses (stmt), ctx);
@@ -1912,7 +1921,11 @@ scan_omp_1_op (tree *tp, int *walk_subtrees, void *data)
if (ctx && TYPE_P (t))
*tp = remap_type (t, &ctx->cb);
else if (!DECL_P (t))
- *walk_subtrees = 1;
+ {
+ *walk_subtrees = 1;
+ if (ctx)
+ TREE_TYPE (t) = remap_type (TREE_TYPE (t), &ctx->cb);
+ }
break;
}
@@ -2515,8 +2528,8 @@ lower_lastprivate_clauses (tree clauses, tree predicate, gimple_seq *stmt_list,
gimple stmt;
tree label_true, arm1, arm2;
- label = create_artificial_label ();
- label_true = create_artificial_label ();
+ label = create_artificial_label (UNKNOWN_LOCATION);
+ label_true = create_artificial_label (UNKNOWN_LOCATION);
arm1 = TREE_OPERAND (predicate, 0);
arm2 = TREE_OPERAND (predicate, 1);
gimplify_expr (&arm1, stmt_list, NULL, is_gimple_val, fb_rvalue);
@@ -5010,7 +5023,6 @@ expand_omp_atomic_pipeline (basic_block load_bb, basic_block store_bb,
false, NULL_TREE, true, GSI_SAME_STMT);
stmt = gimple_build_assign (iaddr, iaddr_val);
gsi_insert_before (&si, stmt, GSI_SAME_STMT);
- DECL_NO_TBAA_P (iaddr) = 1;
DECL_POINTER_ALIAS_SET (iaddr) = 0;
loadedi = create_tmp_var (itype, NULL);
if (gimple_in_ssa_p (cfun))
@@ -5593,8 +5605,9 @@ lower_omp_sections (gimple_stmt_iterator *gsi_p, omp_context *ctx)
static void
lower_omp_single_simple (gimple single_stmt, gimple_seq *pre_p)
{
- tree tlabel = create_artificial_label ();
- tree flabel = create_artificial_label ();
+ location_t loc = gimple_location (single_stmt);
+ tree tlabel = create_artificial_label (loc);
+ tree flabel = create_artificial_label (loc);
gimple call, cond;
tree lhs, decl;
@@ -5648,15 +5661,16 @@ lower_omp_single_copy (gimple single_stmt, gimple_seq *pre_p, omp_context *ctx)
{
tree ptr_type, t, l0, l1, l2;
gimple_seq copyin_seq;
+ location_t loc = gimple_location (single_stmt);
ctx->sender_decl = create_tmp_var (ctx->record_type, ".omp_copy_o");
ptr_type = build_pointer_type (ctx->record_type);
ctx->receiver_decl = create_tmp_var (ptr_type, ".omp_copy_i");
- l0 = create_artificial_label ();
- l1 = create_artificial_label ();
- l2 = create_artificial_label ();
+ l0 = create_artificial_label (loc);
+ l1 = create_artificial_label (loc);
+ l2 = create_artificial_label (loc);
t = build_call_expr (built_in_decls[BUILT_IN_GOMP_SINGLE_COPY_START], 0);
t = fold_convert (ptr_type, t);
@@ -6104,7 +6118,8 @@ task_copyfn_remap_type (struct omp_taskcopy_context *tcctx, tree orig_type)
type = lang_hooks.types.make_type (RECORD_TYPE);
name = DECL_NAME (TYPE_NAME (orig_type));
- name = build_decl (TYPE_DECL, name, type);
+ name = build_decl (gimple_location (tcctx->ctx->stmt),
+ TYPE_DECL, name, type);
TYPE_NAME (type) = name;
for (f = TYPE_FIELDS (orig_type); f ; f = TREE_CHAIN (f))
diff --git a/gcc/optabs.c b/gcc/optabs.c
index 7eab811f066..99da304b5c1 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -54,42 +54,31 @@ along with GCC; see the file COPYING3. If not see
See expr.h for documentation of these optabs. */
-#if GCC_VERSION >= 4000
-__extension__ struct optab optab_table[OTI_MAX]
+#if GCC_VERSION >= 4000 && HAVE_DESIGNATED_INITIALIZERS
+__extension__ struct optab_d optab_table[OTI_MAX]
= { [0 ... OTI_MAX - 1].handlers[0 ... NUM_MACHINE_MODES - 1].insn_code
= CODE_FOR_nothing };
#else
/* init_insn_codes will do runtime initialization otherwise. */
-struct optab optab_table[OTI_MAX];
+struct optab_d optab_table[OTI_MAX];
#endif
rtx libfunc_table[LTI_MAX];
/* Tables of patterns for converting one mode to another. */
-#if GCC_VERSION >= 4000
-__extension__ struct convert_optab convert_optab_table[COI_MAX]
+#if GCC_VERSION >= 4000 && HAVE_DESIGNATED_INITIALIZERS
+__extension__ struct convert_optab_d convert_optab_table[COI_MAX]
= { [0 ... COI_MAX - 1].handlers[0 ... NUM_MACHINE_MODES - 1]
[0 ... NUM_MACHINE_MODES - 1].insn_code
= CODE_FOR_nothing };
#else
/* init_convert_optab will do runtime initialization otherwise. */
-struct convert_optab convert_optab_table[COI_MAX];
+struct convert_optab_d convert_optab_table[COI_MAX];
#endif
/* Contains the optab used for each rtx code. */
optab code_to_optab[NUM_RTX_CODE + 1];
-/* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
- gives the gen_function to make a branch to test that condition. */
-
-rtxfun bcc_gen_fctn[NUM_RTX_CODE];
-
-/* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
- gives the insn code to make a store-condition insn
- to test that condition. */
-
-enum insn_code setcc_gen_code[NUM_RTX_CODE];
-
#ifdef HAVE_conditional_move
/* Indexed by the machine mode, gives the insn code to make a conditional
move insn. This is not indexed by the rtx-code like bcc_gen_fctn and
@@ -105,23 +94,13 @@ enum insn_code movcc_gen_code[NUM_MACHINE_MODES];
enum insn_code vcond_gen_code[NUM_MACHINE_MODES];
enum insn_code vcondu_gen_code[NUM_MACHINE_MODES];
-/* The insn generating function can not take an rtx_code argument.
- TRAP_RTX is used as an rtx argument. Its code is replaced with
- the code to be used in the trap insn and all other fields are ignored. */
-static GTY(()) rtx trap_rtx;
-
-static void prepare_float_lib_cmp (rtx *, rtx *, enum rtx_code *,
- enum machine_mode *, int *);
+static void prepare_float_lib_cmp (rtx, rtx, enum rtx_code, rtx *,
+ enum machine_mode *);
static rtx expand_unop_direct (enum machine_mode, optab, rtx, rtx, int);
/* Debug facility for use in GDB. */
void debug_optab_libfuncs (void);
-#ifndef HAVE_conditional_trap
-#define HAVE_conditional_trap 0
-#define gen_conditional_trap(a,b) (gcc_unreachable (), NULL_RTX)
-#endif
-
/* Prefixes for the current version of decimal floating point (BID vs. DPD) */
#if ENABLE_DECIMAL_BID_FORMAT
#define DECIMAL_PREFIX "bid_"
@@ -2269,7 +2248,7 @@ sign_expand_binop (enum machine_mode mode, optab uoptab, optab soptab,
{
rtx temp;
optab direct_optab = unsignedp ? uoptab : soptab;
- struct optab wide_soptab;
+ struct optab_d wide_soptab;
/* Do it without widening, if possible. */
temp = expand_binop (mode, direct_optab, op0, op1, target,
@@ -2295,12 +2274,12 @@ sign_expand_binop (enum machine_mode mode, optab uoptab, optab soptab,
if (temp || methods == OPTAB_WIDEN)
return temp;
- /* Use the right width lib call if that exists. */
+ /* Use the right width libcall if that exists. */
temp = expand_binop (mode, direct_optab, op0, op1, target, unsignedp, OPTAB_LIB);
if (temp || methods == OPTAB_LIB)
return temp;
- /* Must widen and use a lib call, use either signed or unsigned. */
+ /* Must widen and use a libcall, use either signed or unsigned. */
temp = expand_binop (mode, &wide_soptab, op0, op1, target,
unsignedp, methods);
if (temp != 0)
@@ -3985,16 +3964,6 @@ can_compare_p (enum rtx_code code, enum machine_mode mode,
{
int icode;
- if (optab_handler (cmp_optab, mode)->insn_code != CODE_FOR_nothing)
- {
- if (purpose == ccp_jump)
- return bcc_gen_fctn[(int) code] != NULL;
- else if (purpose == ccp_store_flag)
- return setcc_gen_code[(int) code] != CODE_FOR_nothing;
- else
- /* There's only one cmov entry point, and it's allowed to fail. */
- return 1;
- }
if (purpose == ccp_jump
&& (icode = optab_handler (cbranch_optab, mode)->insn_code) != CODE_FOR_nothing
&& insn_data[icode].operand[0].predicate (test, mode))
@@ -4020,7 +3989,7 @@ can_compare_p (enum rtx_code code, enum machine_mode mode,
*PMODE is the mode of the inputs (in case they are const_int).
*PUNSIGNEDP nonzero says that the operands are unsigned;
- this matters if they need to be widened.
+ this matters if they need to be widened (as given by METHODS).
If they have mode BLKmode, then SIZE specifies the size of both operands.
@@ -4033,17 +4002,20 @@ can_compare_p (enum rtx_code code, enum machine_mode mode,
comparisons must have already been folded. */
static void
-prepare_cmp_insn (rtx *px, rtx *py, enum rtx_code *pcomparison, rtx size,
- enum machine_mode *pmode, int *punsignedp,
- enum can_compare_purpose purpose)
+prepare_cmp_insn (rtx x, rtx y, enum rtx_code comparison, rtx size,
+ int unsignedp, enum optab_methods methods,
+ rtx *ptest, enum machine_mode *pmode)
{
enum machine_mode mode = *pmode;
- rtx x = *px, y = *py;
- int unsignedp = *punsignedp;
- rtx libfunc;
+ rtx libfunc, test;
+ enum machine_mode cmp_mode;
+ enum mode_class mclass;
- /* If we are inside an appropriately-short loop and we are optimizing,
- force expensive constants into a register. */
+ /* The other methods are not needed. */
+ gcc_assert (methods == OPTAB_DIRECT || methods == OPTAB_WIDEN
+ || methods == OPTAB_LIB_WIDEN);
+
+ /* If we are optimizing, force expensive constants into a register. */
if (CONSTANT_P (x) && optimize
&& (rtx_cost (x, COMPARE, optimize_insn_for_speed_p ())
> COSTS_N_INSNS (1)))
@@ -4064,12 +4036,14 @@ prepare_cmp_insn (rtx *px, rtx *py, enum rtx_code *pcomparison, rtx size,
/* Don't let both operands fail to indicate the mode. */
if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
x = force_reg (mode, x);
+ if (mode == VOIDmode)
+ mode = GET_MODE (x) != VOIDmode ? GET_MODE (x) : GET_MODE (y);
/* Handle all BLKmode compares. */
if (mode == BLKmode)
{
- enum machine_mode cmp_mode, result_mode;
+ enum machine_mode result_mode;
enum insn_code cmp_code;
tree length_type;
rtx libfunc;
@@ -4105,12 +4079,14 @@ prepare_cmp_insn (rtx *px, rtx *py, enum rtx_code *pcomparison, rtx size,
size = convert_to_mode (cmp_mode, size, 1);
emit_insn (GEN_FCN (cmp_code) (result, x, y, size, opalign));
- *px = result;
- *py = const0_rtx;
- *pmode = result_mode;
+ *ptest = gen_rtx_fmt_ee (comparison, VOIDmode, result, const0_rtx);
+ *pmode = result_mode;
return;
}
+ if (methods != OPTAB_LIB && methods != OPTAB_LIB_WIDEN)
+ goto fail;
+
/* Otherwise call a library function, memcmp. */
libfunc = memcmp_libfunc;
length_type = sizetype;
@@ -4124,8 +4100,8 @@ prepare_cmp_insn (rtx *px, rtx *py, enum rtx_code *pcomparison, rtx size,
XEXP (x, 0), Pmode,
XEXP (y, 0), Pmode,
size, cmp_mode);
- *px = result;
- *py = const0_rtx;
+
+ *ptest = gen_rtx_fmt_ee (comparison, VOIDmode, result, const0_rtx);
*pmode = result_mode;
return;
}
@@ -4140,22 +4116,58 @@ prepare_cmp_insn (rtx *px, rtx *py, enum rtx_code *pcomparison, rtx size,
y = force_reg (mode, y);
}
- *px = x;
- *py = y;
if (GET_MODE_CLASS (mode) == MODE_CC)
{
- gcc_assert (can_compare_p (*pcomparison, CCmode, purpose));
+ gcc_assert (can_compare_p (comparison, CCmode, ccp_jump));
+ *ptest = gen_rtx_fmt_ee (comparison, VOIDmode, x, y);
return;
}
- else if (can_compare_p (*pcomparison, mode, purpose))
- return;
- /* Handle a lib call just for the mode we are using. */
- libfunc = optab_libfunc (cmp_optab, mode);
- if (libfunc && !SCALAR_FLOAT_MODE_P (mode))
+ mclass = GET_MODE_CLASS (mode);
+ test = gen_rtx_fmt_ee (comparison, VOIDmode, x, y);
+ cmp_mode = mode;
+ do
+ {
+ enum insn_code icode;
+ icode = optab_handler (cbranch_optab, cmp_mode)->insn_code;
+ if (icode != CODE_FOR_nothing
+ && insn_data[icode].operand[0].predicate (test, VOIDmode))
+ {
+ rtx last = get_last_insn ();
+ rtx op0 = prepare_operand (icode, x, 1, mode, cmp_mode, unsignedp);
+ rtx op1 = prepare_operand (icode, y, 2, mode, cmp_mode, unsignedp);
+ if (op0 && op1
+ && insn_data[icode].operand[1].predicate
+ (op0, insn_data[icode].operand[1].mode)
+ && insn_data[icode].operand[2].predicate
+ (op1, insn_data[icode].operand[2].mode))
+ {
+ XEXP (test, 0) = op0;
+ XEXP (test, 1) = op1;
+ *ptest = test;
+ *pmode = cmp_mode;
+ return;
+ }
+ delete_insns_since (last);
+ }
+
+ if (methods == OPTAB_DIRECT || !CLASS_HAS_WIDER_MODES_P (mclass))
+ break;
+ cmp_mode = GET_MODE_WIDER_MODE (cmp_mode);
+ }
+ while (cmp_mode != VOIDmode);
+
+ if (methods != OPTAB_LIB_WIDEN)
+ goto fail;
+
+ if (!SCALAR_FLOAT_MODE_P (mode))
{
rtx result;
+ /* Handle a libcall just for the mode we are using. */
+ libfunc = optab_libfunc (cmp_optab, mode);
+ gcc_assert (libfunc);
+
/* If we want unsigned, and this mode has a distinct unsigned
comparison routine, use that. */
if (unsignedp)
@@ -4177,22 +4189,28 @@ prepare_cmp_insn (rtx *px, rtx *py, enum rtx_code *pcomparison, rtx size,
case. For unsigned comparisons always compare against 1 after
biasing the unbiased result by adding 1. This gives us a way to
represent LTU. */
- *px = result;
- *pmode = word_mode;
- *py = const1_rtx;
+ x = result;
+ y = const1_rtx;
if (!TARGET_LIB_INT_CMP_BIASED)
{
- if (*punsignedp)
- *px = plus_constant (result, 1);
+ if (unsignedp)
+ x = plus_constant (result, 1);
else
- *py = const0_rtx;
+ y = const0_rtx;
}
- return;
+
+ *pmode = word_mode;
+ prepare_cmp_insn (x, y, comparison, NULL_RTX, unsignedp, methods,
+ ptest, pmode);
}
+ else
+ prepare_float_lib_cmp (x, y, comparison, ptest, pmode);
- gcc_assert (SCALAR_FLOAT_MODE_P (mode));
- prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp);
+ return;
+
+ fail:
+ *ptest = NULL_RTX;
}
/* Before emitting an insn with code ICODE, make sure that X, which is going
@@ -4200,7 +4218,7 @@ prepare_cmp_insn (rtx *px, rtx *py, enum rtx_code *pcomparison, rtx size,
WIDER_MODE (UNSIGNEDP determines whether it is an unsigned conversion), and
that it is accepted by the operand predicate. Return the new value. */
-static rtx
+rtx
prepare_operand (int icode, rtx x, int opnum, enum machine_mode mode,
enum machine_mode wider_mode, int unsignedp)
{
@@ -4219,71 +4237,22 @@ prepare_operand (int icode, rtx x, int opnum, enum machine_mode mode,
}
/* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
- we can do the comparison.
- The arguments are the same as for emit_cmp_and_jump_insns; but LABEL may
- be NULL_RTX which indicates that only a comparison is to be generated. */
+ we can do the branch. */
static void
-emit_cmp_and_jump_insn_1 (rtx x, rtx y, enum machine_mode mode,
- enum rtx_code comparison, int unsignedp, rtx label)
+emit_cmp_and_jump_insn_1 (rtx test, enum machine_mode mode, rtx label)
{
- rtx test = gen_rtx_fmt_ee (comparison, mode, x, y);
- enum mode_class mclass = GET_MODE_CLASS (mode);
- enum machine_mode wider_mode = mode;
-
- /* Try combined insns first. */
- do
- {
- enum machine_mode optab_mode = mclass == MODE_CC ? CCmode : wider_mode;
- enum insn_code icode;
- PUT_MODE (test, wider_mode);
-
- if (label)
- {
- icode = optab_handler (cbranch_optab, optab_mode)->insn_code;
-
- if (icode != CODE_FOR_nothing
- && insn_data[icode].operand[0].predicate (test, wider_mode))
- {
- x = prepare_operand (icode, x, 1, mode, wider_mode, unsignedp);
- y = prepare_operand (icode, y, 2, mode, wider_mode, unsignedp);
- emit_jump_insn (GEN_FCN (icode) (test, x, y, label));
- return;
- }
- }
-
- /* Handle some compares against zero. */
- icode = optab_handler (tst_optab, optab_mode)->insn_code;
- if (y == CONST0_RTX (mode) && icode != CODE_FOR_nothing)
- {
- x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
- emit_insn (GEN_FCN (icode) (x));
- if (label)
- emit_jump_insn (bcc_gen_fctn[(int) comparison] (label));
- return;
- }
-
- /* Handle compares for which there is a directly suitable insn. */
-
- icode = optab_handler (cmp_optab, optab_mode)->insn_code;
- if (icode != CODE_FOR_nothing)
- {
- x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
- y = prepare_operand (icode, y, 1, mode, wider_mode, unsignedp);
- emit_insn (GEN_FCN (icode) (x, y));
- if (label)
- emit_jump_insn (bcc_gen_fctn[(int) comparison] (label));
- return;
- }
-
- if (!CLASS_HAS_WIDER_MODES_P (mclass))
- break;
+ enum machine_mode optab_mode;
+ enum mode_class mclass;
+ enum insn_code icode;
- wider_mode = GET_MODE_WIDER_MODE (wider_mode);
- }
- while (wider_mode != VOIDmode);
+ mclass = GET_MODE_CLASS (mode);
+ optab_mode = (mclass == MODE_CC) ? CCmode : mode;
+ icode = optab_handler (cbranch_optab, optab_mode)->insn_code;
- gcc_unreachable ();
+ gcc_assert (icode != CODE_FOR_nothing);
+ gcc_assert (insn_data[icode].operand[0].predicate (test, VOIDmode));
+ emit_jump_insn (GEN_FCN (icode) (test, XEXP (test, 0), XEXP (test, 1), label));
}
/* Generate code to compare X with Y so that the condition codes are
@@ -4292,32 +4261,27 @@ emit_cmp_and_jump_insn_1 (rtx x, rtx y, enum machine_mode mode,
ensure that the comparison RTL has the canonical form.
UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
- need to be widened by emit_cmp_insn. UNSIGNEDP is also used to select
- the proper branch condition code.
+ need to be widened. UNSIGNEDP is also used to select the proper
+ branch condition code.
If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y.
MODE is the mode of the inputs (in case they are const_int).
- COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). It will
- be passed unchanged to emit_cmp_insn, then potentially converted into an
- unsigned variant based on UNSIGNEDP to select a proper jump instruction. */
+ COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
+ It will be potentially converted into an unsigned variant based on
+ UNSIGNEDP to select a proper jump instruction. */
void
emit_cmp_and_jump_insns (rtx x, rtx y, enum rtx_code comparison, rtx size,
enum machine_mode mode, int unsignedp, rtx label)
{
rtx op0 = x, op1 = y;
+ rtx test;
/* Swap operands and condition to ensure canonical RTL. */
if (swap_commutative_operands_p (x, y))
{
- /* If we're not emitting a branch, callers are required to pass
- operands in an order conforming to canonical RTL. We relax this
- for commutative comparisons so callers using EQ don't need to do
- swapping by hand. */
- gcc_assert (label || (comparison == swap_condition (comparison)));
-
op0 = y, op1 = x;
comparison = swap_condition (comparison);
}
@@ -4332,32 +4296,21 @@ emit_cmp_and_jump_insns (rtx x, rtx y, enum rtx_code comparison, rtx size,
if (unsignedp)
comparison = unsigned_condition (comparison);
- prepare_cmp_insn (&op0, &op1, &comparison, size, &mode, &unsignedp,
- ccp_jump);
- emit_cmp_and_jump_insn_1 (op0, op1, mode, comparison, unsignedp, label);
+ prepare_cmp_insn (op0, op1, comparison, size, unsignedp, OPTAB_LIB_WIDEN,
+ &test, &mode);
+ emit_cmp_and_jump_insn_1 (test, mode, label);
}
-/* Like emit_cmp_and_jump_insns, but generate only the comparison. */
-
-void
-emit_cmp_insn (rtx x, rtx y, enum rtx_code comparison, rtx size,
- enum machine_mode mode, int unsignedp)
-{
- emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, 0);
-}
/* Emit a library call comparison between floating point X and Y.
COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
static void
-prepare_float_lib_cmp (rtx *px, rtx *py, enum rtx_code *pcomparison,
- enum machine_mode *pmode, int *punsignedp)
+prepare_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison,
+ rtx *ptest, enum machine_mode *pmode)
{
- enum rtx_code comparison = *pcomparison;
enum rtx_code swapped = swap_condition (comparison);
enum rtx_code reversed = reverse_condition_maybe_unordered (comparison);
- rtx x = *px;
- rtx y = *py;
enum machine_mode orig_mode = GET_MODE (x);
enum machine_mode mode, cmp_mode;
rtx value, target, insns, equiv;
@@ -4369,10 +4322,12 @@ prepare_float_lib_cmp (rtx *px, rtx *py, enum rtx_code *pcomparison,
mode != VOIDmode;
mode = GET_MODE_WIDER_MODE (mode))
{
- if ((libfunc = optab_libfunc (code_to_optab[comparison], mode)))
+ if (code_to_optab[comparison]
+ && (libfunc = optab_libfunc (code_to_optab[comparison], mode)))
break;
- if ((libfunc = optab_libfunc (code_to_optab[swapped] , mode)))
+ if (code_to_optab[swapped]
+ && (libfunc = optab_libfunc (code_to_optab[swapped], mode)))
{
rtx tmp;
tmp = x; x = y; y = tmp;
@@ -4380,7 +4335,8 @@ prepare_float_lib_cmp (rtx *px, rtx *py, enum rtx_code *pcomparison,
break;
}
- if ((libfunc = optab_libfunc (code_to_optab[reversed], mode))
+ if (code_to_optab[reversed]
+ && (libfunc = optab_libfunc (code_to_optab[reversed], mode))
&& FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, reversed))
{
comparison = reversed;
@@ -4467,11 +4423,8 @@ prepare_float_lib_cmp (rtx *px, rtx *py, enum rtx_code *pcomparison,
|| FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
comparison = reversed_p ? EQ : NE;
- *px = target;
- *py = const0_rtx;
+ *ptest = gen_rtx_fmt_ee (comparison, VOIDmode, target, const0_rtx);
*pmode = cmp_mode;
- *pcomparison = comparison;
- *punsignedp = 0;
}
/* Generate code to indirectly jump to a location given in the rtx LOC. */
@@ -4571,27 +4524,38 @@ emit_conditional_move (rtx target, enum rtx_code code, rtx op0, rtx op1,
(op3, insn_data[icode].operand[3].mode))
op3 = copy_to_mode_reg (insn_data[icode].operand[3].mode, op3);
- /* Everything should now be in the suitable form, so emit the compare insn
- and then the conditional move. */
+ /* Everything should now be in the suitable form. */
- comparison
- = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX);
+ code = unsignedp ? unsigned_condition (code) : code;
+ comparison = simplify_gen_relational (code, VOIDmode, cmode, op0, op1);
- /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)? */
/* We can get const0_rtx or const_true_rtx in some circumstances. Just
return NULL and let the caller figure out how best to deal with this
situation. */
- if (GET_CODE (comparison) != code)
+ if (!COMPARISON_P (comparison))
return NULL_RTX;
- insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
+ do_pending_stack_adjust ();
+ start_sequence ();
+ prepare_cmp_insn (XEXP (comparison, 0), XEXP (comparison, 1),
+ GET_CODE (comparison), NULL_RTX, unsignedp, OPTAB_WIDEN,
+ &comparison, &cmode);
+ if (!comparison)
+ insn = NULL_RTX;
+ else
+ insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
/* If that failed, then give up. */
if (insn == 0)
- return 0;
+ {
+ end_sequence ();
+ return 0;
+ }
emit_insn (insn);
-
+ insn = get_insns ();
+ end_sequence ();
+ emit_insn (insn);
if (subtarget != target)
convert_move (target, subtarget, 0);
@@ -4699,27 +4663,38 @@ emit_conditional_add (rtx target, enum rtx_code code, rtx op0, rtx op1,
(op3, insn_data[icode].operand[3].mode))
op3 = copy_to_mode_reg (insn_data[icode].operand[3].mode, op3);
- /* Everything should now be in the suitable form, so emit the compare insn
- and then the conditional move. */
+ /* Everything should now be in the suitable form. */
- comparison
- = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX);
+ code = unsignedp ? unsigned_condition (code) : code;
+ comparison = simplify_gen_relational (code, VOIDmode, cmode, op0, op1);
- /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)? */
/* We can get const0_rtx or const_true_rtx in some circumstances. Just
return NULL and let the caller figure out how best to deal with this
situation. */
- if (GET_CODE (comparison) != code)
+ if (!COMPARISON_P (comparison))
return NULL_RTX;
- insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
+ do_pending_stack_adjust ();
+ start_sequence ();
+ prepare_cmp_insn (XEXP (comparison, 0), XEXP (comparison, 1),
+ GET_CODE (comparison), NULL_RTX, unsignedp, OPTAB_WIDEN,
+ &comparison, &cmode);
+ if (!comparison)
+ insn = NULL_RTX;
+ else
+ insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
/* If that failed, then give up. */
if (insn == 0)
- return 0;
+ {
+ end_sequence ();
+ return 0;
+ }
emit_insn (insn);
-
+ insn = get_insns ();
+ end_sequence ();
+ emit_insn (insn);
if (subtarget != target)
convert_move (target, subtarget, 0);
@@ -6069,7 +6044,8 @@ init_one_libfunc (const char *name)
targetm.encode_section_info. */
/* ??? We don't have any type information except for this is
a function. Pretend this is "int foo()". */
- decl = build_decl (FUNCTION_DECL, get_identifier (name),
+ decl = build_decl (UNKNOWN_LOCATION,
+ FUNCTION_DECL, get_identifier (name),
build_function_type (integer_type_node, NULL_TREE));
DECL_ARTIFICIAL (decl) = 1;
DECL_EXTERNAL (decl) = 1;
@@ -6167,9 +6143,6 @@ init_optabs (void)
libfunc_hash = htab_create_ggc (10, hash_libfunc, eq_libfunc, NULL);
/* Start by initializing all tables to contain CODE_FOR_nothing. */
- for (i = 0; i < NUM_RTX_CODE; i++)
- setcc_gen_code[i] = CODE_FOR_nothing;
-
#ifdef HAVE_conditional_move
for (i = 0; i < NUM_MACHINE_MODES; i++)
movcc_gen_code[i] = CODE_FOR_nothing;
@@ -6181,7 +6154,7 @@ init_optabs (void)
vcondu_gen_code[i] = CODE_FOR_nothing;
}
-#if GCC_VERSION >= 4000
+#if GCC_VERSION >= 4000 && HAVE_DESIGNATED_INITIALIZERS
/* We statically initialize the insn_codes with CODE_FOR_nothing. */
if (reinit)
init_insn_codes ();
@@ -6247,12 +6220,16 @@ init_optabs (void)
have_insn_for. */
init_optab (mov_optab, SET);
init_optab (movstrict_optab, STRICT_LOW_PART);
- init_optab (cmp_optab, COMPARE);
+ init_optab (cbranch_optab, COMPARE);
+
+ init_optab (cmov_optab, UNKNOWN);
+ init_optab (cstore_optab, UNKNOWN);
+ init_optab (ctrap_optab, UNKNOWN);
init_optab (storent_optab, UNKNOWN);
+ init_optab (cmp_optab, UNKNOWN);
init_optab (ucmp_optab, UNKNOWN);
- init_optab (tst_optab, UNKNOWN);
init_optab (eq_optab, EQ);
init_optab (ne_optab, NE);
@@ -6308,9 +6285,6 @@ init_optabs (void)
init_optab (isinf_optab, UNKNOWN);
init_optab (strlen_optab, UNKNOWN);
- init_optab (cbranch_optab, UNKNOWN);
- init_optab (cmov_optab, UNKNOWN);
- init_optab (cstore_optab, UNKNOWN);
init_optab (push_optab, UNKNOWN);
init_optab (reduc_smax_optab, UNKNOWN);
@@ -6660,9 +6634,6 @@ init_optabs (void)
gcov_flush_libfunc = init_one_libfunc ("__gcov_flush");
- if (HAVE_conditional_trap)
- trap_rtx = gen_rtx_fmt_ee (EQ, VOIDmode, NULL_RTX, NULL_RTX);
-
/* Allow the target to add more libcalls or rename some, etc. */
targetm.init_libfuncs ();
@@ -6726,43 +6697,45 @@ debug_optab_libfuncs (void)
CODE. Return 0 on failure. */
rtx
-gen_cond_trap (enum rtx_code code ATTRIBUTE_UNUSED, rtx op1,
- rtx op2 ATTRIBUTE_UNUSED, rtx tcode ATTRIBUTE_UNUSED)
+gen_cond_trap (enum rtx_code code, rtx op1, rtx op2, rtx tcode)
{
enum machine_mode mode = GET_MODE (op1);
enum insn_code icode;
rtx insn;
-
- if (!HAVE_conditional_trap)
- return 0;
+ rtx trap_rtx;
if (mode == VOIDmode)
return 0;
- icode = optab_handler (cmp_optab, mode)->insn_code;
+ icode = optab_handler (ctrap_optab, mode)->insn_code;
if (icode == CODE_FOR_nothing)
return 0;
+ /* Some targets only accept a zero trap code. */
+ if (insn_data[icode].operand[3].predicate
+ && !insn_data[icode].operand[3].predicate (tcode, VOIDmode))
+ return 0;
+
+ do_pending_stack_adjust ();
start_sequence ();
- op1 = prepare_operand (icode, op1, 0, mode, mode, 0);
- op2 = prepare_operand (icode, op2, 1, mode, mode, 0);
- if (!op1 || !op2)
+ prepare_cmp_insn (op1, op2, code, NULL_RTX, false, OPTAB_DIRECT,
+ &trap_rtx, &mode);
+ if (!trap_rtx)
+ insn = NULL_RTX;
+ else
+ insn = GEN_FCN (icode) (trap_rtx, XEXP (trap_rtx, 0), XEXP (trap_rtx, 1),
+ tcode);
+
+ /* If that failed, then give up. */
+ if (insn == 0)
{
end_sequence ();
return 0;
}
- emit_insn (GEN_FCN (icode) (op1, op2));
- PUT_CODE (trap_rtx, code);
- gcc_assert (HAVE_conditional_trap);
- insn = gen_conditional_trap (trap_rtx, tcode);
- if (insn)
- {
- emit_insn (insn);
- insn = get_insns ();
- }
+ emit_insn (insn);
+ insn = get_insns ();
end_sequence ();
-
return insn;
}
@@ -7035,9 +7008,9 @@ expand_bool_compare_and_swap (rtx mem, rtx old_val, rtx new_val, rtx target)
emit_insn (seq);
if (cc_reg)
- return emit_store_flag (target, EQ, cc_reg, const0_rtx, VOIDmode, 0, 1);
+ return emit_store_flag_force (target, EQ, cc_reg, const0_rtx, VOIDmode, 0, 1);
else
- return emit_store_flag (target, EQ, subtarget, old_val, VOIDmode, 1, 1);
+ return emit_store_flag_force (target, EQ, subtarget, old_val, VOIDmode, 1, 1);
}
/* This is a helper function for the other atomic operations. This function
diff --git a/gcc/optabs.h b/gcc/optabs.h
index a518dc6ab86..096feda7df2 100644
--- a/gcc/optabs.h
+++ b/gcc/optabs.h
@@ -1,5 +1,5 @@
/* Definitions for code generation pass of GNU compiler.
- Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+ Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
Free Software Foundation, Inc.
This file is part of GCC.
@@ -36,37 +36,37 @@ along with GCC; see the file COPYING3. If not see
The `lib_call' slot is the name of the library function that
can be used to perform the operation.
- A few optabs, such as move_optab and cmp_optab, are used
- by special code. */
+ A few optabs, such as move_optab, are used by special code. */
struct optab_handlers
{
enum insn_code insn_code;
};
-struct optab
+struct optab_d
{
enum rtx_code code;
const char *libcall_basename;
char libcall_suffix;
- void (*libcall_gen)(struct optab *, const char *name, char suffix, enum machine_mode);
+ void (*libcall_gen)(struct optab_d *, const char *name, char suffix,
+ enum machine_mode);
struct optab_handlers handlers[NUM_MACHINE_MODES];
};
-typedef struct optab * optab;
+typedef struct optab_d * optab;
/* A convert_optab is for some sort of conversion operation between
modes. The first array index is the destination mode, the second
is the source mode. */
-struct convert_optab
+struct convert_optab_d
{
enum rtx_code code;
const char *libcall_basename;
- void (*libcall_gen)(struct convert_optab *, const char *name,
+ void (*libcall_gen)(struct convert_optab_d *, const char *name,
enum machine_mode,
enum machine_mode);
struct optab_handlers handlers[NUM_MACHINE_MODES][NUM_MACHINE_MODES];
};
-typedef struct convert_optab *convert_optab;
+typedef struct convert_optab_d *convert_optab;
/* Given an enum insn_code, access the function to construct
the body of that kind of insn. */
@@ -271,12 +271,9 @@ enum optab_index
/* Test for infinite value */
OTI_isinf,
- /* Compare insn; two operands. */
+ /* Compare insn; two operands. Used only for libcalls. */
OTI_cmp,
- /* Used only for libcalls for unsigned comparisons. */
OTI_ucmp,
- /* tst insn; compare one operand against 0 */
- OTI_tst,
/* Floating point comparison optabs - used primarily for libfuncs */
OTI_eq,
@@ -290,10 +287,11 @@ enum optab_index
/* String length */
OTI_strlen,
- /* Combined compare & jump/store flags/move operations. */
+ /* Combined compare & jump/move/store flags/trap operations. */
OTI_cbranch,
OTI_cmov,
OTI_cstore,
+ OTI_ctrap,
/* Push instruction. */
OTI_push,
@@ -372,7 +370,7 @@ enum optab_index
OTI_MAX
};
-extern struct optab optab_table[OTI_MAX];
+extern struct optab_d optab_table[OTI_MAX];
#define ssadd_optab (&optab_table[OTI_ssadd])
#define usadd_optab (&optab_table[OTI_usadd])
@@ -484,7 +482,6 @@ extern struct optab optab_table[OTI_MAX];
#define cmp_optab (&optab_table[OTI_cmp])
#define ucmp_optab (&optab_table[OTI_ucmp])
-#define tst_optab (&optab_table[OTI_tst])
#define eq_optab (&optab_table[OTI_eq])
#define ne_optab (&optab_table[OTI_ne])
@@ -499,6 +496,8 @@ extern struct optab optab_table[OTI_MAX];
#define cbranch_optab (&optab_table[OTI_cbranch])
#define cmov_optab (&optab_table[OTI_cmov])
#define cstore_optab (&optab_table[OTI_cstore])
+#define ctrap_optab (&optab_table[OTI_ctrap])
+
#define push_optab (&optab_table[OTI_push])
#define addcc_optab (&optab_table[OTI_addcc])
@@ -573,7 +572,7 @@ enum convert_optab_index
COI_MAX
};
-extern struct convert_optab convert_optab_table[COI_MAX];
+extern struct convert_optab_d convert_optab_table[COI_MAX];
#define sext_optab (&convert_optab_table[COI_sext])
#define zext_optab (&convert_optab_table[COI_zext])
@@ -605,17 +604,6 @@ extern optab code_to_optab[NUM_RTX_CODE + 1];
typedef rtx (*rtxfun) (rtx);
-/* Indexed by the rtx-code for a conditional (e.g. EQ, LT,...)
- gives the gen_function to make a branch to test that condition. */
-
-extern rtxfun bcc_gen_fctn[NUM_RTX_CODE];
-
-/* Indexed by the rtx-code for a conditional (e.g. EQ, LT,...)
- gives the insn code to make a store-condition insn
- to test that condition. */
-
-extern enum insn_code setcc_gen_code[NUM_RTX_CODE];
-
#ifdef HAVE_conditional_move
/* Indexed by the machine mode, gives the insn code to make a conditional
move insn. */
@@ -723,10 +711,6 @@ extern rtx expand_copysign (rtx, rtx, rtx);
extern void emit_unop_insn (int, rtx, rtx, enum rtx_code);
extern bool maybe_emit_unop_insn (int, rtx, rtx, enum rtx_code);
-/* Emit one rtl insn to compare two rtx's. */
-extern void emit_cmp_insn (rtx, rtx, enum rtx_code, rtx, enum machine_mode,
- int);
-
/* An extra flag to control optab_for_tree_code's behavior. This is needed to
distinguish between machines with a vector shift that takes a scalar for the
shift amount vs. machines that take a vector for the shift amount. */
diff --git a/gcc/opth-gen.awk b/gcc/opth-gen.awk
index ecccbdd9ac9..fb262bd93b7 100644
--- a/gcc/opth-gen.awk
+++ b/gcc/opth-gen.awk
@@ -333,6 +333,8 @@ for (i = 0; i < n_opts; i++) {
enum = "OPT_" opts[i]
if (opts[i] == "finline-limit=" || opts[i] == "Wlarger-than=")
enum = enum "eq"
+ if (opts[i] == "gdwarf+")
+ enum = "OPT_gdwarfplus"
gsub ("[^A-Za-z0-9]", "_", enum)
# If this switch takes joined arguments, back-chain all
@@ -348,7 +350,7 @@ for (i = 0; i < n_opts; i++) {
}
}
- s = substr(" ", length (opts[i]))
+ s = substr(" ", length (enum))
if (i + 1 == n_opts)
comma = ""
diff --git a/gcc/opts.c b/gcc/opts.c
index 818acdf8f65..210140c63c3 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -2033,8 +2033,12 @@ common_handle_option (size_t scode, const char *arg, int value,
set_debug_level (SDB_DEBUG, false, arg);
break;
- case OPT_gdwarf_2:
- set_debug_level (DWARF2_DEBUG, false, arg);
+ case OPT_gdwarf_:
+ if (value < 2 || value > 3)
+ error ("dwarf version %d is not supported", value);
+ else
+ dwarf_version = value;
+ set_debug_level (DWARF2_DEBUG, false, "");
break;
case OPT_ggdb:
@@ -2063,6 +2067,7 @@ common_handle_option (size_t scode, const char *arg, int value,
flag_pedantic_errors = pedantic = 1;
break;
+ case OPT_fcse_skip_blocks:
case OPT_floop_optimize:
case OPT_frerun_loop_opt:
case OPT_fstrength_reduce:
diff --git a/gcc/output.h b/gcc/output.h
index e7871f980e2..9e2b704920a 100644
--- a/gcc/output.h
+++ b/gcc/output.h
@@ -1,7 +1,7 @@
/* Declarations for insn-output.c. These functions are defined in recog.c,
final.c, and varasm.c.
Copyright (C) 1987, 1991, 1994, 1997, 1998, 1999, 2000, 2001, 2002,
- 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+ 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
This file is part of GCC.
@@ -94,6 +94,10 @@ extern int insn_current_reference_address (rtx);
Defined in final.c. */
extern int label_to_alignment (rtx);
+/* Find the alignment maximum skip associated with a CODE_LABEL.
+ Defined in final.c. */
+extern int label_to_max_skip (rtx);
+
/* Output a LABEL_REF, or a bare CODE_LABEL, as an assembler symbol. */
extern void output_asm_label (rtx);
@@ -299,6 +303,11 @@ extern bool constructor_static_from_elts_p (const_tree);
arithmetic-combinations of integers. */
extern tree initializer_constant_valid_p (tree, tree);
+/* Return true if VALUE is a valid constant-valued expression
+ for use in initializing a static bit-field; one that can be
+ an element of a "constant" initializer. */
+extern bool initializer_constant_valid_for_bitfield_p (tree);
+
/* Output assembler code for constant EXP to FILE, with no label.
This includes the pseudo-op such as ".int" or ".byte", and a newline.
Assumes output_addressed_constants has been done on EXP already.
diff --git a/gcc/params.def b/gcc/params.def
index da6225c3535..dc5ceaf573e 100644
--- a/gcc/params.def
+++ b/gcc/params.def
@@ -38,36 +38,6 @@ along with GCC; see the file COPYING3. If not see
Be sure to add an entry to invoke.texi summarizing the parameter. */
-/* The maximum structure size at which the scalar replacement of
- aggregates (SRA) pass will perform block copies. The default
- value, 0, implies that GCC will select the most appropriate size
- itself. */
-DEFPARAM (PARAM_SRA_MAX_STRUCTURE_SIZE,
- "sra-max-structure-size",
- "The maximum structure size (in bytes) for which GCC will "
- "use by-element copies",
- 0, 0, 0)
-
-/* The maximum number of structure fields which the SRA pass will
- instantiate to avoid block copies. The default value, 0, implies
- that GCC will select the appropriate value itself. */
-DEFPARAM (PARAM_SRA_MAX_STRUCTURE_COUNT,
- "sra-max-structure-count",
- "The maximum number of structure fields for which GCC will "
- "use by-element copies",
- 0, 0, 0)
-
-/* The ratio between instantiated fields and the complete structure
- size. We say that if the ratio of the number of bytes in
- instantiated fields to the number of bytes in the complete
- structure exceeds this parameter, or if the number of instantiated
- fields to the total number of fields exceeds this parameter, then
- block copies are not used. The default is 75%. */
-DEFPARAM (PARAM_SRA_FIELD_STRUCTURE_RATIO,
- "sra-field-structure-ratio",
- "The threshold ratio between instantiated fields and the total structure size",
- 75, 0, 100)
-
/* The threshold ratio between current and hottest structure counts.
We say that if the ratio of the current structure count,
calculated by profiling, to the hottest structure count
@@ -100,7 +70,7 @@ DEFPARAM (PARAM_PREDICTABLE_BRANCH_OUTCOME,
DEFPARAM (PARAM_MAX_INLINE_INSNS_SINGLE,
"max-inline-insns-single",
"The maximum number of instructions in a single function eligible for inlining",
- 450, 0, 0)
+ 400, 0, 0)
/* The single function inlining limit for functions that are
inlined by virtue of -finline-functions (-O3).
@@ -112,7 +82,7 @@ DEFPARAM (PARAM_MAX_INLINE_INSNS_SINGLE,
DEFPARAM (PARAM_MAX_INLINE_INSNS_AUTO,
"max-inline-insns-auto",
"The maximum number of instructions when automatically inlining",
- 90, 0, 0)
+ 60, 0, 0)
DEFPARAM (PARAM_MAX_INLINE_INSNS_RECURSIVE,
"max-inline-insns-recursive",
@@ -139,6 +109,14 @@ DEFPARAM (PARAM_MIN_INLINE_RECURSIVE_PROBABILITY,
"Inline recursively only when the probability of call being executed exceeds the parameter",
10, 0, 0)
+/* Limit of iterations of early inliner. This basically bounds number of
+ nested indirect calls early inliner can resolve. Deeper chains are still
+ handled by late inlining. */
+DEFPARAM (PARAM_EARLY_INLINER_MAX_ITERATIONS,
+ "max-early-inliner-iterations",
+ "The maximum number of nested indirect inlining performed by early inliner",
+ 10, 0, 0)
+
/* Limit the number of expansions created by the variable expansion
optimization to avoid register pressure. */
DEFPARAM (PARAM_MAX_VARIABLE_EXPANSIONS,
@@ -204,9 +182,9 @@ DEFPARAM(PARAM_IPCP_UNIT_GROWTH,
"ipcp-unit-growth",
"how much can given compilation unit grow because of the interprocedural constant propagation (in percent)",
10, 0, 0)
-DEFPARAM(PARAM_INLINE_CALL_COST,
- "inline-call-cost",
- "expense of call operation relative to ordinary arithmetic operations",
+DEFPARAM(PARAM_EARLY_INLINING_INSNS,
+ "early-inlining-insns",
+ "maximal estimated growth of function body caused by early inlining of single call",
12, 0, 0)
DEFPARAM(PARAM_LARGE_STACK_FRAME,
"large-stack-frame",
@@ -757,6 +735,23 @@ DEFPARAM (PARAM_LOOP_INVARIANT_MAX_BBS_IN_LOOP,
"max basic blocks number in loop for loop invariant motion",
10000, 0, 0)
+/* Avoid SLP vectorization of large basic blocks. */
+DEFPARAM (PARAM_SLP_MAX_INSNS_IN_BB,
+ "slp-max-insns-in-bb",
+ "Maximum number of instructions in basic block to be considered for SLP vectorization",
+ 1000, 0, 0)
+
+DEFPARAM (PARAM_MIN_INSN_TO_PREFETCH_RATIO,
+ "min-insn-to-prefetch-ratio",
+ "min. ratio of insns to prefetches to enable prefetching for "
+ "a loop with an unknown trip count",
+ 10, 0, 0)
+
+DEFPARAM (PARAM_PREFETCH_MIN_INSN_TO_MEM_RATIO,
+ "prefetch-min-insn-to-mem-ratio",
+ "min. ratio of insns to mem ops to enable prefetching in a loop",
+ 3, 0, 0)
+
/* Set minimum insn uid for non-debug insns. */
DEFPARAM (PARAM_MIN_NONDEBUG_INSN_UID,
diff --git a/gcc/params.h b/gcc/params.h
index 4f029cc5c9c..67a7a05c3de 100644
--- a/gcc/params.h
+++ b/gcc/params.h
@@ -94,12 +94,6 @@ typedef enum compiler_param
(compiler_params[(int) ENUM].set)
/* Macros for the various parameters. */
-#define SRA_MAX_STRUCTURE_SIZE \
- PARAM_VALUE (PARAM_SRA_MAX_STRUCTURE_SIZE)
-#define SRA_MAX_STRUCTURE_COUNT \
- PARAM_VALUE (PARAM_SRA_MAX_STRUCTURE_COUNT)
-#define SRA_FIELD_STRUCTURE_RATIO \
- PARAM_VALUE (PARAM_SRA_FIELD_STRUCTURE_RATIO)
#define STRUCT_REORG_COLD_STRUCT_RATIO \
PARAM_VALUE (PARAM_STRUCT_REORG_COLD_STRUCT_RATIO)
#define MAX_INLINE_INSNS_SINGLE \
@@ -170,6 +164,12 @@ typedef enum compiler_param
PARAM_VALUE (PARAM_SWITCH_CONVERSION_BRANCH_RATIO)
#define LOOP_INVARIANT_MAX_BBS_IN_LOOP \
PARAM_VALUE (PARAM_LOOP_INVARIANT_MAX_BBS_IN_LOOP)
+#define SLP_MAX_INSNS_IN_BB \
+ PARAM_VALUE (PARAM_SLP_MAX_INSNS_IN_BB)
+#define MIN_INSN_TO_PREFETCH_RATIO \
+ PARAM_VALUE (PARAM_MIN_INSN_TO_PREFETCH_RATIO)
+#define PREFETCH_MIN_INSN_TO_MEM_RATIO \
+ PARAM_VALUE (PARAM_PREFETCH_MIN_INSN_TO_MEM_RATIO)
#define MIN_NONDEBUG_INSN_UID \
PARAM_VALUE (PARAM_MIN_NONDEBUG_INSN_UID)
#endif /* ! GCC_PARAMS_H */
diff --git a/gcc/passes.c b/gcc/passes.c
index b66ed1d340b..6870973229d 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -239,7 +239,7 @@ rest_of_type_compilation (tree type, int toplev)
void
finish_optimization_passes (void)
{
- enum tree_dump_index i;
+ int i;
struct dump_file_info *dfi;
char *name;
@@ -554,7 +554,11 @@ init_optimization_passes (void)
NEXT_PASS (pass_rename_ssa_copies);
NEXT_PASS (pass_ccp);
NEXT_PASS (pass_forwprop);
- NEXT_PASS (pass_update_address_taken);
+ /* pass_build_ealias is a dummy pass that ensures that we
+ execute TODO_rebuild_alias at this point. Re-building
+ alias information also rewrites no longer addressed
+ locals into SSA form if possible. */
+ NEXT_PASS (pass_build_ealias);
NEXT_PASS (pass_sra_early);
NEXT_PASS (pass_copy_prop);
NEXT_PASS (pass_merge_phi);
@@ -634,6 +638,7 @@ init_optimization_passes (void)
NEXT_PASS (pass_copy_prop);
NEXT_PASS (pass_fold_builtins);
NEXT_PASS (pass_cse_sincos);
+ NEXT_PASS (pass_optimize_bswap);
NEXT_PASS (pass_split_crit_edges);
NEXT_PASS (pass_pre);
NEXT_PASS (pass_sink_code);
@@ -644,7 +649,6 @@ init_optimization_passes (void)
NEXT_PASS (pass_copy_prop);
NEXT_PASS (pass_dce_loop);
NEXT_PASS (pass_lim);
- NEXT_PASS (pass_predcom);
NEXT_PASS (pass_tree_unswitch);
NEXT_PASS (pass_scev_cprop);
NEXT_PASS (pass_empty_loop);
@@ -661,7 +665,9 @@ init_optimization_passes (void)
NEXT_PASS (pass_lower_vector_ssa);
NEXT_PASS (pass_dce_loop);
}
+ NEXT_PASS (pass_predcom);
NEXT_PASS (pass_complete_unroll);
+ NEXT_PASS (pass_slp_vectorize);
NEXT_PASS (pass_parallelize_loops);
NEXT_PASS (pass_loop_prefetch);
NEXT_PASS (pass_iv_optimize);
@@ -839,7 +845,8 @@ do_per_function (void (*callback) (void *data), void *data)
{
struct cgraph_node *node;
for (node = cgraph_nodes; node; node = node->next)
- if (node->analyzed && gimple_has_body_p (node->decl))
+ if (node->analyzed && gimple_has_body_p (node->decl)
+ && (!node->clone_of || node->decl != node->clone_of->decl))
{
push_cfun (DECL_STRUCT_FUNCTION (node->decl));
current_function_decl = node->decl;
@@ -1152,14 +1159,14 @@ update_properties_after_pass (void *data)
static void
add_ipa_transform_pass (void *data)
{
- struct ipa_opt_pass *ipa_pass = (struct ipa_opt_pass *) data;
+ struct ipa_opt_pass_d *ipa_pass = (struct ipa_opt_pass_d *) data;
VEC_safe_push (ipa_opt_pass, heap, cfun->ipa_transforms_to_apply, ipa_pass);
}
/* Execute summary generation for all of the passes in IPA_PASS. */
static void
-execute_ipa_summary_passes (struct ipa_opt_pass *ipa_pass)
+execute_ipa_summary_passes (struct ipa_opt_pass_d *ipa_pass)
{
while (ipa_pass)
{
@@ -1173,7 +1180,7 @@ execute_ipa_summary_passes (struct ipa_opt_pass *ipa_pass)
ipa_pass->generate_summary ();
pass_fini_dump_file (pass);
}
- ipa_pass = (struct ipa_opt_pass *)ipa_pass->pass.next;
+ ipa_pass = (struct ipa_opt_pass_d *)ipa_pass->pass.next;
}
}
@@ -1181,7 +1188,7 @@ execute_ipa_summary_passes (struct ipa_opt_pass *ipa_pass)
static void
execute_one_ipa_transform_pass (struct cgraph_node *node,
- struct ipa_opt_pass *ipa_pass)
+ struct ipa_opt_pass_d *ipa_pass)
{
struct opt_pass *pass = &ipa_pass->pass;
unsigned int todo_after = 0;
@@ -1353,7 +1360,7 @@ execute_ipa_pass_list (struct opt_pass *pass)
{
if (!quiet_flag && !cfun)
fprintf (stderr, " <summary generate>");
- execute_ipa_summary_passes ((struct ipa_opt_pass *) pass);
+ execute_ipa_summary_passes ((struct ipa_opt_pass_d *) pass);
}
summaries_generated = true;
}
diff --git a/gcc/plugin.c b/gcc/plugin.c
index dec336d70b7..93151f8a8a7 100644
--- a/gcc/plugin.c
+++ b/gcc/plugin.c
@@ -38,6 +38,8 @@ along with GCC; see the file COPYING3. If not see
#include "intl.h"
#include "plugin.h"
#include "timevar.h"
+#include "ggc.h"
+
#ifdef ENABLE_PLUGIN
#include "plugin-version.h"
#endif
@@ -51,22 +53,13 @@ const char *plugin_event_name[] =
"PLUGIN_CXX_CP_PRE_GENERICIZE",
"PLUGIN_FINISH",
"PLUGIN_INFO",
+ "PLUGIN_GGC_START",
+ "PLUGIN_GGC_MARKING",
+ "PLUGIN_GGC_END",
+ "PLUGIN_REGISTER_GGC_ROOTS",
"PLUGIN_EVENT_LAST"
};
-/* Object that keeps track of the plugin name and its arguments
- when parsing the command-line options -fplugin=/path/to/NAME.so and
- -fplugin-arg-NAME-<key>[=<value>]. */
-struct plugin_name_args
-{
- char *base_name;
- const char *full_name;
- int argc;
- struct plugin_argument *argv;
- const char *version;
- const char *help;
-};
-
/* Hash table for the plugin_name_args objects created during command-line
parsing. */
static htab_t plugin_name_args_tab = NULL;
@@ -343,6 +336,11 @@ position_pass (struct plugin_pass *plugin_pass_info,
case PASS_POS_INSERT_AFTER:
new_pass->next = pass->next;
pass->next = new_pass;
+
+ /* Skip newly inserted pass to avoid repeated
+ insertions in the case where the new pass and the
+ existing one have the same name. */
+ pass = new_pass;
break;
case PASS_POS_INSERT_BEFORE:
new_pass->next = pass;
@@ -485,14 +483,24 @@ register_callback (const char *plugin_name,
switch (event)
{
case PLUGIN_PASS_MANAGER_SETUP:
+ gcc_assert (!callback);
register_pass (plugin_name, (struct plugin_pass *) user_data);
break;
case PLUGIN_INFO:
+ gcc_assert (!callback);
register_plugin_info (plugin_name, (struct plugin_info *) user_data);
break;
+ case PLUGIN_REGISTER_GGC_ROOTS:
+ gcc_assert (!callback);
+ ggc_register_root_tab ((const struct ggc_root_tab*) user_data);
+ break;
case PLUGIN_FINISH_TYPE:
case PLUGIN_FINISH_UNIT:
case PLUGIN_CXX_CP_PRE_GENERICIZE:
+ case PLUGIN_GGC_START:
+ case PLUGIN_GGC_MARKING:
+ case PLUGIN_GGC_END:
+ case PLUGIN_ATTRIBUTES:
case PLUGIN_FINISH:
{
struct callback_info *new_callback;
@@ -534,7 +542,11 @@ invoke_plugin_callbacks (enum plugin_event event, void *gcc_data)
case PLUGIN_FINISH_TYPE:
case PLUGIN_FINISH_UNIT:
case PLUGIN_CXX_CP_PRE_GENERICIZE:
+ case PLUGIN_ATTRIBUTES:
case PLUGIN_FINISH:
+ case PLUGIN_GGC_START:
+ case PLUGIN_GGC_MARKING:
+ case PLUGIN_GGC_END:
{
/* Iterate over every callback registered with this event and
call it. */
@@ -546,6 +558,7 @@ invoke_plugin_callbacks (enum plugin_event event, void *gcc_data)
case PLUGIN_PASS_MANAGER_SETUP:
case PLUGIN_EVENT_LAST:
+ case PLUGIN_REGISTER_GGC_ROOTS:
default:
gcc_assert (false);
}
@@ -594,8 +607,7 @@ try_init_one_plugin (struct plugin_name_args *plugin)
}
/* Call the plugin-provided initialization routine with the arguments. */
- if ((*plugin_init) (plugin->base_name, &gcc_version, plugin->argc,
- plugin->argv))
+ if ((*plugin_init) (plugin, &gcc_version))
{
error ("Fail to initialize plugin %s", plugin->full_name);
return false;
@@ -765,7 +777,7 @@ print_plugins_help (FILE *file, const char *indent)
bool
plugins_active_p (void)
{
- enum plugin_event event;
+ int event;
for (event = PLUGIN_PASS_MANAGER_SETUP; event < PLUGIN_EVENT_LAST; event++)
if (plugin_callbacks[event])
@@ -781,7 +793,7 @@ plugins_active_p (void)
void
dump_active_plugins (FILE *file)
{
- enum plugin_event event;
+ int event;
if (!plugins_active_p ())
return;
diff --git a/gcc/plugin.h b/gcc/plugin.h
index c1f566ba80f..b610b23ed93 100644
--- a/gcc/plugin.h
+++ b/gcc/plugin.h
@@ -22,6 +22,8 @@ along with GCC; see the file COPYING3. If not see
#include "gcc-plugin.h"
+struct attribute_spec;
+
extern void add_new_plugin (const char *);
extern void parse_plugin_arg_opt (const char *);
extern void invoke_plugin_callbacks (enum plugin_event, void *);
@@ -33,4 +35,8 @@ extern void print_plugins_versions (FILE *file, const char *indent);
extern void print_plugins_help (FILE *file, const char *indent);
extern void finalize_plugins (void);
+/* In attribs.c. */
+
+extern void register_attribute (const struct attribute_spec *attr);
+
#endif /* PLUGIN_H */
diff --git a/gcc/predict.c b/gcc/predict.c
index 732283d4c22..e3b4b83b863 100644
--- a/gcc/predict.c
+++ b/gcc/predict.c
@@ -168,8 +168,8 @@ cgraph_maybe_hot_edge_p (struct cgraph_edge *edge)
if (lookup_attribute ("hot", DECL_ATTRIBUTES (edge->caller->decl)))
return true;
if (flag_guess_branch_prob
- && edge->frequency < (CGRAPH_FREQ_MAX
- / PARAM_VALUE (HOT_BB_FREQUENCY_FRACTION)))
+ && edge->frequency <= (CGRAPH_FREQ_BASE
+ / PARAM_VALUE (HOT_BB_FREQUENCY_FRACTION)))
return false;
return true;
}
diff --git a/gcc/print-rtl.c b/gcc/print-rtl.c
index d58e0d3913b..c443a5030b9 100644
--- a/gcc/print-rtl.c
+++ b/gcc/print-rtl.c
@@ -1,6 +1,6 @@
/* Print RTL for GCC.
Copyright (C) 1987, 1988, 1992, 1997, 1998, 1999, 2000, 2002, 2003,
- 2004, 2005, 2007, 2008
+ 2004, 2005, 2007, 2008, 2009
Free Software Foundation, Inc.
This file is part of GCC.
diff --git a/gcc/print-tree.c b/gcc/print-tree.c
index 0d352642157..969c6ea4ba7 100644
--- a/gcc/print-tree.c
+++ b/gcc/print-tree.c
@@ -425,8 +425,6 @@ print_node (FILE *file, const char *prefix, tree node, int indent)
fputs (" virtual", file);
if (DECL_PRESERVE_P (node))
fputs (" preserve", file);
- if (DECL_NO_TBAA_P (node))
- fputs (" no-tbaa", file);
if (DECL_LANG_FLAG_0 (node))
fputs (" decl_0", file);
if (DECL_LANG_FLAG_1 (node))
diff --git a/gcc/real.c b/gcc/real.c
index 3803ed69c1b..f4c493bd041 100644
--- a/gcc/real.c
+++ b/gcc/real.c
@@ -4513,6 +4513,167 @@ const struct real_format decimal_quad_format =
false
};
+/* Encode half-precision floats. This routine is used both for the IEEE
+ ARM alternative encodings. */
+static void
+encode_ieee_half (const struct real_format *fmt, long *buf,
+ const REAL_VALUE_TYPE *r)
+{
+ unsigned long image, sig, exp;
+ unsigned long sign = r->sign;
+ bool denormal = (r->sig[SIGSZ-1] & SIG_MSB) == 0;
+
+ image = sign << 15;
+ sig = (r->sig[SIGSZ-1] >> (HOST_BITS_PER_LONG - 11)) & 0x3ff;
+
+ switch (r->cl)
+ {
+ case rvc_zero:
+ break;
+
+ case rvc_inf:
+ if (fmt->has_inf)
+ image |= 31 << 10;
+ else
+ image |= 0x7fff;
+ break;
+
+ case rvc_nan:
+ if (fmt->has_nans)
+ {
+ if (r->canonical)
+ sig = (fmt->canonical_nan_lsbs_set ? (1 << 9) - 1 : 0);
+ if (r->signalling == fmt->qnan_msb_set)
+ sig &= ~(1 << 9);
+ else
+ sig |= 1 << 9;
+ if (sig == 0)
+ sig = 1 << 8;
+
+ image |= 31 << 10;
+ image |= sig;
+ }
+ else
+ image |= 0x3ff;
+ break;
+
+ case rvc_normal:
+ /* Recall that IEEE numbers are interpreted as 1.F x 2**exp,
+ whereas the intermediate representation is 0.F x 2**exp.
+ Which means we're off by one. */
+ if (denormal)
+ exp = 0;
+ else
+ exp = REAL_EXP (r) + 15 - 1;
+ image |= exp << 10;
+ image |= sig;
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+
+ buf[0] = image;
+}
+
+/* Decode half-precision floats. This routine is used both for the IEEE
+ ARM alternative encodings. */
+static void
+decode_ieee_half (const struct real_format *fmt, REAL_VALUE_TYPE *r,
+ const long *buf)
+{
+ unsigned long image = buf[0] & 0xffff;
+ bool sign = (image >> 15) & 1;
+ int exp = (image >> 10) & 0x1f;
+
+ memset (r, 0, sizeof (*r));
+ image <<= HOST_BITS_PER_LONG - 11;
+ image &= ~SIG_MSB;
+
+ if (exp == 0)
+ {
+ if (image && fmt->has_denorm)
+ {
+ r->cl = rvc_normal;
+ r->sign = sign;
+ SET_REAL_EXP (r, -14);
+ r->sig[SIGSZ-1] = image << 1;
+ normalize (r);
+ }
+ else if (fmt->has_signed_zero)
+ r->sign = sign;
+ }
+ else if (exp == 31 && (fmt->has_nans || fmt->has_inf))
+ {
+ if (image)
+ {
+ r->cl = rvc_nan;
+ r->sign = sign;
+ r->signalling = (((image >> (HOST_BITS_PER_LONG - 2)) & 1)
+ ^ fmt->qnan_msb_set);
+ r->sig[SIGSZ-1] = image;
+ }
+ else
+ {
+ r->cl = rvc_inf;
+ r->sign = sign;
+ }
+ }
+ else
+ {
+ r->cl = rvc_normal;
+ r->sign = sign;
+ SET_REAL_EXP (r, exp - 15 + 1);
+ r->sig[SIGSZ-1] = image | SIG_MSB;
+ }
+}
+
+/* Half-precision format, as specified in IEEE 754R. */
+const struct real_format ieee_half_format =
+ {
+ encode_ieee_half,
+ decode_ieee_half,
+ 2,
+ 11,
+ 11,
+ -13,
+ 16,
+ 15,
+ 15,
+ false,
+ true,
+ true,
+ true,
+ true,
+ true,
+ true,
+ false
+ };
+
+/* ARM's alternative half-precision format, similar to IEEE but with
+ no reserved exponent value for NaNs and infinities; rather, it just
+ extends the range of exponents by one. */
+const struct real_format arm_half_format =
+ {
+ encode_ieee_half,
+ decode_ieee_half,
+ 2,
+ 11,
+ 11,
+ -13,
+ 17,
+ 15,
+ 15,
+ false,
+ true,
+ false,
+ false,
+ true,
+ true,
+ false,
+ false
+ };
+
/* A synthetic "format" for internal arithmetic. It's the size of the
internal significand minus the two bits needed for proper rounding.
The encode and decode routines exist only to satisfy our paranoia
diff --git a/gcc/real.h b/gcc/real.h
index 47efac5d2ae..0fc915cae5b 100644
--- a/gcc/real.h
+++ b/gcc/real.h
@@ -24,6 +24,9 @@
#ifndef GENERATOR_FILE
#include <gmp.h>
#include <mpfr.h>
+#ifdef HAVE_mpc
+#include <mpc.h>
+#endif
#endif
#include "machmode.h"
@@ -303,6 +306,8 @@ extern const struct real_format real_internal_format;
extern const struct real_format decimal_single_format;
extern const struct real_format decimal_double_format;
extern const struct real_format decimal_quad_format;
+extern const struct real_format ieee_half_format;
+extern const struct real_format arm_half_format;
/* ====================================================================== */
diff --git a/gcc/recog.c b/gcc/recog.c
index a578fa40f42..ae8c8d1bed2 100644
--- a/gcc/recog.c
+++ b/gcc/recog.c
@@ -1256,11 +1256,15 @@ pop_operand (rtx op, enum machine_mode mode)
int
memory_address_p (enum machine_mode mode ATTRIBUTE_UNUSED, rtx addr)
{
+#ifdef GO_IF_LEGITIMATE_ADDRESS
GO_IF_LEGITIMATE_ADDRESS (mode, addr, win);
return 0;
win:
return 1;
+#else
+ return targetm.legitimate_address_p (mode, addr, 0);
+#endif
}
/* Return 1 if OP is a valid memory reference with mode MODE,
@@ -3056,6 +3060,26 @@ peep2_find_free_register (int from, int to, const char *class_str,
return NULL_RTX;
}
+/* Forget all currently tracked instructions, only remember current
+ LIVE regset. */
+
+static void
+peep2_reinit_state (regset live)
+{
+ int i;
+
+ /* Indicate that all slots except the last holds invalid data. */
+ for (i = 0; i < MAX_INSNS_PER_PEEP2; ++i)
+ peep2_insn_data[i].insn = NULL_RTX;
+ peep2_current_count = 0;
+
+ /* Indicate that the last slot contains live_after data. */
+ peep2_insn_data[MAX_INSNS_PER_PEEP2].insn = PEEP2_EOB;
+ peep2_current = MAX_INSNS_PER_PEEP2;
+
+ COPY_REG_SET (peep2_insn_data[MAX_INSNS_PER_PEEP2].live_before, live);
+}
+
/* Perform the peephole2 optimization pass. */
static void
@@ -3079,19 +3103,11 @@ peephole2_optimize (void)
FOR_EACH_BB_REVERSE (bb)
{
rtl_profile_for_bb (bb);
- /* Indicate that all slots except the last holds invalid data. */
- for (i = 0; i < MAX_INSNS_PER_PEEP2; ++i)
- peep2_insn_data[i].insn = NULL_RTX;
- peep2_current_count = 0;
-
- /* Indicate that the last slot contains live_after data. */
- peep2_insn_data[MAX_INSNS_PER_PEEP2].insn = PEEP2_EOB;
- peep2_current = MAX_INSNS_PER_PEEP2;
/* Start up propagation. */
bitmap_copy (live, DF_LR_OUT (bb));
df_simulate_initialize_backwards (bb, live);
- bitmap_copy (peep2_insn_data[MAX_INSNS_PER_PEEP2].live_before, live);
+ peep2_reinit_state (live);
for (insn = BB_END (bb); ; insn = prev)
{
@@ -3118,7 +3134,7 @@ peephole2_optimize (void)
/* If an insn has RTX_FRAME_RELATED_P set, peephole
substitution would lose the
REG_FRAME_RELATED_EXPR that is attached. */
- peep2_current_count = 0;
+ peep2_reinit_state (live);
attempt = NULL;
}
else
diff --git a/gcc/reg-notes.def b/gcc/reg-notes.def
index 60e41bb9803..90b5fde3feb 100644
--- a/gcc/reg-notes.def
+++ b/gcc/reg-notes.def
@@ -118,6 +118,41 @@ REG_NOTE (BR_PRED)
instead of intuition. */
REG_NOTE (FRAME_RELATED_EXPR)
+/* Attached to insns that are RTX_FRAME_RELATED_P, but are too complex
+ for FRAME_RELATED_EXPR intuition. The insn's first pattern must be
+ a SET, and the destination must be the CFA register. The attached
+ rtx is an expression that defines the CFA. In the simplest case, the
+ rtx could be just the stack_pointer_rtx; more common would be a PLUS
+ with a base register and a constant offset. In the most complicated
+ cases, this will result in a DW_CFA_def_cfa_expression with the rtx
+ expression rendered in a dwarf location expression. */
+REG_NOTE (CFA_DEF_CFA)
+
+/* Attached to insns that are RTX_FRAME_RELATED_P, but are too complex
+ for FRAME_RELATED_EXPR intuition. This note adjusts the expression
+ from which the CFA is computed. The attached rtx defines a new CFA
+ expression, relative to the old CFA expression. This rtx must be of
+ the form (SET new-cfa-reg (PLUS old-cfa-reg const_int)). If the note
+ rtx is NULL, we use the first SET of the insn. */
+REG_NOTE (CFA_ADJUST_CFA)
+
+/* Similar to FRAME_RELATED_EXPR, with the additional information that
+ this is a save to memory, i.e. will result in DW_CFA_offset or the
+ like. The pattern or the insn should be a simple store relative to
+ the CFA. */
+REG_NOTE (CFA_OFFSET)
+
+/* Similar to FRAME_RELATED_EXPR, with the additional information that this
+ is a save to a register, i.e. will result in DW_CFA_register. The insn
+ or the pattern should be simple reg-reg move. */
+REG_NOTE (CFA_REGISTER)
+
+/* Attached to insns that are RTX_FRAME_RELATED_P, with the information
+ that this is a restore operation, i.e. will result in DW_CFA_restore
+ or the like. Either the attached rtx, or the destination of the insn's
+ first pattern is the register to be restored. */
+REG_NOTE (CFA_RESTORE)
+
/* Indicates that REG holds the exception context for the function.
This context is shared by inline functions, so the code to acquire
the real exception context is delayed until after inlining. */
diff --git a/gcc/reg-stack.c b/gcc/reg-stack.c
index 55577eca23e..540047ce72e 100644
--- a/gcc/reg-stack.c
+++ b/gcc/reg-stack.c
@@ -1398,21 +1398,23 @@ subst_stack_regs_pat (rtx insn, stack regstack, rtx pat)
if (pat != PATTERN (insn))
{
- /* The fix_truncdi_1 pattern wants to be able to allocate
- its own scratch register. It does this by clobbering
- an fp reg so that it is assured of an empty reg-stack
- register. If the register is live, kill it now.
- Remove the DEAD/UNUSED note so we don't try to kill it
- later too. */
+ /* The fix_truncdi_1 pattern wants to be able to
+ allocate its own scratch register. It does this by
+ clobbering an fp reg so that it is assured of an
+ empty reg-stack register. If the register is live,
+ kill it now. Remove the DEAD/UNUSED note so we
+ don't try to kill it later too.
+
+ In reality the UNUSED note can be absent in some
+ complicated cases when the register is reused for
+ partially set variable. */
if (note)
emit_pop_insn (insn, regstack, *dest, EMIT_BEFORE);
else
- {
- note = find_reg_note (insn, REG_UNUSED, *dest);
- gcc_assert (note);
- }
- remove_note (insn, note);
+ note = find_reg_note (insn, REG_UNUSED, *dest);
+ if (note)
+ remove_note (insn, note);
replace_reg (dest, FIRST_STACK_REG + 1);
}
else
diff --git a/gcc/reginfo.c b/gcc/reginfo.c
index 5ab67ef5b00..1f8684fbdd0 100644
--- a/gcc/reginfo.c
+++ b/gcc/reginfo.c
@@ -1322,7 +1322,7 @@ invalid_mode_change_p (unsigned int regno,
enum machine_mode from)
{
struct subregs_of_mode_node dummy, *node;
- enum machine_mode to;
+ unsigned int to;
unsigned char mask;
gcc_assert (subregs_of_mode);
@@ -1335,7 +1335,7 @@ invalid_mode_change_p (unsigned int regno,
mask = 1 << (regno & 7);
for (to = VOIDmode; to < NUM_MACHINE_MODES; to++)
if (node->modes[to] & mask)
- if (CANNOT_CHANGE_MODE_CLASS (from, to, rclass))
+ if (CANNOT_CHANGE_MODE_CLASS (from, (enum machine_mode) to, rclass))
return true;
return false;
diff --git a/gcc/regstat.c b/gcc/regstat.c
index fbf7b305d42..70ddfa4d84f 100644
--- a/gcc/regstat.c
+++ b/gcc/regstat.c
@@ -1,5 +1,5 @@
/* Scanning of rtl for dataflow analysis.
- Copyright (C) 2007, 2008
+ Copyright (C) 2007, 2008, 2009
Free Software Foundation, Inc.
Contributed by Kenneth Zadeck (zadeck@naturalbridge.com).
@@ -37,7 +37,6 @@ along with GCC; see the file COPYING3. If not see
struct regstat_n_sets_and_refs_t *regstat_n_sets_and_refs;
-struct regstat_n_sets_and_refs_t *regstat_n_sets_and_refs;
/*----------------------------------------------------------------------------
REG_N_SETS and REG_N_REFS.
diff --git a/gcc/reload.c b/gcc/reload.c
index d89faba8e99..4d1bc634111 100644
--- a/gcc/reload.c
+++ b/gcc/reload.c
@@ -2135,11 +2135,15 @@ hard_reg_set_here_p (unsigned int beg_regno, unsigned int end_regno, rtx x)
int
strict_memory_address_p (enum machine_mode mode ATTRIBUTE_UNUSED, rtx addr)
{
+#ifdef GO_IF_LEGITIMATE_ADDRESS
GO_IF_LEGITIMATE_ADDRESS (mode, addr, win);
return 0;
win:
return 1;
+#else
+ return targetm.legitimate_address_p (mode, addr, 1);
+#endif
}
/* Like rtx_equal_p except that it allows a REG and a SUBREG to match
diff --git a/gcc/reorg.c b/gcc/reorg.c
index 059bf755e79..74e84eb8116 100644
--- a/gcc/reorg.c
+++ b/gcc/reorg.c
@@ -173,8 +173,8 @@ static int max_uid;
static int stop_search_p (rtx, int);
static int resource_conflicts_p (struct resources *, struct resources *);
-static int insn_references_resource_p (rtx, struct resources *, int);
-static int insn_sets_resource_p (rtx, struct resources *, int);
+static int insn_references_resource_p (rtx, struct resources *, bool);
+static int insn_sets_resource_p (rtx, struct resources *, bool);
static rtx find_end_label (void);
static rtx emit_delay_sequence (rtx, rtx, int);
static rtx add_to_delay_list (rtx, rtx);
@@ -297,7 +297,7 @@ resource_conflicts_p (struct resources *res1, struct resources *res2)
static int
insn_references_resource_p (rtx insn, struct resources *res,
- int include_delayed_effects)
+ bool include_delayed_effects)
{
struct resources insn_res;
@@ -313,7 +313,7 @@ insn_references_resource_p (rtx insn, struct resources *res,
static int
insn_sets_resource_p (rtx insn, struct resources *res,
- int include_delayed_effects)
+ bool include_delayed_effects)
{
struct resources insn_sets;
@@ -1246,7 +1246,7 @@ steal_delay_list_from_target (rtx insn, rtx condition, rtx seq,
rtx trial = XEXP (temp, 0);
mark_set_resources (trial, &cc_set, 0, MARK_SRC_DEST_CALL);
- if (insn_references_resource_p (XVECEXP (seq , 0, 0), &cc_set, 0))
+ if (insn_references_resource_p (XVECEXP (seq , 0, 0), &cc_set, false))
return delay_list;
}
@@ -1268,9 +1268,9 @@ steal_delay_list_from_target (rtx insn, rtx condition, rtx seq,
rtx trial = XVECEXP (seq, 0, i);
int flags;
- if (insn_references_resource_p (trial, sets, 0)
- || insn_sets_resource_p (trial, needed, 0)
- || insn_sets_resource_p (trial, sets, 0)
+ if (insn_references_resource_p (trial, sets, false)
+ || insn_sets_resource_p (trial, needed, false)
+ || insn_sets_resource_p (trial, sets, false)
#ifdef HAVE_cc0
/* If TRIAL sets CC0, we can't copy it, so we can't steal this
delay list. */
@@ -1293,7 +1293,7 @@ steal_delay_list_from_target (rtx insn, rtx condition, rtx seq,
if (! must_annul
&& ((condition == const_true_rtx
- || (! insn_sets_resource_p (trial, other_needed, 0)
+ || (! insn_sets_resource_p (trial, other_needed, false)
&& ! may_trap_or_fault_p (PATTERN (trial)))))
? eligible_for_delay (insn, total_slots_filled, trial, flags)
: (must_annul || (delay_list == NULL && new_delay_list == NULL))
@@ -1368,9 +1368,9 @@ steal_delay_list_from_fallthrough (rtx insn, rtx condition, rtx seq,
/* If TRIAL sets CC0, stealing it will move it too far from the use
of CC0. */
- if (insn_references_resource_p (trial, sets, 0)
- || insn_sets_resource_p (trial, needed, 0)
- || insn_sets_resource_p (trial, sets, 0)
+ if (insn_references_resource_p (trial, sets, false)
+ || insn_sets_resource_p (trial, needed, false)
+ || insn_sets_resource_p (trial, sets, false)
#ifdef HAVE_cc0
|| sets_cc0_p (PATTERN (trial))
#endif
@@ -1387,7 +1387,7 @@ steal_delay_list_from_fallthrough (rtx insn, rtx condition, rtx seq,
if (! must_annul
&& ((condition == const_true_rtx
- || (! insn_sets_resource_p (trial, other_needed, 0)
+ || (! insn_sets_resource_p (trial, other_needed, false)
&& ! may_trap_or_fault_p (PATTERN (trial)))))
? eligible_for_delay (insn, *pslots_filled, trial, flags)
: (must_annul || delay_list == NULL) && (must_annul = 1,
@@ -1448,7 +1448,8 @@ try_merge_delay_insns (rtx insn, rtx thread)
if (! annul_p)
for (i = 1 ; i < num_slots; i++)
if (XVECEXP (PATTERN (insn), 0, i))
- mark_referenced_resources (XVECEXP (PATTERN (insn), 0, i), &needed, 1);
+ mark_referenced_resources (XVECEXP (PATTERN (insn), 0, i), &needed,
+ true);
for (trial = thread; !stop_search_p (trial, 1); trial = next_trial)
{
@@ -1467,9 +1468,9 @@ try_merge_delay_insns (rtx insn, rtx thread)
/* We can't share an insn that sets cc0. */
&& ! sets_cc0_p (pat)
#endif
- && ! insn_references_resource_p (trial, &set, 1)
- && ! insn_sets_resource_p (trial, &set, 1)
- && ! insn_sets_resource_p (trial, &needed, 1)
+ && ! insn_references_resource_p (trial, &set, true)
+ && ! insn_sets_resource_p (trial, &set, true)
+ && ! insn_sets_resource_p (trial, &needed, true)
&& (trial = try_split (pat, trial, 0)) != 0
/* Update next_trial, in case try_split succeeded. */
&& (next_trial = next_nonnote_insn (trial))
@@ -1500,7 +1501,7 @@ try_merge_delay_insns (rtx insn, rtx thread)
}
mark_set_resources (trial, &set, 0, MARK_SRC_DEST_CALL);
- mark_referenced_resources (trial, &needed, 1);
+ mark_referenced_resources (trial, &needed, true);
}
/* See if we stopped on a filled insn. If we did, try to see if its
@@ -1515,15 +1516,15 @@ try_merge_delay_insns (rtx insn, rtx thread)
/* Account for resources set/needed by the filled insn. */
mark_set_resources (filled_insn, &set, 0, MARK_SRC_DEST_CALL);
- mark_referenced_resources (filled_insn, &needed, 1);
+ mark_referenced_resources (filled_insn, &needed, true);
for (i = 1; i < XVECLEN (pat, 0); i++)
{
rtx dtrial = XVECEXP (pat, 0, i);
- if (! insn_references_resource_p (dtrial, &set, 1)
- && ! insn_sets_resource_p (dtrial, &set, 1)
- && ! insn_sets_resource_p (dtrial, &needed, 1)
+ if (! insn_references_resource_p (dtrial, &set, true)
+ && ! insn_sets_resource_p (dtrial, &set, true)
+ && ! insn_sets_resource_p (dtrial, &needed, true)
#ifdef HAVE_cc0
&& ! sets_cc0_p (PATTERN (dtrial))
#endif
@@ -1554,7 +1555,7 @@ try_merge_delay_insns (rtx insn, rtx thread)
/* Keep track of the set/referenced resources for the delay
slots of any trial insns we encounter. */
mark_set_resources (dtrial, &set, 0, MARK_SRC_DEST_CALL);
- mark_referenced_resources (dtrial, &needed, 1);
+ mark_referenced_resources (dtrial, &needed, true);
}
}
}
@@ -1690,7 +1691,7 @@ redundant_insn (rtx insn, rtx target, rtx delay_list)
CLEAR_RESOURCE (&needed);
CLEAR_RESOURCE (&set);
mark_set_resources (insn, &set, 0, MARK_SRC_DEST_CALL);
- mark_referenced_resources (insn, &needed, 1);
+ mark_referenced_resources (insn, &needed, true);
/* If TARGET is a SEQUENCE, get the main insn. */
if (NONJUMP_INSN_P (target) && GET_CODE (PATTERN (target)) == SEQUENCE)
@@ -1702,8 +1703,8 @@ redundant_insn (rtx insn, rtx target, rtx delay_list)
#endif
/* The insn requiring the delay may not set anything needed or set by
INSN. */
- || insn_sets_resource_p (target_main, &needed, 1)
- || insn_sets_resource_p (target_main, &set, 1))
+ || insn_sets_resource_p (target_main, &needed, true)
+ || insn_sets_resource_p (target_main, &set, true))
return 0;
/* Insns we pass may not set either NEEDED or SET, so merge them for
@@ -1717,14 +1718,15 @@ redundant_insn (rtx insn, rtx target, rtx delay_list)
while (delay_list)
{
- if (insn_sets_resource_p (XEXP (delay_list, 0), &needed, 1))
+ if (insn_sets_resource_p (XEXP (delay_list, 0), &needed, true))
return 0;
delay_list = XEXP (delay_list, 1);
}
if (NONJUMP_INSN_P (target) && GET_CODE (PATTERN (target)) == SEQUENCE)
for (i = 1; i < XVECLEN (PATTERN (target), 0); i++)
- if (insn_sets_resource_p (XVECEXP (PATTERN (target), 0, i), &needed, 1))
+ if (insn_sets_resource_p (XVECEXP (PATTERN (target), 0, i), &needed,
+ true))
return 0;
/* Scan backwards until we reach a label or an insn that uses something
@@ -1783,13 +1785,13 @@ redundant_insn (rtx insn, rtx target, rtx delay_list)
we must stop if it sets anything needed or set by INSN. */
if ((! INSN_ANNULLED_BRANCH_P (XVECEXP (pat, 0, 0))
|| ! INSN_FROM_TARGET_P (candidate))
- && insn_sets_resource_p (candidate, &needed, 1))
+ && insn_sets_resource_p (candidate, &needed, true))
return 0;
}
/* If the insn requiring the delay slot conflicts with INSN, we
must stop. */
- if (insn_sets_resource_p (XVECEXP (pat, 0, 0), &needed, 1))
+ if (insn_sets_resource_p (XVECEXP (pat, 0, 0), &needed, true))
return 0;
}
else
@@ -1800,7 +1802,7 @@ redundant_insn (rtx insn, rtx target, rtx delay_list)
return trial;
/* Can't go any further if TRIAL conflicts with INSN. */
- if (insn_sets_resource_p (trial, &needed, 1))
+ if (insn_sets_resource_p (trial, &needed, true))
return 0;
}
}
@@ -2138,7 +2140,7 @@ fill_simple_delay_slots (int non_jumps_p)
CLEAR_RESOURCE (&needed);
CLEAR_RESOURCE (&set);
mark_set_resources (insn, &set, 0, MARK_SRC_DEST);
- mark_referenced_resources (insn, &needed, 0);
+ mark_referenced_resources (insn, &needed, false);
for (trial = prev_nonnote_insn (insn); ! stop_search_p (trial, 1);
trial = next_trial)
@@ -2154,9 +2156,9 @@ fill_simple_delay_slots (int non_jumps_p)
/* Check for resource conflict first, to avoid unnecessary
splitting. */
- if (! insn_references_resource_p (trial, &set, 1)
- && ! insn_sets_resource_p (trial, &set, 1)
- && ! insn_sets_resource_p (trial, &needed, 1)
+ if (! insn_references_resource_p (trial, &set, true)
+ && ! insn_sets_resource_p (trial, &set, true)
+ && ! insn_sets_resource_p (trial, &needed, true)
#ifdef HAVE_cc0
/* Can't separate set of cc0 from its use. */
&& ! (reg_mentioned_p (cc0_rtx, pat) && ! sets_cc0_p (pat))
@@ -2184,7 +2186,7 @@ fill_simple_delay_slots (int non_jumps_p)
}
mark_set_resources (trial, &set, 0, MARK_SRC_DEST_CALL);
- mark_referenced_resources (trial, &needed, 1);
+ mark_referenced_resources (trial, &needed, true);
}
}
@@ -2255,13 +2257,13 @@ fill_simple_delay_slots (int non_jumps_p)
if (CALL_P (insn))
{
mark_set_resources (insn, &set, 0, MARK_SRC_DEST_CALL);
- mark_referenced_resources (insn, &needed, 1);
+ mark_referenced_resources (insn, &needed, true);
maybe_never = 1;
}
else
{
mark_set_resources (insn, &set, 0, MARK_SRC_DEST_CALL);
- mark_referenced_resources (insn, &needed, 1);
+ mark_referenced_resources (insn, &needed, true);
if (JUMP_P (insn))
target = JUMP_LABEL (insn);
}
@@ -2296,9 +2298,9 @@ fill_simple_delay_slots (int non_jumps_p)
/* See if we have a resource problem before we try to
split. */
if (GET_CODE (pat) != SEQUENCE
- && ! insn_references_resource_p (trial, &set, 1)
- && ! insn_sets_resource_p (trial, &set, 1)
- && ! insn_sets_resource_p (trial, &needed, 1)
+ && ! insn_references_resource_p (trial, &set, true)
+ && ! insn_sets_resource_p (trial, &set, true)
+ && ! insn_sets_resource_p (trial, &needed, true)
#ifdef HAVE_cc0
&& ! (reg_mentioned_p (cc0_rtx, pat) && ! sets_cc0_p (pat))
#endif
@@ -2322,7 +2324,7 @@ fill_simple_delay_slots (int non_jumps_p)
}
mark_set_resources (trial, &set, 0, MARK_SRC_DEST_CALL);
- mark_referenced_resources (trial, &needed, 1);
+ mark_referenced_resources (trial, &needed, true);
/* Ensure we don't put insns between the setting of cc and the
comparison by moving a setting of cc into an earlier delay
@@ -2349,9 +2351,9 @@ fill_simple_delay_slots (int non_jumps_p)
&& ! (NONJUMP_INSN_P (next_trial)
&& GET_CODE (PATTERN (next_trial)) == SEQUENCE)
&& !JUMP_P (next_trial)
- && ! insn_references_resource_p (next_trial, &set, 1)
- && ! insn_sets_resource_p (next_trial, &set, 1)
- && ! insn_sets_resource_p (next_trial, &needed, 1)
+ && ! insn_references_resource_p (next_trial, &set, true)
+ && ! insn_sets_resource_p (next_trial, &set, true)
+ && ! insn_sets_resource_p (next_trial, &needed, true)
#ifdef HAVE_cc0
&& ! reg_mentioned_p (cc0_rtx, PATTERN (next_trial))
#endif
@@ -2458,9 +2460,9 @@ fill_simple_delay_slots (int non_jumps_p)
if (GET_CODE (pat) == USE || GET_CODE (pat) == CLOBBER)
continue;
- if (! insn_references_resource_p (trial, &set, 1)
- && ! insn_sets_resource_p (trial, &needed, 1)
- && ! insn_sets_resource_p (trial, &set, 1)
+ if (! insn_references_resource_p (trial, &set, true)
+ && ! insn_sets_resource_p (trial, &needed, true)
+ && ! insn_sets_resource_p (trial, &set, true)
#ifdef HAVE_cc0
/* Don't want to mess with cc0 here. */
&& ! reg_mentioned_p (cc0_rtx, pat)
@@ -2476,7 +2478,7 @@ fill_simple_delay_slots (int non_jumps_p)
crtl->epilogue_delay_list
= gen_rtx_INSN_LIST (VOIDmode, trial,
crtl->epilogue_delay_list);
- mark_end_of_function_resources (trial, 1);
+ mark_end_of_function_resources (trial, true);
update_block (trial, trial);
delete_related_insns (trial);
@@ -2490,7 +2492,7 @@ fill_simple_delay_slots (int non_jumps_p)
}
mark_set_resources (trial, &set, 0, MARK_SRC_DEST_CALL);
- mark_referenced_resources (trial, &needed, 1);
+ mark_referenced_resources (trial, &needed, true);
}
note_delay_statistics (slots_filled, 0);
@@ -2635,9 +2637,9 @@ fill_slots_from_thread (rtx insn, rtx condition, rtx thread,
/* If TRIAL conflicts with the insns ahead of it, we lose. Also,
don't separate or copy insns that set and use CC0. */
- if (! insn_references_resource_p (trial, &set, 1)
- && ! insn_sets_resource_p (trial, &set, 1)
- && ! insn_sets_resource_p (trial, &needed, 1)
+ if (! insn_references_resource_p (trial, &set, true)
+ && ! insn_sets_resource_p (trial, &set, true)
+ && ! insn_sets_resource_p (trial, &needed, true)
#ifdef HAVE_cc0
&& ! (reg_mentioned_p (cc0_rtx, pat)
&& (! own_thread || ! sets_cc0_p (pat)))
@@ -2678,7 +2680,7 @@ fill_slots_from_thread (rtx insn, rtx condition, rtx thread,
go into an annulled delay slot. */
if (!must_annul
&& (condition == const_true_rtx
- || (! insn_sets_resource_p (trial, &opposite_needed, 1)
+ || (! insn_sets_resource_p (trial, &opposite_needed, true)
&& ! may_trap_or_fault_p (pat))))
{
old_trial = trial;
@@ -2793,10 +2795,11 @@ fill_slots_from_thread (rtx insn, rtx condition, rtx thread,
may be branching to a location that has a
redundant insn. Skip any if so. */
while (new_thread && ! own_thread
- && ! insn_sets_resource_p (new_thread, &set, 1)
- && ! insn_sets_resource_p (new_thread, &needed, 1)
+ && ! insn_sets_resource_p (new_thread, &set, true)
+ && ! insn_sets_resource_p (new_thread, &needed,
+ true)
&& ! insn_references_resource_p (new_thread,
- &set, 1)
+ &set, true)
&& (prior_insn
= redundant_insn (new_thread, insn,
delay_list)))
@@ -2818,7 +2821,7 @@ fill_slots_from_thread (rtx insn, rtx condition, rtx thread,
/* This insn can't go into a delay slot. */
lose = 1;
mark_set_resources (trial, &set, 0, MARK_SRC_DEST_CALL);
- mark_referenced_resources (trial, &needed, 1);
+ mark_referenced_resources (trial, &needed, true);
/* Ensure we don't put insns between the setting of cc and the comparison
by moving a setting of cc into an earlier delay slot since these insns
diff --git a/gcc/resource.c b/gcc/resource.c
index 66ff2085071..de5ad41e8db 100644
--- a/gcc/resource.c
+++ b/gcc/resource.c
@@ -1,6 +1,6 @@
/* Definitions for computing resource usage of specific insns.
- Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
- Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
+ 2009 Free Software Foundation, Inc.
This file is part of GCC.
@@ -203,7 +203,7 @@ next_insn_no_annul (rtx insn)
void
mark_referenced_resources (rtx x, struct resources *res,
- int include_delayed_effects)
+ bool include_delayed_effects)
{
enum rtx_code code = GET_CODE (x);
int i, j;
@@ -226,7 +226,7 @@ mark_referenced_resources (rtx x, struct resources *res,
case SUBREG:
if (!REG_P (SUBREG_REG (x)))
- mark_referenced_resources (SUBREG_REG (x), res, 0);
+ mark_referenced_resources (SUBREG_REG (x), res, false);
else
{
unsigned int regno = subreg_regno (x);
@@ -253,7 +253,7 @@ mark_referenced_resources (rtx x, struct resources *res,
res->volatil |= MEM_VOLATILE_P (x);
/* Mark registers used to access memory. */
- mark_referenced_resources (XEXP (x, 0), res, 0);
+ mark_referenced_resources (XEXP (x, 0), res, false);
return;
case CC0:
@@ -276,14 +276,14 @@ mark_referenced_resources (rtx x, struct resources *res,
traditional asms unlike their normal usage. */
for (i = 0; i < ASM_OPERANDS_INPUT_LENGTH (x); i++)
- mark_referenced_resources (ASM_OPERANDS_INPUT (x, i), res, 0);
+ mark_referenced_resources (ASM_OPERANDS_INPUT (x, i), res, false);
return;
case CALL:
/* The first operand will be a (MEM (xxx)) but doesn't really reference
memory. The second operand may be referenced, though. */
- mark_referenced_resources (XEXP (XEXP (x, 0), 0), res, 0);
- mark_referenced_resources (XEXP (x, 1), res, 0);
+ mark_referenced_resources (XEXP (XEXP (x, 0), 0), res, false);
+ mark_referenced_resources (XEXP (x, 1), res, false);
return;
case SET:
@@ -291,16 +291,16 @@ mark_referenced_resources (rtx x, struct resources *res,
registers used to access memory are referenced. SET_DEST is
also referenced if it is a ZERO_EXTRACT. */
- mark_referenced_resources (SET_SRC (x), res, 0);
+ mark_referenced_resources (SET_SRC (x), res, false);
x = SET_DEST (x);
if (GET_CODE (x) == ZERO_EXTRACT
|| GET_CODE (x) == STRICT_LOW_PART)
- mark_referenced_resources (x, res, 0);
+ mark_referenced_resources (x, res, false);
else if (GET_CODE (x) == SUBREG)
x = SUBREG_REG (x);
if (MEM_P (x))
- mark_referenced_resources (XEXP (x, 0), res, 0);
+ mark_referenced_resources (XEXP (x, 0), res, false);
return;
case CLOBBER:
@@ -372,7 +372,7 @@ mark_referenced_resources (rtx x, struct resources *res,
}
if (i >= seq_size)
mark_referenced_resources (XEXP (XEXP (link, 0), 0),
- res, 0);
+ res, false);
}
}
}
@@ -519,7 +519,7 @@ find_dead_or_set_registers (rtx target, struct resources *res,
if (jump_count >= 10)
break;
- mark_referenced_resources (insn, &needed, 1);
+ mark_referenced_resources (insn, &needed, true);
/* For an annulled branch, mark_set_resources ignores slots
filled by instructions from the target. This is correct
@@ -585,7 +585,7 @@ find_dead_or_set_registers (rtx target, struct resources *res,
}
}
- mark_referenced_resources (insn, &needed, 1);
+ mark_referenced_resources (insn, &needed, true);
mark_set_resources (insn, &set, 0, MARK_SRC_DEST_CALL);
COPY_HARD_REG_SET (scratch, set.regs);
@@ -888,7 +888,7 @@ mark_target_live_regs (rtx insns, rtx target, struct resources *res)
else if (return_insn_p (target))
{
*res = end_of_function_needs;
- mark_referenced_resources (target, res, 0);
+ mark_referenced_resources (target, res, false);
return;
}
@@ -1104,7 +1104,7 @@ mark_target_live_regs (rtx insns, rtx target, struct resources *res)
/* Include JUMP_INSN in the needed registers. */
for (insn = target; insn != stop_insn; insn = next_active_insn (insn))
{
- mark_referenced_resources (insn, &needed, 1);
+ mark_referenced_resources (insn, &needed, true);
COPY_HARD_REG_SET (scratch, needed.regs);
AND_COMPL_HARD_REG_SET (scratch, set.regs);
@@ -1158,7 +1158,7 @@ init_resource_info (rtx epilogue_insn)
if (crtl->return_rtx != 0)
mark_referenced_resources (crtl->return_rtx,
- &end_of_function_needs, 1);
+ &end_of_function_needs, true);
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
if (global_regs[i]
@@ -1277,7 +1277,7 @@ incr_ticks_for_insn (rtx insn)
/* Add TRIAL to the set of resources used at the end of the current
function. */
void
-mark_end_of_function_resources (rtx trial, int include_delayed_effects)
+mark_end_of_function_resources (rtx trial, bool include_delayed_effects)
{
mark_referenced_resources (trial, &end_of_function_needs,
include_delayed_effects);
diff --git a/gcc/resource.h b/gcc/resource.h
index 26cd294946b..b13782f1ab0 100644
--- a/gcc/resource.h
+++ b/gcc/resource.h
@@ -1,5 +1,6 @@
/* Definitions for computing resource usage of specific insns.
- Copyright (C) 1999, 2003, 2004, 2006, 2007 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2003, 2004, 2006, 2007, 2009
+ Free Software Foundation, Inc.
This file is part of GCC.
@@ -48,10 +49,10 @@ enum mark_resource_type
extern void mark_target_live_regs (rtx, rtx, struct resources *);
extern void mark_set_resources (rtx, struct resources *, int,
enum mark_resource_type);
-extern void mark_referenced_resources (rtx, struct resources *, int);
+extern void mark_referenced_resources (rtx, struct resources *, bool);
extern void clear_hashed_info_for_insn (rtx);
extern void incr_ticks_for_insn (rtx);
-extern void mark_end_of_function_resources (rtx, int);
+extern void mark_end_of_function_resources (rtx, bool);
extern void init_resource_info (rtx);
extern void free_resource_info (void);
diff --git a/gcc/rtl.def b/gcc/rtl.def
index efd085f66ba..bcb5cbcd9b0 100644
--- a/gcc/rtl.def
+++ b/gcc/rtl.def
@@ -2,7 +2,7 @@
Register Transfer Expressions (rtx's) that make up the
Register Transfer Language (rtl) used in the Back End of the GNU compiler.
Copyright (C) 1987, 1988, 1992, 1994, 1995, 1997, 1998, 1999, 2000, 2004,
- 2005, 2006, 2007, 2008
+ 2005, 2006, 2007, 2008, 2009
Free Software Foundation, Inc.
This file is part of GCC.
@@ -81,6 +81,13 @@ along with GCC; see the file COPYING3. If not see
value zero. */
DEF_RTL_EXPR(UNKNOWN, "UnKnown", "*", RTX_EXTRA)
+/* Used in the cselib routines to describe a value. Objects of this
+ kind are only allocated in cselib.c, in an alloc pool instead of in
+ GC memory. The only operand of a VALUE is a cselib_val_struct.
+ var-tracking requires this to have a distinct integral value from
+ DECL codes in trees. */
+DEF_RTL_EXPR(VALUE, "value", "0", RTX_OBJ)
+
/* ---------------------------------------------------------------------
Expressions used in constructing lists.
--------------------------------------------------------------------- */
@@ -284,6 +291,10 @@ DEF_RTL_EXPR(CALL, "call", "ee", RTX_EXTRA)
DEF_RTL_EXPR(RETURN, "return", "", RTX_EXTRA)
+/* Special for EH return from subroutine. */
+
+DEF_RTL_EXPR(EH_RETURN, "eh_return", "", RTX_EXTRA)
+
/* Conditional trap.
Operand 1 is the condition.
Operand 2 is the trap code.
@@ -328,11 +339,6 @@ DEF_RTL_EXPR(CONST, "const", "e", RTX_CONST_OBJ)
by a SET whose first operand is (PC). */
DEF_RTL_EXPR(PC, "pc", "", RTX_OBJ)
-/* Used in the cselib routines to describe a value. Objects of this
- kind are only allocated in cselib.c, in an alloc pool instead of
- in GC memory. The only operand of a VALUE is a cselib_val_struct. */
-DEF_RTL_EXPR(VALUE, "value", "0", RTX_OBJ)
-
/* A register. The "operand" is the register number, accessed with
the REGNO macro. If this number is less than FIRST_PSEUDO_REGISTER
than a hardware register is being referred to. The second operand
diff --git a/gcc/rtl.h b/gcc/rtl.h
index e7f5e021b58..9b8df575405 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -759,6 +759,12 @@ extern void rtl_check_failed_flag (const char *, const_rtx, const char *,
#define BLOCK_FOR_INSN(INSN) XBBDEF (INSN, 3)
#define INSN_LOCATOR(INSN) XINT (INSN, 4)
+/* LOCATION of an RTX if relevant. */
+#define RTL_LOCATION(X) (INSN_P (X) ? \
+ locator_location (INSN_LOCATOR (x)) \
+ : UNKNOWN_LOCATION)
+/* LOCATION of current INSN. */
+#define CURR_INSN_LOCATION (locator_location (curr_insn_locator ()))
/* The body of an insn. */
#define PATTERN(INSN) XEXP (INSN, 5)
@@ -2138,6 +2144,7 @@ extern rtx pc_set (const_rtx);
extern rtx condjump_label (const_rtx);
extern int simplejump_p (const_rtx);
extern int returnjump_p (rtx);
+extern int eh_returnjump_p (rtx);
extern int onlyjump_p (const_rtx);
extern int only_sets_cc0_p (const_rtx);
extern int sets_cc0_p (const_rtx);
@@ -2251,6 +2258,7 @@ extern int prologue_epilogue_contains (const_rtx);
extern int sibcall_epilogue_contains (const_rtx);
extern void mark_temp_addr_taken (rtx);
extern void update_temp_slot_address (rtx, rtx);
+extern void maybe_copy_epilogue_insn (rtx, rtx);
/* In stmt.c */
extern void expand_null_return (void);
diff --git a/gcc/sdbout.c b/gcc/sdbout.c
index 818ff63cd76..cc8687419ff 100644
--- a/gcc/sdbout.c
+++ b/gcc/sdbout.c
@@ -117,7 +117,7 @@ static void sdbout_start_source_file (unsigned int, const char *);
static void sdbout_end_source_file (unsigned int);
static void sdbout_begin_block (unsigned int, unsigned int);
static void sdbout_end_block (unsigned int, unsigned int);
-static void sdbout_source_line (unsigned int, const char *);
+static void sdbout_source_line (unsigned int, const char *, int);
static void sdbout_end_epilogue (unsigned int, const char *);
static void sdbout_global_decl (tree);
#ifndef MIPS_DEBUGGING_INFO
@@ -1541,7 +1541,8 @@ sdbout_end_block (unsigned int line, unsigned int n ATTRIBUTE_UNUSED)
number LINE. */
static void
-sdbout_source_line (unsigned int line, const char *filename ATTRIBUTE_UNUSED)
+sdbout_source_line (unsigned int line, const char *filename ATTRIBUTE_UNUSED,
+ int discriminator ATTRIBUTE_UNUSED)
{
/* COFF relative line numbers must be positive. */
if ((int) line > sdb_begin_function_line)
diff --git a/gcc/sel-sched-ir.c b/gcc/sel-sched-ir.c
index d7cba074f4f..123cea97959 100644
--- a/gcc/sel-sched-ir.c
+++ b/gcc/sel-sched-ir.c
@@ -3763,7 +3763,8 @@ get_seqno_of_a_pred (insn_t insn)
return seqno;
}
-/* Find the proper seqno for inserting at INSN. */
+/* Find the proper seqno for inserting at INSN. Returns -1 if no predecessors
+ with positive seqno exist. */
int
get_seqno_by_preds (rtx insn)
{
@@ -3782,7 +3783,6 @@ get_seqno_by_preds (rtx insn)
for (i = 0, seqno = -1; i < n; i++)
seqno = MAX (seqno, INSN_SEQNO (preds[i]));
- gcc_assert (seqno > 0);
return seqno;
}
diff --git a/gcc/sel-sched.c b/gcc/sel-sched.c
index 04635edf50f..102dc19187f 100644
--- a/gcc/sel-sched.c
+++ b/gcc/sel-sched.c
@@ -448,7 +448,7 @@ struct code_motion_path_driver_info_def *code_motion_path_driver_info;
/* Set of hooks for performing move_op and find_used_regs routines with
code_motion_path_driver. */
-struct code_motion_path_driver_info_def move_op_hooks, fur_hooks;
+extern struct code_motion_path_driver_info_def move_op_hooks, fur_hooks;
/* True if/when we want to emulate Haifa scheduler in the common code.
This is used in sched_rgn_local_init and in various places in
@@ -4727,11 +4727,27 @@ find_seqno_for_bookkeeping (insn_t place_to_insert, insn_t join_point)
if (INSN_P (next)
&& JUMP_P (next)
&& BLOCK_FOR_INSN (next) == BLOCK_FOR_INSN (place_to_insert))
- seqno = INSN_SEQNO (next);
+ {
+ gcc_assert (INSN_SCHED_TIMES (next) == 0);
+ seqno = INSN_SEQNO (next);
+ }
else if (INSN_SEQNO (join_point) > 0)
seqno = INSN_SEQNO (join_point);
else
- seqno = get_seqno_by_preds (place_to_insert);
+ {
+ seqno = get_seqno_by_preds (place_to_insert);
+
+ /* Sometimes the fences can move in such a way that there will be
+ no instructions with positive seqno around this bookkeeping.
+ This means that there will be no way to get to it by a regular
+ fence movement. Never mind because we pick up such pieces for
+ rescheduling anyways, so any positive value will do for now. */
+ if (seqno < 0)
+ {
+ gcc_assert (pipelining_p);
+ seqno = 1;
+ }
+ }
gcc_assert (seqno > 0);
return seqno;
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index a72026f0671..55149412723 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -1839,18 +1839,6 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode,
break;
case COMPARE:
-#ifdef HAVE_cc0
- /* Convert (compare FOO (const_int 0)) to FOO unless we aren't
- using cc0, in which case we want to leave it as a COMPARE
- so we can distinguish it from a register-register-copy.
-
- In IEEE floating point, x-0 is not the same as x. */
- if (!(HONOR_SIGNED_ZEROS (mode)
- && HONOR_SIGN_DEPENDENT_ROUNDING (mode))
- && trueop1 == CONST0_RTX (mode))
- return op0;
-#endif
-
/* Convert (compare (gt (flags) 0) (lt (flags) 0)) to (flags). */
if (((GET_CODE (op0) == GT && GET_CODE (op1) == LT)
|| (GET_CODE (op0) == GTU && GET_CODE (op1) == LTU))
@@ -3915,8 +3903,8 @@ simplify_relational_operation (enum rtx_code code, enum machine_mode mode,
/* If op0 is a compare, extract the comparison arguments from it. */
if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
- return simplify_relational_operation (code, mode, VOIDmode,
- XEXP (op0, 0), XEXP (op0, 1));
+ return simplify_gen_relational (code, mode, VOIDmode,
+ XEXP (op0, 0), XEXP (op0, 1));
if (GET_MODE_CLASS (cmp_mode) == MODE_CC
|| CC0_P (op0))
diff --git a/gcc/statistics.c b/gcc/statistics.c
index d2f665f3b20..b7bfd45dd97 100644
--- a/gcc/statistics.c
+++ b/gcc/statistics.c
@@ -82,7 +82,10 @@ hash_statistics_free (void *p)
static htab_t
curr_statistics_hash (void)
{
- unsigned idx = current_pass->static_pass_number;
+ unsigned idx;
+
+ gcc_assert (current_pass->static_pass_number >= 0);
+ idx = current_pass->static_pass_number;
if (idx < nr_statistics_hashes
&& statistics_hashes[idx] != NULL)
@@ -294,9 +297,12 @@ statistics_counter_event (struct function *fn, const char *id, int incr)
|| incr == 0)
return;
- counter = lookup_or_add_counter (curr_statistics_hash (), id, 0, false);
- gcc_assert (!counter->histogram_p);
- counter->count += incr;
+ if (current_pass->static_pass_number != -1)
+ {
+ counter = lookup_or_add_counter (curr_statistics_hash (), id, 0, false);
+ gcc_assert (!counter->histogram_p);
+ counter->count += incr;
+ }
if (!statistics_dump_file
|| !(statistics_dump_flags & TDF_DETAILS))
diff --git a/gcc/stmt.c b/gcc/stmt.c
index 7fc4038aaf5..31b0b7d8365 100644
--- a/gcc/stmt.c
+++ b/gcc/stmt.c
@@ -2905,7 +2905,9 @@ emit_case_nodes (rtx index, case_node_ptr node, rtx default_label,
/* Neither node is bounded. First distinguish the two sides;
then emit the code for one side at a time. */
- tree test_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
+ tree test_label
+ = build_decl (CURR_INSN_LOCATION,
+ LABEL_DECL, NULL_TREE, NULL_TREE);
/* See if the value is on the right. */
emit_cmp_and_jump_insns (index,
@@ -3028,7 +3030,8 @@ emit_case_nodes (rtx index, case_node_ptr node, rtx default_label,
/* Right hand node requires testing.
Branch to a label where we will handle it later. */
- test_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
+ test_label = build_decl (CURR_INSN_LOCATION,
+ LABEL_DECL, NULL_TREE, NULL_TREE);
emit_cmp_and_jump_insns (index,
convert_modes
(mode, imode,
diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c
index fab5817d3c2..d65452bc710 100644
--- a/gcc/stor-layout.c
+++ b/gcc/stor-layout.c
@@ -1547,7 +1547,8 @@ finish_builtin_struct (tree type, const char *name, tree fields,
#if 0 /* not yet, should get fixed properly later */
TYPE_NAME (type) = make_type_decl (get_identifier (name), type);
#else
- TYPE_NAME (type) = build_decl (TYPE_DECL, get_identifier (name), type);
+ TYPE_NAME (type) = build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, get_identifier (name), type);
#endif
TYPE_STUB_DECL (type) = TYPE_NAME (type);
layout_decl (TYPE_NAME (type), 0);
diff --git a/gcc/store-motion.c b/gcc/store-motion.c
index 5dabd1a8f20..64260ac165f 100644
--- a/gcc/store-motion.c
+++ b/gcc/store-motion.c
@@ -39,7 +39,6 @@ along with GCC; see the file COPYING3. If not see
#include "expr.h"
#include "except.h"
#include "ggc.h"
-#include "params.h"
#include "intl.h"
#include "timevar.h"
#include "tree-pass.h"
diff --git a/gcc/stub-objc.c b/gcc/stub-objc.c
index a907d51d684..fc3d4169f0a 100644
--- a/gcc/stub-objc.c
+++ b/gcc/stub-objc.c
@@ -224,7 +224,7 @@ objc_build_protocol_expr (tree ARG_UNUSED (expr))
}
tree
-objc_build_selector_expr (tree ARG_UNUSED (expr))
+objc_build_selector_expr (location_t ARG_UNUSED (loc), tree ARG_UNUSED (expr))
{
return 0;
}
@@ -279,7 +279,7 @@ objc_get_class_ivars (tree ARG_UNUSED (name))
}
tree
-objc_build_throw_stmt (tree ARG_UNUSED (expr))
+objc_build_throw_stmt (location_t ARG_UNUSED (loc), tree ARG_UNUSED (expr))
{
return 0;
}
diff --git a/gcc/system.h b/gcc/system.h
index 223a9dd01b4..51d9c995c3c 100644
--- a/gcc/system.h
+++ b/gcc/system.h
@@ -452,7 +452,8 @@ extern int vsnprintf(char *, size_t, const char *, va_list);
/* 1 if we have C99 designated initializers. */
#if !defined(HAVE_DESIGNATED_INITIALIZERS)
#define HAVE_DESIGNATED_INITIALIZERS \
- ((GCC_VERSION >= 2007) || (__STDC_VERSION__ >= 199901L))
+ (((GCC_VERSION >= 2007) || (__STDC_VERSION__ >= 199901L)) \
+ && !defined(__cplusplus))
#endif
#if HAVE_SYS_STAT_H
@@ -786,6 +787,9 @@ extern void fancy_abort (const char *, int, const char *) ATTRIBUTE_NORETURN;
change after the fact). Beyond these uses, most other cases of
using this macro should be viewed with extreme caution. */
+#ifdef __cplusplus
+#define CONST_CAST2(TOTYPE,FROMTYPE,X) (const_cast<TOTYPE> (X))
+#else
#if defined(__GNUC__) && GCC_VERSION > 4000
/* GCC 4.0.x has a bug where it may ICE on this expression,
so does GCC 3.4.x (PR17436). */
@@ -793,6 +797,7 @@ extern void fancy_abort (const char *, int, const char *) ATTRIBUTE_NORETURN;
#else
#define CONST_CAST2(TOTYPE,FROMTYPE,X) ((TOTYPE)(FROMTYPE)(X))
#endif
+#endif
#define CONST_CAST(TYPE,X) CONST_CAST2(TYPE, const TYPE, (X))
#define CONST_CAST_TREE(X) CONST_CAST(union tree_node *, (X))
#define CONST_CAST_RTX(X) CONST_CAST(struct rtx_def *, (X))
diff --git a/gcc/target-def.h b/gcc/target-def.h
index 93a3369fc13..92905d18834 100644
--- a/gcc/target-def.h
+++ b/gcc/target-def.h
@@ -423,6 +423,7 @@
/* In cse.c. */
#define TARGET_ADDRESS_COST default_address_cost
+#define TARGET_CONST_ANCHOR 0
/* In builtins.c. */
#define TARGET_INIT_BUILTINS hook_void_void
@@ -488,6 +489,7 @@
#define TARGET_COMMUTATIVE_P hook_bool_const_rtx_commutative_p
#define TARGET_LEGITIMIZE_ADDRESS default_legitimize_address
#define TARGET_DELEGITIMIZE_ADDRESS delegitimize_mem_from_attrs
+#define TARGET_LEGITIMATE_ADDRESS_P default_legitimate_address_p
#define TARGET_USE_BLOCKS_FOR_CONSTANT_P hook_bool_mode_const_rtx_false
#define TARGET_MIN_ANCHOR_OFFSET 0
#define TARGET_MAX_ANCHOR_OFFSET 0
@@ -535,6 +537,10 @@
#define TARGET_INVALID_CONVERSION hook_constcharptr_const_tree_const_tree_null
#define TARGET_INVALID_UNARY_OP hook_constcharptr_int_const_tree_null
#define TARGET_INVALID_BINARY_OP hook_constcharptr_int_const_tree_const_tree_null
+#define TARGET_INVALID_PARAMETER_TYPE hook_constcharptr_const_tree_null
+#define TARGET_INVALID_RETURN_TYPE hook_constcharptr_const_tree_null
+#define TARGET_PROMOTED_TYPE hook_tree_const_tree_null
+#define TARGET_CONVERT_TO_TYPE hook_tree_tree_tree_null
#define TARGET_FIXED_CONDITION_CODE_REGS hook_bool_uintp_uintp_false
@@ -872,6 +878,7 @@
TARGET_COMMUTATIVE_P, \
TARGET_LEGITIMIZE_ADDRESS, \
TARGET_DELEGITIMIZE_ADDRESS, \
+ TARGET_LEGITIMATE_ADDRESS_P, \
TARGET_USE_BLOCKS_FOR_CONSTANT_P, \
TARGET_MIN_ANCHOR_OFFSET, \
TARGET_MAX_ANCHOR_OFFSET, \
@@ -916,10 +923,15 @@
TARGET_STACK_PROTECT_FAIL, \
TARGET_INVALID_WITHIN_DOLOOP, \
TARGET_VALID_DLLIMPORT_ATTRIBUTE_P, \
+ TARGET_CONST_ANCHOR, \
TARGET_CALLS, \
TARGET_INVALID_CONVERSION, \
TARGET_INVALID_UNARY_OP, \
TARGET_INVALID_BINARY_OP, \
+ TARGET_INVALID_PARAMETER_TYPE, \
+ TARGET_INVALID_RETURN_TYPE, \
+ TARGET_PROMOTED_TYPE, \
+ TARGET_CONVERT_TO_TYPE, \
TARGET_IRA_COVER_CLASSES, \
TARGET_SECONDARY_RELOAD, \
TARGET_EXPAND_TO_RTL_HOOK, \
diff --git a/gcc/target.h b/gcc/target.h
index b6935264e91..bbc6cd87699 100644
--- a/gcc/target.h
+++ b/gcc/target.h
@@ -481,7 +481,7 @@ struct gcc_target
/* Target builtin that implements vector permute. */
tree (* builtin_vec_perm) (tree, tree*);
-} vectorize;
+ } vectorize;
/* The initial value of target_flags. */
int default_target_flags;
@@ -564,7 +564,8 @@ struct gcc_target
complete expression that implements the operation. PARAMS really
has type VEC(tree,gc)*, but we don't want to include tree.h
here. */
- tree (*resolve_overloaded_builtin) (tree decl, void *params);
+ tree (*resolve_overloaded_builtin) (unsigned int /*location_t*/,
+ tree decl, void *params);
/* Fold a target-specific builtin. */
tree (* fold_builtin) (tree fndecl, tree arglist, bool ignore);
@@ -616,6 +617,9 @@ struct gcc_target
/* Given an address RTX, undo the effects of LEGITIMIZE_ADDRESS. */
rtx (* delegitimize_address) (rtx);
+ /* Given an address RTX, say whether it is valid. */
+ bool (* legitimate_address_p) (enum machine_mode, rtx, bool);
+
/* True if the given constant can be put into an object_block. */
bool (* use_blocks_for_constant_p) (enum machine_mode, const_rtx);
@@ -822,6 +826,10 @@ struct gcc_target
checks to handle_dll_attribute (). */
bool (* valid_dllimport_attribute_p) (const_tree decl);
+ /* If non-zero, align constant anchors in CSE to a multiple of this
+ value. */
+ unsigned HOST_WIDE_INT const_anchor;
+
/* Functions relating to calls - argument passing, returns, etc. */
struct calls {
bool (*promote_function_args) (const_tree fntype);
@@ -910,6 +918,24 @@ struct gcc_target
is not permitted on TYPE1 and TYPE2, NULL otherwise. */
const char *(*invalid_binary_op) (int op, const_tree type1, const_tree type2);
+ /* Return the diagnostic message string if TYPE is not valid as a
+ function parameter type, NULL otherwise. */
+ const char *(*invalid_parameter_type) (const_tree type);
+
+ /* Return the diagnostic message string if TYPE is not valid as a
+ function return type, NULL otherwise. */
+ const char *(*invalid_return_type) (const_tree type);
+
+ /* If values of TYPE are promoted to some other type when used in
+ expressions (analogous to the integer promotions), return that type,
+ or NULL_TREE otherwise. */
+ tree (*promoted_type) (const_tree type);
+
+ /* Convert EXPR to TYPE, if target-specific types with special conversion
+ rules are involved. Return the converted expression, or NULL to apply
+ the standard conversion rules. */
+ tree (*convert_to_type) (tree type, tree expr);
+
/* Return the array of IRA cover classes for the current target. */
const enum reg_class *(*ira_cover_classes) (void);
diff --git a/gcc/targhooks.c b/gcc/targhooks.c
index 1dd6c7c6de8..4d799c5d73d 100644
--- a/gcc/targhooks.c
+++ b/gcc/targhooks.c
@@ -68,6 +68,22 @@ along with GCC; see the file COPYING3. If not see
#include "recog.h"
+bool
+default_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED,
+ rtx addr ATTRIBUTE_UNUSED,
+ bool strict ATTRIBUTE_UNUSED)
+{
+#ifdef GO_IF_LEGITIMATE_ADDRESS
+ /* Defer to the old implementation using a goto. */
+ if (strict)
+ return strict_memory_address_p (mode, addr);
+ else
+ return memory_address_p (mode, addr);
+#else
+ gcc_unreachable ();
+#endif
+}
+
void
default_external_libcall (rtx fun ATTRIBUTE_UNUSED)
{
@@ -382,7 +398,7 @@ default_invalid_within_doloop (const_rtx insn)
/* Mapping of builtin functions to vectorized variants. */
tree
-default_builtin_vectorized_function (enum built_in_function fn ATTRIBUTE_UNUSED,
+default_builtin_vectorized_function (unsigned int fn ATTRIBUTE_UNUSED,
tree type_out ATTRIBUTE_UNUSED,
tree type_in ATTRIBUTE_UNUSED)
{
@@ -392,7 +408,7 @@ default_builtin_vectorized_function (enum built_in_function fn ATTRIBUTE_UNUSED,
/* Vectorized conversion. */
tree
-default_builtin_vectorized_conversion (enum tree_code code ATTRIBUTE_UNUSED,
+default_builtin_vectorized_conversion (unsigned int code ATTRIBUTE_UNUSED,
tree type ATTRIBUTE_UNUSED)
{
return NULL_TREE;
@@ -401,7 +417,7 @@ default_builtin_vectorized_conversion (enum tree_code code ATTRIBUTE_UNUSED,
/* Reciprocal. */
tree
-default_builtin_reciprocal (enum built_in_function fn ATTRIBUTE_UNUSED,
+default_builtin_reciprocal (unsigned int fn ATTRIBUTE_UNUSED,
bool md_fn ATTRIBUTE_UNUSED,
bool sqrt ATTRIBUTE_UNUSED)
{
@@ -461,7 +477,8 @@ default_stack_protect_guard (void)
if (t == NULL)
{
- t = build_decl (VAR_DECL, get_identifier ("__stack_chk_guard"),
+ t = build_decl (UNKNOWN_LOCATION,
+ VAR_DECL, get_identifier ("__stack_chk_guard"),
ptr_type_node);
TREE_STATIC (t) = 1;
TREE_PUBLIC (t) = 1;
@@ -487,7 +504,8 @@ default_external_stack_protect_fail (void)
if (t == NULL_TREE)
{
t = build_function_type_list (void_type_node, NULL_TREE);
- t = build_decl (FUNCTION_DECL, get_identifier ("__stack_chk_fail"), t);
+ t = build_decl (UNKNOWN_LOCATION,
+ FUNCTION_DECL, get_identifier ("__stack_chk_fail"), t);
TREE_STATIC (t) = 1;
TREE_PUBLIC (t) = 1;
DECL_EXTERNAL (t) = 1;
@@ -519,7 +537,7 @@ default_hidden_stack_protect_fail (void)
if (t == NULL_TREE)
{
t = build_function_type_list (void_type_node, NULL_TREE);
- t = build_decl (FUNCTION_DECL,
+ t = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL,
get_identifier ("__stack_chk_fail_local"), t);
TREE_STATIC (t) = 1;
TREE_PUBLIC (t) = 1;
diff --git a/gcc/targhooks.h b/gcc/targhooks.h
index 19b78cbca33..5d77ce5854b 100644
--- a/gcc/targhooks.h
+++ b/gcc/targhooks.h
@@ -18,6 +18,8 @@ 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/>. */
+extern bool default_legitimate_address_p (enum machine_mode, rtx, bool);
+
extern void default_external_libcall (rtx);
extern rtx default_legitimize_address (rtx, rtx, enum machine_mode);
@@ -64,12 +66,11 @@ extern bool default_fixed_point_supported_p (void);
extern const char * default_invalid_within_doloop (const_rtx);
-extern tree default_builtin_vectorized_function
- (enum built_in_function, tree, tree);
+extern tree default_builtin_vectorized_function (unsigned int, tree, tree);
-extern tree default_builtin_vectorized_conversion (enum tree_code, tree);
+extern tree default_builtin_vectorized_conversion (unsigned int, tree);
-extern tree default_builtin_reciprocal (enum built_in_function, bool, bool);
+extern tree default_builtin_reciprocal (unsigned int, bool, bool);
extern bool default_builtin_vector_alignment_reachable (const_tree, bool);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index b6b0949c3de..f84f90cc639 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,1149 @@
+2009-06-05 Olatunji Ruwase <tjruwase@google.com>
+
+ * gcc.dg/plugin/one_time_plugin.c: New test.
+ * gcc.dg/plugin/one_time-test-1.c: New test.
+ * gcc.dg/plugin/plugin.exp: Added one_time_plugin.c test.
+
+2009-06-16 Ian Lance Taylor <iant@google.com>
+
+ * g++.dg/warn/skip-1.C: New testcase.
+
+2009-06-16 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/40446
+ * g++.dg/other/pr40446.C: New test.
+
+2009-06-16 Richard Guenther <rguenther@suse.de>
+
+ * gcc.dg/tree-ssa/pta-escape-1.c: New testcase.
+ * gcc.dg/tree-ssa/pta-escape-2.c: Likewise.
+ * gcc.dg/tree-ssa/pta-escape-3.c: Likewise.
+ * gcc.dg/tree-ssa/ssa-fre-27.c: Likewise.
+
+2009-06-16 Martin Jambor <mjambor@suse.cz>
+
+ * testsuite/gcc.c-torture/compile/pr40432.c: New file.
+
+2009-06-16 Martin Jambor <mjambor@suse.cz>
+
+ * testsuite/gfortran.fortran-torture/compile/pr40413.f90: New file.
+
+2009-06-16 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/36947
+ PR fortran/40039
+ * gfortran.dg/dummy_procedure_1.f90: Extended test case.
+ * gfortran.dg/interface_20.f90: Modified error messages.
+ * gfortran.dg/interface_21.f90: Ditto.
+ * gfortran.dg/interface_26.f90: Ditto.
+ * gfortran.dg/interface_27.f90: Ditto.
+ * gfortran.dg/interface_28.f90: Extended test case.
+ * gfortran.dg/interface_29.f90: New.
+ * gfortran.dg/proc_decl_7.f90: Modified error messages.
+ * gfortran.dg/proc_decl_8.f90: Ditto.
+ * gfortran.dg/proc_ptr_11.f90: Ditto.
+ * gfortran.dg/proc_ptr_15.f90: Ditto.
+
+2009-06-16 Ira Rosen <irar@il.ibm.com>
+
+ * gcc.dg/vect/vect-outer-4g.c: Don't look for pattern not allowed
+ printing.
+ * gcc.dg/vect/vect-outer-4k.c, gcc.dg/vect/vect-outer-4l.c,
+ gcc.dg/vect/vect-outer-4f.c: Likewise.
+ * gcc.dg/vect/vect-nest-cycle-1.c: New test.
+ * gcc.dg/vect/vect-nest-cycle-2.c, gcc.dg/vect/vect-nest-cycle-3.c:
+ Likewise.
+ * gcc.dg/vect/vect-outer-1a.c: Fail because of strided access in outer
+ loop.
+
+2009-06-16 Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/40383
+ * gfortran.dg/bounds_check_strlen_8.f90: New test.
+
+2009-06-15 Ian Lance Taylor <iant@google.com>
+
+ * gcc.dg/Wjump-misses-init-1.c: New testcase.
+ * gcc.dg/Wjump-misses-init-2.c: New testcase.
+ * gcc.dg/c99-vla-jump-5.c: Adjust expected error messages.
+ Recognize new notes.
+ * gcc.dg/stmt-expr-label-2.c: Likewise.
+ * gcc.dg/c99-vla-jump-1.c: Recognize new notes. Fix column
+ numbers.
+ * gcc.dg/c99-vla-jump-2.c: Recognize new notes.
+ * gcc.dg/c99-vla-jump-3.c: Recognize new notes.
+ * gcc.dg/c99-vla-jump-4.c: Likewise.
+ * gcc.dg/stmt-expr-label-1.c: Likewise.
+ * gcc.dg/stmt-expr-label-3.c: Likewise.
+ * gcc.dg/vla-8.c: Likewise. Move error message to different
+ line.
+
+2009-06-16 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * gcc.dg/torture/builtin-math-6.c: Robustify and fix clog cases.
+
+2009-06-15 Jakub Jelinek <jakub@redhat.com>
+
+ * gcc.dg/builtin-object-size-7.c: New test.
+
+2009-06-15 Jakub Jelinek <jakub@redhat.com>
+
+ PR testsuite/40426
+ * lib/gcc-dg.exp (gcc-dg-debug-runtest): For type -gdwarf-2 and
+ level != "" use separate -gdwarf-2 -g${level} options instead of
+ -gdwarf-2${level}.
+ * lib/gfortran-dg.exp (gfortran-dg-debug-runtest): Likewise.
+ * gfortran.dg/debug/pr37738.f: Also skip if -gdwarf-2 -g1.
+ * gfortran.dg/debug/pr35154-dwarf2.f: Likewise.
+
+2009-06-15 Rafael Avila de Espindola <espindola@google.com>
+
+ * g++.dg/abi/mangle11.C: Update warning line.
+ * g++.dg/abi/mangle12.C: Update warning line.
+ * g++.dg/abi/mangle17.C: Update warning line.
+ * g++.dg/abi/mangle20-2.C: Update warning line.
+
+2009-06-14 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
+
+ * gcc.dg/optimize-bswap-1.c: Split into these two:
+ * gcc.dg/optimize-bswapsi-1.c: New testcase.
+ * gcc.dg/optimize-bswapdi-1.c: New testcase.
+
+2009-06-14 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
+
+ * gcc.dg/optimize-bswap-1.c: New testcase.
+
+2009-06-14 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/40389
+ * g++.dg/torture/pr40389.C: New testcase.
+
+2009-06-13 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/40421
+ * gfortran.fortran-torture/compile/pr40421.f: New testcase.
+
+2009-06-12 Aldy Hernandez <aldyh@redhat.com>
+
+ * gcc.dg/old-style-prom-3.c: Add column info.
+ * gcc.dg/overflow-warn-1.c
+ * gcc.dg/gomp/pr27415.c
+ * gcc.dg/gomp/for-1.c: Same.
+ * gcc.dg/enum-compat-1.c: Same.
+ * gcc.dg/c99-tag-3.c: Same.
+ * gcc.dg/Wredundant-decls-2.c: Same.
+ * gcc.dg/func-ptr-conv-1.c: Same.
+ * gcc.dg/asm-wide-1.c: Same.
+ * gcc.dg/nofixed-point-2.c: Same.
+ * gcc.dg/cpp/line3.c: Same.
+ * gcc.dg/array-10.c: Same.
+ * gcc.dg/c99-vla-jump-1.c: Same.
+ * gcc.dg/pr20368-1.c: Same.
+ * gcc.dg/Wshadow-3.c: Same.
+ * gcc.dg/c90-const-expr-8.c: Same.
+ * gcc.dg/label-decl-2.c: Same.
+ * gcc.dg/dremf-type-compat-2.c: Same.
+ * gcc.dg/c90-const-expr-5.c: Same.
+ * gcc.dg/builtins-30.c: Same.
+ * gcc.dg/Warray-bounds.c: Same.
+ * gcc.dg/Wcxx-compat-2.c: Same.
+ * gcc.dg/tree-ssa/col-1.c: Same.
+ * gcc.dg/old-style-prom-2.c: Same.
+ * gcc.dg/cast-function-1.c: Same.
+ * gcc.dg/pr15698-1.c: Same.
+ * gcc.dg/dremf-type-compat-3.c: Same.
+ * gcc.dg/vla-8.c: Same.
+ * gcc.dg/gomp/pr27415.c: Move firstprivate diagnostics to correct
+ line.
+ * gcc.dg/label-decl-2.c: Move label diagnostic to correct line.
+ * gcc.dg/old-style-prom-3.c: Check for error on the correct line.
+ * gcc.dg/enum-compat-1.c: Same.
+ * gcc.dg/dremf-type-compat-2.c: Same.
+ * gcc.dg/old-style-prom-2.c: Same.
+ * gcc.dg/pr15698-1.c: Same.
+ * gcc.dg/pr20368-1.c: Same.
+ * gcc.dg/dremf-type-compat-3.c: Same.
+ * gcc.dg/builtins-30.c: Same. Test for columns.
+
+2009-06-12 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/40176
+ * gfortran.dg/proc_decl_1.f90: Extended.
+
+2009-06-12 Ian Lance Taylor <iant@google.com>
+
+ * gcc.dg/Wcxx-compat-13.c: New testcase.
+
+2009-06-12 Andrew Pinski <andrew_pinski@playstation.sony.com>
+
+ PR tree-opt/38865
+ * gcc.dg/tree-ssa/fre-vce-1.c
+
+2009-06-12 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR testsuite/40384
+ * gcc.dg/tree-ssa/prefetch-5.c: Add --param min-insn-to-prefetch-ratio=5.
+
+2009-06-12 Joey Ye <joey.ye@intel.com>
+ H.J. Lu <hongjiu.lu@intel.com>
+
+ PR middle-end/39146
+ * gcc.target/i386/stackalign/pr39146.c: New.
+
+2009-06-11 H.J. Lu <hongjiu.lu@intel.com>
+
+ * gcc.target/i386/crc32-1.c: New.
+ * gcc.target/i386/crc32-2.c: Likewise.
+
+2009-06-11 David Daney <ddaney@caviumnetworks.com>
+
+ PR c/39252
+ * gcc.dg/builtin-unreachable-1.c: New test.
+ * gcc.dg/builtin-unreachable-2.c: Same.
+
+2009-06-11 Paul Thomas <pault@gcc.gnu.org>
+
+ PR fortran/40402
+ * gfortran.dg/data_value_1.f90: New test.
+
+2009-06-11 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+
+ PR testsuite/39831
+ * gcc.target/i386/excess-precision-1.c: Use -mfpmath=387, and
+ remove ilp32 requirement.
+ * gcc.target/i386/excess-precision-2.c: Likewise.
+ * gcc.target/i386/excess-precision-3.c: Likewise.
+ * gcc.target/i386/excess-precision-4.c: Likewise.
+ * gcc.target/i386/excess-precision-5.c: Likewise.
+ * gcc.target/i386/excess-precision-6.c: Likewise.
+
+2009-06-11 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+
+ PR fortran/38718
+ * gfortran.dg/is_iostat_end_eor_2.f90: New test.
+ * gfortran.dg/nan_5.f90: New test.
+
+2009-06-10 Nathan Froyd <froydnj@codesourcery.com>
+
+ * gcc.target/arm/neon-modes-1.c: New test.
+
+2009-06-10 Kai Tietz <kai.tietz@onevision.com>
+
+ * g++.dg/torture/pr31579.C: Cast pointer
+ via __SIZE_TYPE__ instead of 'unsigned long'.
+
+2009-06-10 Anthony Green <green@moxielogic.com>
+
+ * testsuite/lib/target-supports.exp (check_profiling_available):
+ Profiling is not available for testing purposes on moxie.
+
+2009-06-09 Ian Lance Taylor <iant@google.com>
+
+ * gcc.dg/Wcxx-compat-12.c: New testcase.
+
+2009-06-09 Janne Blomqvist <jb@gcc.gnu.org>
+
+ PR libfortran/40334
+ * gfortran.dg/backspace_11.f90: New.
+
+2009-06-09 Jason Merrill <jason@redhat.com>
+
+ * g++.dg/cpp0x/defaulted10.C: New.
+
+2009-06-09 Martin Jambor <mjambor@suse.cz>
+
+ * testsuite/gcc.c-torture/compile/pr40351.c: New file.
+
+2009-06-09 Olivier Hainque <hainque@adacore.com>
+
+ * gnat.dg/align_max.adb: New test.
+
+2009-06-08 Jason Merrill <jason@redhat.com>
+
+ * g++.dg/cpp0x/auto15.C: New.
+
+2009-06-08 Jan Hubicka <jh@suse.cz>
+
+ PR debug/39834
+ * gcc.dg/torture/pr39834.c
+
+2009-06-08 Jan Hubicka <jh@suse.cz>
+
+ PR middle-end/40102
+ * g++.dg/torture/pr40102.C: New testcase.
+
+2009-06-08 Jakub Jelinek <jakub@redhat.com>
+
+ * gcc.dg/builtin-object-size-2.c (test1): Adjust expected results.
+ * gcc.dg/builtin-object-size-4.c (test1): Adjust expected results.
+ * gcc.dg/builtin-object-size-6.c: New test.
+
+ PR c++/40373
+ * g++.dg/template/dtor7.C: New test.
+
+ PR c++/40370
+ PR c++/40372
+ * g++.dg/template/error41.C: New test.
+ * g++.dg/template/error42.C: New test.
+
+2009-06-08 Revital Eres <eres@il.ibm.com>
+
+ PR testsuite/40359
+ * gcc.dg/vect/vect-58.c: Change checks to use vect_hw_misalign.
+ * gcc.dg/vect/vect-88.c: Likewise.
+ * gcc.dg/vect/no-section-anchors-vect-66.c: Likewise.
+ * gcc.dg/vect/pr25413.c: Likewise.
+ * lib/target-supports.exp: Add i?86 to vect_hw_misalign.
+
+2009-06-07 Ian Lance Taylor <iant@google.com>
+
+ * g++.dg/warn/Wswitch-3.C: New testcase.
+ * gcc.dg/Wswitch.c: Adjust for -Wswitch change.
+ * gcc.dg/Wswitch-enum-error.c: Likewise.
+ * gcc.dg/Wswitch-error.c: Likewise.
+
+2009-06-07 Jerry DeLisle <jvdelisle@gcc.gnu.org>
+
+ PR fortran/40008
+ * gfortran.dg/negative_unit.f: Update test.
+ * gfortran.dg/negative_unit_int8.f: Update test.
+ * gfortran.dg/newunit_1.f90: New test.
+
+2009-06-07 Daniel Franke <franke.daniel@gmail.com>
+
+ PR fortran/25104
+ PR fortran/29962
+ * gfortran.dg/spread_init_expr.f03: New.
+ * gfortran.dg/unpack_init_expr.f03: New.
+ * gfortran.dg/intrinsic_argument_conformance_2.f90: Adjusted
+ error message.
+
+2009-06-07 Daniel Franke <franke.daniel@gmail.com>
+
+ PR fortran/25104
+ PR fortran/29962
+ * gfortran.dg/count_init_expr.f03
+ * gfortran.dg/product_init_expr.f03
+ * gfortran.dg/sum_init_expr.f03
+
+2009-06-07 Daniel Franke <franke.daniel@gmail.com>
+
+ PR fortran/36874
+ * gfortran.dg/intrinsic_argument_conformance_2.f90: Adjusted error message.
+ * gfortran.dg/zero_sized_1.f90: Removed checks with incompatible shapes.
+ * gfortran.dg/zero_sized_5.f90: Likewise.
+
+2009-06-07 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR middle-end/32950
+ * g++.dg/torture/pr32950.C: New.
+
+2009-06-07 Daniel Franke <franke.daniel@gmail.com>
+
+ PR fortran/25104
+ PR fortran/29962
+ * gfortran.dg/dot_product_1.f03: New.
+ * gfortran.dg/matmul_8.f03: New.
+ * gfortran.dg/transpose_3.f03: New.
+
+2009-06-06 Ian Lance Taylor <iant@google.com>
+
+ * gcc.dg/Wunused-label-1.c: New test case.
+ * g++.dg/warn/Wunused-label-1.C: New test case.
+ * g++.dg/warn/Wunused-label-2.C: New test case.
+ * g++.dg/warn/Wunused-label-3.C: New test case.
+
+2009-06-06 Daniel Franke <franke.daniel@gmail.com>
+
+ PR fortran/37203
+ * reshape_zerosize_2.f90: New.
+
+2009-06-06 Daniel Franke <franke.daniel@gmail.com>
+
+ PR fortran/32890
+ * gfortran.dg/pack_assign_1.f90: New.
+ * gfortran.dg/pack_vector_1.f90: New.
+
+2009-06-05 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/40340
+ * gcc.dg/pr40340-1.c: New test.
+ * gcc.dg/pr40340-2.c: New test.
+ * gcc.dg/pr40340-3.c: New test.
+ * gcc.dg/pr40340-4.c: New test.
+ * gcc.dg/pr40340-5.c: New test.
+ * gcc.dg/pr40340.h: New file.
+
+2009-06-05 Revital Eres <eres@il.ibm.com>
+
+ * lib/target-supports.exp:
+ (check_effective_target_vect_hw_misalign): New procedure.
+ * gcc.dg/vect/vect-50.c: Change checks to use vect_hw_misalign.
+ * gcc.dg/vect/vect-33.c: Likewise.
+ * gcc.dg/vect/vect-92.c: Likewise.
+ * gcc.dg/vect/vect-58.c: Likewise.
+ * gcc.dg/vect/no-section-anchors-vect-69.c: Likewise.
+ * gcc.dg/vect/vect-42.c: Likewise.
+ * gcc.dg/vect/slp-25.c: Likewise.
+ * gcc.dg/vect/vect-align-1.c: Likewise.
+ * gcc.dg/vect/vect-align-2.c: Likewise.
+ * gcc.dg/vect/vect-93.c: Likewise.
+ * gcc.dg/vect/no-scevccp-outer-8.c: Likewise.
+ * gcc.dg/vect/costmodel/i386/costmodel-vect-31.c: Likewise.
+ * gcc.dg/vect/costmodel/i386/costmodel-vect-33.c: Likewise.
+ * gcc.dg/vect/costmodel/x86_64/costmodel-vect-31.c: Likewise.
+ * gcc.dg/vect/costmodel/x86_64/costmodel-vect-33.c: Likewise.
+ * gcc.dg/vect/vect-26.c: Likewise.
+ * gcc.dg/vect/vect-44.c: Likewise.
+ * gcc.dg/vect/vect-70.c: Likewise.
+ * gcc.dg/vect/vect-95.c: Likewise.
+ * gcc.dg/vect/no-section-anchors-vect-64.c: Likewise.
+ * gcc.dg/vect/vect-28.c: Likewise.
+ * gcc.dg/vect/no-section-anchors-vect-31.c: Likewise.
+ * gcc.dg/vect/vect-87.c: Likewise.
+ * gcc.dg/vect/vect-109.c: Likewise.
+ * gcc.dg/vect/vect-54.c: Likewise.
+ * gcc.dg/vect/vect-96.c: Likewise.
+ * gcc.dg/vect/vect-multitypes-1.c: Likewise.
+ * gcc.dg/vect/vect-88.c: Likewise.
+ * gcc.dg/vect/no-section-anchors-vect-66.c: Likewise.
+ * gcc.dg/vect/vect-89.c: Likewise.
+ * gcc.dg/vect/vect-91.c: Likewise.
+ * gcc.dg/vect/no-section-anchors-vect-68.c: Likewise.
+ * gcc.dg/vect/vect-multitypes-4.c: Likewise.
+ * gfortran.dg/vect/vect-2.f90: Likewise.
+ * gfortran.dg/vect/vect-3.f90: Likewise.
+ * gfortran.dg/vect/vect-4.f90: Likewise.
+ * gfortran.dg/vect/vect-5.f90: Likewise.
+
+2009-06-05 Alexander Strange <astrange@ithinksw.com>
+
+ PR tree-optimization/36318
+ * gcc.dg/tree-ssa/sra-7.c: New test.
+
+2009-06-04 Daniel Franke <franke.daniel@gmail.com>
+
+ PR fortran/37203
+ * gfortran.dg/reshape_order_5.f90: New.
+ * gfortran.dg/reshape_shape_1.f90: New.
+
+2009-06-04 Jason Merrill <jason@redhat.com>
+
+ * g++.dg/template/error38.C: Add pointer-to-typedef case.
+
+2009-06-04 Steve Ellcey <sje@cup.hp.com>
+
+ * gcc.dg/vect/vect-42.c: Modify vect_no_align case.
+ * gcc.dg/vect/no-vfa-vect-43.c: Ditto.
+
+2009-06-04 Richard Guenther <rguenther@suse.de>
+
+ PR c++/39371
+ * g++.dg/torture/pr40335.C: New testcase.
+
+2009-06-03 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/40328
+ * gcc.dg/torture/pr40328.c: New testcase.
+
+2009-06-03 Martin Jambor <mjambor@suse.cz>
+
+ * g++.dg/torture/pr40323.C: New file.
+
+2009-06-03 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/specs/root.ads: New test.
+ * gnat.dg/specs/root-level_1.ads: Likewise.
+ * gnat.dg/specs/root-level_2.ads: Likewise.
+ * gnat.dg/specs/root-level_1-level_2.ads: Likewise.
+
+2009-06-02 Mark Mitchell <mark@codesourcery.com>
+
+ * g++.dg/init/ref15.C: Require unwrapped targets.
+
+2009-06-02 Jason Merrill <jason@redhat.com>
+
+ * g++.dg/cpp0x/initlist13.C: Remove expected error.
+ * g++.dg/cpp0x/initlist18.C: New.
+ * g++.dg/cpp0x/initlist19.C: New.
+
+ * g++.dg/cpp0x/auto14.C: New.
+
+2009-06-02 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/alignment6.adb: Remove XFAIL.
+
+2009-06-02 Simon Martin <simartin@users.sourceforge.net>
+
+ PR c++/38089
+ * g++.dg/template/spec36.C: New test.
+
+2009-06-01 Ian Lance Taylor <iant@google.com>
+
+ * gcc.dg/cast-qual-3.c: New testcase.
+ * g++.dg/warn/Wcast-qual2.C: New testcase.
+
+2009-06-01 Aldy Hernandez <aldyh@redhat.com>
+
+ * lib/gcc-dg.exp (dg-bogus): Override dg-bogus.
+ (process-message): Expect column numbers.
+ * gcc.dg/va-arg-2.c: Use line 0 to indicate no column.
+ * gcc.dg/pch/counter-2.c: Same.
+ * gcc.dg/pch/valid-2.c: Same.
+ * gcc.dg/pch/warn-1.c: Same.
+ * gcc.dg/pch/valid-1.c: Same.
+ * gcc.dg/cpp/include2a.c: Handle lack of columns.
+ * gcc.dg/cpp/syshdr.c: Same.
+ * gcc.dg/cpp/19940712-1.c: Same.
+ * gcc.dg/cpp/missing-header-1.c: Same.
+ * gcc.dg/cpp/unc4.c: Remove -fno-show-column.
+ * gcc.dg/cpp/tr-warn3.c: Same.
+ * gcc.dg/cpp/pr29612-2.c: Same.
+ * gcc.dg/cpp/tr-warn4.c: Same.
+ * gcc.dg/cpp/Wtrigraphs.c: Same.
+ * gcc.dg/cpp/poison.c: Same.
+ * gcc.dg/cpp/arith-3.c: Same.
+ * gcc.dg/cpp/sysmac2.c: Same.
+ * gcc.dg/cpp/cpp.exp: Same.
+ * gcc.dg/cpp/tr-warn5.c: Same.
+ * gcc.dg/cpp/include2.c: Same.
+ * gcc.dg/cpp/Wmissingdirs.c: Same.
+ * gcc.dg/cpp/Wmissingdirs.c: Same.
+ * gcc.dg/cpp/tr-warn6.c: Same.
+ * gcc.dg/cpp/Wtrigraphs-2.c: Same.
+ * gcc.dg/cpp/macspace1.c: Same.
+ * gcc.dg/cpp/escape-2.c: Same.
+ * gcc.dg/cpp/assert2.c: Same.
+ * gcc.dg/cpp/undef2.c: Same.
+ * gcc.dg/cpp/macspace2.c: Same.
+ * gcc.dg/cpp/tr-warn1.c: Same.
+ * gcc.dg/cpp/extratokens2.c: Same.
+ * gcc.dg/cpp/strify2.c: Same.
+ * gcc.dg/cpp/Wsignprom.c: Same.
+ * gcc.dg/cpp/redef2.c: Same.
+ * gcc.dg/cpp/trad/trad.exp: Same.
+ * gcc.dg/cpp/arith-1.c: Same.
+ * gcc.dg/cpp/extratokens.c: Same.
+ * gcc.dg/cpp/if-mpar.c: Same.
+
+2009-06-01 Olivier Hainque <hainque@adacore.com>
+
+ * gnat.dg/nested_float_packed.ads: New test.
+
+2009-06-01 Olivier Hainque <hainque@adacore.com>
+ Eric Botcazou <botcazou@adacore.com>
+
+ * gnat.dg/oconst[1-6].ad[bs]: New tests. Also support for ...
+ * gnat.dg/test_oconst.adb: New test.
+
+2009-05-31 Basile Starynkevitch <basile@starynkevitch.net>
+
+ * gcc.dg/plugin/ggcplug.c: moved comment.
+ (plugin_init): fixed typo, declared i, returned 0 at end.
+
+2009-05-31 Ira Rosen <irar@il.ibm.com>
+
+ PR testsuite/40244
+ * gcc.dg/vect/bb-slp-4.c: Change the number of data accesses to 2.
+ * gcc.dg/vect/bb-slp-10.c: Change the store misalignment to 1.
+
+2009-05-29 Ian Lance Taylor <iant@google.com>
+
+ * gcc.dg/Wcxx-compat-11.c: New testcase.
+
+2009-05-29 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+
+ PR fortran/40019
+ * gfortran.dg/leadz_trailz_1.f90: New test.
+ * gfortran.dg/leadz_trailz_2.f90: New test.
+
+2009-05-29 Martin Jambor <mjambor@suse.cz>
+
+ * gfortran.dg/pr25923.f90: XFAIL warning expectation.
+ * gcc.dg/tree-ssa/ssa-fre-7.c: Compile with -fno-tree-sra.
+ * gcc.dg/tree-ssa/ssa-fre-8.c: Likewise.
+ * gcc.dg/tree-ssa/ssa-fre-9.c: Likewise.
+ * gcc.dg/memcpy-1.c: Removed param sra-max-structure-size.
+ * gcc.dg/tree-ssa/sra-2.c: Likewise.
+ * gcc.dg/tree-ssa/sra-3.c: Likewise.
+ * gcc.dg/tree-ssa/sra-1.c: Likewise.
+ * gcc.dg/tree-ssa/sra-4.c: Changed comment.
+ * gcc.dg/tree-ssa/sra-5.c: New file.
+ * gcc.dg/tree-ssa/sra-6.c: New file.
+ * gcc.c-torture/compile/sra-1.c: New file.
+
+2009-05-29 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/40291
+ * gcc.c-torture/compile/pr40291.c: New test.
+
+ PR target/40017
+ * gcc.target/powerpc/altivec-types-1.c: Don't expect error for
+ __vector _Bool.
+ * gcc.target/powerpc/altivec-30.c: New test.
+ * gcc.target/powerpc/altivec-31.c: New test.
+
+2009-05-28 Richard Guenther <rguenther@suse.de>
+
+ * gcc.dg/tree-ssa/ssa-fre-26.c: New testcase.
+ * gcc.c-torture/execute/20090527-1.c: Likewise.
+
+2009-05-28 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/39754
+ * g++.dg/template/canon-type-1.C: New test.
+ * g++.dg/template/canon-type-2.C: Likewise.
+ * g++.dg/template/canon-type-3.C: Likewise.
+ * g++.dg/template/canon-type-4.C: Likewise.
+ * g++.dg/template/canon-type-5.C: Likewise.
+ * g++.dg/template/canon-type-6.C: Likewise.
+ * g++.dg/template/canon-type-7.C: Likewise.
+
+2009-05-28 Dave Korn <dave.korn.cygwin@gmail.com>
+ Uros Bizjak <ubizjak@gmail.com>
+ Danny Smith <dansmister@gmail.com>
+
+ PR target/37216
+
+ * lib/target-supports.exp (check_effective_target_pe_aligned_commons):
+ New function.
+ * gcc.target/i386/pr37216.c: New test source file.
+ * gcc.dg/compat/struct-layout-1_generate.c (dg_options[]): No longer
+ use -fno-common for testing Cygwin and MinGW targets.
+
+2009-05-28 Kai Tietz <kai.tietz@onevision.com>
+
+ * g++.dg/ext/packed6.C (size_t): Use __extension__ and __SIZE_TYPE__.
+ * g++.dg/opt/memcpy1.C (size_t): Likewise.
+ * g++.dg/pr37742.C (size_t): Likewise.
+ * g++.dg/torture/pr34850.C (size_t): Likewise.
+ * g++.dg/torture/20070621-1.C (ptrdiff_t): Use __extension__ and
+ _PTRDIFF_TYPE__.
+ * g++.dg/torture/pr34222.C (ptrdiff_t): Likewise.
+ * g++.dg/tree-ssa/pr22444.C (ptrdiff_t): Likewise.
+ (size_t): Use __extension__ and __SIZE_TYPE__.
+ * gcc.c-torture/compile/20000211-1.c (size_t): Typedef size_t via
+ __SIZE_TYPE__.
+ * gcc.c-torture/compile/20010328-1.c (size_t): Likewise,
+ * gcc.c-torture/compile/20030320-1.c (size_t): Likewise,
+ * gcc.c-torture/compile/20030405-1.c (size_t): Likewise,
+ * gcc.c-torture/compile/20030902-1.c (size_t): Likewise,
+ * gcc.c-torture/compile/20060202-1.c (size_t): Likewise,
+ * gcc.c-torture/compile/20080613-1.c (size_t): Likewise,
+ * gcc.c-torture/compile/920428-2.c (size_t): Likewise,
+ * gcc.c-torture/compile/980329-1.c (size_t): Likewise,
+ * gcc.c-torture/compile/980816-1.c (size_t): Likewise,
+ * gcc.c-torture/compile/pr32584.c (size_t): Likewise,
+ * (__ssize_t): Likewise.
+ * gcc.c-torture/compile/pr33173.c (size_t): Likewise,
+ * gcc.c-torture/compile/pr33382.c (size_t): Likewise,
+ * gcc.c-torture/compile/pr34334.c (size_t): Likewise,
+ * gcc.c-torture/compile/pr34688.c (size_t): Likewise,
+ * gcc.c-torture/compile/pr35043.c (size_t): Likewise,
+ * gcc.c-torture/compile/pr37669.c (size_t): Likewise,
+ * gcc.dg/20050629-1.c (size_t): Typedef size_t via __SIZE_TYPE__.
+ * gcc.dg/pr33667.c (size_t): Likewise.
+ * gcc.dg/prefetch-loop-arrays-1.c (size_t): Likewise.
+ * gcc.dg/torture/pr39204.c (size_t): Likewise.
+ * gcc.dg/tree-ssa/20041122-1.c (size_t): Likewise.
+ * gcc.dg/tree-ssa/pr36908.c (size_t): Likewise.
+ * gcc.dg/tree-ssa/pr38250.c (size_t): Likewise.
+ * gcc.dg/tree-ssa/ssa-dse-10.c (size_t): Likewise.
+
+2009-05-28 Ira Rosen <irar@il.ibm.com>
+
+ PR tree-optimization/40254
+ * gcc.dg/vect/pr40254.c: New test.
+
+2009-05-28 Adam Nemet <anemet@caviumnetworks.com>
+
+ PR middle-end/33699
+ * gcc.target/mips/const-anchor-1.c: New test.
+ * gcc.target/mips/const-anchor-2.c: New test.
+
+2009-05-27 Jason Merrill <jason@redhat.com>
+
+ * g++.dg/cpp0x/initlist15.C: New.
+ * g++.dg/cpp0x/initlist16.C: New.
+ * g++.dg/cpp0x/initlist17.C: New.
+
+2009-05-27 Janne Blomqvist <jb@gcc.gnu.org>
+
+ PR fortran/39178
+ * gfortran.dg/elemental_dependency_1.f90: Fix scan-tree-dump-times
+ patterns to reflect frontend changes.
+ * gfortran.dg/vector_subscript_4.f90: Likewise.
+
+2009-05-27 Olivier Hainque <hainque@adacore.com>
+ Eric Botcazou <botcazou@adacore.com>
+
+ * gcc.c-torture/execute/align-nest.c: New testcase.
+ * gnat.dg/misaligned_nest.adb: New testcase.
+
+2009-05-27 Rafael Avila de Espindola <espindola@google.com>
+
+ * g++.dg/plugin/attribute_plugin.c: Include gcc-plugin.h first.
+ * g++.dg/plugin/dumb_plugin.c: Include gcc-plugin.h first.
+ * g++.dg/plugin/selfassign.c: Include gcc-plugin.h first.
+ * gcc.dg/plugin/selfassign.c: Include gcc-plugin.h first.
+
+2009-05-27 Kai TIetz <kai.tietz@onevision.com>
+
+ * g++.old-deja/g++.brendan/array1.C (array): Use __SIZE_TYPE__
+ cast instead of assuming 0ul.
+ * g++.old-deja/g++.brendan/crash64.C (size_t): Define it via
+ __SIZE_TYPE__.
+ (_type_desc): Make first argument const.
+ * g++.old-deja/g++.jason/new3.C (dg-options): Add -Wno-long-long.
+
+2009-05-27 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR libfortran/40187
+ * gfortran.dg/c_f_pointer_shape_tests_4.f03: New file.
+ * gfortran.dg/c_f_pointer_shape_tests_4_driver.c: New file.
+
+2009-05-26 Basile Starynkevitch <basile@starynkevitch.net>
+
+ * testsuite/gcc.dg/plugin/plugin.exp: Added ggcplug.c test plugin
+ with ggcplug-test-1.c for testing PLUGIN_GGC_MARKING etc...
+ * testsuite/gcc.dg/plugin/ggcplug-test-1.c: Added new file.
+ * testsuite/gcc.dg/plugin/ggcplug.c: Added new file.
+
+2009-05-26 Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/40246
+ * gfortran.dg/nullify_4.f90: New test.
+
+2009-05-26 Richard Guenther <rguenther@suse.de>
+
+ * gcc.dg/tree-ssa/inline-3.c: Remove dump file.
+
+2009-05-26 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/40252
+ * gcc.c-torture/compile/pr40252.c: New testcase.
+
+2009-05-26 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/40007
+ * g++.dg/template/typedef18.C: New test.
+ * g++.dg/template/typedef19.C: Likewise.
+ * g++.dg/template/typedef20.C: Likewise.
+ * g++.dg/template/access11.C: Adjust.
+
+2009-05-26 Richard Guenther <rguenther@suse.de>
+
+ PR testsuite/40247
+ * gcc.dg/struct/wo_prof_escape_substr_pointer.c: Obfuscate.
+
+2009-05-25 Jason Merrill <jason@redhat.com>
+
+ PR c++/38064
+ * g++.dg/cpp0x/enum3.C: New test.
+
+2009-05-25 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/36327
+ * gcc.dg/tree-ssa/ssa-fre-24.c: New testcase.
+ * gcc.dg/tree-ssa/ssa-fre-25.c: Likewise.
+ * gcc.dg/tree-ssa/sra-2.c: Disable FRE.
+ * gcc.dg/vect/no-vfa-vect-43.c: Adjust.
+ * gcc.dg/vect/vect-40.c: Likewise.
+ * gcc.dg/vect/vect-42.c: Likewise.
+ * gcc.dg/vect/vect-46.c: Likewise.
+ * gcc.dg/vect/vect-76.c: Likewise.
+
+2009-05-25 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/40176
+ * gfortran.dg/proc_ptr_18.f90: New.
+ * gfortran.dg/proc_ptr_19.f90: New.
+ * gfortran.dg/proc_ptr_comp_9.f90: New.
+ * gfortran.dg/proc_ptr_comp_10.f90: New.
+
+2009-05-25 Richard Guenther <rguenther@suse.de>
+
+ * gcc.dg/tree-ssa/ssa-fre-14.c: Adjust.
+ * gcc.dg/tree-ssa/ssa-fre-15.c: Likewise.
+
+2009-05-25 Ira Rosen <irar@il.ibm.com>
+
+ PR tree-optimization/40238
+ * gcc.dg/vect/pr40238.c: New test.
+
+2009-05-24 Jerry DeLisle <jvdelisle@gcc.gnu.org>
+ Dominique Dhumieres <dominiq@lps.ens.fr>
+
+ PR fortran/35732
+ PR fortran/39872
+ * gfortran.dg/bounds_check_fail_3.f90: New test.
+ * gfortran.dg/bounds_check_fail_4.f90: New test.
+ * gfortran.dg/bounds_check_14.f90: Update test.
+ * gfortran.dg/bound_4.f90: Update test.
+
+2009-05-24 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/40233
+ * gcc.c-torture/compile/pr40233.c: New testcase.
+
+2009-05-24 Uros Bizjak <ubizjak@gmail.com>
+
+ * gfortran.dg/erf_2.F90 (dg-options): Add -mieee
+ for alpha*-*-* targets.
+
+2009-05-24 Ira Rosen <irar@il.ibm.com>
+
+ * gcc.dg/vect/bb-slp-1.c: New test.
+ * gcc.dg/vect/bb-slp-2.c, gcc.dg/vect/bb-slp-3.c,
+ gcc.dg/vect/bb-slp-4.c, gcc.dg/vect/bb-slp-5.c,
+ gcc.dg/vect/bb-slp-6.c, gcc.dg/vect/bb-slp-7.c,
+ gcc.dg/vect/bb-slp-8.c, gcc.dg/vect/bb-slp-9.c,
+ gcc.dg/vect/bb-slp-10.c, gcc.dg/vect/bb-slp-11.c,
+ gcc.dg/vect/no-tree-reassoc-bb-slp-12.c, gcc.dg/vect/bb-slp-13.c,
+ gcc.dg/vect/bb-slp-14.c, gcc.dg/vect/bb-slp-15.c,
+ gcc.dg/vect/bb-slp-16.c, gcc.dg/vect/bb-slp-17.c,
+ gcc.dg/vect/bb-slp-18.c, gcc.dg/vect/bb-slp-19.c,
+ gcc.dg/vect/bb-slp-20.c, gcc.dg/vect/bb-slp-21.c,
+ gcc.dg/vect/bb-slp-22.c: Likewise.
+ * gcc.dg/vect/vect.exp: Run basic block SLP tests.
+
+2009-05-23 Mark Mitchell <mark@codesourcery.com>
+ Maxim Kuvyrkov <maxim@codesourcery.com>
+
+ * gcc.dg/falign-labels-1.c: New test.
+
+2009-05-23 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/specs/rep_clause3.ads: New test.
+
+2009-05-23 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/addr6.adb: New test.
+
+2009-05-22 Mark Mitchell <mark@codesourcery.com>
+
+ * lib/target-supports.exp (check_effective_target_arm_thumb2_ok):
+ New function.
+ * gcc.target/arm/thumb2-mul-space.c: New file.
+ * gcc.target/arm/thumb2-mul-space-2.c: New file.
+ * gcc.target/arm/thumb2-mul-space-3.c: New file.
+ * gcc.target/arm/thumb2-mul-speed.c: New file.
+
+2009-05-22 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/38964
+ * g++.dg/warn/Wstrict-aliasing-float-ref-int-obj.C: XFAIL.
+ * gcc.dg/Wstrict-aliasing-converted-assigned.c: Likewise.
+ * gcc.dg/Wstrict-aliasing-float-ptr-int-obj.c: Likewise.
+
+2009-05-22 Mark Mitchell <mark@codesourcery.com>
+
+ * gcc.dg/dll-6.c: New test.
+ * gcc.dg/dll-6a.c: Likewise.
+ * gcc.dg/dll-7.c: Likewise.
+ * gcc.dg/dll-7a.c: Likewise.
+ * g++.dg/ext/dllexport2.C: Likewise.
+ * g++.dg/ext/dllexport2a.cc: Likewise.
+
+2009-05-21 Steve Ellcey <sje@cup.hp.com>
+
+ PR target/37846
+ * gcc.target/ia64/mfused-madd-vect.c: New test.
+ * gcc.target/ia64/mfused-madd.c: New test.
+ * gcc.target/ia64/mno-fused-madd-vect.c: New test.
+ * gcc.target/ia64/mno-fused-madd.c: New test.
+
+2009-05-21 H.J. Lu <hongjiu.lu@intel.com>
+
+ * gcc.target/i386/movbe-1.c: New.
+ * gcc.target/i386/movbe-2.c: Likewise.
+
+2009-05-21 Taras Glek <tglek@mozilla.com>
+
+ * gcc.dg/plugin/selfassign.c (plugin_init): Updated to new
+ plugin_init signature.
+ * g++.dg/plugin/selfassign.c (plugin_init): Likewise.
+ * g++.dg/plugin/dumb_plugin.c (plugin_init): Likewise.
+ * g++.dg/plugin/attribute_plugin.c (plugin_init): Likewise.
+
+2009-05-21 Mark Mitchell <mark@codesourcery.com>
+
+ * gcc.dg/target/arm/neon-vmla-1.c: New.
+ * gcc.dg/target/arm/neon-vmls-1.c: Likewise.
+
+2009-05-20 Adam Nemet <anemet@caviumnetworks.com>
+
+ * gcc.target/mips/octeon-exts-6.c: New test.
+ * gcc.target/mips/extend-1.c: New test.
+ * gcc.target/mips/octeon-exts-2.c: Adjust to not match sign-extension
+ EXTS.
+ * gcc.target/mips/octeon-exts-5.c: Likewise.
+
+2009-05-20 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/40204
+ * gcc.c-torture/compile/pr40204.c: New test.
+
+2009-05-20 Richard Guenther <rguenther@suse.de>
+
+ * gcc.c-torture/compile/20090518-1.c: New testcase.
+
+2009-05-19 Zdenek Dvorak <ook@ucw.cz>
+
+ PR tree-optimization/40087
+ * gcc.dg/tree-ssa/pr40087.c: New test.
+
+2009-05-19 Andrew Pinski <andrew_pinski@playstation.sony.com>
+
+ * gcc.dg/vector-4.c: New testcase.
+ * gcc.dg/simd-1b.c: % is now allowed for integer vectors.
+ * g++.dg/ext/vector16.C: New testcase.
+
+2009-05-19 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR c/40172
+ * gcc.dg/pr40172.c: Renamed to ...
+ * gcc.dg/pr40172-1.c: This.
+
+ * gcc.dg/pr40172-2.c: New.
+ * gcc.dg/pr40172-3.c: Likewise.
+
+2009-05-19 Manuel López-Ibáñez <manu@gcc.gnu.org>
+
+ PR c/40172
+ * gcc.dg/pr40172.c: Add -Wlogical-op to dg-options.
+
+2009-05-19 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/loop_optimization6.ad[sb]: New test.
+
+2009-05-19 Richard Guenther <rguenther@suse.de>
+
+ * gcc.c-torture/compile/20090519-1.c: New testcase.
+
+2009-05-18 Jason Merrill <jason@redhat.com>
+
+ * g++.dg/cpp0x/explicit1.C: New.
+ * g++.dg/cpp0x/explicit2.C: New.
+
+2009-05-18 Dodji Seketeli <dodji@redhat.com>
+
+ PR debug/40109
+ * g++.dg/debug/dwarf2/nested-1.C: New test.
+
+2009-05-18 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR testsuite/39907
+ * gcc.target/x86_64/abi/asm-support.S (snapshot_ret): Preserve
+ stack alignment.
+
+2009-05-18 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/40164
+ * gfortran.dg/proc_ptr_comp_8.f90: New.
+
+2009-05-18 Richard Guenther <rguenther@suse.de>
+
+ PR fortran/40168
+ * gfortran.dg/array_memset_2.f90: Adjust.
+
+2009-05-18 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/36947
+ PR fortran/40039
+ * gfortran.dg/interface_27.f90: New.
+ * gfortran.dg/interface_28.f90: New.
+ * gfortran.dg/proc_ptr_11.f90: Fixing invalid test case.
+ * gfortran.dg/proc_ptr_result_1.f90: Ditto.
+
+2009-05-18 Maxim Kuvyrkov <maxim@codesourcery.com>
+
+ * gcc.target/m68k/tls-ie.c: New test.
+ * gcc.target/m68k/tls-le.c: New test.
+ * gcc.target/m68k/tls-gd.c: New test.
+ * gcc.target/m68k/tls-ld.c: New test.
+ * gcc.target/m68k/tls-ie-xgot.c: New test.
+ * gcc.target/m68k/tls-le-xtls.c: New test.
+ * gcc.target/m68k/tls-gd-xgot.c: New test.
+ * gcc.target/m68k/tls-ld-xgot.c: New test.
+ * gcc.target/m68k/tls-ld-xtls.c: New test.
+ * gcc.target/m68k/tls-ld-xgot-xtls.c: New test.
+
+2009-05-18 Martin Jambor <mjambor@suse.cz>
+
+ * gcc.dg/ipa/modif-1.c: Do not check for unmodified int parameter.
+
+2009-05-17 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR c/40172
+ * gcc.dg/pr40172.c: New.
+
+2009-05-17 Jason Merrill <jason@redhat.com>
+
+ PR c++/40139
+ * g++.dg/template/dtor6.C: New.
+
+2009-05-17 Joseph Myers <joseph@codesourcery.com>
+
+ * g++.dg/warn/translate-ice-1.C: New test.
+
+2009-05-17 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+
+ * gfortran.dg/c_kind_int128_test1.f03: Also test C_INT_FAST128_T.
+ * gfortran.dg/c_kind_int128_test2.f03: Update comment.
+ * gfortran.dg/c_kind_params.f90: Also test int_fast*_t.
+ * gfortran.dg/c_kinds.c: Add int_fast*_t arguments.
+
+2009-05-16 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+
+ PR fortran/33197
+ * gfortran.dg/erf_2.F90: New test.
+ * gfortran.dg/erfc_scaled_2.f90: New test.
+
+2009-05-16 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+
+ PR fortran/31243
+ * gcc/testsuite/gfortran.dg/string_1.f90: New test.
+ * gcc/testsuite/gfortran.dg/string_2.f90: New test.
+ * gcc/testsuite/gfortran.dg/string_3.f90: New test.
+
+2009-05-16 David Billinghurst <billingd@gcc.gnu.org>
+
+ * gfortran.dg/default_format_denormal_1.f90: XFAIL on cygwin.
+ * gfortran.dg/default_format_1.f90: Revert change of 2009-05-12
+
+2009-05-15 Ian Lance Taylor <iant@google.com>
+
+ * gcc.dg/Wcxx-compat-10.c: New testcase.
+
+2009-05-15 Manuel López-Ibáñez <manu@gcc.gnu.org>
+
+ PR 16302
+ * gcc.dg/pr16302.c: New.
+ * g++.dg/warn/pr16302.C: New.
+
+2009-05-15 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * gcc.dg/torture/builtin-math-5.c: New.
+ * gcc.dg/torture/builtin-math-6.c: New.
+ * lib/target-supports.exp (check_effective_target_mpc): New.
+
+2009-05-15 Jan Hubicka <jh@suse.cz>
+
+ * testsuite/gcc.dg/tree-ssa/inline-3.c: New testcase
+
+2009-05-15 Jan Hubicka <jh@suse.cz>
+
+ * gcc.target/i386/align-main-1.c (check): Mark noinline.
+ * gcc.target/i386/align-main-2.c (check): Mark noinline.
+ * gcc.dg/ipa/ipa-4.c: Disable early inlining.
+ * gcc.dg/vect/vect-iv-10.c (main1): Mark noinline.
+ * gcc.dg/vect/costmodel/i386/costmodel-vect-33.c (main1):
+ Mark noinline.
+ * gcc.dg/vect/costmodel/x86_64/costmodel-vect-33.c (main1):
+ Mark noinline.
+ * gcc.dg/vect/pr31699.c (foo): Mark noinline.
+ * gcc.dg/vect/pr18400.c (main1): Mark noinline.
+
+2009-05-15 Jan Hubicka <jh@suse.cz>
+
+ * sibcall-6.c: Add no-ipa-cp argument and mark the function to be
+ optimized by sibcall noinline.
+
+2009-05-15 Jan Hubicka <jh@suse.cz>
+
+ * sibcall-1.c (track): Mark noinline.
+ * sibcall-2.c (track): Mark noinline.
+ * sibcall-3.c (track): Mark noinline.
+ * sibcall-4.c (track): Mark noinline.
+
+2009-05-15 Jan Hubicka <jh@suse.cz>
+
+ * flatten-2.c: Disable early inlining; add comment.
+ * flatten-3.c: New test based on flatten-2.c.
+
+2009-05-15 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/39999
+ * gcc.c-torture/compile/pr39999.c: New testcase.
+
+2009-05-15 Joseph Myers <joseph@codesourcery.com>
+
+ * gcc.c-torture/compile/ptr-conv-1.c: New test.
+
+2009-05-14 Ian Lance Taylor <iant@google.com>
+
+ * gcc.dg/Wcxx-compat-9.c: New testcase.
+
+2009-05-14 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/39996
+ * gfortran.dg/func_decl_2.f90: Modified (replacing warnings by errors).
+ * gfortran.dg/duplicate_type_2.f90: Ditto.
+ * gfortran.dg/duplicate_type_3.f90: New.
+
+2009-05-14 Laurent GUERBY <laurent@guerby.net>
+
+ * ada/acats/tests/c3/c38202a.ada: Use Impdef.
+ * ada/acats/tests/c5/c59002c.ada: Likewise.
+
+2009-05-13 Taras Glek <tglek@mozilla.com>
+
+ * g++.dg/plugin/attribute_plugin-test-1.C: Testcase input for custom
+ attributes and decl smashing.
+ * g++.dg/plugin/attribute_plugin.c: Testcase plugin to test user
+ attributes.
+ * g++.dg/plugin/dumb_plugin.c: Fixed typo.
+ * g++.dg/plugin/plugin.exp: Added attribute_plugin test .
+
+2009-05-14 Jakub Jelinek <jakub@redhat.com>
+
+ PR fortran/39865
+ * gfortran.dg/pr39865.f90: New test.
+ * gfortran.dg/hollerith.f90: Don't expect errors for CHARACTER
+ arrays in FMT=.
+ * gfortran.dg/hollerith_f95.f90: Likewise.
+ * gfortran.dg/hollerith6.f90: New test.
+ * gfortran.dg/hollerith7.f90: New test.
+
+2009-05-14 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR cpp/36674
+ * gcc.dg/cpp/pr36674.i: New.
+
+2009-05-14 Ben Elliston <bje@au.ibm.com>
+
+ PR middle-end/40035
+ * gcc.c-torture/compile/pr40035.c: New test.
+
+2009-05-13 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * gcc.target/i386/pr39543-2.c: Skip if ilp32 && pic.
+
+2009-05-12 Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/40110
+ * gfortran.dg/bind_c_usage_18.f90: Change dg-error into dg-warning.
+ * gfortran.dg/c_kind_tests_2.f03: Ditto.
+ * gfortran.dg/interop_params.f03: Ditto.
+
+2009-05-12 Jan Hubicka <jh@suse.cz>
+
+ * gcc.dg/tree-ssa/loop-36.c: Reduce amount of iterations to 2
+ so unrolling still happens.
+ * gcc.dg/ipa/ipacost-1.c: Prevent inlining
+ * gcc.dg/ipa/ipacost-2.c: Likewise.
+ * gcc.dg/vect/slp-3.c: Loop is no longer unrolled.
+
+2009-05-12 David Billinghurst <billingd@gcc.gnu.org>
+
+ * gfortran.dg/default_format_1.f90: XFAIL on cygwin.
+
+2009-05-12 David Billinghurst <billingd@gcc.gnu.org>
+
+ * lib/target-supports.exp (check_profiling_available): Return
+ false for -p on *-*-cygwin* targets.
+
2009-05-11 H.J. Lu <hongjiu.lu@intel.com>
PR tree-optimization/38632
diff --git a/gcc/testsuite/ada/acats/tests/c3/c38202a.ada b/gcc/testsuite/ada/acats/tests/c3/c38202a.ada
index e0b3b856476..d0350fc1fc9 100644
--- a/gcc/testsuite/ada/acats/tests/c3/c38202a.ada
+++ b/gcc/testsuite/ada/acats/tests/c3/c38202a.ada
@@ -30,6 +30,7 @@
-- AH 9/12/86
-- EDS 7/14/98 AVOID OPTIMIZATION
+with Impdef;
WITH REPORT; USE REPORT;
PROCEDURE C38202A IS
BEGIN
@@ -84,7 +85,7 @@ BEGIN
P.GO_ON;
ACCEPT TSK_DONE;
WHILE (NOT P'TERMINATED AND COUNTER <= 3) LOOP
- DELAY 10.0;
+ DELAY 10.0 * Impdef.One_Second;
COUNTER := COUNTER + 1;
END LOOP;
@@ -166,7 +167,7 @@ BEGIN
F1.ALL.GO_ON;
ACCEPT TSK_DONE;
WHILE (NOT F1'TERMINATED AND COUNTER <= 3) LOOP
- DELAY 10.0;
+ DELAY 10.0 * Impdef.One_Second;
COUNTER := COUNTER + 1;
END LOOP;
diff --git a/gcc/testsuite/ada/acats/tests/c5/c59002c.ada b/gcc/testsuite/ada/acats/tests/c5/c59002c.ada
index a81c1c1e9ce..cc01a7e6c3a 100644
--- a/gcc/testsuite/ada/acats/tests/c5/c59002c.ada
+++ b/gcc/testsuite/ada/acats/tests/c5/c59002c.ada
@@ -33,6 +33,7 @@
-- SPS 12/13/82
-- PWN 11/30/94 REMOVED PRAGMA PRIORITY INSTANCES FOR ADA 9X.
+with Impdef;
WITH REPORT;
WITH SYSTEM;
USE SYSTEM;
@@ -64,7 +65,7 @@ BEGIN
BEGIN
WHILE E2'COUNT <= 0 LOOP
- DELAY 1.0 ;
+ DELAY 1.0 * Impdef.One_Second;
END LOOP;
SELECT
@@ -76,7 +77,7 @@ BEGIN
GOTO L123 ;
FAILED( "'GOTO' NOT OBEYED (1)" );
OR
- DELAY 10.0 ;
+ DELAY 10.0 * Impdef.One_Second;
FAILED( "DELAY ALTERNATIVE SELECTED (1)" );
END SELECT;
@@ -116,7 +117,7 @@ BEGIN
FAILED( " E2 ACCEPTED; NO ENTRY CALL (2)" );
END ;
OR
- DELAY 10.0 ;
+ DELAY 10.0 * Impdef.One_Second;
GOTO L321 ;
FAILED( "'GOTO' NOT OBEYED (2)" );
END SELECT;
diff --git a/gcc/testsuite/g++.dg/abi/mangle11.C b/gcc/testsuite/g++.dg/abi/mangle11.C
index 6d09b51a6a1..a049a956671 100644
--- a/gcc/testsuite/g++.dg/abi/mangle11.C
+++ b/gcc/testsuite/g++.dg/abi/mangle11.C
@@ -1,10 +1,10 @@
// { dg-options "-Wabi -fabi-version=1" }
template <typename Q>
-void f (typename Q::X) {} // { dg-warning "mangle" }
+void f (typename Q::X) {}
struct S {
typedef int X;
};
-template void f<S> (int);
+template void f<S> (int); // { dg-warning "mangle" }
diff --git a/gcc/testsuite/g++.dg/abi/mangle12.C b/gcc/testsuite/g++.dg/abi/mangle12.C
index a3bd9ff6fa7..7176fcd28dc 100644
--- a/gcc/testsuite/g++.dg/abi/mangle12.C
+++ b/gcc/testsuite/g++.dg/abi/mangle12.C
@@ -1,11 +1,11 @@
// { dg-options "-Wabi -fabi-version=1" }
template <template <typename> class Q>
-void f (typename Q<int>::X) {} // { dg-warning "mangle" }
+void f (typename Q<int>::X) {}
template <typename Q>
struct S {
typedef int X;
};
-template void f<S> (int);
+template void f<S> (int); // { dg-warning "mangle" }
diff --git a/gcc/testsuite/g++.dg/abi/mangle17.C b/gcc/testsuite/g++.dg/abi/mangle17.C
index 134b976a271..0a5fe9a60e8 100644
--- a/gcc/testsuite/g++.dg/abi/mangle17.C
+++ b/gcc/testsuite/g++.dg/abi/mangle17.C
@@ -4,8 +4,8 @@ enum E { e = 3 };
template <int I> struct S {};
-template <int I> void f (S<I + e + int (3.7)>) {} // { dg-warning "mangle" }
-template void f<7>(S<7 + e + int (3.7)>);
+template <int I> void f (S<I + e + int (3.7)>) {}
+template void f<7>(S<7 + e + int (3.7)>); // { dg-warning "mangle" }
-template <int I> void g (S<I + e + int (3.7)>) {} // { dg-warning "mangle" }
-template void g<7>(S<7 + e + int (3.7)>);
+template <int I> void g (S<I + e + int (3.7)>) {}
+template void g<7>(S<7 + e + int (3.7)>); // { dg-warning "mangle" }
diff --git a/gcc/testsuite/g++.dg/abi/mangle20-2.C b/gcc/testsuite/g++.dg/abi/mangle20-2.C
index 38ac52371ab..bf3d189bf0c 100644
--- a/gcc/testsuite/g++.dg/abi/mangle20-2.C
+++ b/gcc/testsuite/g++.dg/abi/mangle20-2.C
@@ -7,10 +7,10 @@
// PR 9043
// mangled array types in templates
-template <int I> void f(int (*)[2]) {} // { dg-warning "mangled name" }
+template <int I> void f(int (*)[2]) {}
template <int I> void g(int (*)[I+2]) {}
-template void f<1>(int (*)[2]);
+template void f<1>(int (*)[2]); // { dg-warning "mangled name" }
// { dg-final { scan-assembler "\n_?_Z1fILi1EEvPALi2E_i\[: \t\n\]" } }
template void g<1>(int (*)[3]);
// { dg-final { scan-assembler "\n_?_Z1gILi1EEvPAplT_Li2E_i\[: \t\n\]" } }
diff --git a/gcc/testsuite/g++.dg/cpp0x/auto14.C b/gcc/testsuite/g++.dg/cpp0x/auto14.C
new file mode 100644
index 00000000000..cb2c4e0351a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/auto14.C
@@ -0,0 +1,29 @@
+// PR c++/40306, c++/40307
+// { dg-options "-std=c++0x" }
+// { dg-do run }
+
+template< typename T >
+struct test {
+ test run() {
+ auto tmp = *this;
+ return tmp;
+ }
+ test run_pass() {
+ test tmp( *this );
+ return tmp;
+ }
+
+ test run_fail() {
+ auto tmp( *this );
+ return tmp;
+ }
+};
+
+int main()
+{
+ test<int> x;
+ x.run();
+ x.run_pass();
+ x.run_fail();
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/auto15.C b/gcc/testsuite/g++.dg/cpp0x/auto15.C
new file mode 100644
index 00000000000..b23e1e2fd6f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/auto15.C
@@ -0,0 +1,13 @@
+// { dg-options "-std=c++0x" }
+
+template< typename Fn > struct function;
+
+template< typename Result, typename ... ArgTypes >
+struct function< auto (ArgTypes...)->Result > {
+};
+
+int main()
+{
+ function< auto(double)->int > y;
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/defaulted10.C b/gcc/testsuite/g++.dg/cpp0x/defaulted10.C
new file mode 100644
index 00000000000..d169e0c6007
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/defaulted10.C
@@ -0,0 +1,14 @@
+// PR c++/40381
+// { dg-options "-std=gnu++0x" }
+
+struct A
+{
+ template<typename T> void foo(T) = delete; // { dg-error "previously|deleted" }
+};
+
+template<typename T> void A::foo(T) {} // { dg-error "redefinition" }
+
+void bar()
+{
+ A().foo(0); // { dg-error "used" }
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/enum3.C b/gcc/testsuite/g++.dg/cpp0x/enum3.C
new file mode 100644
index 00000000000..5555ab2aac8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/enum3.C
@@ -0,0 +1,17 @@
+// PR c++/38064
+// { dg-options "-std=c++0x" }
+// { dg-do run }
+
+enum class E { elem };
+
+template <class T>
+void f (T t);
+
+bool f (bool b) { return b; }
+
+int main()
+{
+ E e = E::elem;
+ if (!f (e == E::elem))
+ return 1;
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/explicit1.C b/gcc/testsuite/g++.dg/cpp0x/explicit1.C
new file mode 100644
index 00000000000..fe164fc8cb1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/explicit1.C
@@ -0,0 +1,58 @@
+// Test for explicit conversion ops from N2437.
+// { dg-options "-std=c++0x" }
+
+class U; class V;
+class T
+{
+public:
+ T( U const & );
+ //implicit converting ctor
+ explicit T( V const & );
+ // explicit ctor
+};
+class U
+{
+};
+class V
+{
+};
+class W
+{
+public:
+ operator T() const;
+};
+class X
+{
+public:
+ explicit operator T() const; // theoretical
+};
+int main()
+{
+ U u; V v; W w; X x;
+ // Direct initialization:
+ T t1( u );
+ T t2( v );
+ T t3( w );
+ T t4( x );
+ // Copy initialization:
+ T t5 = u;
+ T t6 = v; // { dg-error "" }
+ T t7 = w;
+ T t8 = x; // { dg-error "" }
+ // Cast notation:
+ T t9 = (T) u;
+ T t10 = (T) v;
+ T t11 = (T) w;
+ T t12 = (T) x;
+ // Static cast:
+ T t13 = static_cast<T>( u );
+ T t14 = static_cast<T>( v );
+ T t15 = static_cast<T>( w );
+ T t16 = static_cast<T>( x );
+ // Function-style cast:
+ T t17 = T( u );
+ T t18 = T( v );
+ T t19 = T( w );
+ T t20 = T( x );
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/explicit2.C b/gcc/testsuite/g++.dg/cpp0x/explicit2.C
new file mode 100644
index 00000000000..c2327c140d8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/explicit2.C
@@ -0,0 +1,29 @@
+// Test for explicit conversion ops in various conversion situations.
+// { dg-options "-std=c++0x" }
+
+typedef void (*pfn)();
+
+struct A
+{
+ explicit operator int() const;
+ explicit operator pfn() const;
+};
+
+int main()
+{
+ A a;
+ int i = a; // { dg-error "" }
+ const int &ir = a; // { dg-error "" }
+ a(); // { dg-error "" }
+ a + 1; // { dg-message "" } (error and note on same line)
+
+ int j (a);
+ (int)a;
+ static_cast<int>(a);
+}
+
+struct B
+{
+ int i;
+ B(const A& a): i(a) { }
+};
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist13.C b/gcc/testsuite/g++.dg/cpp0x/initlist13.C
index 98af92bca53..9ed6c74419f 100644
--- a/gcc/testsuite/g++.dg/cpp0x/initlist13.C
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist13.C
@@ -2,4 +2,7 @@
// { dg-do compile }
// { dg-options "-std=gnu++0x" }
-__complex__ int i ({0}); // { dg-error "cannot convert" }
+#include <complex>
+
+__complex__ int i ({0});
+std::complex<int> i2 ({0});
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist15.C b/gcc/testsuite/g++.dg/cpp0x/initlist15.C
new file mode 100644
index 00000000000..d59e5af640b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist15.C
@@ -0,0 +1,17 @@
+// { dg-options "-std=c++0x" }
+
+#include <vector>
+#include <typeinfo>
+
+using namespace std;
+
+template< typename ... ArgTypes >
+void test( ArgTypes ... args ) {
+ vector<type_info*> x = { &typeid(ArgTypes)... }; // { dg-error "" }
+}
+
+int main()
+{
+ test( 1, 3.14f, 2.78 );
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist16.C b/gcc/testsuite/g++.dg/cpp0x/initlist16.C
new file mode 100644
index 00000000000..86a00396051
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist16.C
@@ -0,0 +1,12 @@
+// { dg-options "-std=c++0x" }
+// { dg-do run }
+
+extern "C" void abort();
+
+void f(int i) { if (i != 42) abort(); }
+
+int main()
+{
+ f({42});
+ return {0};
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist17.C b/gcc/testsuite/g++.dg/cpp0x/initlist17.C
new file mode 100644
index 00000000000..86371e81969
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist17.C
@@ -0,0 +1,9 @@
+// { dg-options "-std=c++0x" }
+
+void f(int i);
+
+int main()
+{
+ f({42.0}); // { dg-error "narrowing" }
+ return {1.0}; // { dg-error "narrowing" }
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist18.C b/gcc/testsuite/g++.dg/cpp0x/initlist18.C
new file mode 100644
index 00000000000..c9a9bcd9415
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist18.C
@@ -0,0 +1,19 @@
+// PR c++/40308, 40311
+// { dg-do run }
+// { dg-options "-std=c++0x" }
+
+template< typename T >
+struct test {
+ test() : data{} {}
+
+ T data;
+};
+
+int main()
+{
+ test<int> x;
+ test<int*> y;
+ int * a = new int{};
+ int * b = new int{5};
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist19.C b/gcc/testsuite/g++.dg/cpp0x/initlist19.C
new file mode 100644
index 00000000000..418cddc618a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist19.C
@@ -0,0 +1,8 @@
+// { dg-options "-std=c++0x" }
+
+void f(double);
+int main()
+{
+ f({{1}}); // { dg-error "too many braces" }
+ // { dg-error "" "" { target *-*-* } 6 } allow other errors, too
+}
diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/nested-1.C b/gcc/testsuite/g++.dg/debug/dwarf2/nested-1.C
new file mode 100644
index 00000000000..336582c112a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/debug/dwarf2/nested-1.C
@@ -0,0 +1,29 @@
+// Contributed by Dodji Seketeli <dodji@redhat.com>
+// Origin PR debug/40109
+// { dg-do compile }
+// { dg-options "-g -dA -O0" }
+
+namespace A
+{
+
+ class B
+ {
+ };
+ typedef A::B AB;
+};
+
+int
+main()
+{
+ A::AB ab;
+ return 0;
+}
+
+// { dg-final { scan-assembler "DW_TAG_typedef" } }
+//
+// What we want to do here is to be sure that the DIE of A::AB is generated
+// as a child of the DIE of the namespace A declaration.
+// So this test won't catch a regression on this fix yet. To write a proper
+// test for this fix, we would need a dwarf reader written in tcl,
+// or something along those lines.
+
diff --git a/gcc/testsuite/g++.dg/ext/dllexport2.C b/gcc/testsuite/g++.dg/ext/dllexport2.C
new file mode 100644
index 00000000000..71ccf670b4b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/dllexport2.C
@@ -0,0 +1,52 @@
+// { dg-do link }
+// { dg-require-dll "" }
+// { dg-additional-sources "dllexport2a.cc" }
+// { dg-options "-O2" }
+
+/* Test that inline functions declared "dllexport" appear in object
+ files, even if they are not called.
+
+ This behavior is required by the ARM C++ ABI:
+
+ Exporting a function that can be inlined should force the
+ creation and export of an out-of-line copy of it.
+
+ and should presumably also apply.
+
+ Visual Studio 2005 also honors that rule. */
+
+__declspec(dllexport) inline void i1() {}
+
+__declspec(dllexport) extern inline void e1() {}
+
+/* It is invalid to declare the function inline after its definition. */
+#if 0
+__declspec(dllexport) void i2() {}
+inline void i2();
+
+__declspec(dllexport) extern void e2() {}
+inline void e2();
+#endif
+
+__declspec(dllexport) inline void i3() {}
+void i3();
+
+__declspec(dllexport) inline void e3() {}
+extern void e3();
+
+__declspec(dllexport) void i4();
+inline void i4() {};
+
+__declspec(dllexport) extern void e4();
+inline void e4() {};
+
+__declspec(dllexport) inline void i5();
+void i5() {};
+
+__declspec(dllexport) inline void e5();
+extern void e5() {};
+
+/* Make sure that just declaring the function -- without defining it
+ -- does not cause errors. */
+__declspec(dllexport) inline void i6();
+__declspec(dllexport) extern inline void e6();
diff --git a/gcc/testsuite/g++.dg/ext/dllexport2a.cc b/gcc/testsuite/g++.dg/ext/dllexport2a.cc
new file mode 100644
index 00000000000..80caf321742
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/dllexport2a.cc
@@ -0,0 +1,21 @@
+extern void i1();
+extern void i3();
+extern void i4();
+extern void i5();
+
+extern void e1();
+extern void e3();
+extern void e4();
+extern void e5();
+
+int main () {
+ i1();
+ i3();
+ i4();
+ i5();
+
+ e1();
+ e3();
+ e4();
+ e5();
+}
diff --git a/gcc/testsuite/g++.dg/ext/packed6.C b/gcc/testsuite/g++.dg/ext/packed6.C
index f89aafec163..6a176b62442 100644
--- a/gcc/testsuite/g++.dg/ext/packed6.C
+++ b/gcc/testsuite/g++.dg/ext/packed6.C
@@ -1,7 +1,7 @@
// PR c++/15209
// { dg-options "-w" }
-typedef unsigned int size_t;
+__extension__ typedef __SIZE_TYPE__ size_t;
typedef unsigned char uint8_t;
typedef unsigned short int uint16_t;
diff --git a/gcc/testsuite/g++.dg/ext/vector16.C b/gcc/testsuite/g++.dg/ext/vector16.C
new file mode 100644
index 00000000000..7964a881f4a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/vector16.C
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+#define vector __attribute__((vector_size(4*sizeof(int)) ))
+
+vector int a, b, c;
+
+
+/* Test that remainder works for vectors. */
+void f(void)
+{
+ a = b % c;
+}
diff --git a/gcc/testsuite/g++.dg/init/ref15.C b/gcc/testsuite/g++.dg/init/ref15.C
index d3a94227fd0..bc9c01dc229 100644
--- a/gcc/testsuite/g++.dg/init/ref15.C
+++ b/gcc/testsuite/g++.dg/init/ref15.C
@@ -1,6 +1,8 @@
// PR c++/20416. We correctly constructed the temporary S in foo(),
// but incorrectly destroyed it every time foo() was called.
-// { dg-do run }
+// When using a wrapped target, there is no way to override the exit
+// code after returning from main.
+// { dg-do run { target unwrapped } }
extern "C" void abort (void);
extern "C" void _exit (int);
diff --git a/gcc/testsuite/g++.dg/opt/memcpy1.C b/gcc/testsuite/g++.dg/opt/memcpy1.C
index f9887ee2314..f2913459973 100644
--- a/gcc/testsuite/g++.dg/opt/memcpy1.C
+++ b/gcc/testsuite/g++.dg/opt/memcpy1.C
@@ -6,7 +6,7 @@
typedef unsigned char uint8_t;
typedef uint8_t uint8;
-typedef long unsigned int size_t;
+__extension__ typedef __SIZE_TYPE__ size_t;
class csVector2
{
public:float x;
diff --git a/gcc/testsuite/g++.dg/other/pr40446.C b/gcc/testsuite/g++.dg/other/pr40446.C
new file mode 100644
index 00000000000..33dbcec7159
--- /dev/null
+++ b/gcc/testsuite/g++.dg/other/pr40446.C
@@ -0,0 +1,46 @@
+// PR middle-end/40446
+// { dg-do run { target i?86-*-* x86_64-*-* } }
+// { dg-options "-O1 -msse2" }
+
+#include <emmintrin.h>
+#include "cpuid.h"
+
+extern "C" void abort ();
+
+struct S
+{
+ S (double r, double i) { __real__ s = r; __imag__ s = i; }
+ __complex__ double s;
+};
+
+__m128d
+foo ()
+{
+ S c (0, 1);
+ return _mm_load_pd ((double *) &c);
+}
+
+static void
+__attribute__((noinline))
+sse2_test ()
+{
+ union { __m128d vec; double val[2]; } u;
+ u.vec = foo ();
+ if (u.val[0] != 0 || u.val[1] != 1)
+ abort ();
+}
+
+int
+main ()
+{
+ unsigned int eax, ebx, ecx, edx;
+
+ if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
+ return 0;
+
+ /* Run SSE2 test only if host has SSE2 support. */
+ if (edx & bit_SSE2)
+ sse2_test ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/plugin/attribute_plugin-test-1.C b/gcc/testsuite/g++.dg/plugin/attribute_plugin-test-1.C
new file mode 100644
index 00000000000..abb1328670a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/plugin/attribute_plugin-test-1.C
@@ -0,0 +1,16 @@
+// { dg-warning "Callback to register attributes" }
+
+void normal_func (char c, char c2);
+void normal_func (char __attribute__((user("param"))) c, char);
+void normal_func (char c, char __attribute__((user("param"))) c2)
+{
+} // { dg-warning "attribute 'user' on param 'c' of function normal_func" }
+// { dg-warning "attribute 'user' on param 'c2' of function normal_func" "" { target *-*-* } 7 }
+
+class Foo {
+ void method (char __attribute__((user("param"))) c);
+};
+
+void Foo::method(char c)
+{
+} // { dg-warning "attribute 'user' on param 'c' of function method" }
diff --git a/gcc/testsuite/g++.dg/plugin/attribute_plugin.c b/gcc/testsuite/g++.dg/plugin/attribute_plugin.c
new file mode 100644
index 00000000000..16b34964350
--- /dev/null
+++ b/gcc/testsuite/g++.dg/plugin/attribute_plugin.c
@@ -0,0 +1,66 @@
+/* Demonstrates how to add custom attributes */
+
+#include "gcc-plugin.h"
+#include <stdlib.h>
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tree.h"
+#include "tree-pass.h"
+#include "intl.h"
+
+/* Attribute handler callback */
+
+static tree
+handle_user_attribute (tree *node, tree name, tree args,
+ int flags, bool *no_add_attrs)
+{
+ return NULL_TREE;
+}
+
+/* Attribute definition */
+
+static struct attribute_spec user_attr =
+ { "user", 1, 1, false, false, false, handle_user_attribute };
+
+/* Plugin callback called during attribute registration */
+
+static void
+register_attributes (void *event_data, void *data)
+{
+ warning (0, G_("Callback to register attributes"));
+ register_attribute (&user_attr);
+}
+
+/* Callback function to invoke before the function body is genericized. */
+
+void
+handle_pre_generic (void *event_data, void *data)
+{
+ tree fndecl = (tree) event_data;
+ tree arg;
+ for (arg = DECL_ARGUMENTS(fndecl); arg; arg = TREE_CHAIN (arg)) {
+ tree attr;
+ for (attr = DECL_ATTRIBUTES (arg); attr; attr = TREE_CHAIN (attr)) {
+ tree attrname = TREE_PURPOSE (attr);
+ tree attrargs = TREE_VALUE (attr);
+ warning (0, G_("attribute '%s' on param '%s' of function %s"),
+ IDENTIFIER_POINTER (attrname),
+ IDENTIFIER_POINTER (DECL_NAME (arg)),
+ IDENTIFIER_POINTER (DECL_NAME (fndecl))
+ );
+ }
+ }
+}
+
+int
+plugin_init (struct plugin_name_args *plugin_info,
+ struct plugin_gcc_version *version)
+{
+ const char *plugin_name = plugin_info->base_name;
+ register_callback (plugin_name, PLUGIN_CXX_CP_PRE_GENERICIZE,
+ handle_pre_generic, NULL);
+
+ register_callback (plugin_name, PLUGIN_ATTRIBUTES, register_attributes, NULL);
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/plugin/dumb_plugin.c b/gcc/testsuite/g++.dg/plugin/dumb_plugin.c
index 0c62f89e109..24da5440391 100644
--- a/gcc/testsuite/g++.dg/plugin/dumb_plugin.c
+++ b/gcc/testsuite/g++.dg/plugin/dumb_plugin.c
@@ -1,6 +1,7 @@
/* A trivial (dumb) plugin example that shows how to use the GCC plugin
mechanism. */
+#include "gcc-plugin.h"
#include <stdlib.h>
#include "config.h"
#include "system.h"
@@ -8,7 +9,6 @@
#include "tree.h"
#include "tree-pass.h"
#include "intl.h"
-#include "gcc-plugin.h"
/* Callback function to invoke after GCC finishes parsing a struct. */
@@ -21,7 +21,7 @@ handle_struct (void *event_data, void *data)
IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
}
-/* Callback function to invoke before the program is genericized. */
+/* Callback function to invoke before the function body is genericized. */
void
handle_pre_generic (void *event_data, void *data)
@@ -78,11 +78,13 @@ static struct gimple_opt_pass pass_dumb_plugin_example =
both of which determine where the plugin pass should be inserted. */
int
-plugin_init (const char *plugin_name,
- struct plugin_gcc_version *version __attribute__((unused)),
- int argc, struct plugin_argument *argv)
+plugin_init (struct plugin_name_args *plugin_info,
+ struct plugin_gcc_version *version)
{
struct plugin_pass pass_info;
+ const char *plugin_name = plugin_info->base_name;
+ int argc = plugin_info->argc;
+ struct plugin_argument *argv = plugin_info->argv;
char *ref_pass_name = NULL;
int ref_instance_number = 0;
int i;
diff --git a/gcc/testsuite/g++.dg/plugin/plugin.exp b/gcc/testsuite/g++.dg/plugin/plugin.exp
index e1f6d89ae28..eb019986ffe 100644
--- a/gcc/testsuite/g++.dg/plugin/plugin.exp
+++ b/gcc/testsuite/g++.dg/plugin/plugin.exp
@@ -47,6 +47,7 @@ load_lib plugin-support.exp
# Specify the plugin source file and the associated test files in a list.
# plugin_test_list={ {plugin1 test1 test2 ...} {plugin2 test1 ...} ... }
set plugin_test_list [list \
+ { attribute_plugin.c attribute_plugin-test-1.C } \
{ selfassign.c self-assign-test-1.C self-assign-test-2.C self-assign-test-3.C } \
{ dumb_plugin.c dumb-plugin-test-1.C } ]
diff --git a/gcc/testsuite/g++.dg/plugin/selfassign.c b/gcc/testsuite/g++.dg/plugin/selfassign.c
index 6fbce83c01d..2bc1d861358 100644
--- a/gcc/testsuite/g++.dg/plugin/selfassign.c
+++ b/gcc/testsuite/g++.dg/plugin/selfassign.c
@@ -2,6 +2,7 @@
self-assignment statements. */
/* { dg-options "-O" } */
+#include "gcc-plugin.h"
#include "config.h"
#include "system.h"
#include "coretypes.h"
@@ -12,7 +13,6 @@
#include "tree.h"
#include "tree-pass.h"
#include "intl.h"
-#include "gcc-plugin.h"
/* Indicate whether to check overloaded operator '=', which is performed by
@@ -294,10 +294,13 @@ static struct gimple_opt_pass pass_warn_self_assign =
Note that this function needs to be named exactly "plugin_init". */
int
-plugin_init (const char *plugin_name, struct plugin_gcc_version *version,
- int argc, struct plugin_argument *argv)
+plugin_init (struct plugin_name_args *plugin_info,
+ struct plugin_gcc_version *version)
{
struct plugin_pass pass_info;
+ const char *plugin_name = plugin_info->base_name;
+ int argc = plugin_info->argc;
+ struct plugin_argument *argv = plugin_info->argv;
bool enabled = true;
int i;
diff --git a/gcc/testsuite/g++.dg/pr37742.C b/gcc/testsuite/g++.dg/pr37742.C
index 784eb498487..2bbb01723fb 100644
--- a/gcc/testsuite/g++.dg/pr37742.C
+++ b/gcc/testsuite/g++.dg/pr37742.C
@@ -1,6 +1,6 @@
/* { dg-do compile } */
-typedef long unsigned int size_t;
+__extension__ typedef __SIZE_TYPE__ size_t;
void* __valarray_get_memory(size_t __n);
int*__restrict__
__valarray_get_storage(size_t __n)
diff --git a/gcc/testsuite/g++.dg/template/access11.C b/gcc/testsuite/g++.dg/template/access11.C
index 38bd5155f65..c9364a82399 100644
--- a/gcc/testsuite/g++.dg/template/access11.C
+++ b/gcc/testsuite/g++.dg/template/access11.C
@@ -17,7 +17,7 @@ template <> struct X::Y<int> {
A::X x; // { dg-error "this context" }
};
-template <typename T> struct X::Y { // { dg-error "this context" }
+template <typename T> struct X::Y {
typename T::X x; // { dg-error "this context" }
};
diff --git a/gcc/testsuite/g++.dg/template/canon-type-1.C b/gcc/testsuite/g++.dg/template/canon-type-1.C
new file mode 100644
index 00000000000..2a36dc09951
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/canon-type-1.C
@@ -0,0 +1,18 @@
+// Contributed by Dodji Seketeli <dodji@redhat.com>
+// Origin PR c++/39754
+// { dg-do "compile" }
+
+template < typename > struct A ;
+template < typename T , typename = A < T > > struct B { } ;
+template < class W , class > struct D
+{
+ typedef W X ;
+ A<X*> a ;
+};
+
+template < class Y > struct E
+{
+ B<Y*> b ;
+} ;
+E<int> e ;
+
diff --git a/gcc/testsuite/g++.dg/template/canon-type-2.C b/gcc/testsuite/g++.dg/template/canon-type-2.C
new file mode 100644
index 00000000000..dd23ec5ea6d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/canon-type-2.C
@@ -0,0 +1,18 @@
+// Contributed by Dodji Seketeli <dodji@redhat.com>
+// Origin PR c++/39754
+// { dg-do "compile" }
+
+template < typename > struct A ;
+template < typename T , typename = A < T > > struct B { } ;
+template < class W , class > struct D
+{
+ typedef W X ;
+ A< X()> a ;
+};
+
+template < class Y > struct E
+{
+ B< Y()> b ;
+};
+E<int> e ;
+
diff --git a/gcc/testsuite/g++.dg/template/canon-type-3.C b/gcc/testsuite/g++.dg/template/canon-type-3.C
new file mode 100644
index 00000000000..a43169addc5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/canon-type-3.C
@@ -0,0 +1,20 @@
+// Contributed by Dodji Seketeli <dodji@redhat.com>
+// Origin PR c++/39754
+// { dg-do "compile" }
+
+template<typename> struct A ;
+template<typename T , typename = A<T> > struct B { } ;
+template<class W , class > struct D
+{
+ typedef W X ;
+ typedef X (FP) ();
+ A<FP&> a ;
+} ;
+
+template < class Y > struct E
+{
+ typedef Y (FP) ();
+ B<FP&> b ;
+} ;
+E < int > e ;
+
diff --git a/gcc/testsuite/g++.dg/template/canon-type-4.C b/gcc/testsuite/g++.dg/template/canon-type-4.C
new file mode 100644
index 00000000000..ec5e1e6a200
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/canon-type-4.C
@@ -0,0 +1,22 @@
+// Contributed by Dodji Seketeli <dodji@redhat.com>
+// Origin PR c++/39754
+// { dg-do "compile" }
+
+template<typename> struct A ;
+template<typename T ,typename = A<T> > struct B { } ;
+
+template<class W, class>
+struct D
+{
+ typedef W X;
+ A<X[2]> a;
+} ;
+
+template<class Y>
+struct E
+{
+ B<Y[2]> b;
+};
+
+E < int > e;
+
diff --git a/gcc/testsuite/g++.dg/template/canon-type-5.C b/gcc/testsuite/g++.dg/template/canon-type-5.C
new file mode 100644
index 00000000000..7331c3086fb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/canon-type-5.C
@@ -0,0 +1,22 @@
+// Contributed by Dodji Seketeli <dodji@redhat.com>
+// Origin PR c++/39754
+// { dg-do "compile" }
+
+struct Foo {};
+template<typename> struct A ;
+template<typename T ,typename = A<T> > struct B { } ;
+
+template<class W, class>
+struct D
+{
+ typedef W X ;
+ A<X Foo::*> a ;
+} ;
+
+template<class Y>
+struct E
+{
+ B<Y Foo::*> b ;
+} ;
+E < int > e ;
+
diff --git a/gcc/testsuite/g++.dg/template/canon-type-6.C b/gcc/testsuite/g++.dg/template/canon-type-6.C
new file mode 100644
index 00000000000..5065c395dc4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/canon-type-6.C
@@ -0,0 +1,22 @@
+// Contributed by Dodji Seketeli <dodji@redhat.com>
+// Origin PR c++/39754
+// { dg-do "compile" }
+
+struct Foo {};
+template<typename> struct A ;
+template<typename T ,typename = A<T> > struct B { } ;
+
+template<class W, class>
+struct D
+{
+ typedef W X;
+ A<void (Foo::*) (X)> a;
+} ;
+
+template<class Y>
+struct E
+{
+ B<void (Foo::*) (Y)> b;
+};
+E < int > e ;
+
diff --git a/gcc/testsuite/g++.dg/template/canon-type-7.C b/gcc/testsuite/g++.dg/template/canon-type-7.C
new file mode 100644
index 00000000000..80e8f87e834
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/canon-type-7.C
@@ -0,0 +1,21 @@
+// Contributed by Dodji Seketeli <dodji@redhat.com>
+// Origin PR c++/39754
+// { dg-do "compile" }
+
+struct Foo {};
+template<typename> struct A ;
+template<typename T ,typename = A<T> > struct B { } ;
+
+template<class W, class>
+struct D
+{
+ typedef W X;
+ A<X (Foo::*) (X)> a ;
+};
+
+template<class Y>
+struct E
+{
+ B<Y (Foo::*) (Y)> b ;
+};
+E<int> e ;
diff --git a/gcc/testsuite/g++.dg/template/dtor6.C b/gcc/testsuite/g++.dg/template/dtor6.C
new file mode 100644
index 00000000000..c44b780294c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/dtor6.C
@@ -0,0 +1,16 @@
+// PR c++/40139
+
+template<int> struct A
+{
+ static int i;
+};
+
+template<int N> int A<N>::i = { A::~A }; // { dg-error "non-static member function" }
+
+template class A<0>;
+
+struct X { };
+
+int i1 = X::~X; // { dg-error "non-static member function" }
+int i2 = &X::~X; // { dg-error "address of destructor" }
+int i3 = &A<0>::~A; // { dg-error "address of destructor" }
diff --git a/gcc/testsuite/g++.dg/template/dtor7.C b/gcc/testsuite/g++.dg/template/dtor7.C
new file mode 100644
index 00000000000..0dac69e8948
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/dtor7.C
@@ -0,0 +1,24 @@
+// PR c++/40373
+// { dg-compile }
+
+struct A; // { dg-bogus "candidates are" "" { xfail *-*-* } }
+namespace
+{
+ struct A; // { dg-bogus "struct" "" { xfail *-*-* } }
+}
+
+struct B {};
+
+template <typename T> void
+foo (T t)
+{
+ t.~A (); // { dg-error "does not match destructor name" }
+}
+
+void
+bar ()
+{
+ foo (B ()); // { dg-bogus "instantiated from here" "" { xfail *-*-* } }
+}
+
+// { dg-bogus "is ambiguous" "" { xfail *-*-* } 15 }
diff --git a/gcc/testsuite/g++.dg/template/error38.C b/gcc/testsuite/g++.dg/template/error38.C
index e26345f29a3..6c25b9f9c0f 100644
--- a/gcc/testsuite/g++.dg/template/error38.C
+++ b/gcc/testsuite/g++.dg/template/error38.C
@@ -26,6 +26,7 @@ void f (T &t, int = 0); // { dg-message "" }
typedef int myint;
myint i;
+myint *p;
int main()
{
@@ -34,4 +35,5 @@ int main()
a.g(); // { dg-error "" }
f(i); // { dg-error "" }
+ f(p); // { dg-error "" }
}
diff --git a/gcc/testsuite/g++.dg/template/error41.C b/gcc/testsuite/g++.dg/template/error41.C
new file mode 100644
index 00000000000..c92b8497aff
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/error41.C
@@ -0,0 +1,12 @@
+// PR c++/40370
+// { dg-do compile }
+
+struct A
+{
+ static int i;
+};
+
+template <int> struct B
+{
+ int x[A::i]; // { dg-error "array bound is not an integer constant" }
+};
diff --git a/gcc/testsuite/g++.dg/template/error42.C b/gcc/testsuite/g++.dg/template/error42.C
new file mode 100644
index 00000000000..0d651e31620
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/error42.C
@@ -0,0 +1,20 @@
+// PR c++/40372
+// { dg-do compile }
+
+template <int> struct A
+{
+ int i; // { dg-error "invalid use of non-static data member" }
+ friend void foo ()
+ {
+ int x[i]; // { dg-error "from this location" }
+ }
+};
+
+struct B
+{
+ int j; // { dg-error "invalid use of non-static data member" }
+ friend int bar ()
+ {
+ return j; // { dg-error "from this location" }
+ }
+};
diff --git a/gcc/testsuite/g++.dg/template/spec36.C b/gcc/testsuite/g++.dg/template/spec36.C
new file mode 100644
index 00000000000..71ff3a5c545
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/spec36.C
@@ -0,0 +1,16 @@
+/* PR c++/38089 */
+/* { dg-do "compile" } */
+
+struct basic_string
+{
+ basic_string(const int __s);
+};
+namespace MyNS {
+ class MyClass {
+ template <typename T>
+ T test() { } /* { dg-error "from definition" } */
+ };
+}
+template <>
+basic_string MyNS::MyClass::test() /* { dg-error "specialization of" } */
+{ return 1; }
diff --git a/gcc/testsuite/g++.dg/template/typedef18.C b/gcc/testsuite/g++.dg/template/typedef18.C
new file mode 100644
index 00000000000..8ea3c736a0a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/typedef18.C
@@ -0,0 +1,24 @@
+// Contributed by Dodji Seketeli <dodji@redhat.com>
+// Origin PR c++/40007
+// { dg-do compile }
+
+template<typename T>
+struct x
+{
+ protected:
+ typedef int type;
+};
+
+template<typename T>
+struct y : public x<T>
+{
+ typename x<T>::type z;
+};
+
+template<>
+struct y<void> : public x<void>
+{
+ typedef x<void>::type z;
+};
+
+template class y<int>;
diff --git a/gcc/testsuite/g++.dg/template/typedef19.C b/gcc/testsuite/g++.dg/template/typedef19.C
new file mode 100644
index 00000000000..f576d4828e4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/typedef19.C
@@ -0,0 +1,21 @@
+// Contributed by Dodji Seketeli <dodji@redhat.com>
+// Origin PR c++/40007
+// { dg-do compile }
+
+class A
+{
+ typedef int mytype; // { dg-error "'typedef int A::mytype' is private" }
+};
+
+template <class T>
+class B : public A
+{
+};
+
+template<class T>
+class B<T*> : public A
+{ // { dg-error "within this context" }
+ mytype mem;
+};
+
+B<int*> b;
diff --git a/gcc/testsuite/g++.dg/template/typedef20.C b/gcc/testsuite/g++.dg/template/typedef20.C
new file mode 100644
index 00000000000..a5cbdeb236b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/typedef20.C
@@ -0,0 +1,27 @@
+// Contributed by Dodji Seketeli <dodji@redhat.com>
+// Origin PR c++/40007
+// { dg-do compile }
+
+class x
+{
+ typedef int privtype; // { dg-error "is private" }
+
+protected:
+ typedef int type;
+};
+
+template<typename T>
+struct y : public x
+{
+ typename x::type z;
+};
+
+template<typename T>
+struct y<T*> : public x
+{ // { dg-error "within this context" }
+ typedef x::type good;
+ typedef x::privtype bad;
+};
+
+template class y<int>;
+template class y<int*>;
diff --git a/gcc/testsuite/g++.dg/torture/20070621-1.C b/gcc/testsuite/g++.dg/torture/20070621-1.C
index d17db9763ae..185314a47ca 100644
--- a/gcc/testsuite/g++.dg/torture/20070621-1.C
+++ b/gcc/testsuite/g++.dg/torture/20070621-1.C
@@ -6,7 +6,7 @@
*/
-typedef long int ptrdiff_t;
+__extension__ typedef __PTRDIFF_TYPE__ ptrdiff_t;
namespace std __attribute__ ((__visibility__ ("default"))) {
template<typename, typename> struct __are_same {
enum {
diff --git a/gcc/testsuite/g++.dg/torture/pr31579.C b/gcc/testsuite/g++.dg/torture/pr31579.C
index 1effa66d25c..131532e6360 100644
--- a/gcc/testsuite/g++.dg/torture/pr31579.C
+++ b/gcc/testsuite/g++.dg/torture/pr31579.C
@@ -5,6 +5,6 @@
struct Industry {
unsigned char produced_cargo[2];
};
-unsigned int a = (((unsigned long)&reinterpret_cast<const volatile
+unsigned int a = (((__SIZE_TYPE__)&reinterpret_cast<const volatile
char&>((((Industry*)(char*)8)->produced_cargo[0]))) - 8);
diff --git a/gcc/testsuite/g++.dg/torture/pr32950.C b/gcc/testsuite/g++.dg/torture/pr32950.C
new file mode 100644
index 00000000000..8d64296e40b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr32950.C
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+
+struct A
+{
+ __complex__ double c;
+};
+
+struct B
+{
+ A a;
+ B(A x) : a(x) {}
+ void foo();
+};
+
+void bar()
+{
+ B b = A();
+ B(b).foo();
+}
diff --git a/gcc/testsuite/g++.dg/torture/pr34222.C b/gcc/testsuite/g++.dg/torture/pr34222.C
index 1939b5015b1..130896dc9da 100644
--- a/gcc/testsuite/g++.dg/torture/pr34222.C
+++ b/gcc/testsuite/g++.dg/torture/pr34222.C
@@ -3,7 +3,7 @@
namespace std __attribute__ ((__visibility__ ("default"))) {
template<class _CharT> struct char_traits;
}
-typedef long int ptrdiff_t;
+__extension__ typedef __PTRDIFF_TYPE__ ptrdiff_t;
namespace std __attribute__ ((__visibility__ ("default"))) {
typedef ptrdiff_t streamsize;
template<typename _CharT, typename _Traits = char_traits<_CharT> > class basic_ifstream;
diff --git a/gcc/testsuite/g++.dg/torture/pr34850.C b/gcc/testsuite/g++.dg/torture/pr34850.C
index e7caa7b6638..88df5a3382b 100644
--- a/gcc/testsuite/g++.dg/torture/pr34850.C
+++ b/gcc/testsuite/g++.dg/torture/pr34850.C
@@ -5,7 +5,7 @@ typedef unsigned char uint8_t;
typedef unsigned int uint32_t;
typedef uint8_t byte;
typedef uint32_t u32bit;
-typedef unsigned int size_t;
+__extension__ typedef __SIZE_TYPE__ size_t;
extern "C" {
extern void __warn_memset_zero_len (void) __attribute__((__warning__ ("")));
extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__, __artificial__))
diff --git a/gcc/testsuite/g++.dg/torture/pr40102.C b/gcc/testsuite/g++.dg/torture/pr40102.C
new file mode 100644
index 00000000000..49f56b5bc5a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr40102.C
@@ -0,0 +1,41 @@
+/* { dg-do compile } */
+bool foo0(int) { return true; }
+
+bool foo1();
+
+struct A
+{
+ A();
+ ~A();
+
+ template<typename T> void bar1(T f)
+ {
+ if (f(0))
+ foo1();
+ }
+
+ template<typename T> void bar2(T);
+};
+
+template<typename T> void A::bar2(T f)
+{
+ A a, b[1], *p;
+
+ while (foo1())
+ {
+ if (p)
+ ++p;
+ if (p && foo1())
+ bar1(f);
+ if (p)
+ ++p;
+ }
+
+ if (foo1())
+ bar1(f);
+}
+
+void baz()
+{
+ A().bar2(foo0);
+}
diff --git a/gcc/testsuite/g++.dg/torture/pr40323.C b/gcc/testsuite/g++.dg/torture/pr40323.C
new file mode 100644
index 00000000000..adecf7fe5f3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr40323.C
@@ -0,0 +1,68 @@
+/* Testcase for PR 40323. */
+/* { dg-do compile } */
+/* { dg-options "-fno-early-inlining" } */
+/* { dg-options "-fno-early-inlining -fpie" { target { ! nonpic } } } */
+
+extern void do_something (const char *, int);
+
+class Parent
+{
+private:
+ const char *data;
+
+public:
+ Parent (const char *d) : data(d)
+ {}
+
+ int funcOne (int delim) const;
+};
+
+class AnotherParent
+{
+private:
+ double d;
+public:
+ AnotherParent (void) : d(0)
+ {}
+};
+
+
+class Child : public AnotherParent, Parent
+{
+private:
+ int zzz;
+public:
+ Child (const char *d) : Parent(d)
+ {}
+};
+
+
+int Parent::funcOne (int delim) const
+{
+ int i;
+ for (i = 0; i < delim; i++)
+ do_something(data, i);
+
+ return 1;
+}
+
+int docalling (int (Child::* f)(int delim) const)
+{
+ Child S ("muhehehe");
+
+ return (S.*f)(4);
+}
+
+typedef int (Parent::* my_mp_type)(int delim);
+
+int main (int argc, char *argv[])
+{
+ int i;
+ int (Parent::* f)(int ) const;
+ int (Child::* g)(int ) const;
+
+ f = &Parent::funcOne;
+ g = (int (Child::* )(int) const) f;
+ i = docalling (g);
+ return i;
+}
diff --git a/gcc/testsuite/g++.dg/torture/pr40335.C b/gcc/testsuite/g++.dg/torture/pr40335.C
new file mode 100644
index 00000000000..14ea95d4086
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr40335.C
@@ -0,0 +1,16 @@
+/* { dg-do run } */
+
+extern "C" void abort (void);
+int
+main (void)
+{
+ int i = -1;
+ switch ((signed char) i)
+ {
+ case 255: /* { dg-bogus "exceeds maximum value" "" { xfail *-*-* } } */
+ abort ();
+ default:
+ break;
+ }
+}
+
diff --git a/gcc/testsuite/g++.dg/torture/pr40389.C b/gcc/testsuite/g++.dg/torture/pr40389.C
new file mode 100644
index 00000000000..e3ceb1238b6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr40389.C
@@ -0,0 +1,84 @@
+/* { dg-do run } */
+
+template <typename V> struct S
+{
+ V *f, *l;
+ __attribute__ ((noinline)) S (void) { f = 0, l = 0; }
+ void foo (V *x)
+ {
+ if (x->p != 0)
+ x->p->n = x->n;
+ else
+ f = x->n;
+ if (x->n != 0)
+ x->n->p = x->p;
+ else
+ l = x->p;
+ }
+ __attribute__ ((noinline)) void bar (V *x)
+ {
+ x->n = 0;
+ x->p = l;
+ if (l != 0)
+ l->n = x;
+ else
+ f = x;
+ l = x;
+ }
+};
+
+struct H;
+
+struct A
+{
+ S <H> k;
+};
+
+struct H
+{
+ A *a;
+ H *p, *n;
+ __attribute__ ((noinline)) H (void) { p = 0, n = 0, a = 0; }
+ __attribute__ ((noinline)) H (A *b) : a (b)
+ {
+ p = 0;
+ n = 0;
+ if (a != 0)
+ a->k.bar (this);
+ }
+ __attribute__ ((noinline)) H (const H &h) : a (h.a)
+ {
+ p = 0;
+ n = 0;
+ if (a != 0)
+ a->k.bar (this);
+ }
+ ~H (void) { if (a != 0) a->k.foo (this); }
+ H &operator= (const H &o)
+ {
+ if (a != 0 || &o == this)
+ __builtin_abort ();
+ a = o.a;
+ if (a != 0)
+ a->k.bar (this);
+ return *this;
+ }
+};
+
+__attribute__ ((noinline))
+H baz (void)
+{
+ return H (new A);
+}
+
+H g;
+
+int
+main (void)
+{
+ g = baz ();
+ if (g.a->k.f != &g)
+ __builtin_abort ();
+ return 0;
+}
+
diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr22444.C b/gcc/testsuite/g++.dg/tree-ssa/pr22444.C
index 2cc84bb9d1e..7df4b9cce15 100644
--- a/gcc/testsuite/g++.dg/tree-ssa/pr22444.C
+++ b/gcc/testsuite/g++.dg/tree-ssa/pr22444.C
@@ -4,8 +4,8 @@
// with the subvars leading to the subvars not being renamed when they should
// { dg-do compile }
// { dg-options "-O2" }
-typedef int ptrdiff_t;
-typedef unsigned int size_t;
+__extension__ typedef __PTRDIFF_TYPE__ ptrdiff_t;
+__extension__ typedef __SIZE_TYPE__ size_t;
namespace std
{
template<class _T1, class _T2> struct pair
diff --git a/gcc/testsuite/g++.dg/warn/Wcast-qual2.C b/gcc/testsuite/g++.dg/warn/Wcast-qual2.C
new file mode 100644
index 00000000000..88fdcfb38f5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wcast-qual2.C
@@ -0,0 +1,167 @@
+/* { dg-do compile } */
+/* { dg-options "-Wcast-qual" } */
+
+/* The files gcc.dg/cast-qual-3.c and g++.dg/warn/Wcast-qual2.c are
+ duals. they are intended to show that gcc -Wcast-qual and g++
+ -Wcast-qual emit warnings in the same cases. If you change this
+ file, please also change the other one. */
+
+void
+f1 (void *bar)
+{
+ const void *p1 = (const void *) bar;
+ const char *p2 = (const char *) bar;
+ const void **p3 = (const void **) bar;
+ const char **p4 = (const char **) bar;
+ const void * const *p5 = (const void * const *) bar;
+ const char * const *p6 = (const char * const *) bar;
+ void * const *p7 = (void * const *) bar;
+ char * const *p8 = (char * const *) bar;
+ const void ***p9 = (const void ***) bar;
+ const char ***p10 = (const char ***) bar;
+ void * const **p11 = (void * const **) bar;
+ char * const **p12 = (char * const **) bar;
+ void ** const *p13 = (void ** const *) bar;
+ char ** const *p14 = (char ** const *) bar;
+ const void * const **p15 = (const void * const **) bar;
+ const char * const **p16 = (const char * const **) bar;
+ const void ** const *p17 = (const void ** const *) bar;
+ const char ** const *p18 = (const char ** const *) bar;
+ void * const * const * p19 = (void * const * const *) bar;
+ char * const * const * p20 = (char * const * const *) bar;
+ const void * const * const *p21 = (const void * const * const *) bar;
+ const char * const * const *p22 = (const char * const * const *) bar;
+}
+
+void
+f2 (void **bar)
+{
+ const void *p1 = (const void *) bar;
+ const char *p2 = (const char *) bar;
+ const void **p3 = (const void **) bar; /* { dg-warning "cast" } */
+ const char **p4 = (const char **) bar;
+ const void * const *p5 = (const void * const *) bar;
+ const char * const *p6 = (const char * const *) bar;
+ void * const *p7 = (void * const *) bar;
+ char * const *p8 = (char * const *) bar;
+ const void ***p9 = (const void ***) bar;
+ const char ***p10 = (const char ***) bar;
+ void * const **p11 = (void * const **) bar;
+ char * const **p12 = (char * const **) bar;
+ void ** const *p13 = (void ** const *) bar;
+ char ** const *p14 = (char ** const *) bar;
+ const void * const **p15 = (const void * const **) bar;
+ const char * const **p16 = (const char * const **) bar;
+ const void ** const *p17 = (const void ** const *) bar;
+ const char ** const *p18 = (const char ** const *) bar;
+ void * const * const * p19 = (void * const * const *) bar;
+ char * const * const * p20 = (char * const * const *) bar;
+ const void * const * const *p21 = (const void * const * const *) bar;
+ const char * const * const *p22 = (const char * const * const *) bar;
+}
+
+void
+f3 (void ***bar)
+{
+ const void *p1 = (const void *) bar;
+ const char *p2 = (const char *) bar;
+ const void **p3 = (const void **) bar;
+ const char **p4 = (const char **) bar;
+ const void * const *p5 = (const void * const *) bar;
+ const char * const *p6 = (const char * const *) bar;
+ void * const *p7 = (void * const *) bar;
+ char * const *p8 = (char * const *) bar;
+ const void ***p9 = (const void ***) bar; /* { dg-warning "cast" } */
+ const char ***p10 = (const char ***) bar;
+ void * const **p11 = (void * const **) bar; /* { dg-warning "cast" } */
+ char * const **p12 = (char * const **) bar;
+ void ** const *p13 = (void ** const *) bar;
+ char ** const *p14 = (char ** const *) bar;
+ const void * const **p15 = (const void * const **) bar; /* { dg-warning "cast" } */
+ const char * const **p16 = (const char * const **) bar;
+ const void ** const *p17 = (const void ** const *) bar; /* { dg-warning "cast" } */
+ const char ** const *p18 = (const char ** const *) bar;
+ void * const * const * p19 = (void * const * const *) bar;
+ char * const * const * p20 = (char * const * const *) bar;
+ const void * const * const *p21 = (const void * const * const *) bar;
+ const char * const * const *p22 = (const char * const * const *) bar;
+}
+
+void
+f4 (void * const **bar)
+{
+ const void ***p9 = (const void ***) bar; /* { dg-warning "cast" } */
+ void * const **p11 = (void * const **) bar;
+ void ** const *p13 = (void ** const *) bar; /* { dg-warning "cast" } */
+ const void * const **p15 = (const void * const **) bar; /* { dg-warning "cast" } */
+ const void ** const *p17 = (const void ** const *) bar; /* { dg-warning "cast" } */
+ void * const * const * p19 = (void * const * const *) bar;
+ const void * const * const *p21 = (const void * const * const *) bar;
+}
+
+void
+f5 (char ***bar)
+{
+ volatile const char ***p9 = (volatile const char ***) bar; /* { dg-warning "cast" } */
+ volatile char * const **p11 = (volatile char * const **) bar; /* { dg-warning "cast" } */
+ volatile char ** const *p13 = (volatile char ** const *) bar; /* { dg-warning "cast" } */
+ volatile const char * const **p15 = (volatile const char * const **) bar; /* { dg-warning "cast" } */
+ volatile const char ** const *p17 = (volatile const char ** const *) bar; /* { dg-warning "cast" } */
+ volatile char * const * const * p19 = (volatile char * const * const *) bar;
+ volatile const char * const * const *p21 = (volatile const char * const * const *) bar;
+}
+
+void
+f6 (char ***bar)
+{
+ const char * volatile **p9 = (const char * volatile **) bar; /* { dg-warning "cast" } */
+ char * volatile const **p11 = (char * volatile const **) bar; /* { dg-warning "cast" } */
+ char * volatile * const *p13 = (char * volatile * const *) bar;
+ const char * volatile const **p15 = (const char * volatile const **) bar; /* { dg-warning "cast" } */
+ const char * volatile * const *p17 = (const char * volatile * const *) bar; /* { dg-warning "cast" } */
+ char * volatile const * const * p19 = (char * volatile const * const *) bar;
+ const char * volatile const * const *p21 = (const char * volatile const * const *) bar;
+}
+
+void
+f7 (char ***bar)
+{
+ const char ** volatile *p9 = (const char ** volatile *) bar; /* { dg-warning "cast" } */
+ char * const * volatile *p11 = (char * const * volatile *) bar; /* { dg-warning "cast" } */
+ char ** volatile const *p13 = (char ** volatile const *) bar;
+ const char * const * volatile *p15 = (const char * const * volatile *) bar; /* { dg-warning "cast" } */
+ const char ** volatile const *p17 = (const char ** volatile const *) bar; /* { dg-warning "cast" } */
+ char * const * volatile const * p19 = (char * const * volatile const *) bar;
+ const char * const * volatile const *p21 = (const char * const * volatile const *) bar;
+}
+
+typedef int (intfn) (int);
+typedef intfn *pintfn;
+typedef const intfn *constfn;
+
+void
+f8 (constfn ***bar)
+{
+ const constfn *p1 = (const constfn *) bar;
+ const pintfn *p2 = (const pintfn *) bar;
+ const constfn **p3 = (const constfn **) bar;
+ const pintfn **p4 = (const pintfn **) bar;
+ const constfn * const *p5 = (const constfn * const *) bar;
+ const pintfn * const *p6 = (const pintfn * const *) bar;
+ constfn * const *p7 = (constfn * const *) bar;
+ pintfn * const *p8 = (pintfn * const *) bar;
+ const constfn ***p9 = (const constfn ***) bar; /* { dg-warning "cast" } */
+ const pintfn ***p10 = (const pintfn ***) bar; /* { dg-warning "cast" } */
+ constfn * const **p11 = (constfn * const **) bar; /* { dg-warning "cast" } */
+ pintfn * const **p12 = (pintfn * const **) bar; /* { dg-warning "cast" } */
+ constfn ** const *p13 = (constfn ** const *) bar;
+ pintfn ** const *p14 = (pintfn ** const *) bar;
+ const constfn * const **p15 = (const constfn * const **) bar; /* { dg-warning "cast" } */
+ const pintfn * const **p16 = (const pintfn * const **) bar; /* { dg-warning "cast" } */
+ const constfn ** const *p17 = (const constfn ** const *) bar; /* { dg-warning "cast" } */
+ const pintfn ** const *p18 = (const pintfn ** const *) bar; /* { dg-warning "cast" } */
+ constfn * const * const * p19 = (constfn * const * const *) bar;
+ pintfn * const * const * p20 = (pintfn * const * const *) bar;
+ const constfn * const * const *p21 = (const constfn * const * const *) bar;
+ const pintfn * const * const *p22 = (const pintfn * const * const *) bar;
+}
diff --git a/gcc/testsuite/g++.dg/warn/Wstrict-aliasing-float-ref-int-obj.C b/gcc/testsuite/g++.dg/warn/Wstrict-aliasing-float-ref-int-obj.C
index d88ed4314b3..8b82874f51d 100644
--- a/gcc/testsuite/g++.dg/warn/Wstrict-aliasing-float-ref-int-obj.C
+++ b/gcc/testsuite/g++.dg/warn/Wstrict-aliasing-float-ref-int-obj.C
@@ -4,8 +4,8 @@
int foo() {
int x;
- float& q = reinterpret_cast<float&> (x); /* { dg-message "initialized" } */
- q = 1.0; /* { dg-warning "does break strict-aliasing" } */
+ float& q = reinterpret_cast<float&> (x); /* { dg-message "initialized" "" { xfail *-*-* } } */
+ q = 1.0; /* { dg-warning "does break strict-aliasing" "" { xfail *-*-* } } */
return x;
}
diff --git a/gcc/testsuite/g++.dg/warn/Wswitch-3.C b/gcc/testsuite/g++.dg/warn/Wswitch-3.C
new file mode 100644
index 00000000000..df1f8956dad
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wswitch-3.C
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-options "-Wswitch" } */
+
+enum E { A, B, C, D, E, F };
+
+int
+f1 (enum E e)
+{
+ switch (e)
+ {
+ case A: return 1;
+ case B: return 2;
+ case C: return 3;
+ case D: return 4;
+ case E: return 5;
+ case F: return 6;
+ case 7: return 7; /* { dg-warning "not in enumerated type" } */
+ }
+ return 0;
+}
+
+int
+f2 (enum E e)
+{
+ switch (e)
+ {
+ case A: return 1;
+ case B: return 2;
+ case C: return 3;
+ case D: return 4;
+ case E: return 5;
+ case F: return 6;
+ case 7: return 7; /* { dg-warning "not in enumerated type" } */
+ default: return 8;
+ }
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/warn/Wunused-label-1.C b/gcc/testsuite/g++.dg/warn/Wunused-label-1.C
new file mode 100644
index 00000000000..96f49b321cd
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wunused-label-1.C
@@ -0,0 +1,28 @@
+// { dg-do compile }
+// { dg-options "-Wunused-label" }
+
+extern void f9();
+
+void
+f1()
+{
+ l1: f9(); // { dg-warning "not used" }
+ l3: ; f9(); // { dg-warning "not used" }
+ l4: __attribute__ ((unused)) ; f9();
+}
+
+void
+f2()
+{
+ label: __attribute ((unused)) ;
+}
+
+void
+f3()
+{
+ // The next line would be OK in C but is a syntax error in C++.
+ l2: __attribute__ ((unused)) f9(); // { dg-error "expected" }
+ // We still get an unused label warning--this is
+ // optional and can be removed if it ever changes.
+ // { dg-warning "not used" "expected" { target *-*-* } 24 }
+}
diff --git a/gcc/testsuite/g++.dg/warn/Wunused-label-2.C b/gcc/testsuite/g++.dg/warn/Wunused-label-2.C
new file mode 100644
index 00000000000..a53fdedf317
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wunused-label-2.C
@@ -0,0 +1,13 @@
+// { dg-do compile }
+// { dg-options "-Wunused" }
+
+// If __attribute__ ((unused)) follows a label and precedes a
+// declaration, we should get a warning for the label, not the
+// declaration.
+
+void
+f1()
+{
+ int i1; // { dg-warning "unused variable" }
+ l1: __attribute__ ((unused)) int i2; // { dg-warning "label \[^\n\]* not used" }
+}
diff --git a/gcc/testsuite/g++.dg/warn/Wunused-label-3.C b/gcc/testsuite/g++.dg/warn/Wunused-label-3.C
new file mode 100644
index 00000000000..7479ca20c37
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wunused-label-3.C
@@ -0,0 +1,51 @@
+// { dg-do compile }
+// { dg-options "-Wunused-label" }
+
+extern void f9();
+
+template<int i>
+void
+f1()
+{
+ if (i)
+ return;
+
+ l1: f9(); // { dg-warning "not used" }
+ l3: ; f9(); // { dg-warning "not used" }
+ l4: __attribute__ ((unused)) ; f9();
+}
+
+template
+void f1<0>();
+
+template<int i>
+void
+f2()
+{
+ if (i)
+ return;
+
+ l1: f9(); // { dg-warning "not used" }
+ l3: ; f9(); // { dg-warning "not used" }
+ l4: __attribute__ ((unused)) ; f9();
+}
+
+template
+void f2<1>();
+
+template<int i>
+void
+f3()
+{
+ void* lab;
+ l1: f9();
+ l2: __attribute__ ((unused)) ; f9();
+ lab = i ? &&l1 : &&l2;
+ goto *lab;
+}
+
+template
+void f3<0>();
+
+template
+void f3<1>();
diff --git a/gcc/testsuite/g++.dg/warn/pr16302.C b/gcc/testsuite/g++.dg/warn/pr16302.C
new file mode 100644
index 00000000000..a6f1a457407
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/pr16302.C
@@ -0,0 +1,76 @@
+// PR 16302
+/* { dg-do compile } */
+/* { dg-options "-Wlogical-op" } */
+void bar (int);
+int
+foo (int argc, char *argv[])
+{
+ if (argc != 1 || argc != 2) return 1; /* { dg-warning "'or' of collectively exhaustive tests is always true" } */
+ if (argc < 0 && argc > 10) return 1; /* { dg-warning "'and' of mutually exclusive tests is always false" } */
+ if (argc || !argc) return 1; /* { dg-warning "'or' of collectively exhaustive tests is always true" } */
+ if (argc && !argc) return 1; /* { dg-warning "'and' of mutually exclusive tests is always false" } */
+ bar (argc != 1 || argc != 2); /* { dg-warning "'or' of collectively exhaustive tests is always true" } */
+ bar (argc < 0 && argc > 10); /* { dg-warning "'and' of mutually exclusive tests is always false" } */
+ bar (argc || !argc); /* { dg-warning "'or' of collectively exhaustive tests is always true" } */
+ bar (argc && !argc); /* { dg-warning "'and' of mutually exclusive tests is always false" } */
+ return (argc != 1 || argc != 2) ? 1 : 0 ; /* { dg-warning "'or' of collectively exhaustive tests is always true" } */
+ return (argc < 0 && argc > 10) ? 1 : 0; /* { dg-warning "'and' of mutually exclusive tests is always false" } */
+ return (argc || !argc) ? 1 : 0; /* { dg-warning "'or' of collectively exhaustive tests is always true" } */
+ return (argc && !argc) ? 1 : 0; /* { dg-warning "'and' of mutually exclusive tests is always false" } */
+
+ if (argc == 2 && argc == 1) return 1; /* { dg-warning "'and' of mutually exclusive tests is always false" } */
+ if (argc < 0 && argc > 10) return 1; /* { dg-warning "'and' of mutually exclusive tests is always false" } */
+ if (argc || !argc) return 1; /* { dg-warning "'or' of collectively exhaustive tests is always true" } */
+ if (argc && !argc) return 1; /* { dg-warning "'and' of mutually exclusive tests is always false" } */
+ bar (argc == 2 && argc == 1); /* { dg-warning "'and' of mutually exclusive tests is always false" } */
+ bar (argc < 0 && argc > 10); /* { dg-warning "'and' of mutually exclusive tests is always false" } */
+ bar (argc || !argc); /* { dg-warning "'or' of collectively exhaustive tests is always true" } */
+ bar (argc && !argc); /* { dg-warning "'and' of mutually exclusive tests is always false" } */
+ return (argc == 2 && argc == 1) ? 1 : 0 ; /* { dg-warning "'and' of mutually exclusive tests is always false" } */
+ return (argc < 0 && argc > 10) ? 1 : 0; /* { dg-warning "'and' of mutually exclusive tests is always false" } */
+ return (argc || !argc) ? 1 : 0; /* { dg-warning "'or' of collectively exhaustive tests is always true" } */
+ return (argc && !argc) ? 1 : 0; /* { dg-warning "'and' of mutually exclusive tests is always false" } */
+
+ if (argc == 2 && argc == 1) return 1; /* { dg-warning "'and' of mutually exclusive tests is always false" } */
+ if (argc < 0 && argc > 10) return 1; /* { dg-warning "'and' of mutually exclusive tests is always false" } */
+ if (!argc || argc) return 1; /* { dg-warning "'or' of collectively exhaustive tests is always true" } */
+ if (!argc && argc) return 1; /* { dg-warning "'and' of mutually exclusive tests is always false" } */
+ bar (argc == 2 && argc == 1); /* { dg-warning "'and' of mutually exclusive tests is always false" } */
+ bar (argc < 0 && argc > 10); /* { dg-warning "'and' of mutually exclusive tests is always false" } */
+ bar (!argc || argc); /* { dg-warning "'or' of collectively exhaustive tests is always true" } */
+ bar (!argc && argc); /* { dg-warning "'and' of mutually exclusive tests is always false" } */
+ return (argc == 2 && argc == 1) ? 1 : 0 ; /* { dg-warning "'and' of mutually exclusive tests is always false" } */
+ return (argc < 0 && argc > 10) ? 1 : 0; /* { dg-warning "'and' of mutually exclusive tests is always false" } */
+ return (!argc || argc) ? 1 : 0; /* { dg-warning "'or' of collectively exhaustive tests is always true" } */
+ return (!argc && argc) ? 1 : 0; /* { dg-warning "'and' of mutually exclusive tests is always false" } */
+
+ return 0;
+}
+
+int
+foo2 (int argc)
+{
+ if (5 != 1 || 5 != 2) return 1;
+ if (5 < 0 && 5 > 10) return 1;
+ if (1 || 0) return 1;
+ if (0 && 1) return 1;
+ if (2 || !2) return 1;
+ if (2 && !2) return 1;
+ if (!(!2) || !(2)) return 1;
+ if (!(!2) && !(2)) return 1;
+ bar (5 != 1 || 5 != 2);
+ bar (5 < 0 && 5 > 10);
+ bar (1 || 0);
+ bar (0 && 1);
+ bar (2 || !2);
+ bar (2 && !2);
+ return (5 != 1 || 5 != 2) ? 1 : 0 ;
+ return (5 < 0 && 5 > 10) ? 1 : 0;
+ return (1 || 0) ? 1 : 0 ;
+ return (0 && 1) ? 1 : 0;
+ return (2 || !2) ? 1 : 0;
+ return (2 && !2) ? 1 : 0;
+
+ return 0;
+}
+
diff --git a/gcc/testsuite/g++.dg/warn/skip-1.C b/gcc/testsuite/g++.dg/warn/skip-1.C
new file mode 100644
index 00000000000..027c405d462
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/skip-1.C
@@ -0,0 +1,17 @@
+// { dg-do compile }
+// { dg-options "-Wall" }
+
+// Check that we don't warn about code that will not be executed.
+extern int f2(int);
+void
+f1(int i)
+{
+ f2(1 == 1 ? 0 : f2(i >> -10));
+ f2(1 == 1 ? 0 : f2(i >> 128));
+ f2(1 == 1 ? 0 : f2(i << -10));
+ f2(1 == 1 ? 0 : f2(1 << 128));
+ f2(1 != 1 ? f2(i >> -10) : 0);
+ f2(1 != 1 ? f2(i >> 128) : 0);
+ f2(1 != 1 ? f2(i << -10) : 0);
+ f2(1 != 1 ? f2(1 << 128) : 0);
+}
diff --git a/gcc/testsuite/g++.dg/warn/translate-ice-1.C b/gcc/testsuite/g++.dg/warn/translate-ice-1.C
new file mode 100644
index 00000000000..22e103c2980
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/translate-ice-1.C
@@ -0,0 +1,45 @@
+// Test ICE in caching printable names for a function.
+// { dg-options "-std=c++98 -pedantic -O2" }
+
+void g (int a) __attribute__((warning("g")));
+void g2 (int a, int *p);
+static inline __attribute__((__always_inline__)) void
+gg (int a)
+{
+ if (a == 0)
+ return g(a); // { dg-warning "attribute" }
+ __extension__ int v[a];
+ return g2(a, v);
+}
+
+void h (int a) __attribute__((warning("h")));
+void h2 (int a, int *p);
+static inline __attribute__((__always_inline__)) void
+hh (int a)
+{
+ if (a == 0)
+ return h(a); // { dg-warning "attribute" }
+ __extension__ int v[a];
+ return h2(a, v);
+}
+
+void i (int a) __attribute__((warning("i")));
+void i2 (int a, int *p);
+static inline __attribute__((__always_inline__)) void
+ii (int a)
+{
+ if (a == 0)
+ return i(a); // { dg-warning "attribute" }
+ __extension__ int v[a];
+ return i2(a, v);
+}
+
+void
+f (void)
+{
+ long long l; // { dg-warning "long long" }
+ const char *p = __PRETTY_FUNCTION__;
+ gg(0);
+ hh(0);
+ ii(0);
+}
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/array1.C b/gcc/testsuite/g++.old-deja/g++.brendan/array1.C
index df132ea9024..a58d3363bcd 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/array1.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/array1.C
@@ -3,5 +3,5 @@
// GROUPS passed array-bindings
extern "C" int printf (const char *, ...);
-char array[~(~0ul>>1)|~(0ul>>3)]; // { dg-error "" } overflow in array dimension.*
+char array[~(~((__SIZE_TYPE__)0ul)>>1)|~(((__SIZE_TYPE__)0ul)>>3)]; // { dg-error "" } overflow in array dimension.*
int main () { printf ("PASS\n"); return 0; }
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/crash64.C b/gcc/testsuite/g++.old-deja/g++.brendan/crash64.C
index b3717a5d999..6046cb1c9ee 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/crash64.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/crash64.C
@@ -1,6 +1,6 @@
// { dg-do assemble }
// GROUPS passed old-abort
-typedef long unsigned int size_t;
+typedef __SIZE_TYPE__ size_t;
typedef void (*RF_Ptr)(void *);
struct _im_pers_mem_spec {
@@ -9,7 +9,7 @@ struct _im_pers_mem_spec {
};
struct _type_desc {
- _type_desc(char *, int , RF_Ptr , int , int ,...);
+ _type_desc(const char *, int , RF_Ptr , int , int ,...);
};
struct metatype { int base_list; };
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/new3.C b/gcc/testsuite/g++.old-deja/g++.jason/new3.C
index 62e9b7dd1b6..d950259e72a 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/new3.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/new3.C
@@ -1,5 +1,5 @@
// { dg-do run }
-// { dg-options "-fcheck-new -pedantic" }
+// { dg-options "-fcheck-new -pedantic -Wno-long-long" }
// PRMS Id: 6037
extern "C" void * malloc (__SIZE_TYPE__);
diff --git a/gcc/testsuite/gcc.c-torture/compile/20000211-1.c b/gcc/testsuite/gcc.c-torture/compile/20000211-1.c
index 8d8a4074e0f..7a7c8c0cb20 100644
--- a/gcc/testsuite/gcc.c-torture/compile/20000211-1.c
+++ b/gcc/testsuite/gcc.c-torture/compile/20000211-1.c
@@ -1,4 +1,4 @@
-typedef long unsigned int size_t;
+typedef __SIZE_TYPE__ size_t;
typedef unsigned char Bufbyte;
typedef int Bytecount;
typedef int Charcount;
diff --git a/gcc/testsuite/gcc.c-torture/compile/20010328-1.c b/gcc/testsuite/gcc.c-torture/compile/20010328-1.c
index d92c6dae113..951ae78b950 100644
--- a/gcc/testsuite/gcc.c-torture/compile/20010328-1.c
+++ b/gcc/testsuite/gcc.c-torture/compile/20010328-1.c
@@ -1,4 +1,4 @@
-typedef unsigned int size_t;
+typedef __SIZE_TYPE__ size_t;
typedef unsigned int __u_int;
typedef unsigned long __u_long;
diff --git a/gcc/testsuite/gcc.c-torture/compile/20030320-1.c b/gcc/testsuite/gcc.c-torture/compile/20030320-1.c
index 40243f28f93..72d0d0966c6 100644
--- a/gcc/testsuite/gcc.c-torture/compile/20030320-1.c
+++ b/gcc/testsuite/gcc.c-torture/compile/20030320-1.c
@@ -2,7 +2,7 @@
conditional returns without updating dominance info.
Extracted from glibc's dl-load.c. */
-typedef unsigned long size_t;
+typedef __SIZE_TYPE__ size_t;
static size_t
is_dst (const char *start, const char *name, const char *str,
diff --git a/gcc/testsuite/gcc.c-torture/compile/20030405-1.c b/gcc/testsuite/gcc.c-torture/compile/20030405-1.c
index f84e606c045..0bdafb9239f 100644
--- a/gcc/testsuite/gcc.c-torture/compile/20030405-1.c
+++ b/gcc/testsuite/gcc.c-torture/compile/20030405-1.c
@@ -6,7 +6,7 @@
and when the PHI node at the end of the while() is visited the first
time, CCP will try to assign it a value of UNDEFINED, but the default
value for *str is a constant. */
-typedef unsigned int size_t;
+typedef __SIZE_TYPE__ size_t;
size_t strlength (const char * const);
char foo();
diff --git a/gcc/testsuite/gcc.c-torture/compile/20030902-1.c b/gcc/testsuite/gcc.c-torture/compile/20030902-1.c
index 443b43921b8..56c2650b86b 100644
--- a/gcc/testsuite/gcc.c-torture/compile/20030902-1.c
+++ b/gcc/testsuite/gcc.c-torture/compile/20030902-1.c
@@ -1,4 +1,4 @@
-typedef unsigned int size_t;
+typedef __SIZE_TYPE__ size_t;
typedef unsigned long int reg_syntax_t;
struct re_pattern_buffer
{
diff --git a/gcc/testsuite/gcc.c-torture/compile/20060202-1.c b/gcc/testsuite/gcc.c-torture/compile/20060202-1.c
index 9d440741c6b..d16e7b7c5ad 100644
--- a/gcc/testsuite/gcc.c-torture/compile/20060202-1.c
+++ b/gcc/testsuite/gcc.c-torture/compile/20060202-1.c
@@ -1,4 +1,4 @@
-typedef unsigned int size_t;
+typedef __SIZE_TYPE__ size_t;
typedef const struct objc_selector
{
void *sel_id;
diff --git a/gcc/testsuite/gcc.c-torture/compile/20080613-1.c b/gcc/testsuite/gcc.c-torture/compile/20080613-1.c
index f64964e7740..20e3878420e 100644
--- a/gcc/testsuite/gcc.c-torture/compile/20080613-1.c
+++ b/gcc/testsuite/gcc.c-torture/compile/20080613-1.c
@@ -1,7 +1,7 @@
/* PR middle-end/36520 */
/* Testcase by Richard Guenther <rguenth@gcc.gnu.org> */
-typedef long unsigned int size_t;
+typedef __SIZE_TYPE__ size_t;
typedef unsigned short int sa_family_t;
struct cmsghdr {
size_t cmsg_len;
diff --git a/gcc/testsuite/gcc.c-torture/compile/20090518-1.c b/gcc/testsuite/gcc.c-torture/compile/20090518-1.c
new file mode 100644
index 00000000000..709504c405a
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/20090518-1.c
@@ -0,0 +1,6 @@
+float
+foo(int i)
+{
+ int j = i == 42;
+ return *(float *)&j;
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/20090519-1.c b/gcc/testsuite/gcc.c-torture/compile/20090519-1.c
new file mode 100644
index 00000000000..54add6b2e1a
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/20090519-1.c
@@ -0,0 +1,11 @@
+typedef struct { int licensed; } __pmPDUInfo;
+void __pmDecodeXtendError (int *);
+void do_handshake(void)
+{
+ __pmPDUInfo *pduinfo;
+ int challenge;
+ __pmDecodeXtendError(&challenge);
+ pduinfo = (__pmPDUInfo *)&challenge;
+ *pduinfo = *pduinfo;
+}
+
diff --git a/gcc/testsuite/gcc.c-torture/compile/920428-2.c b/gcc/testsuite/gcc.c-torture/compile/920428-2.c
index 23f32a83a9d..f313b32986b 100644
--- a/gcc/testsuite/gcc.c-torture/compile/920428-2.c
+++ b/gcc/testsuite/gcc.c-torture/compile/920428-2.c
@@ -41,7 +41,7 @@ extern struct _iobuf {
short _flag;
char _file;
} _iob[];
-typedef unsigned long size_t;
+typedef __SIZE_TYPE__ size_t;
typedef char *va_list;
struct _iobuf *fopen(const char *filename, const char *type);
struct _iobuf *freopen(const char *filename, const char *type, struct _iobuf *stream);
diff --git a/gcc/testsuite/gcc.c-torture/compile/980329-1.c b/gcc/testsuite/gcc.c-torture/compile/980329-1.c
index d11b49b01c7..3b3fe27cf71 100644
--- a/gcc/testsuite/gcc.c-torture/compile/980329-1.c
+++ b/gcc/testsuite/gcc.c-torture/compile/980329-1.c
@@ -1,4 +1,4 @@
-typedef unsigned long int size_t;
+typedef __SIZE_TYPE__ size_t;
struct re_pattern_buffer
{
unsigned char *buffer;
diff --git a/gcc/testsuite/gcc.c-torture/compile/980816-1.c b/gcc/testsuite/gcc.c-torture/compile/980816-1.c
index c56b6c9b92c..a79100fab57 100644
--- a/gcc/testsuite/gcc.c-torture/compile/980816-1.c
+++ b/gcc/testsuite/gcc.c-torture/compile/980816-1.c
@@ -1,4 +1,4 @@
-typedef unsigned int size_t;
+typedef __SIZE_TYPE__ size_t;
typedef void *XtPointer;
typedef struct _WidgetRec *Widget;
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr32584.c b/gcc/testsuite/gcc.c-torture/compile/pr32584.c
index 02799fc7449..403ea9b12fa 100644
--- a/gcc/testsuite/gcc.c-torture/compile/pr32584.c
+++ b/gcc/testsuite/gcc.c-torture/compile/pr32584.c
@@ -1,5 +1,8 @@
-typedef long unsigned int size_t;
-typedef long int __ssize_t;
+typedef __SIZE_TYPE__ size_t;
+/* Kludge */
+#define unsigned
+typedef __SIZE_TYPE__ __ssize_t;
+#undef unsigned
typedef struct
{
} __mbstate_t;
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr33173.c b/gcc/testsuite/gcc.c-torture/compile/pr33173.c
index 503c7afbdac..f599297e79a 100644
--- a/gcc/testsuite/gcc.c-torture/compile/pr33173.c
+++ b/gcc/testsuite/gcc.c-torture/compile/pr33173.c
@@ -1,4 +1,4 @@
-typedef long unsigned int size_t;
+typedef __SIZE_TYPE__ size_t;
typedef struct
{
}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr33382.c b/gcc/testsuite/gcc.c-torture/compile/pr33382.c
index d83f74e42cc..c939cf7b772 100644
--- a/gcc/testsuite/gcc.c-torture/compile/pr33382.c
+++ b/gcc/testsuite/gcc.c-torture/compile/pr33382.c
@@ -1,4 +1,4 @@
-typedef unsigned int size_t;
+typedef __SIZE_TYPE__ size_t;
typedef struct {
int disable;
char *searchconfig[];
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr34334.c b/gcc/testsuite/gcc.c-torture/compile/pr34334.c
index 15f895f1cba..30bb782626f 100644
--- a/gcc/testsuite/gcc.c-torture/compile/pr34334.c
+++ b/gcc/testsuite/gcc.c-torture/compile/pr34334.c
@@ -1,4 +1,4 @@
-typedef unsigned int size_t;
+__extension__ typedef __SIZE_TYPE__ size_t;
__extension__ typedef long long int __quad_t;
__extension__ typedef unsigned int __mode_t;
__extension__ typedef __quad_t __off64_t;
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr34688.c b/gcc/testsuite/gcc.c-torture/compile/pr34688.c
index 9891c72d93d..60e0f3c9f15 100644
--- a/gcc/testsuite/gcc.c-torture/compile/pr34688.c
+++ b/gcc/testsuite/gcc.c-torture/compile/pr34688.c
@@ -1,4 +1,4 @@
-typedef unsigned int size_t;
+typedef __SIZE_TYPE__ size_t;
typedef struct {
}
HashTable;
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr35043.c b/gcc/testsuite/gcc.c-torture/compile/pr35043.c
index 29c685207b9..a14379dc148 100644
--- a/gcc/testsuite/gcc.c-torture/compile/pr35043.c
+++ b/gcc/testsuite/gcc.c-torture/compile/pr35043.c
@@ -1,4 +1,4 @@
-typedef long unsigned int size_t;
+typedef __SIZE_TYPE__ size_t;
typedef struct {
long double dat[2];
} gsl_complex_long_double;
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr37669.c b/gcc/testsuite/gcc.c-torture/compile/pr37669.c
index 9b003cdf099..68e96c621cf 100644
--- a/gcc/testsuite/gcc.c-torture/compile/pr37669.c
+++ b/gcc/testsuite/gcc.c-torture/compile/pr37669.c
@@ -1,6 +1,6 @@
/* This testcase used to fail because a miscompiled execute_fold_all_builtins. */
-typedef long unsigned int size_t;
+typedef __SIZE_TYPE__ size_t;
extern __inline __attribute__ ((__always_inline__)) int __attribute__
((__nothrow__)) snprintf (char *__restrict __s, size_t __n, __const char
*__restrict __fmt, ...) {
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr39834.c b/gcc/testsuite/gcc.c-torture/compile/pr39834.c
new file mode 100644
index 00000000000..ecc3977a1f0
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr39834.c
@@ -0,0 +1,13 @@
+/* { dg-options "-O1 -Winline" } */
+void quit_mined ();
+void bottom_line ();
+typedef enum { False, True } FLAG;
+inline void
+nextfile (FLAG exitiflast)
+{
+ if (exitiflast)
+ quit_mined ();
+ else
+ bottom_line ();
+ nextfile (True);
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr39999.c b/gcc/testsuite/gcc.c-torture/compile/pr39999.c
new file mode 100644
index 00000000000..c46a651a18a
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr39999.c
@@ -0,0 +1,18 @@
+void foo(void *);
+void
+MMAPGCD (int *A1, int *A2)
+{
+ int *t;
+
+ do
+ {
+ t = A1;
+ A1 = A2;
+ A2 = t;
+ }
+ while (A2[-1]);
+
+ foo (A1-1);
+ foo (A2-1);
+}
+
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr40035.c b/gcc/testsuite/gcc.c-torture/compile/pr40035.c
new file mode 100644
index 00000000000..1bf1a7c4c41
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr40035.c
@@ -0,0 +1,20 @@
+typedef __SIZE_TYPE__ size_t;
+void *memmove (void *dest, const void *src, size_t count);
+size_t strlen (const char *s);
+
+int
+foo (char *param, char *val)
+{
+ if (val)
+ {
+ if (val == param + strlen (param) + 1)
+ val[-1] = '=';
+ else if (val == param + strlen (param) + 2)
+ {
+ val[-2] = '=';
+ memmove (val - 1, val, strlen (val) + 1);
+ val--;
+ }
+ }
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr40204.c b/gcc/testsuite/gcc.c-torture/compile/pr40204.c
new file mode 100644
index 00000000000..3193284ff7a
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr40204.c
@@ -0,0 +1,14 @@
+/* PR middle-end/40204 */
+
+struct S
+{
+ unsigned int a : 4;
+ unsigned int b : 28;
+} s;
+char c;
+
+void
+f (void)
+{
+ s.a = (c >> 4) & ~(1 << 4);
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr40233.c b/gcc/testsuite/gcc.c-torture/compile/pr40233.c
new file mode 100644
index 00000000000..b3487edde74
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr40233.c
@@ -0,0 +1,10 @@
+typedef int aligned __attribute__((aligned(64)));
+struct Frame {
+ aligned i;
+};
+
+void foo(struct Frame *p)
+{
+ aligned *q = &p->i;
+ *q = 0;
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr40252.c b/gcc/testsuite/gcc.c-torture/compile/pr40252.c
new file mode 100644
index 00000000000..f58e799b01f
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr40252.c
@@ -0,0 +1,6 @@
+typedef unsigned int uint32_t;
+static void IP(uint32_t v[2])
+{
+ v[0] = ((v[0] << 1) | ((v[0] >> 31) & 1L)) & 0xffffffffL;
+}
+
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr40291.c b/gcc/testsuite/gcc.c-torture/compile/pr40291.c
new file mode 100644
index 00000000000..d50bbee6608
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr40291.c
@@ -0,0 +1,7 @@
+/* PR middle-end/40291 */
+
+int
+foo (void *x, char *y, unsigned long long z)
+{
+ return memcmp (x, y, z);
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr40351.c b/gcc/testsuite/gcc.c-torture/compile/pr40351.c
new file mode 100644
index 00000000000..9b7e0ccfae1
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr40351.c
@@ -0,0 +1,22 @@
+/* PR tree-optimizations/40351 */
+
+struct IO_APIC_route_entry {
+ unsigned int vector : 8;
+ unsigned int delivery_mode : 1;
+ unsigned int mask : 1;
+ unsigned int __reserved_2 : 15;
+ unsigned int __reserved_3 : 8;
+} __attribute__ ((packed));
+union entry_union {
+ struct {
+ unsigned int w1, w2;
+ };
+ struct IO_APIC_route_entry entry;
+};
+unsigned int io_apic_read(void);
+struct IO_APIC_route_entry ioapic_read_entry(void)
+{
+ union entry_union eu;
+ eu.w1 = io_apic_read();
+ return eu.entry;
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr40432.c b/gcc/testsuite/gcc.c-torture/compile/pr40432.c
new file mode 100644
index 00000000000..767f5949887
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr40432.c
@@ -0,0 +1,17 @@
+/* Test that SRA produces valid gimple when handling both type punning by means
+ of VCE and creating an access to a union. */
+
+union U {
+ struct something *sth;
+ void *nothing;
+};
+
+void
+foo (union U *target, void *p)
+{
+ union U u;
+
+ u.nothing = p;
+ *target = u;
+ return;
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/ptr-conv-1.c b/gcc/testsuite/gcc.c-torture/compile/ptr-conv-1.c
new file mode 100644
index 00000000000..11dc8ce8957
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/ptr-conv-1.c
@@ -0,0 +1,11 @@
+/* The intermediate conversion to __PTRDIFF_TYPE__ could be lost,
+ resulting in an "invalid types in nop conversion" ICE. */
+long long a;
+void
+f (void)
+{
+ int c = 1;
+ volatile int *p = &c;
+ a = (long long) (__PTRDIFF_TYPE__) p;
+ *p;
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/sra-1.c b/gcc/testsuite/gcc.c-torture/compile/sra-1.c
new file mode 100644
index 00000000000..06dcf1002be
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/sra-1.c
@@ -0,0 +1,75 @@
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+/* Let gimple verifier check what SRA does to unions and single-field
+ strucutres . */
+
+struct sim_struct
+{
+ int x;
+};
+
+extern struct sim_struct get_x(void);
+
+struct sim_struct foo (void)
+{
+ struct sim_struct simple;
+
+ simple = get_x ();
+ if (simple.x % 2)
+ simple.x = 39;
+ else
+ simple.x -=8;
+
+ return simple;
+}
+
+struct sim_cmplx
+{
+ _Complex double c;
+};
+
+extern struct sim_cmplx get_sc (void);
+
+_Complex double foo_c (void)
+{
+ struct sim_cmplx simple;
+
+ simple = get_sc ();
+ if (__real__ simple.c > 200.3)
+ __imag__ simple.c -= 2.4;
+
+ return simple.c;
+}
+
+
+union sim_union
+{
+ int i;
+ float d;
+};
+
+extern union sim_union get_y (void);
+
+union sim_union bar (void)
+{
+ union sim_union simple;
+
+ simple = get_y ();
+ if (simple.d > 8.2)
+ simple.i = 300;
+
+ return simple;
+}
+
+extern int get_int (void);
+
+int bar_i (void)
+{
+ union sim_union simple;
+
+ simple = get_y ();
+ if (simple.d > 8.2)
+ simple.i = get_int ();
+
+ return simple.i;
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/20090527-1.c b/gcc/testsuite/gcc.c-torture/execute/20090527-1.c
new file mode 100644
index 00000000000..d8e3711cdf6
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20090527-1.c
@@ -0,0 +1,38 @@
+typedef enum { POSITION_ASIS, POSITION_UNSPECIFIED } unit_position;
+
+typedef enum { STATUS_UNKNOWN, STATUS_UNSPECIFIED } unit_status;
+
+typedef struct
+{
+ unit_position position;
+ unit_status status;
+} unit_flags;
+
+extern void abort (void);
+
+void
+new_unit (unit_flags * flags)
+{
+ if (flags->status == STATUS_UNSPECIFIED)
+ flags->status = STATUS_UNKNOWN;
+
+ if (flags->position == POSITION_UNSPECIFIED)
+ flags->position = POSITION_ASIS;
+
+ switch (flags->status)
+ {
+ case STATUS_UNKNOWN:
+ break;
+
+ default:
+ abort ();
+ }
+}
+
+int main()
+{
+ unit_flags f;
+ f.status = STATUS_UNSPECIFIED;
+ new_unit (&f);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/align-nest.c b/gcc/testsuite/gcc.c-torture/execute/align-nest.c
new file mode 100644
index 00000000000..2ff2952c70c
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/align-nest.c
@@ -0,0 +1,28 @@
+
+void foo(int n)
+{
+ typedef struct
+ {
+ int value;
+ } myint;
+
+ struct S
+ {
+ int i[n];
+ unsigned int b:1;
+ myint mi;
+ } __attribute__ ((packed)) __attribute__ ((aligned (4)));
+
+ struct S s[2];
+ int k;
+
+ for (k = 0; k < 2; k ++)
+ s[k].mi.value = 0;
+}
+
+int main ()
+{
+ foo (2);
+ return 0;
+}
+
diff --git a/gcc/testsuite/gcc.dg/20050629-1.c b/gcc/testsuite/gcc.dg/20050629-1.c
index 67d73f0eb66..0dd47f7024b 100644
--- a/gcc/testsuite/gcc.dg/20050629-1.c
+++ b/gcc/testsuite/gcc.dg/20050629-1.c
@@ -5,7 +5,7 @@
contains many warnings, but it exposes a copy propagation bug that
is somewhat difficult to reproduce otherwise. */
-typedef long unsigned int size_t;
+__extension__ typedef __SIZE_TYPE__ size_t;
extern void fancy_abort (const char *, int, const char *) __attribute__ ((__noreturn__));
typedef union tree_node *tree;
enum tree_code {
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds.c b/gcc/testsuite/gcc.dg/Warray-bounds.c
index ac384e6bb2f..44120392c73 100644
--- a/gcc/testsuite/gcc.dg/Warray-bounds.c
+++ b/gcc/testsuite/gcc.dg/Warray-bounds.c
@@ -18,40 +18,40 @@ int* f(void) {
int c[10];
} c;
- a[-1] = 0; /* { dg-warning "array subscript" } */
+ a[-1] = 0; /* { dg-warning "6:array subscript" } */
a[ 0] = 0;
a[ 1] = 0;
a[ 9] = 0;
- a[10] = 0; /* { dg-warning "array subscript" } */
- a[11] = 0; /* { dg-warning "array subscript" } */
- a[2 * n() - 11] = 1; /* { dg-warning "array subscript" } */
+ a[10] = 0; /* { dg-warning "6:array subscript" } */
+ a[11] = 0; /* { dg-warning "6:array subscript" } */
+ a[2 * n() - 11] = 1; /* { dg-warning "6:array subscript" } */
a[2 * n() - 10] = 1;
a[2 * n() - 1] = 1;
- a[2 * n() - 0] = 1; /* { dg-warning "array subscript" } */
+ a[2 * n() - 0] = 1; /* { dg-warning "6:array subscript" } */
- b[-1] = 0; /* { dg-warning "array subscript" } */
+ b[-1] = 0; /* { dg-warning "6:array subscript" } */
b[ 0] = 0;
b[ 1] = 0;
b[ 9] = 0;
- b[10] = 0; /* { dg-warning "array subscript" } */
- b[11] = 0; /* { dg-warning "array subscript" } */
- b[2 * n() - 11] = 1; /* { dg-warning "array subscript" } */
+ b[10] = 0; /* { dg-warning "6:array subscript" } */
+ b[11] = 0; /* { dg-warning "6:array subscript" } */
+ b[2 * n() - 11] = 1; /* { dg-warning "6:array subscript" } */
b[2 * n() - 10] = 1;
b[2 * n() - 1] = 1;
b[2 * n() - 0] = 1; /* { dg-warning "array subscript" } */
- c.c[-1] = 0; /* { dg-warning "array subscript" } */
+ c.c[-1] = 0; /* { dg-warning "8:array subscript" } */
c.c[ 0] = 0;
c.c[ 1] = 0;
c.c[ 9] = 0;
- c.c[10] = 0; /* { dg-warning "array subscript" } */
- c.c[11] = 0; /* { dg-warning "array subscript" } */
- c.c[2 * n() - 11] = 1; /* { dg-warning "array subscript" } */
+ c.c[10] = 0; /* { dg-warning "8:array subscript" } */
+ c.c[11] = 0; /* { dg-warning "8:array subscript" } */
+ c.c[2 * n() - 11] = 1; /* { dg-warning "8:array subscript" } */
c.c[2 * n() - 10] = 1;
c.c[2 * n() - 1] = 1;
- c.c[2 * n() - 0] = 1; /* { dg-warning "array subscript" } */
+ c.c[2 * n() - 0] = 1; /* { dg-warning "8:array subscript" } */
g(&a[8]);
g(&a[9]);
@@ -86,7 +86,7 @@ int* f(void) {
c.c[-1] = 0;
for (i = 20; i < 30; ++i)
- a[i] = 1; /* { dg-warning "array subscript" } */
+ a[i] = 1; /* { dg-warning "15:array subscript" } */
return a;
}
diff --git a/gcc/testsuite/gcc.dg/Wcxx-compat-10.c b/gcc/testsuite/gcc.dg/Wcxx-compat-10.c
new file mode 100644
index 00000000000..0f1d037bfea
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wcxx-compat-10.c
@@ -0,0 +1,73 @@
+/* { dg-do compile } */
+/* { dg-options "-Wc++-compat" } */
+
+struct s1 { int f; };
+typedef int s2;
+void
+f1 ()
+{
+ typedef int s1;
+ struct s2 { int f; };
+}
+
+struct s3 { int f; };
+typedef struct s3 s3;
+
+typedef struct s4 s4;
+struct s4 { int f; };
+
+struct s5 { int f; }; /* { dg-message "note: originally defined here" } */
+typedef int s5; /* { dg-warning "invalid in C\[+\]\[+\]" } */
+
+typedef int s6; /* { dg-message "note: originally defined here" } */
+struct s6 { int f; }; /* { dg-warning "invalid in C\[+\]\[+\]" } */
+
+void
+f2 ()
+{
+ struct s7 { int f; }; /* { dg-message "note: originally defined here" } */
+ typedef int s7; /* { dg-warning "invalid in C\[+\]\[+\]" } */
+
+ typedef int s8; /* { dg-message "note: originally defined here" } */
+ struct s8 { int f; }; /* { dg-warning "invalid in C\[+\]\[+\]" } */
+
+ struct s9 { int f; };
+ { typedef int s9; }
+
+ typedef int s10;
+ { struct s10 { int f; }; }
+}
+
+enum e1 { A };
+typedef int e2;
+void
+f3 ()
+{
+ typedef int e1;
+ enum e2 { B };
+}
+
+enum e3 { C };
+typedef enum e3 e3;
+
+enum e5 { E }; /* { dg-message "note: originally defined here" } */
+typedef int e5; /* { dg-warning "invalid in C\[+\]\[+\]" } */
+
+typedef int e6; /* { dg-message "note: originally defined here" } */
+enum e6 { F }; /* { dg-warning "invalid in C\[+\]\[+\]" } */
+
+void
+f4 ()
+{
+ enum e7 { G }; /* { dg-message "note: originally defined here" } */
+ typedef int e7; /* { dg-warning "invalid in C\[+\]\[+\]" } */
+
+ typedef int e8; /* { dg-message "note: originally defined here" } */
+ enum e8 { H }; /* { dg-warning "invalid in C\[+\]\[+\]" } */
+
+ enum e9 { I };
+ { typedef int e9; }
+
+ typedef int e10;
+ { enum e10 { J }; }
+}
diff --git a/gcc/testsuite/gcc.dg/Wcxx-compat-11.c b/gcc/testsuite/gcc.dg/Wcxx-compat-11.c
new file mode 100644
index 00000000000..8818338ad5e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wcxx-compat-11.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-Wc++-compat" } */
+
+#include <stdarg.h>
+
+enum E { A };
+
+extern void f2 (int);
+void
+f1 (int n, ...)
+{
+ va_list ap;
+
+ va_start (ap, n);
+ f2 (va_arg (ap, int));
+ f2 (va_arg (ap, _Bool)); /* { dg-warning "promoted" } */
+ f2 (va_arg (ap, enum E)); /* { dg-warning "promoted" } */
+}
+
+/* Match extra informative notes. */
+/* { dg-message "note:" "expected" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/gcc.dg/Wcxx-compat-12.c b/gcc/testsuite/gcc.dg/Wcxx-compat-12.c
new file mode 100644
index 00000000000..a6094e183be
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wcxx-compat-12.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-Wc++-compat" } */
+
+enum E { A };
+
+enum E v;
+unsigned int *p = &v; /* { dg-warning "incompatible in C\[+\]\[+\]" } */
+
+void foo(unsigned int);
+void (*pfn)(enum E) = &foo; /* { dg-warning "incompatible in C\[+\]\[+\]" } */
diff --git a/gcc/testsuite/gcc.dg/Wcxx-compat-13.c b/gcc/testsuite/gcc.dg/Wcxx-compat-13.c
new file mode 100644
index 00000000000..18823964460
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wcxx-compat-13.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-Wc++-compat" } */
+
+int and; /* { dg-warning "operator" } */
+int and_eq; /* { dg-warning "operator" } */
+int bitand; /* { dg-warning "operator" } */
+int bitor; /* { dg-warning "operator" } */
+int compl; /* { dg-warning "operator" } */
+int not; /* { dg-warning "operator" } */
+int not_eq; /* { dg-warning "operator" } */
+int or; /* { dg-warning "operator" } */
+int or_eq; /* { dg-warning "operator" } */
+int xor; /* { dg-warning "operator" } */
+int xor_eq; /* { dg-warning "operator" } */
+
+#define M1 and /* { dg-warning "operator" } */
+#define M2 and_eq /* { dg-warning "operator" } */
+#define M3 bitand /* { dg-warning "operator" } */
+#define M4 bitor /* { dg-warning "operator" } */
+#define M5 compl /* { dg-warning "operator" } */
+#define M6 not /* { dg-warning "operator" } */
+#define M7 not_eq /* { dg-warning "operator" } */
+#define M8 or /* { dg-warning "operator" } */
+#define M9 or_eq /* { dg-warning "operator" } */
+#define M10 xor /* { dg-warning "operator" } */
+#define M11 xor_eq /* { dg-warning "operator" } */
diff --git a/gcc/testsuite/gcc.dg/Wcxx-compat-2.c b/gcc/testsuite/gcc.dg/Wcxx-compat-2.c
index a091c6dd8b5..14edc1a4215 100644
--- a/gcc/testsuite/gcc.dg/Wcxx-compat-2.c
+++ b/gcc/testsuite/gcc.dg/Wcxx-compat-2.c
@@ -1,36 +1,36 @@
/* { dg-options "-Wc++-compat" } */
_Bool foo; /* This is okay. */
-int bool; /* { dg-warning "keyword" } */
-int catch; /* { dg-warning "keyword" } */
-int char16_t; /* { dg-warning "keyword" } */
-int char32_t; /* { dg-warning "keyword" } */
-int class; /* { dg-warning "keyword" } */
-int const_cast; /* { dg-warning "keyword" } */
-int decltype; /* { dg-warning "keyword" } */
-int delete; /* { dg-warning "keyword" } */
-int dynamic_cast; /* { dg-warning "keyword" } */
-int explicit; /* { dg-warning "keyword" } */
-int export; /* { dg-warning "keyword" } */
-int false; /* { dg-warning "keyword" } */
-int friend; /* { dg-warning "keyword" } */
-int mutable; /* { dg-warning "keyword" } */
-int namespace; /* { dg-warning "keyword" } */
-int new; /* { dg-warning "keyword" } */
-int operator; /* { dg-warning "keyword" } */
-int private; /* { dg-warning "keyword" } */
-int protected; /* { dg-warning "keyword" } */
-int public; /* { dg-warning "keyword" } */
-int reinterpret_cast; /* { dg-warning "keyword" } */
-int static_assert; /* { dg-warning "keyword" } */
-int static_cast; /* { dg-warning "keyword" } */
-int template; /* { dg-warning "keyword" } */
-int this; /* { dg-warning "keyword" } */
-int throw; /* { dg-warning "keyword" } */
-int true; /* { dg-warning "keyword" } */
-int try; /* { dg-warning "keyword" } */
-int typename; /* { dg-warning "keyword" } */
-int typeid; /* { dg-warning "keyword" } */
-int using; /* { dg-warning "keyword" } */
-int virtual; /* { dg-warning "keyword" } */
+int bool; /* { dg-warning "5:keyword" } */
+int catch; /* { dg-warning "5:keyword" } */
+int char16_t; /* { dg-warning "5:keyword" } */
+int char32_t; /* { dg-warning "5:keyword" } */
+int class; /* { dg-warning "5:keyword" } */
+int const_cast; /* { dg-warning "5:keyword" } */
+int decltype; /* { dg-warning "5:keyword" } */
+int delete; /* { dg-warning "5:keyword" } */
+int dynamic_cast; /* { dg-warning "5:keyword" } */
+int explicit; /* { dg-warning "5:keyword" } */
+int export; /* { dg-warning "5:keyword" } */
+int false; /* { dg-warning "5:keyword" } */
+int friend; /* { dg-warning "5:keyword" } */
+int mutable; /* { dg-warning "5:keyword" } */
+int namespace; /* { dg-warning "5:keyword" } */
+int new; /* { dg-warning "5:keyword" } */
+int operator; /* { dg-warning "5:keyword" } */
+int private; /* { dg-warning "5:keyword" } */
+int protected; /* { dg-warning "5:keyword" } */
+int public; /* { dg-warning "5:keyword" } */
+int reinterpret_cast; /* { dg-warning "5:keyword" } */
+int static_assert; /* { dg-warning "5:keyword" } */
+int static_cast; /* { dg-warning "5:keyword" } */
+int template; /* { dg-warning "5:keyword" } */
+int this; /* { dg-warning "5:keyword" } */
+int throw; /* { dg-warning "5:keyword" } */
+int true; /* { dg-warning "5:keyword" } */
+int try; /* { dg-warning "5:keyword" } */
+int typename; /* { dg-warning "5:keyword" } */
+int typeid; /* { dg-warning "5:keyword" } */
+int using; /* { dg-warning "5:keyword" } */
+int virtual; /* { dg-warning "5:keyword" } */
int wchar_t;
diff --git a/gcc/testsuite/gcc.dg/Wcxx-compat-9.c b/gcc/testsuite/gcc.dg/Wcxx-compat-9.c
new file mode 100644
index 00000000000..8a3867c11c9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wcxx-compat-9.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-Wc++-compat" } */
+
+enum e { FIRST, LAST };
+
+extern void f2 (enum e);
+
+void
+f1 ()
+{
+ enum e v;
+
+ for (v = FIRST; v < LAST; ++v) /* { dg-warning "invalid in C\[+\]\[+\]" } */
+ f2 (v);
+ for (v = FIRST; v < LAST; v++) /* { dg-warning "invalid in C\[+\]\[+\]" } */
+ f2 (v);
+ for (v = LAST; v > FIRST; --v) /* { dg-warning "invalid in C\[+\]\[+\]" } */
+ f2 (v);
+ for (v = LAST; v > FIRST; v--) /* { dg-warning "invalid in C\[+\]\[+\]" } */
+ f2 (v);
+}
diff --git a/gcc/testsuite/gcc.dg/Wjump-misses-init-1.c b/gcc/testsuite/gcc.dg/Wjump-misses-init-1.c
new file mode 100644
index 00000000000..86117f1f2f0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wjump-misses-init-1.c
@@ -0,0 +1,156 @@
+/* { dg-do compile } */
+/* { dg-options "-Wjump-misses-init" } */
+int
+f1 (int a)
+{
+ if (a > 0)
+ {
+ int i = 7; /* { dg-message "here" } */
+ lab: /* { dg-message "here" } */
+ return a;
+ }
+ else
+ {
+ if (a < 0)
+ goto lab; /* { dg-warning "jump" } */
+ return 1;
+ }
+}
+
+int
+f2 (int a)
+{
+ if (a > 0)
+ {
+ if (a < 0)
+ goto lab; /* { dg-warning "jump" } */
+ return 1;
+ }
+ else
+ {
+ int i = 7; /* { dg-message "here" } */
+ lab: /* { dg-message "here" } */
+ return a;
+ }
+}
+
+int
+f3 (int a)
+{
+ if (a > 0)
+ {
+ static int i = 7;
+ lab:
+ return a;
+ }
+ else
+ {
+ if (a < 0)
+ goto lab;
+ return 1;
+ }
+}
+
+int
+f4 (int a)
+{
+ if (a > 0)
+ {
+ if (a < 0)
+ goto lab;
+ return 1;
+ }
+ else
+ {
+ static int i = 7;
+ lab:
+ return a;
+ }
+}
+
+int
+f5 (int a)
+{
+ if (a > 0)
+ {
+ int b = 1;
+ if (a < 0)
+ goto lab;
+ }
+ lab:
+ return a;
+}
+
+int
+f6 (int a)
+{
+ if (a > 0)
+ {
+ lab:
+ return a;
+ }
+ else
+ {
+ int b = 1;
+ goto lab;
+ }
+}
+
+int
+f7 (int a)
+{
+ switch (a) /* { dg-message "switch" } */
+ {
+ int b = 1; /* { dg-message "here" } */
+
+ case 1: /* { dg-warning "jump" } */
+ return a;
+ }
+}
+
+int
+f8 (int a)
+{
+ switch (a) /* { dg-message "switch" } */
+ {
+ int b = 1; /* { dg-message "here" } */
+
+ case 1: /* { dg-warning "jump" } */
+ goto lab;
+ }
+ lab:
+ return a;
+}
+
+int
+f9 (int a)
+{
+ switch (a)
+ {
+ case 0:
+ {
+ int b = 1;
+ return b;
+ }
+ case 1:
+ return a;
+ }
+}
+
+int
+f10 (int a)
+{
+ switch (a)
+ {
+ case 0:
+ {
+ int b = 1;
+ goto lab;
+ }
+
+ case 1:
+ goto lab;
+ }
+ lab:
+ return a;
+}
diff --git a/gcc/testsuite/gcc.dg/Wjump-misses-init-2.c b/gcc/testsuite/gcc.dg/Wjump-misses-init-2.c
new file mode 100644
index 00000000000..042c02aa7bd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wjump-misses-init-2.c
@@ -0,0 +1,52 @@
+/* { dg-do compile } */
+/* { dg-options "-Wjump-misses-init -std=c99" } */
+extern void f1 ();
+int
+f2 (int a)
+{
+ switch (a) /* { dg-message "switch" } */
+ {
+ case 1:
+ f1 ();
+ int v2 = 3; /* { dg-message "here" } */
+ case 2: /* { dg-warning "jump" } */
+ if (v2 == 7)
+ f1 ();
+ }
+ return 0;
+}
+
+int
+f3 (int i)
+{
+ if (i)
+ goto bad; /* { dg-warning "jump" } */
+ int a = f2 (i); /* { dg-message "here" } */
+ bad: /* { dg-message "here" } */
+ return a;
+}
+
+int
+f4 (int a)
+{
+ switch (a)
+ {
+ case 1:
+ f1 ();
+ static int v2 = 3;
+ case 2:
+ if (v2 == 7)
+ f1 ();
+ }
+ return 0;
+}
+
+int
+f5 (int i)
+{
+ if (i)
+ goto bad;
+ static int a = 6;
+ bad:
+ return a;
+}
diff --git a/gcc/testsuite/gcc.dg/Wredundant-decls-2.c b/gcc/testsuite/gcc.dg/Wredundant-decls-2.c
index 89f57b427c6..27c8e5d9f7d 100644
--- a/gcc/testsuite/gcc.dg/Wredundant-decls-2.c
+++ b/gcc/testsuite/gcc.dg/Wredundant-decls-2.c
@@ -2,22 +2,22 @@
/* { dg-do compile } */
/* { dg-options "-Wredundant-decls" } */
-int j = 5; /* { dg-message "note: previous" } */
-int j; /* { dg-warning "redundant" } */
+int j = 5; /* { dg-message "5:note: previous" } */
+int j; /* { dg-warning "5:redundant" } */
static int k;
-static int k = 5; /* { dg-message "note: previous" } */
-static int k; /* { dg-warning "redundant" } */
+static int k = 5; /* { dg-message "12:note: previous" } */
+static int k; /* { dg-warning "12:redundant" } */
-static int l = 5; /* { dg-message "note: previous" } */
-static int l; /* { dg-warning "redundant" } */
+static int l = 5; /* { dg-message "12:note: previous" } */
+static int l; /* { dg-warning "12:redundant" } */
-static int m; /* { dg-message "note: previous" } */
-static int m; /* { dg-warning "redundant" } */
+static int m; /* { dg-message "12:note: previous" } */
+static int m; /* { dg-warning "12:redundant" } */
static int m = 5;
-int n; /* { dg-message "note: previous" } */
-int n; /* { dg-warning "redundant" } */
+int n; /* { dg-message "5:note: previous" } */
+int n; /* { dg-warning "5:redundant" } */
int n = 5;
static int o;
diff --git a/gcc/testsuite/gcc.dg/Wshadow-3.c b/gcc/testsuite/gcc.dg/Wshadow-3.c
index a7f06a26f96..b6d78b1d38b 100644
--- a/gcc/testsuite/gcc.dg/Wshadow-3.c
+++ b/gcc/testsuite/gcc.dg/Wshadow-3.c
@@ -1,21 +1,61 @@
-/* Test warnings for shadowing in function prototype scope: generally
- useless but of use if the parameter is used within the scope. Bug
- 529. */
-/* Origin: Joseph Myers <joseph@codesourcery.com> */
+/* PR middle-end/36902 Array bound warning with dead code after optimization */
/* { dg-do compile } */
-/* { dg-options "-std=gnu89 -Wshadow" } */
-
-int v; /* { dg-warning "shadowed declaration" } */
-int f1(int v);
-int f2(int v, int x[v]); /* { dg-warning "declaration of 'v' shadows a global declaration" } */
-int f3(int v, int y[sizeof(v)]); /* { dg-warning "declaration of 'v' shadows a global declaration" } */
-int f4(int v) { return 0; } /* { dg-warning "declaration of 'v' shadows a global declaration" } */
-int f5(int v, int x[v]) { return 0; } /* { dg-warning "declaration of 'v' shadows a global declaration" } */
-int f6(int x) { return 0; }
-int f7(v) int v; { return 0; } /* { dg-warning "declaration of 'v' shadows a global declaration" } */
-int f8(v, w) int v; int w[v]; { return 0; } /* { dg-warning "declaration of 'v' shadows a global declaration" } */
-int f9(x) int x; { return 0; }
-int f10(v) { return 0; } /* { dg-warning "declaration of 'v' shadows a global declaration" } */
-int f11(int a, int b(int a));
-int f12(int a, int b(int a, int x[a])); /* { dg-warning "declaration of 'a' shadows a parameter" } */
-/* { dg-warning "shadowed declaration" "outer parm" { target *-*-* } 20 } */
+/* { dg-options "-O2 -Warray-bounds -Wall -Wextra" } */
+typedef unsigned char __u8;
+typedef unsigned short __u16;
+
+static inline unsigned char *
+foo(unsigned char * to, const unsigned char * from, int n)
+{
+ switch ( n )
+ {
+ case 3:
+ *to = *from;
+ break;
+ case 5:
+ to[4] = from [4];
+ break;
+ }
+ return to;
+}
+
+struct {
+ int size_of_select;
+ unsigned char pcr_select[4];
+} sel;
+
+int bar(void)
+{
+ static unsigned char buf[64];
+
+ sel.size_of_select = 3;
+ foo(buf, sel.pcr_select, sel.size_of_select);
+
+ return 1;
+}
+
+
+static inline unsigned char *
+foo2(unsigned char * to, const unsigned char * from, int n)
+{
+ switch ( n )
+ {
+ case 3:
+ *to = *from;
+ break;
+ case 5:
+ to[63] = from [111]; /* { dg-warning "array subscript is above array bounds" } */
+ break;
+ }
+ return to;
+}
+
+int baz(void)
+{
+ static unsigned char buf[64];
+
+ sel.size_of_select = 5;
+ foo2(buf, sel.pcr_select, sel.size_of_select);
+
+ return 1;
+}
diff --git a/gcc/testsuite/gcc.dg/Wstrict-aliasing-converted-assigned.c b/gcc/testsuite/gcc.dg/Wstrict-aliasing-converted-assigned.c
index 1fef7947c9b..b77373d56bd 100644
--- a/gcc/testsuite/gcc.dg/Wstrict-aliasing-converted-assigned.c
+++ b/gcc/testsuite/gcc.dg/Wstrict-aliasing-converted-assigned.c
@@ -9,5 +9,5 @@ int foo()
return i;
}
-/* { dg-message "does break strict-aliasing" "" { target { *-*-* && lp64 } } 8 } */
-/* { dg-message "initialized" "" { target { *-*-* && lp64 } } 8 } */
+/* { dg-message "does break strict-aliasing" "" { target { *-*-* && lp64 } xfail *-*-* } 8 } */
+/* { dg-message "initialized" "" { target { *-*-* && lp64 } xfail *-*-* } 8 } */
diff --git a/gcc/testsuite/gcc.dg/Wstrict-aliasing-float-ptr-int-obj.c b/gcc/testsuite/gcc.dg/Wstrict-aliasing-float-ptr-int-obj.c
index fccc178d224..b90fb76c28b 100644
--- a/gcc/testsuite/gcc.dg/Wstrict-aliasing-float-ptr-int-obj.c
+++ b/gcc/testsuite/gcc.dg/Wstrict-aliasing-float-ptr-int-obj.c
@@ -11,12 +11,12 @@ int foo() {
float* r;
if (flag) {
- q = (float*) &x; /* { dg-message "initialized" } */
+ q = (float*) &x; /* { dg-message "initialized" "" { xfail *-*-* } } */
} else {
- q = (float*) &y; /* { dg-message "initialized" } */
+ q = (float*) &y; /* { dg-message "initialized" "" { xfail *-*-* } } */
}
- *q = 1.0; /* { dg-warning "does break strict-aliasing" } */
+ *q = 1.0; /* { dg-warning "does break strict-aliasing" "" { xfail *-*-* } } */
return x;
diff --git a/gcc/testsuite/gcc.dg/Wswitch-enum-error.c b/gcc/testsuite/gcc.dg/Wswitch-enum-error.c
index ae9a2c78353..383a29fba9d 100644
--- a/gcc/testsuite/gcc.dg/Wswitch-enum-error.c
+++ b/gcc/testsuite/gcc.dg/Wswitch-enum-error.c
@@ -56,7 +56,7 @@ foo (int i, int j, enum e ei, enum e ej, enum e ek, enum e el,
{
case e1: return 1;
case e2: return 2;
- case 3: return 3; /* { dg-error "case value '3' not in enumerated type 'enum e'" "excess 3" } */
+ case 3: return 3; /* { dg-warning "case value '3' not in enumerated type 'enum e'" "excess 3" } */
default: break;
}
return 0;
diff --git a/gcc/testsuite/gcc.dg/Wswitch-error.c b/gcc/testsuite/gcc.dg/Wswitch-error.c
index 4aa0c2a15b5..31e32957963 100644
--- a/gcc/testsuite/gcc.dg/Wswitch-error.c
+++ b/gcc/testsuite/gcc.dg/Wswitch-error.c
@@ -56,7 +56,7 @@ foo (int i, int j, enum e ei, enum e ej, enum e ek, enum e el,
{
case e1: return 1;
case e2: return 2;
- case 3: return 3; /* { dg-warning "case value '3' not in enumerated type 'enum e'" "excess 3" } */
+ case 3: return 3; /* { dg-error "case value '3' not in enumerated type 'enum e'" "excess 3" } */
default: break;
}
return 0;
diff --git a/gcc/testsuite/gcc.dg/Wswitch.c b/gcc/testsuite/gcc.dg/Wswitch.c
index 686fd41614c..9b43ed445b3 100644
--- a/gcc/testsuite/gcc.dg/Wswitch.c
+++ b/gcc/testsuite/gcc.dg/Wswitch.c
@@ -56,8 +56,8 @@ foo (int i, int j, enum e ei, enum e ej, enum e ek, enum e el,
{
case e1: return 1;
case e2: return 2;
- case 3: return 3;
+ case 3: return 3; /* { dg-warning "case value '3' not in enumerated type 'enum e'" "excess 3" } */
default: break;
- } /* Since there is a default, no warning about ``case 3'' */
+ }
return 0;
}
diff --git a/gcc/testsuite/gcc.dg/Wunused-label-1.c b/gcc/testsuite/gcc.dg/Wunused-label-1.c
new file mode 100644
index 00000000000..1840a8008f4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wunused-label-1.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-Wunused-label" } */
+
+extern void f2 ();
+
+void
+f1 ()
+{
+ l1: f2 (); /* { dg-warning "not used" } */
+ l2: __attribute__ ((unused)) f2 ();
+ l3: ; f2 (); /* { dg-warning "not used" } */
+ l4: __attribute__ ((unused)) ; f2 ();
+}
diff --git a/gcc/testsuite/gcc.dg/array-10.c b/gcc/testsuite/gcc.dg/array-10.c
index aab1538d5e1..3b4d512ba5a 100644
--- a/gcc/testsuite/gcc.dg/array-10.c
+++ b/gcc/testsuite/gcc.dg/array-10.c
@@ -6,28 +6,28 @@
int a;
-int b0[a]; /* { dg-error "at file scope" } */
-int (*b1)[a]; /* { dg-error "at file scope" } */
+int b0[a]; /* { dg-error "5:at file scope" } */
+int (*b1)[a]; /* { dg-error "7:at file scope" } */
int (*b2())[a]; /* { dg-error "at file scope" } */
-struct b3 { int x[a]; }; /* { dg-error "at file scope" } */
-struct b4 { int (*x)[a]; }; /* { dg-error "at file scope" } */
+struct b3 { int x[a]; }; /* { dg-error "17:at file scope" } */
+struct b4 { int (*x)[a]; }; /* { dg-error "19:at file scope" } */
typeof (int [a]) b5; /* { dg-error "at file scope|outside of any function" } */
-int c0[(__SIZE_TYPE__)&a]; /* { dg-error "at file scope" } */
-int (*c1)[(__SIZE_TYPE__)&a]; /* { dg-error "at file scope" } */
-int (*c2())[(__SIZE_TYPE__)&a]; /* { dg-error "at file scope" } */
-struct c3 { int x[(__SIZE_TYPE__)&a]; }; /* { dg-error "at file scope" } */
-struct c4 { int (*x)[(__SIZE_TYPE__)&a]; }; /* { dg-error "at file scope" } */
-typeof (int [(__SIZE_TYPE__)&a]) c5; /* { dg-error "at file scope" } */
+int c0[(__SIZE_TYPE__)&a]; /* { dg-error "5:at file scope" } */
+int (*c1)[(__SIZE_TYPE__)&a]; /* { dg-error "7:at file scope" } */
+int (*c2())[(__SIZE_TYPE__)&a]; /* { dg-error "7:at file scope" } */
+struct c3 { int x[(__SIZE_TYPE__)&a]; }; /* { dg-error "17:at file scope" } */
+struct c4 { int (*x)[(__SIZE_TYPE__)&a]; }; /* { dg-error "19:at file scope" } */
+typeof (int [(__SIZE_TYPE__)&a]) c5; /* { dg-error "34:at file scope" } */
-int d0[1/0]; /* { dg-error "at file scope" } */
-/* { dg-warning "division by zero" "" { target *-*-* } 23 } */
-int (*d1)[1/0]; /* { dg-error "at file scope" } */
-/* { dg-warning "division by zero" "" { target *-*-* } 25 } */
-int (*d2())[1/0]; /* { dg-error "at file scope" } */
-/* { dg-warning "division by zero" "" { target *-*-* } 27 } */
-struct d3 { int x[1/0]; }; /* { dg-error "at file scope" } */
-/* { dg-warning "division by zero" "" { target *-*-* } 29 } */
-struct d4 { int (*x)[1/0]; }; /* { dg-error "at file scope" } */
-/* { dg-warning "division by zero" "" { target *-*-* } 31 } */
-typeof (int [1/0]) d5; /* { dg-error "at file scope" } */
+int d0[1/0]; /* { dg-error "5:at file scope" } */
+/* { dg-warning "9:division by zero" "" { target *-*-* } 23 } */
+int (*d1)[1/0]; /* { dg-error "7:at file scope" } */
+/* { dg-warning "12:division by zero" "" { target *-*-* } 25 } */
+int (*d2())[1/0]; /* { dg-error "7:at file scope" } */
+/* { dg-warning "14:division by zero" "" { target *-*-* } 27 } */
+struct d3 { int x[1/0]; }; /* { dg-error "17:at file scope" } */
+/* { dg-warning "20:division by zero" "" { target *-*-* } 29 } */
+struct d4 { int (*x)[1/0]; }; /* { dg-error "19:at file scope" } */
+/* { dg-warning "23:division by zero" "" { target *-*-* } 31 } */
+typeof (int [1/0]) d5; /* { dg-error "20:at file scope" } */
diff --git a/gcc/testsuite/gcc.dg/asm-wide-1.c b/gcc/testsuite/gcc.dg/asm-wide-1.c
index a42271fd4b1..c14b19d3479 100644
--- a/gcc/testsuite/gcc.dg/asm-wide-1.c
+++ b/gcc/testsuite/gcc.dg/asm-wide-1.c
@@ -3,27 +3,27 @@
/* { dg-do compile } */
/* { dg-options "" } */
-int foo asm (L"bar"); /* { dg-error "wide string literal in 'asm'" } */
+int foo asm (L"bar"); /* { dg-error "14:wide string literal in 'asm'" } */
-asm (L"foo"); /* { dg-error "wide string literal in 'asm'" } */
+asm (L"foo"); /* { dg-error "6:wide string literal in 'asm'" } */
void
f (void)
{
int x = 1;
- asm (L"foo"); /* { dg-error "wide string literal in 'asm'" } */
+ asm (L"foo"); /* { dg-error "8:wide string literal in 'asm'" } */
asm ("foo" :
- L"=g" (x)); /* { dg-error "wide string literal in 'asm'" } */
+ L"=g" (x)); /* { dg-error "8:wide string literal in 'asm'" } */
asm ("foo" : [x]
- L"=g" (x)); /* { dg-error "wide string literal in 'asm'" } */
+ L"=g" (x)); /* { dg-error "8:wide string literal in 'asm'" } */
asm ("foo" : [x] "=g" (x),
- L"=g" (x)); /* { dg-error "wide string literal in 'asm'" } */
+ L"=g" (x)); /* { dg-error "8:wide string literal in 'asm'" } */
asm ("foo" : :
- L"g" (x)); /* { dg-error "wide string literal in 'asm'" } */
+ L"g" (x)); /* { dg-error "8:wide string literal in 'asm'" } */
asm ("foo" : : :
- L"memory"); /* { dg-error "wide string literal in 'asm'" } */
+ L"memory"); /* { dg-error "8:wide string literal in 'asm'" } */
asm ("foo" : : : "memory",
- L"memory"); /* { dg-error "wide string literal in 'asm'" } */
+ L"memory"); /* { dg-error "8:wide string literal in 'asm'" } */
}
/* Extra errors from the substitution of "" for wide strings: */
diff --git a/gcc/testsuite/gcc.dg/builtin-object-size-2.c b/gcc/testsuite/gcc.dg/builtin-object-size-2.c
index 4071c2516ee..34f16759d68 100644
--- a/gcc/testsuite/gcc.dg/builtin-object-size-2.c
+++ b/gcc/testsuite/gcc.dg/builtin-object-size-2.c
@@ -130,15 +130,15 @@ test1 (void *q, int x)
abort ();
if (__builtin_object_size (&vara[5], 1) != (size_t) -1)
abort ();
- if (__builtin_object_size (&vara[0].a, 1) != (size_t) -1)
+ if (__builtin_object_size (&vara[0].a, 1) != sizeof (vara[0].a))
abort ();
- if (__builtin_object_size (&vara[10].a[0], 1) != (size_t) -1)
+ if (__builtin_object_size (&vara[10].a[0], 1) != sizeof (vara[0].a))
abort ();
- if (__builtin_object_size (&vara[5].a[4], 1) != (size_t) -1)
+ if (__builtin_object_size (&vara[5].a[4], 1) != sizeof (vara[0].a) - 4)
abort ();
- if (__builtin_object_size (&vara[5].b, 1) != (size_t) -1)
+ if (__builtin_object_size (&vara[5].b, 1) != sizeof (vara[0].b))
abort ();
- if (__builtin_object_size (&vara[7].c[7], 1) != (size_t) -1)
+ if (__builtin_object_size (&vara[7].c[7], 1) != sizeof (vara[0].c) - 7)
abort ();
if (__builtin_object_size (zerol, 1) != 0)
abort ();
diff --git a/gcc/testsuite/gcc.dg/builtin-object-size-4.c b/gcc/testsuite/gcc.dg/builtin-object-size-4.c
index 453c2d01921..1eb30d1ba53 100644
--- a/gcc/testsuite/gcc.dg/builtin-object-size-4.c
+++ b/gcc/testsuite/gcc.dg/builtin-object-size-4.c
@@ -130,15 +130,15 @@ test1 (void *q, int x)
abort ();
if (__builtin_object_size (&vara[5], 3) != 0)
abort ();
- if (__builtin_object_size (&vara[0].a, 3) != 0)
+ if (__builtin_object_size (&vara[0].a, 3) != sizeof (vara[0].a))
abort ();
- if (__builtin_object_size (&vara[10].a[0], 3) != 0)
+ if (__builtin_object_size (&vara[10].a[0], 3) != sizeof (vara[0].a))
abort ();
- if (__builtin_object_size (&vara[5].a[4], 3) != 0)
+ if (__builtin_object_size (&vara[5].a[4], 3) != sizeof (vara[0].a) - 4)
abort ();
- if (__builtin_object_size (&vara[5].b, 3) != 0)
+ if (__builtin_object_size (&vara[5].b, 3) != sizeof (vara[0].b))
abort ();
- if (__builtin_object_size (&vara[7].c[7], 3) != 0)
+ if (__builtin_object_size (&vara[7].c[7], 3) != sizeof (vara[0].c) - 7)
abort ();
if (__builtin_object_size (zerol, 3) != 0)
abort ();
diff --git a/gcc/testsuite/gcc.dg/builtin-object-size-6.c b/gcc/testsuite/gcc.dg/builtin-object-size-6.c
new file mode 100644
index 00000000000..9a285dfb883
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtin-object-size-6.c
@@ -0,0 +1,435 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+typedef __SIZE_TYPE__ size_t;
+extern void abort (void);
+extern void exit (int);
+extern void *malloc (size_t);
+extern void free (void *);
+
+struct A
+{
+ char a[10];
+ int b;
+ char c[10];
+};
+
+void
+__attribute__ ((noinline))
+test1 (struct A *p)
+{
+ char *c;
+ if (__builtin_object_size (&p->a, 0) != (size_t) -1)
+ abort ();
+ if (__builtin_object_size (&p->a[0], 0) != (size_t) -1)
+ abort ();
+ if (__builtin_object_size (&p->a[3], 0) != (size_t) -1)
+ abort ();
+ if (__builtin_object_size (&p->b, 0) != (size_t) -1)
+ abort ();
+ if (__builtin_object_size (&p->c, 0) != (size_t) -1)
+ abort ();
+ c = p->a;
+ if (__builtin_object_size (c, 0) != (size_t) -1)
+ abort ();
+ c = &p->a[0];
+ if (__builtin_object_size (c, 0) != (size_t) -1)
+ abort ();
+ c = &p->a[3];
+ if (__builtin_object_size (c, 0) != (size_t) -1)
+ abort ();
+ c = (char *) &p->b;
+ if (__builtin_object_size (c, 0) != (size_t) -1)
+ abort ();
+ c = (char *) &p->c;
+ if (__builtin_object_size (c, 0) != (size_t) -1)
+ abort ();
+ if (__builtin_object_size (&p->a, 1) != sizeof (p->a))
+ abort ();
+ if (__builtin_object_size (&p->a[0], 1) != sizeof (p->a))
+ abort ();
+ if (__builtin_object_size (&p->a[3], 1) != sizeof (p->a) - 3)
+ abort ();
+ if (__builtin_object_size (&p->b, 1) != sizeof (p->b))
+ abort ();
+ if (__builtin_object_size (&p->c, 1) != (size_t) -1)
+ abort ();
+ c = p->a;
+ if (__builtin_object_size (c, 1) != sizeof (p->a))
+ abort ();
+ c = &p->a[0];
+ if (__builtin_object_size (c, 1) != sizeof (p->a))
+ abort ();
+ c = &p->a[3];
+ if (__builtin_object_size (c, 1) != sizeof (p->a) - 3)
+ abort ();
+ c = (char *) &p->b;
+ if (__builtin_object_size (c, 1) != sizeof (p->b))
+ abort ();
+ c = (char *) &p->c;
+ if (__builtin_object_size (c, 1) != (size_t) -1)
+ abort ();
+ if (__builtin_object_size (&p->a, 2) != 0)
+ abort ();
+ if (__builtin_object_size (&p->a[0], 2) != 0)
+ abort ();
+ if (__builtin_object_size (&p->a[3], 2) != 0)
+ abort ();
+ if (__builtin_object_size (&p->b, 2) != 0)
+ abort ();
+ if (__builtin_object_size (&p->c, 2) != 0)
+ abort ();
+ c = p->a;
+ if (__builtin_object_size (c, 2) != 0)
+ abort ();
+ c = &p->a[0];
+ if (__builtin_object_size (c, 2) != 0)
+ abort ();
+ c = &p->a[3];
+ if (__builtin_object_size (c, 2) != 0)
+ abort ();
+ c = (char *) &p->b;
+ if (__builtin_object_size (c, 2) != 0)
+ abort ();
+ c = (char *) &p->c;
+ if (__builtin_object_size (c, 2) != 0)
+ abort ();
+ if (__builtin_object_size (&p->a, 3) != sizeof (p->a))
+ abort ();
+ if (__builtin_object_size (&p->a[0], 3) != sizeof (p->a))
+ abort ();
+ if (__builtin_object_size (&p->a[3], 3) != sizeof (p->a) - 3)
+ abort ();
+ if (__builtin_object_size (&p->b, 3) != sizeof (p->b))
+ abort ();
+ if (__builtin_object_size (&p->c, 3) != 0)
+ abort ();
+ c = p->a;
+ if (__builtin_object_size (c, 3) != sizeof (p->a))
+ abort ();
+ c = &p->a[0];
+ if (__builtin_object_size (c, 3) != sizeof (p->a))
+ abort ();
+ c = &p->a[3];
+ if (__builtin_object_size (c, 3) != sizeof (p->a) - 3)
+ abort ();
+ c = (char *) &p->b;
+ if (__builtin_object_size (c, 3) != sizeof (p->b))
+ abort ();
+ c = (char *) &p->c;
+ if (__builtin_object_size (c, 3) != 0)
+ abort ();
+}
+
+void
+__attribute__ ((noinline))
+test2 (void)
+{
+ char *c;
+ size_t s = 2 * sizeof (struct A);
+ struct A *p = malloc (2 * sizeof (struct A));
+ if (__builtin_object_size (&p->a, 0) != s)
+ abort ();
+ if (__builtin_object_size (&p->a[0], 0) != s)
+ abort ();
+ if (__builtin_object_size (&p->a[3], 0) != s - 3)
+ abort ();
+ if (__builtin_object_size (&p->b, 0) != s - __builtin_offsetof (struct A, b))
+ abort ();
+ if (__builtin_object_size (&p->c, 0) != s - __builtin_offsetof (struct A, c))
+ abort ();
+ c = p->a;
+ if (__builtin_object_size (c, 0) != s)
+ abort ();
+ c = &p->a[0];
+ if (__builtin_object_size (c, 0) != s)
+ abort ();
+ c = &p->a[3];
+ if (__builtin_object_size (c, 0) != s - 3)
+ abort ();
+ c = (char *) &p->b;
+ if (__builtin_object_size (c, 0) != s - __builtin_offsetof (struct A, b))
+ abort ();
+ c = (char *) &p->c;
+ if (__builtin_object_size (c, 0) != s - __builtin_offsetof (struct A, c))
+ abort ();
+ if (__builtin_object_size (&p->a, 1) != sizeof (p->a))
+ abort ();
+ if (__builtin_object_size (&p->a[0], 1) != sizeof (p->a))
+ abort ();
+ if (__builtin_object_size (&p->a[3], 1) != sizeof (p->a) - 3)
+ abort ();
+ if (__builtin_object_size (&p->b, 1) != sizeof (p->b))
+ abort ();
+ if (__builtin_object_size (&p->c, 1) != s - __builtin_offsetof (struct A, c))
+ abort ();
+ c = p->a;
+ if (__builtin_object_size (c, 1) != sizeof (p->a))
+ abort ();
+ c = &p->a[0];
+ if (__builtin_object_size (c, 1) != sizeof (p->a))
+ abort ();
+ c = &p->a[3];
+ if (__builtin_object_size (c, 1) != sizeof (p->a) - 3)
+ abort ();
+ c = (char *) &p->b;
+ if (__builtin_object_size (c, 1) != sizeof (p->b))
+ abort ();
+ c = (char *) &p->c;
+ if (__builtin_object_size (c, 1) != s - __builtin_offsetof (struct A, c))
+ abort ();
+ if (__builtin_object_size (&p->a, 2) != s)
+ abort ();
+ if (__builtin_object_size (&p->a[0], 2) != s)
+ abort ();
+ if (__builtin_object_size (&p->a[3], 2) != s - 3)
+ abort ();
+ if (__builtin_object_size (&p->b, 2) != s - __builtin_offsetof (struct A, b))
+ abort ();
+ if (__builtin_object_size (&p->c, 2) != s - __builtin_offsetof (struct A, c))
+ abort ();
+ c = p->a;
+ if (__builtin_object_size (c, 2) != s)
+ abort ();
+ c = &p->a[0];
+ if (__builtin_object_size (c, 2) != s)
+ abort ();
+ c = &p->a[3];
+ if (__builtin_object_size (c, 2) != s - 3)
+ abort ();
+ c = (char *) &p->b;
+ if (__builtin_object_size (c, 2) != s - __builtin_offsetof (struct A, b))
+ abort ();
+ c = (char *) &p->c;
+ if (__builtin_object_size (c, 2) != s - __builtin_offsetof (struct A, c))
+ abort ();
+ if (__builtin_object_size (&p->a, 3) != sizeof (p->a))
+ abort ();
+ if (__builtin_object_size (&p->a[0], 3) != sizeof (p->a))
+ abort ();
+ if (__builtin_object_size (&p->a[3], 3) != sizeof (p->a) - 3)
+ abort ();
+ if (__builtin_object_size (&p->b, 3) != sizeof (p->b))
+ abort ();
+ if (__builtin_object_size (&p->c, 3) != s - __builtin_offsetof (struct A, c))
+ abort ();
+ c = p->a;
+ if (__builtin_object_size (c, 3) != sizeof (p->a))
+ abort ();
+ c = &p->a[0];
+ if (__builtin_object_size (c, 3) != sizeof (p->a))
+ abort ();
+ c = &p->a[3];
+ if (__builtin_object_size (c, 3) != sizeof (p->a) - 3)
+ abort ();
+ c = (char *) &p->b;
+ if (__builtin_object_size (c, 3) != sizeof (p->b))
+ abort ();
+ c = (char *) &p->c;
+ if (__builtin_object_size (c, 3) != s - __builtin_offsetof (struct A, c))
+ abort ();
+ free (p);
+}
+
+void
+__attribute__ ((noinline))
+test3 (void)
+{
+ char *c;
+ size_t s;
+ struct A *p = malloc (4);
+ if (__builtin_object_size (&p->a, 0) != 4)
+ abort ();
+ if (__builtin_object_size (&p->a[0], 0) != 4)
+ abort ();
+ if (__builtin_object_size (&p->a[3], 0) != 1)
+ abort ();
+ if (__builtin_object_size (&p->b, 0) != 0)
+ abort ();
+ if (__builtin_object_size (&p->c, 0) != 0)
+ abort ();
+ if (__builtin_object_size (&p->a, 1) != 4)
+ abort ();
+ if (__builtin_object_size (&p->a[0], 1) != 4)
+ abort ();
+ if (__builtin_object_size (&p->a[3], 1) != 1)
+ abort ();
+ if (__builtin_object_size (&p->b, 1) != 0)
+ abort ();
+ if (__builtin_object_size (&p->c, 1) != 0)
+ abort ();
+ free (p);
+ s = __builtin_offsetof (struct A, c) + 4;
+ p = malloc (s);
+ if (__builtin_object_size (&p->a, 0) != s)
+ abort ();
+ if (__builtin_object_size (&p->a[0], 0) != s)
+ abort ();
+ if (__builtin_object_size (&p->a[3], 0) != s - 3)
+ abort ();
+ if (__builtin_object_size (&p->b, 0) != s - __builtin_offsetof (struct A, b))
+ abort ();
+ if (__builtin_object_size (&p->c, 0) != 4)
+ abort ();
+ if (__builtin_object_size (&p->a, 1) != sizeof (p->a))
+ abort ();
+ if (__builtin_object_size (&p->a[0], 1) != sizeof (p->a))
+ abort ();
+ if (__builtin_object_size (&p->a[3], 1) != sizeof (p->a) - 3)
+ abort ();
+ if (__builtin_object_size (&p->b, 1) != sizeof (p->b))
+ abort ();
+ if (__builtin_object_size (&p->c, 1) != 4)
+ abort ();
+ free (p);
+}
+
+struct B
+{
+ struct A a[4];
+};
+
+void
+__attribute__ ((noinline))
+test4 (struct B *q, int i)
+{
+ if (__builtin_object_size (&q->a[2].a[2], 1) != sizeof (q->a[0].a) - 2)
+ abort ();
+ if (__builtin_object_size (&q->a[2].c[2], 1) != sizeof (q->a[0].c) - 2)
+ abort ();
+ if (__builtin_object_size (&q->a[3].a[2], 1) != sizeof (q->a[0].a) - 2)
+ abort ();
+ if (__builtin_object_size (&q->a[3].c[2], 1) != sizeof (q->a[0].c) - 2)
+ abort ();
+ if (__builtin_object_size (&q->a[i].a[2], 1) != sizeof (q->a[0].a) - 2)
+ abort ();
+ if (__builtin_object_size (&q->a[i].c[2], 1) != sizeof (q->a[0].c) - 2)
+ abort ();
+}
+
+struct C
+{
+ char a[10];
+ char b;
+};
+
+void
+__attribute__ ((noinline))
+test5 (struct C *c)
+{
+ if (__builtin_object_size (&c->b, 0) != (size_t) -1)
+ abort ();
+ if (__builtin_object_size (&c->b, 1) != 1)
+ abort ();
+ if (__builtin_object_size (&c->b, 2) != 0)
+ abort ();
+ if (__builtin_object_size (&c->b, 3) != 1)
+ abort ();
+}
+
+struct D
+{
+ int i;
+ struct D1
+ {
+ char b;
+ char a[10];
+ } j;
+};
+
+void
+__attribute__ ((noinline))
+test6 (struct D *d)
+{
+ if (__builtin_object_size (&d->j.a[3], 0) != (size_t) -1)
+ abort ();
+ if (__builtin_object_size (&d->j.a[3], 1) != sizeof (d->j.a) - 3)
+ abort ();
+ if (__builtin_object_size (&d->j.a[3], 2) != 0)
+ abort ();
+ if (__builtin_object_size (&d->j.a[3], 3) != sizeof (d->j.a) - 3)
+ abort ();
+}
+
+struct E
+{
+ int i;
+ struct E1
+ {
+ char b;
+ char a[10];
+ } j[1];
+};
+
+void
+__attribute__ ((noinline))
+test7 (struct E *e)
+{
+ if (__builtin_object_size (&e->j[0].a[3], 0) != (size_t) -1)
+ abort ();
+ if (__builtin_object_size (&e->j[0].a[3], 1) != sizeof (e->j[0].a) - 3)
+ abort ();
+ if (__builtin_object_size (&e->j[0].a[3], 2) != 0)
+ abort ();
+ if (__builtin_object_size (&e->j[0].a[3], 3) != sizeof (e->j[0].a) - 3)
+ abort ();
+ if (__builtin_object_size ((char *) &e->j[0], 0) != (size_t) -1)
+ abort ();
+ if (__builtin_object_size ((char *) &e->j[0], 1) != (size_t) -1)
+ abort ();
+ if (__builtin_object_size ((char *) &e->j[0], 2) != 0)
+ abort ();
+ if (__builtin_object_size ((char *) &e->j[0], 3) != 0)
+ abort ();
+}
+
+union F
+{
+ char a[1];
+ struct F1
+ {
+ char b;
+ char c[10];
+ } d;
+};
+
+void
+__attribute__ ((noinline))
+test8 (union F *f)
+{
+ if (__builtin_object_size (&f->d.c[3], 0) != (size_t) -1)
+ abort ();
+ if (__builtin_object_size (&f->d.c[3], 1) != sizeof (f->d.c) - 3)
+ abort ();
+ if (__builtin_object_size (&f->d.c[3], 2) != 0)
+ abort ();
+ if (__builtin_object_size (&f->d.c[3], 3) != sizeof (f->d.c) - 3)
+ abort ();
+}
+
+int
+main (void)
+{
+ struct A a, *p = &a;
+ int i = 1;
+ __asm ("" : "+r" (p));
+ test1 (p);
+ test2 ();
+ test3 ();
+ struct B b, *q = &b;
+ __asm ("" : "+r" (q), "+r" (i));
+ test4 (q, i);
+ struct C c, *cp = &c;
+ __asm ("" : "+r" (cp));
+ test5 (cp);
+ struct D d, *dp = &d;
+ __asm ("" : "+r" (dp));
+ test6 (dp);
+ struct E e, *ep = &e;
+ __asm ("" : "+r" (ep));
+ test7 (ep);
+ union F f, *fp = &f;
+ __asm ("" : "+r" (fp));
+ test8 (fp);
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/builtin-object-size-7.c b/gcc/testsuite/gcc.dg/builtin-object-size-7.c
new file mode 100644
index 00000000000..41742b974ef
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtin-object-size-7.c
@@ -0,0 +1,71 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+typedef __SIZE_TYPE__ size_t;
+extern void *malloc (size_t);
+extern void abort (void);
+
+struct A
+{
+ int i, j, k;
+ char buf[255];
+ int l, m, n, o;
+};
+
+int
+main (void)
+{
+ const size_t s = sizeof (struct A);
+ const size_t o = __builtin_offsetof (struct A, buf);
+ struct A *a = malloc (s);
+ struct A *b = malloc (o + 212);
+ if (__builtin_object_size (a->buf, 0) != s - o)
+ abort ();
+ if (__builtin_object_size (a->buf, 1) != sizeof (a->buf))
+ abort ();
+ if (__builtin_object_size (a->buf, 2) != s - o)
+ abort ();
+ if (__builtin_object_size (a->buf, 3) != sizeof (a->buf))
+ abort ();
+ if (__builtin_object_size (&a->buf[0], 0) != s - o)
+ abort ();
+ if (__builtin_object_size (&a->buf[0], 1) != sizeof (a->buf))
+ abort ();
+ if (__builtin_object_size (&a->buf[0], 2) != s - o)
+ abort ();
+ if (__builtin_object_size (&a->buf[0], 3) != sizeof (a->buf))
+ abort ();
+ if (__builtin_object_size (&a->buf[6], 0) != s - o - 6)
+ abort ();
+ if (__builtin_object_size (&a->buf[6], 1) != sizeof (a->buf) - 6)
+ abort ();
+ if (__builtin_object_size (&a->buf[6], 2) != s - o - 6)
+ abort ();
+ if (__builtin_object_size (&a->buf[6], 3) != sizeof (a->buf) - 6)
+ abort ();
+ if (__builtin_object_size (b->buf, 0) != 212)
+ abort ();
+ if (__builtin_object_size (b->buf, 1) != 212)
+ abort ();
+ if (__builtin_object_size (b->buf, 2) != 212)
+ abort ();
+ if (__builtin_object_size (b->buf, 3) != 212)
+ abort ();
+ if (__builtin_object_size (&b->buf[0], 0) != 212)
+ abort ();
+ if (__builtin_object_size (&b->buf[0], 1) != 212)
+ abort ();
+ if (__builtin_object_size (&b->buf[0], 2) != 212)
+ abort ();
+ if (__builtin_object_size (&b->buf[0], 3) != 212)
+ abort ();
+ if (__builtin_object_size (&b->buf[28], 0) != 212 - 28)
+ abort ();
+ if (__builtin_object_size (&b->buf[28], 1) != 212 - 28)
+ abort ();
+ if (__builtin_object_size (&b->buf[28], 2) != 212 - 28)
+ abort ();
+ if (__builtin_object_size (&b->buf[28], 3) != 212 - 28)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/builtin-unreachable-1.c b/gcc/testsuite/gcc.dg/builtin-unreachable-1.c
new file mode 100644
index 00000000000..165da3f944c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtin-unreachable-1.c
@@ -0,0 +1,17 @@
+/* Check that __builtin_unreachable() prevents the 'control reaches
+ end of non-void function' diagnostic. */
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wreturn-type" } */
+int
+f(int a, int b)
+{
+ if (a)
+ {
+ return b;
+ }
+ else
+ {
+ asm ("bug");
+ __builtin_unreachable();
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/builtin-unreachable-2.c b/gcc/testsuite/gcc.dg/builtin-unreachable-2.c
new file mode 100644
index 00000000000..13bdb9f7395
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtin-unreachable-2.c
@@ -0,0 +1,20 @@
+/* Check that __builtin_unreachable() is a no-return function thus
+ causing the dead call to foo() to be removed. The comparison is
+ dead too, and should be removed. */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized -fdump-rtl-cse1" } */
+void foo (void);
+
+int
+f (int i)
+{
+ if (i > 1)
+ __builtin_unreachable();
+ if (i > 1)
+ foo ();
+ return 1;
+}
+/* { dg-final { scan-tree-dump-not "foo" "optimized" } } */
+/* { dg-final { scan-rtl-dump-not "\\(if_then_else" "cse1" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
+/* { dg-final { cleanup-rtl-dump "cse1" } } */
diff --git a/gcc/testsuite/gcc.dg/builtins-30.c b/gcc/testsuite/gcc.dg/builtins-30.c
index 65a78fefe1d..37e5dba2db6 100644
--- a/gcc/testsuite/gcc.dg/builtins-30.c
+++ b/gcc/testsuite/gcc.dg/builtins-30.c
@@ -1,29 +1,27 @@
/* { dg-do compile } */
-/* { dg-options "-Wall -Wshadow" } */
+/* { dg-options "-Wall -Wshadow -fshow-column" } */
extern double strtod (const char *, char **);
#define UNUSED __attribute__ ((unused))
/* A built-in function may be overridden by an old-style definition
specifying too few arguments... */
-double cos () /* { dg-warning "shadows a built-in" } */
+double cos () /* { dg-warning "shadows a built-in|number of arguments" } */
{
- /* { dg-warning "number of arguments doesn't match built-in prototype" "built-in" { target *-*-* } 10 } */
return strtod ("nan", 0);
}
/* the right number, but the wrong type, arguments... */
-double sin (foo) /* { dg-warning "shadows a built-in" } */
- int foo UNUSED;
-{ /* { dg-warning "argument 'foo' doesn't match built-in prototype" } */
+double sin (foo) /* { dg-warning "8:shadows a built-in" } */
+ int foo UNUSED; /* { dg-warning "10:argument 'foo' doesn't match built-in prototype" } */
+{
return strtod ("nan", 0);
}
/* or too many arguments. */
-long double cosl (foo, bar) /* { dg-warning "shadows a built-in" } */
- const char *foo UNUSED;
+long double cosl (foo, bar) /* { dg-warning "shadows a built-in|number of arguments" } */
+ const char *foo UNUSED; /* { dg-warning "18:argument 'foo' doesn't match" } */
int bar UNUSED;
-{ /* { dg-warning "number of arguments doesn't match built-in prototype" } */
- /* { dg-warning "argument 'foo' doesn't match built-in prototype" "foo" { target *-*-* } 26 } */
+{
return strtod ("nan", 0);
}
diff --git a/gcc/testsuite/gcc.dg/c90-const-expr-5.c b/gcc/testsuite/gcc.dg/c90-const-expr-5.c
index 0a5af8124cd..9f5cdef8399 100644
--- a/gcc/testsuite/gcc.dg/c90-const-expr-5.c
+++ b/gcc/testsuite/gcc.dg/c90-const-expr-5.c
@@ -2,7 +2,7 @@
qualified void. */
/* Origin: Joseph Myers <joseph@codesourcery.com> */
/* { dg-do compile } */
-/* { dg-options "-std=iso9899:1990 -pedantic-errors -fshow-column" } */
+/* { dg-options "-std=iso9899:1990 -pedantic-errors" } */
typedef void V;
int *p;
@@ -15,14 +15,14 @@ f (void)
{
/* (V *)0 is a null pointer constant, so the assignment should be
diagnosed. */
- q = (j ? p : (V *)0); /* { dg-error "3:assignment from incompatible pointer type" } */
- q = (j ? p : (void *)0); /* { dg-error "3:assignment from incompatible pointer type" } */
+ q = (j ? p : (V *)0); /* { dg-error "5:assignment from incompatible pointer type" } */
+ q = (j ? p : (void *)0); /* { dg-error "5:assignment from incompatible pointer type" } */
/* And this conversion should be valid. */
(void (*)(void))(V *)0;
(void (*)(void))(void *)0;
/* Pointers to qualified void are not valid null pointer
constants. */
- fp = (const void *)0; /* { dg-error "3:ISO C forbids assignment between function pointer and 'void \\*'" } */
+ fp = (const void *)0; /* { dg-error "6:ISO C forbids assignment between function pointer and 'void \\*'" } */
fp = (void *)0;
fp = (V *)0;
fp = 0;
diff --git a/gcc/testsuite/gcc.dg/c90-const-expr-8.c b/gcc/testsuite/gcc.dg/c90-const-expr-8.c
index 966044c4eff..b00bb9718f8 100644
--- a/gcc/testsuite/gcc.dg/c90-const-expr-8.c
+++ b/gcc/testsuite/gcc.dg/c90-const-expr-8.c
@@ -9,19 +9,19 @@
#include <limits.h>
enum e {
- E0 = 0 * (INT_MAX + 1), /* { dg-warning "integer overflow in expression" } */
- /* { dg-error "overflow in constant expression" "constant" { target *-*-* } 12 } */
- E1 = 0 * (INT_MIN / -1), /* { dg-warning "integer overflow in expression" } */
- /* { dg-error "overflow in constant expression" "constant" { target *-*-* } 14 } */
- E2 = 0 * (INT_MAX * INT_MAX), /* { dg-warning "integer overflow in expression" } */
- /* { dg-error "overflow in constant expression" "constant" { target *-*-* } 16 } */
- E3 = 0 * (INT_MIN - 1), /* { dg-warning "integer overflow in expression" } */
- /* { dg-error "overflow in constant expression" "constant" { target *-*-* } 18 } */
- E4 = 0 * (unsigned)(INT_MIN - 1), /* { dg-warning "integer overflow in expression" } */
- /* { dg-error "overflow in constant expression" "constant" { target *-*-* } 20 } */
- E5 = 0 * -INT_MIN, /* { dg-warning "integer overflow in expression" } */
- /* { dg-error "overflow in constant expression" "constant" { target *-*-* } 22 } */
- E6 = 0 * !-INT_MIN, /* { dg-warning "integer overflow in expression" } */
- /* { dg-error "not an integer constant" "constant" { target *-*-* } 24 } */
+ E0 = 0 * (INT_MAX + 1), /* { dg-warning "21:integer overflow in expression" } */
+ /* { dg-error "3:overflow in constant expression" "constant" { target *-*-* } 12 } */
+ E1 = 0 * (INT_MIN / -1), /* { dg-warning "21:integer overflow in expression" } */
+ /* { dg-error "3:overflow in constant expression" "constant" { target *-*-* } 14 } */
+ E2 = 0 * (INT_MAX * INT_MAX), /* { dg-warning "21:integer overflow in expression" } */
+ /* { dg-error "3:overflow in constant expression" "constant" { target *-*-* } 16 } */
+ E3 = 0 * (INT_MIN - 1), /* { dg-warning "21:integer overflow in expression" } */
+ /* { dg-error "3:overflow in constant expression" "constant" { target *-*-* } 18 } */
+ E4 = 0 * (unsigned)(INT_MIN - 1), /* { dg-warning "31:integer overflow in expression" } */
+ /* { dg-error "3:overflow in constant expression" "constant" { target *-*-* } 20 } */
+ E5 = 0 * -INT_MIN, /* { dg-warning "12:integer overflow in expression" } */
+ /* { dg-error "3:overflow in constant expression" "constant" { target *-*-* } 22 } */
+ E6 = 0 * !-INT_MIN, /* { dg-warning "13:integer overflow in expression" } */
+ /* { dg-error "3:not an integer constant" "constant" { target *-*-* } 24 } */
E7 = INT_MIN % -1 /* Not an overflow. */
};
diff --git a/gcc/testsuite/gcc.dg/c99-tag-3.c b/gcc/testsuite/gcc.dg/c99-tag-3.c
index 7406e7d64c7..a492037b07a 100644
--- a/gcc/testsuite/gcc.dg/c99-tag-3.c
+++ b/gcc/testsuite/gcc.dg/c99-tag-3.c
@@ -13,10 +13,10 @@ void f (void) { struct s0; }
/* A declaration with a qualifier or storage class specifier declares
the tag if no other declaration of it is visible. */
-const union u0; /* { dg-warning "useless type qualifier in empty declaration" } */
+const union u0; /* { dg-warning "13:useless type qualifier in empty declaration" } */
union u0 { long b; };
-extern struct s1; /* { dg-warning "useless storage class specifier in empty declaration" } */
+extern struct s1; /* { dg-warning "15:useless storage class specifier in empty declaration" } */
/* But if a declaration of the tag is visible, whether at the same
scope or an outer scope, the declaration specifies the same type as
@@ -25,13 +25,13 @@ extern struct s1; /* { dg-warning "useless storage class specifier in empty decl
the members of an enumeration, it is a constraint violation. */
struct s2 { char x; };
-const struct s2; /* { dg-error "empty declaration with type qualifier does not redeclare tag" } */
+const struct s2; /* { dg-error "14:empty declaration with type qualifier does not redeclare tag" } */
union u1;
-extern union u1; /* { dg-error "empty declaration with storage class specifier does not redeclare tag" } */
+extern union u1; /* { dg-error "14:empty declaration with storage class specifier does not redeclare tag" } */
union u2 { long b; };
-void g(void) { const union u2; } /* { dg-error "empty declaration with type qualifier does not redeclare tag" } */
+void g(void) { const union u2; } /* { dg-error "28:empty declaration with type qualifier does not redeclare tag" } */
/* And it does not redeclare the tag either if the outer tag is the
wrong kind of tag. This also yields an error for the reference to
@@ -39,21 +39,21 @@ void g(void) { const union u2; } /* { dg-error "empty declaration with type qual
declaration. */
union u3 { float v; };
-void h(void) { const struct u3; } /* { dg-error "'u3' defined as wrong kind of tag" } */
-/* { dg-error "empty declaration with type qualifier does not redeclare tag" "wrong tag empty" { target *-*-* } 42 } */
+void h(void) { const struct u3; } /* { dg-error "29:'u3' defined as wrong kind of tag" } */
+/* { dg-error "29:empty declaration with type qualifier does not redeclare tag" "wrong tag empty" { target *-*-* } 42 } */
/* However, such useless specifiers are OK if the contents of the tag
are being defined, or shadowed in an inner scope with the contents
included in the shadowing. */
struct s3;
-const struct s3 { int a; }; /* { dg-warning "useless type qualifier in empty declaration" } */
+const struct s3 { int a; }; /* { dg-warning "14:useless type qualifier in empty declaration" } */
union u4;
-extern union u4 { int z; }; /* { dg-warning "useless storage class specifier in empty declaration" } */
+extern union u4 { int z; }; /* { dg-warning "14:useless storage class specifier in empty declaration" } */
enum e0 { E0 };
-void i(void) { const enum e0 { E1 }; } /* { dg-warning "useless type qualifier in empty declaration" } */
+void i(void) { const enum e0 { E1 }; } /* { dg-warning "32:useless type qualifier in empty declaration" } */
union u5 { int p; };
-void j(void) { extern struct u5 { int q; }; } /* { dg-warning "useless storage class specifier in empty declaration" } */
+void j(void) { extern struct u5 { int q; }; } /* { dg-warning "30:useless storage class specifier in empty declaration" } */
diff --git a/gcc/testsuite/gcc.dg/c99-vla-jump-1.c b/gcc/testsuite/gcc.dg/c99-vla-jump-1.c
index 4e984d2b81b..8e34b100131 100644
--- a/gcc/testsuite/gcc.dg/c99-vla-jump-1.c
+++ b/gcc/testsuite/gcc.dg/c99-vla-jump-1.c
@@ -15,11 +15,11 @@
/* { dg-options "-std=iso9899:1999 -pedantic-errors" } */
void fa0 (int n) { goto a; a:{ int b[n]; { int c[n]; 0;} { int d[n]; 0;} ; int e[n]; 0;}; { int f[n]; { int g[n]; 0;}; { int h[n]; 0;}; ; int i[n]; 0;}; ; int j[n]; 0; }
-void fa1 (int n) { goto a; { int b[n]; a:{ int c[n]; 0;} { int d[n]; 0;} ; int e[n]; 0;}; { int f[n]; { int g[n]; 0;}; { int h[n]; 0;}; ; int i[n]; 0;}; ; int j[n]; 0; } /* { dg-error "jump into scope of identifier with variably modified type" } */
-void fa2 (int n) { goto a; { int b[n]; { int c[n]; a:0;} { int d[n]; 0;} ; int e[n]; 0;}; { int f[n]; { int g[n]; 0;}; { int h[n]; 0;}; ; int i[n]; 0;}; ; int j[n]; 0; } /* { dg-error "jump into scope of identifier with variably modified type" } */
-void fa3 (int n) { goto a; { int b[n]; { int c[n]; 0;} a:{ int d[n]; 0;} ; int e[n]; 0;}; { int f[n]; { int g[n]; 0;}; { int h[n]; 0;}; ; int i[n]; 0;}; ; int j[n]; 0; } /* { dg-error "jump into scope of identifier with variably modified type" } */
-void fa4 (int n) { goto a; { int b[n]; { int c[n]; 0;} { int d[n]; a:0;} ; int e[n]; 0;}; { int f[n]; { int g[n]; 0;}; { int h[n]; 0;}; ; int i[n]; 0;}; ; int j[n]; 0; } /* { dg-error "jump into scope of identifier with variably modified type" } */
-void fa5 (int n) { goto a; { int b[n]; { int c[n]; 0;} { int d[n]; 0;} a:; int e[n]; 0;}; { int f[n]; { int g[n]; 0;}; { int h[n]; 0;}; ; int i[n]; 0;}; ; int j[n]; 0; } /* { dg-error "jump into scope of identifier with variably modified type" } */
+void fa1 (int n) { goto a; { int b[n]; a:{ int c[n]; 0;} { int d[n]; 0;} ; int e[n]; 0;}; { int f[n]; { int g[n]; 0;}; { int h[n]; 0;}; ; int i[n]; 0;}; ; int j[n]; 0; } /* { dg-error "21:jump into scope of identifier with variably modified type" } */
+void fa2 (int n) { goto a; { int b[n]; { int c[n]; a:0;} { int d[n]; 0;} ; int e[n]; 0;}; { int f[n]; { int g[n]; 0;}; { int h[n]; 0;}; ; int i[n]; 0;}; ; int j[n]; 0; } /* { dg-error "21:jump into scope of identifier with variably modified type" } */
+void fa3 (int n) { goto a; { int b[n]; { int c[n]; 0;} a:{ int d[n]; 0;} ; int e[n]; 0;}; { int f[n]; { int g[n]; 0;}; { int h[n]; 0;}; ; int i[n]; 0;}; ; int j[n]; 0; } /* { dg-error "21:jump into scope of identifier with variably modified type" } */
+void fa4 (int n) { goto a; { int b[n]; { int c[n]; 0;} { int d[n]; a:0;} ; int e[n]; 0;}; { int f[n]; { int g[n]; 0;}; { int h[n]; 0;}; ; int i[n]; 0;}; ; int j[n]; 0; } /* { dg-error "21:jump into scope of identifier with variably modified type" } */
+void fa5 (int n) { goto a; { int b[n]; { int c[n]; 0;} { int d[n]; 0;} a:; int e[n]; 0;}; { int f[n]; { int g[n]; 0;}; { int h[n]; 0;}; ; int i[n]; 0;}; ; int j[n]; 0; } /* { dg-error "21:jump into scope of identifier with variably modified type" } */
void fa6 (int n) { goto a; { int b[n]; { int c[n]; 0;} { int d[n]; 0;} ; int e[n]; a:0;}; { int f[n]; { int g[n]; 0;}; { int h[n]; 0;}; ; int i[n]; 0;}; ; int j[n]; 0; } /* { dg-error "jump into scope of identifier with variably modified type" } */
void fa7 (int n) { goto a; { int b[n]; { int c[n]; 0;} { int d[n]; 0;} ; int e[n]; 0;}; a:{ int f[n]; { int g[n]; 0;}; { int h[n]; 0;}; ; int i[n]; 0;}; ; int j[n]; 0; }
void fa8 (int n) { goto a; { int b[n]; { int c[n]; 0;} { int d[n]; 0;} ; int e[n]; 0;}; { int f[n]; a:{ int g[n]; 0;}; { int h[n]; 0;}; ; int i[n]; 0;}; ; int j[n]; 0; } /* { dg-error "jump into scope of identifier with variably modified type" } */
@@ -303,3 +303,7 @@ void fa285 (int n) { { int b[n]; { int c[n]; 0;} { int d[n]; 0;} ; int e[n]; 0;}
void fa286 (int n) { { int b[n]; { int c[n]; 0;} { int d[n]; 0;} ; int e[n]; 0;}; { int f[n]; { int g[n]; 0;}; { int h[n]; 0;}; ; int i[n]; 0;}; a:; int j[n]; 0; goto a; }
void fa287 (int n) { { int b[n]; { int c[n]; 0;} { int d[n]; 0;} ; int e[n]; 0;}; { int f[n]; { int g[n]; 0;}; { int h[n]; 0;}; ; int i[n]; 0;}; ; int j[n]; a:0; goto a; }
void fa288 (int n) { { int b[n]; { int c[n]; 0;} { int d[n]; 0;} ; int e[n]; 0;}; { int f[n]; { int g[n]; 0;}; { int h[n]; 0;}; ; int i[n]; 0;}; ; int j[n]; 0;a: goto a; }
+
+/* Match extra informative notes. */
+/* { dg-message "note: label '\[^\n'\]*' defined here" "note: expected" { target *-*-* } 0 } */
+/* { dg-message "note: '\[^\n'\]*' declared here" "note: expected" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/gcc.dg/c99-vla-jump-2.c b/gcc/testsuite/gcc.dg/c99-vla-jump-2.c
index 27cecaa604f..2b4d4d56a5d 100644
--- a/gcc/testsuite/gcc.dg/c99-vla-jump-2.c
+++ b/gcc/testsuite/gcc.dg/c99-vla-jump-2.c
@@ -303,3 +303,7 @@ void fb285 (int n) { P0A:goto P0A;{ int b[n]; P01A:goto P01A;{ int c[n]; P012A:g
void fb286 (int n) { P0A:goto P0A;{ int b[n]; P01A:goto P01A;{ int c[n]; P012A:goto P012A;0;} P01B:goto P01B;{ int d[n]; P013A:goto P013A;0;} P01C:goto P01C;; int e[n]; P014A:goto P014A;0;}; P0B:goto P0B;{ int f[n]; P02A:goto P02A;{ int g[n]; P024A:goto P024A;0;}; P02B:goto P02B;{ int h[n]; P025A:goto P025A;0;}; P02C:goto P02C;; int i[n]; P026A:goto P026A;0;}; a:; int j[n]; P03A:goto P03A;0;p03B:goto p03B; goto a; P03B:goto P03B; }
void fb287 (int n) { P0A:goto P0A;{ int b[n]; P01A:goto P01A;{ int c[n]; P012A:goto P012A;0;} P01B:goto P01B;{ int d[n]; P013A:goto P013A;0;} P01C:goto P01C;; int e[n]; P014A:goto P014A;0;}; P0B:goto P0B;{ int f[n]; P02A:goto P02A;{ int g[n]; P024A:goto P024A;0;}; P02B:goto P02B;{ int h[n]; P025A:goto P025A;0;}; P02C:goto P02C;; int i[n]; P026A:goto P026A;0;}; P0C:goto P0C;; int j[n]; a:0;p03B:goto p03B; goto a; P03B:goto P03B; }
void fb288 (int n) { P0A:goto P0A;{ int b[n]; P01A:goto P01A;{ int c[n]; P012A:goto P012A;0;} P01B:goto P01B;{ int d[n]; P013A:goto P013A;0;} P01C:goto P01C;; int e[n]; P014A:goto P014A;0;}; P0B:goto P0B;{ int f[n]; P02A:goto P02A;{ int g[n]; P024A:goto P024A;0;}; P02B:goto P02B;{ int h[n]; P025A:goto P025A;0;}; P02C:goto P02C;; int i[n]; P026A:goto P026A;0;}; P0C:goto P0C;; int j[n]; P03A:goto P03A;0;a: goto a; P03B:goto P03B; }
+
+/* Match extra informative notes. */
+/* { dg-message "note: label '\[^\n'\]*' defined here" "note: expected" { target *-*-* } 0 } */
+/* { dg-message "note: '\[^\n'\]*' declared here" "note: expected" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/gcc.dg/c99-vla-jump-3.c b/gcc/testsuite/gcc.dg/c99-vla-jump-3.c
index 0aff362d61f..ac1ae96c2c9 100644
--- a/gcc/testsuite/gcc.dg/c99-vla-jump-3.c
+++ b/gcc/testsuite/gcc.dg/c99-vla-jump-3.c
@@ -303,3 +303,7 @@ void fc285 (int n) { { typedef int (*b)[n]; { typedef int (*c)[n]; 0;} { typedef
void fc286 (int n) { { typedef int (*b)[n]; { typedef int (*c)[n]; 0;} { typedef int (*d)[n]; 0;} ; typedef int (*e)[n]; 0;}; { typedef int (*f)[n]; { typedef int (*g)[n]; 0;}; { typedef int (*h)[n]; 0;}; ; typedef int (*i)[n]; 0;}; a:; typedef int (*j)[n]; 0; goto a; }
void fc287 (int n) { { typedef int (*b)[n]; { typedef int (*c)[n]; 0;} { typedef int (*d)[n]; 0;} ; typedef int (*e)[n]; 0;}; { typedef int (*f)[n]; { typedef int (*g)[n]; 0;}; { typedef int (*h)[n]; 0;}; ; typedef int (*i)[n]; 0;}; ; typedef int (*j)[n]; a:0; goto a; }
void fc288 (int n) { { typedef int (*b)[n]; { typedef int (*c)[n]; 0;} { typedef int (*d)[n]; 0;} ; typedef int (*e)[n]; 0;}; { typedef int (*f)[n]; { typedef int (*g)[n]; 0;}; { typedef int (*h)[n]; 0;}; ; typedef int (*i)[n]; 0;}; ; typedef int (*j)[n]; 0;a: goto a; }
+
+/* Match extra informative notes. */
+/* { dg-message "note: label '\[^\n'\]*' defined here" "note: expected" { target *-*-* } 0 } */
+/* { dg-message "note: '\[^\n'\]*' declared here" "note: expected" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/gcc.dg/c99-vla-jump-4.c b/gcc/testsuite/gcc.dg/c99-vla-jump-4.c
index e77a14209af..848dfba945c 100644
--- a/gcc/testsuite/gcc.dg/c99-vla-jump-4.c
+++ b/gcc/testsuite/gcc.dg/c99-vla-jump-4.c
@@ -303,3 +303,7 @@ void fd285 (int n) { P0A:goto P0A;{ typedef int (*b)[n]; P01A:goto P01A;{ typede
void fd286 (int n) { P0A:goto P0A;{ typedef int (*b)[n]; P01A:goto P01A;{ typedef int (*c)[n]; P012A:goto P012A;0;} P01B:goto P01B;{ typedef int (*d)[n]; P013A:goto P013A;0;} P01C:goto P01C;; typedef int (*e)[n]; P014A:goto P014A;0;}; P0B:goto P0B;{ typedef int (*f)[n]; P02A:goto P02A;{ typedef int (*g)[n]; P024A:goto P024A;0;}; P02B:goto P02B;{ typedef int (*h)[n]; P025A:goto P025A;0;}; P02C:goto P02C;; typedef int (*i)[n]; P026A:goto P026A;0;}; a:; typedef int (*j)[n]; P03A:goto P03A;0;p03B:goto p03B; goto a; P03B:goto P03B; }
void fd287 (int n) { P0A:goto P0A;{ typedef int (*b)[n]; P01A:goto P01A;{ typedef int (*c)[n]; P012A:goto P012A;0;} P01B:goto P01B;{ typedef int (*d)[n]; P013A:goto P013A;0;} P01C:goto P01C;; typedef int (*e)[n]; P014A:goto P014A;0;}; P0B:goto P0B;{ typedef int (*f)[n]; P02A:goto P02A;{ typedef int (*g)[n]; P024A:goto P024A;0;}; P02B:goto P02B;{ typedef int (*h)[n]; P025A:goto P025A;0;}; P02C:goto P02C;; typedef int (*i)[n]; P026A:goto P026A;0;}; P0C:goto P0C;; typedef int (*j)[n]; a:0;p03B:goto p03B; goto a; P03B:goto P03B; }
void fd288 (int n) { P0A:goto P0A;{ typedef int (*b)[n]; P01A:goto P01A;{ typedef int (*c)[n]; P012A:goto P012A;0;} P01B:goto P01B;{ typedef int (*d)[n]; P013A:goto P013A;0;} P01C:goto P01C;; typedef int (*e)[n]; P014A:goto P014A;0;}; P0B:goto P0B;{ typedef int (*f)[n]; P02A:goto P02A;{ typedef int (*g)[n]; P024A:goto P024A;0;}; P02B:goto P02B;{ typedef int (*h)[n]; P025A:goto P025A;0;}; P02C:goto P02C;; typedef int (*i)[n]; P026A:goto P026A;0;}; P0C:goto P0C;; typedef int (*j)[n]; P03A:goto P03A;0;a: goto a; P03B:goto P03B; }
+
+/* Match extra informative notes. */
+/* { dg-message "note: label '\[^\n'\]*' defined here" "note: expected" { target *-*-* } 0 } */
+/* { dg-message "note: '\[^\n'\]*' declared here" "note: expected" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/gcc.dg/c99-vla-jump-5.c b/gcc/testsuite/gcc.dg/c99-vla-jump-5.c
index ca3f85f5931..683bcf21eb3 100644
--- a/gcc/testsuite/gcc.dg/c99-vla-jump-5.c
+++ b/gcc/testsuite/gcc.dg/c99-vla-jump-5.c
@@ -16,8 +16,8 @@ f (int a, int b)
{
switch (a) {
int v[b];
- case 2: /* { dg-error "case label in scope of identifier with variably modified type not containing enclosing switch statement" } */
- default: /* { dg-error "'default' label in scope of identifier with variably modified type not containing enclosing switch statement" } */
+ case 2: /* { dg-error "switch jumps into scope of identifier with variably modified type" } */
+ default: /* { dg-error "switch jumps into scope of identifier with variably modified type" } */
switch (a)
{
case 4:
@@ -28,3 +28,7 @@ f (int a, int b)
}
}
}
+
+/* Match extra informative notes. */
+/* { dg-message "note: switch starts here" "note: expected" { target *-*-* } 0 } */
+/* { dg-message "note: '\[^\n'\]*' declared here" "note: expected" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/gcc.dg/cast-function-1.c b/gcc/testsuite/gcc.dg/cast-function-1.c
index 8ed7d5da41c..781d0e22191 100644
--- a/gcc/testsuite/gcc.dg/cast-function-1.c
+++ b/gcc/testsuite/gcc.dg/cast-function-1.c
@@ -22,14 +22,14 @@ void bar(void)
int i;
str_t s;
- d = ((double (*) (int)) foo1) (i); /* { dg-warning "non-compatible|abort" } */
- i = ((int (*) (double)) foo1) (d); /* { dg-warning "non-compatible|abort" } */
- s = ((str_t (*) (int)) foo1) (i); /* { dg-warning "non-compatible|abort" } */
+ d = ((double (*) (int)) foo1) (i); /* { dg-warning "33:non-compatible|abort" } */
+ i = ((int (*) (double)) foo1) (d); /* { dg-warning "33:non-compatible|abort" } */
+ s = ((str_t (*) (int)) foo1) (i); /* { dg-warning "32:non-compatible|abort" } */
((void (*) (int)) foo1) (d); /* { dg-warning "non-compatible|abort" } */
i = ((int (*) (int)) foo1) (i); /* { dg-bogus "non-compatible|abort" } */
(void) foo1 (i); /* { dg-bogus "non-compatible|abort" } */
- d = ((double (*) (int)) foo2) (i); /* { dg-warning "non-compatible|abort" } */
+ d = ((double (*) (int)) foo2) (i); /* { dg-warning "33:non-compatible|abort" } */
i = ((int (*) (double)) foo2) (d); /* { dg-bogus "non-compatible|abort" } */
s = ((str_t (*) (int)) foo2) (i); /* { dg-warning "non-compatible|abort" } */
((void (*) (int)) foo2) (d); /* { dg-warning "non-compatible|abort" } */
diff --git a/gcc/testsuite/gcc.dg/cast-qual-3.c b/gcc/testsuite/gcc.dg/cast-qual-3.c
new file mode 100644
index 00000000000..88fdcfb38f5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/cast-qual-3.c
@@ -0,0 +1,167 @@
+/* { dg-do compile } */
+/* { dg-options "-Wcast-qual" } */
+
+/* The files gcc.dg/cast-qual-3.c and g++.dg/warn/Wcast-qual2.c are
+ duals. they are intended to show that gcc -Wcast-qual and g++
+ -Wcast-qual emit warnings in the same cases. If you change this
+ file, please also change the other one. */
+
+void
+f1 (void *bar)
+{
+ const void *p1 = (const void *) bar;
+ const char *p2 = (const char *) bar;
+ const void **p3 = (const void **) bar;
+ const char **p4 = (const char **) bar;
+ const void * const *p5 = (const void * const *) bar;
+ const char * const *p6 = (const char * const *) bar;
+ void * const *p7 = (void * const *) bar;
+ char * const *p8 = (char * const *) bar;
+ const void ***p9 = (const void ***) bar;
+ const char ***p10 = (const char ***) bar;
+ void * const **p11 = (void * const **) bar;
+ char * const **p12 = (char * const **) bar;
+ void ** const *p13 = (void ** const *) bar;
+ char ** const *p14 = (char ** const *) bar;
+ const void * const **p15 = (const void * const **) bar;
+ const char * const **p16 = (const char * const **) bar;
+ const void ** const *p17 = (const void ** const *) bar;
+ const char ** const *p18 = (const char ** const *) bar;
+ void * const * const * p19 = (void * const * const *) bar;
+ char * const * const * p20 = (char * const * const *) bar;
+ const void * const * const *p21 = (const void * const * const *) bar;
+ const char * const * const *p22 = (const char * const * const *) bar;
+}
+
+void
+f2 (void **bar)
+{
+ const void *p1 = (const void *) bar;
+ const char *p2 = (const char *) bar;
+ const void **p3 = (const void **) bar; /* { dg-warning "cast" } */
+ const char **p4 = (const char **) bar;
+ const void * const *p5 = (const void * const *) bar;
+ const char * const *p6 = (const char * const *) bar;
+ void * const *p7 = (void * const *) bar;
+ char * const *p8 = (char * const *) bar;
+ const void ***p9 = (const void ***) bar;
+ const char ***p10 = (const char ***) bar;
+ void * const **p11 = (void * const **) bar;
+ char * const **p12 = (char * const **) bar;
+ void ** const *p13 = (void ** const *) bar;
+ char ** const *p14 = (char ** const *) bar;
+ const void * const **p15 = (const void * const **) bar;
+ const char * const **p16 = (const char * const **) bar;
+ const void ** const *p17 = (const void ** const *) bar;
+ const char ** const *p18 = (const char ** const *) bar;
+ void * const * const * p19 = (void * const * const *) bar;
+ char * const * const * p20 = (char * const * const *) bar;
+ const void * const * const *p21 = (const void * const * const *) bar;
+ const char * const * const *p22 = (const char * const * const *) bar;
+}
+
+void
+f3 (void ***bar)
+{
+ const void *p1 = (const void *) bar;
+ const char *p2 = (const char *) bar;
+ const void **p3 = (const void **) bar;
+ const char **p4 = (const char **) bar;
+ const void * const *p5 = (const void * const *) bar;
+ const char * const *p6 = (const char * const *) bar;
+ void * const *p7 = (void * const *) bar;
+ char * const *p8 = (char * const *) bar;
+ const void ***p9 = (const void ***) bar; /* { dg-warning "cast" } */
+ const char ***p10 = (const char ***) bar;
+ void * const **p11 = (void * const **) bar; /* { dg-warning "cast" } */
+ char * const **p12 = (char * const **) bar;
+ void ** const *p13 = (void ** const *) bar;
+ char ** const *p14 = (char ** const *) bar;
+ const void * const **p15 = (const void * const **) bar; /* { dg-warning "cast" } */
+ const char * const **p16 = (const char * const **) bar;
+ const void ** const *p17 = (const void ** const *) bar; /* { dg-warning "cast" } */
+ const char ** const *p18 = (const char ** const *) bar;
+ void * const * const * p19 = (void * const * const *) bar;
+ char * const * const * p20 = (char * const * const *) bar;
+ const void * const * const *p21 = (const void * const * const *) bar;
+ const char * const * const *p22 = (const char * const * const *) bar;
+}
+
+void
+f4 (void * const **bar)
+{
+ const void ***p9 = (const void ***) bar; /* { dg-warning "cast" } */
+ void * const **p11 = (void * const **) bar;
+ void ** const *p13 = (void ** const *) bar; /* { dg-warning "cast" } */
+ const void * const **p15 = (const void * const **) bar; /* { dg-warning "cast" } */
+ const void ** const *p17 = (const void ** const *) bar; /* { dg-warning "cast" } */
+ void * const * const * p19 = (void * const * const *) bar;
+ const void * const * const *p21 = (const void * const * const *) bar;
+}
+
+void
+f5 (char ***bar)
+{
+ volatile const char ***p9 = (volatile const char ***) bar; /* { dg-warning "cast" } */
+ volatile char * const **p11 = (volatile char * const **) bar; /* { dg-warning "cast" } */
+ volatile char ** const *p13 = (volatile char ** const *) bar; /* { dg-warning "cast" } */
+ volatile const char * const **p15 = (volatile const char * const **) bar; /* { dg-warning "cast" } */
+ volatile const char ** const *p17 = (volatile const char ** const *) bar; /* { dg-warning "cast" } */
+ volatile char * const * const * p19 = (volatile char * const * const *) bar;
+ volatile const char * const * const *p21 = (volatile const char * const * const *) bar;
+}
+
+void
+f6 (char ***bar)
+{
+ const char * volatile **p9 = (const char * volatile **) bar; /* { dg-warning "cast" } */
+ char * volatile const **p11 = (char * volatile const **) bar; /* { dg-warning "cast" } */
+ char * volatile * const *p13 = (char * volatile * const *) bar;
+ const char * volatile const **p15 = (const char * volatile const **) bar; /* { dg-warning "cast" } */
+ const char * volatile * const *p17 = (const char * volatile * const *) bar; /* { dg-warning "cast" } */
+ char * volatile const * const * p19 = (char * volatile const * const *) bar;
+ const char * volatile const * const *p21 = (const char * volatile const * const *) bar;
+}
+
+void
+f7 (char ***bar)
+{
+ const char ** volatile *p9 = (const char ** volatile *) bar; /* { dg-warning "cast" } */
+ char * const * volatile *p11 = (char * const * volatile *) bar; /* { dg-warning "cast" } */
+ char ** volatile const *p13 = (char ** volatile const *) bar;
+ const char * const * volatile *p15 = (const char * const * volatile *) bar; /* { dg-warning "cast" } */
+ const char ** volatile const *p17 = (const char ** volatile const *) bar; /* { dg-warning "cast" } */
+ char * const * volatile const * p19 = (char * const * volatile const *) bar;
+ const char * const * volatile const *p21 = (const char * const * volatile const *) bar;
+}
+
+typedef int (intfn) (int);
+typedef intfn *pintfn;
+typedef const intfn *constfn;
+
+void
+f8 (constfn ***bar)
+{
+ const constfn *p1 = (const constfn *) bar;
+ const pintfn *p2 = (const pintfn *) bar;
+ const constfn **p3 = (const constfn **) bar;
+ const pintfn **p4 = (const pintfn **) bar;
+ const constfn * const *p5 = (const constfn * const *) bar;
+ const pintfn * const *p6 = (const pintfn * const *) bar;
+ constfn * const *p7 = (constfn * const *) bar;
+ pintfn * const *p8 = (pintfn * const *) bar;
+ const constfn ***p9 = (const constfn ***) bar; /* { dg-warning "cast" } */
+ const pintfn ***p10 = (const pintfn ***) bar; /* { dg-warning "cast" } */
+ constfn * const **p11 = (constfn * const **) bar; /* { dg-warning "cast" } */
+ pintfn * const **p12 = (pintfn * const **) bar; /* { dg-warning "cast" } */
+ constfn ** const *p13 = (constfn ** const *) bar;
+ pintfn ** const *p14 = (pintfn ** const *) bar;
+ const constfn * const **p15 = (const constfn * const **) bar; /* { dg-warning "cast" } */
+ const pintfn * const **p16 = (const pintfn * const **) bar; /* { dg-warning "cast" } */
+ const constfn ** const *p17 = (const constfn ** const *) bar; /* { dg-warning "cast" } */
+ const pintfn ** const *p18 = (const pintfn ** const *) bar; /* { dg-warning "cast" } */
+ constfn * const * const * p19 = (constfn * const * const *) bar;
+ pintfn * const * const * p20 = (pintfn * const * const *) bar;
+ const constfn * const * const *p21 = (const constfn * const * const *) bar;
+ const pintfn * const * const *p22 = (const pintfn * const * const *) bar;
+}
diff --git a/gcc/testsuite/gcc.dg/compat/struct-layout-1_generate.c b/gcc/testsuite/gcc.dg/compat/struct-layout-1_generate.c
index f563c2774bd..4f5315df2c2 100644
--- a/gcc/testsuite/gcc.dg/compat/struct-layout-1_generate.c
+++ b/gcc/testsuite/gcc.dg/compat/struct-layout-1_generate.c
@@ -46,7 +46,7 @@ const char *dg_options[] = {
"/* { dg-options \"%s-I%s\" } */\n",
"/* { dg-options \"%s-I%s -Wno-abi\" } */\n",
"/* { dg-options \"%s-I%s -mno-mmx -Wno-abi\" { target i?86-*-* x86_64-*-* } } */\n",
-"/* { dg-options \"%s-I%s -fno-common\" { target hppa*-*-hpux* powerpc*-*-darwin* *-*-mingw32* *-*-cygwin* } } */\n",
+"/* { dg-options \"%s-I%s -fno-common\" { target hppa*-*-hpux* powerpc*-*-darwin* } } */\n",
"/* { dg-options \"%s-I%s -mno-mmx -fno-common -Wno-abi\" { target i?86-*-darwin* x86_64-*-darwin* } } */\n",
"/* { dg-options \"%s-I%s -mno-base-addresses\" { target mmix-*-* } } */\n",
"/* { dg-options \"%s-I%s -mlongcalls -mtext-section-literals\" { target xtensa*-*-* } } */\n"
diff --git a/gcc/testsuite/gcc.dg/cpp/19940712-1.c b/gcc/testsuite/gcc.dg/cpp/19940712-1.c
index 98bcd767966..a79b2f5484d 100644
--- a/gcc/testsuite/gcc.dg/cpp/19940712-1.c
+++ b/gcc/testsuite/gcc.dg/cpp/19940712-1.c
@@ -5,8 +5,9 @@
/* { dg-error "unterminated comment" "" { target *-*-* } 4 } */
/* { dg-error "unterminated comment" "header error" { target *-*-* } 8 } */
-#include "19940712-1.h" /* { dg-message "" } // In file included from: */
-#include "19940712-1a.h" /* { dg-message "" } // In file included from: */
+#include "19940712-1.h"
+/* { dg-message "" "In file included from:" { target *-*-* } 0 } */
+#include "19940712-1a.h"
#include "19940712-1b.h"
/* comment start in comment error
diff --git a/gcc/testsuite/gcc.dg/cpp/Wmissingdirs.c b/gcc/testsuite/gcc.dg/cpp/Wmissingdirs.c
index 915aaa8de98..69b3aae3da6 100644
--- a/gcc/testsuite/gcc.dg/cpp/Wmissingdirs.c
+++ b/gcc/testsuite/gcc.dg/cpp/Wmissingdirs.c
@@ -1,5 +1,5 @@
/* { dg-do preprocess } */
-/* { dg-options "-std=gnu99 -I /jolly/well/better/not/exist -Wmissing-include-dirs -fno-show-column" } */
+/* { dg-options "-std=gnu99 -I /jolly/well/better/not/exist -Wmissing-include-dirs" } */
/* Test that -Wmissing-include-dirs issues a warning when a specified
directory does not exist. Source Ben Elliston, 2004-05-13. */
diff --git a/gcc/testsuite/gcc.dg/cpp/Wsignprom.c b/gcc/testsuite/gcc.dg/cpp/Wsignprom.c
index 7cdbccb3cac..87d422b794f 100644
--- a/gcc/testsuite/gcc.dg/cpp/Wsignprom.c
+++ b/gcc/testsuite/gcc.dg/cpp/Wsignprom.c
@@ -1,5 +1,5 @@
/* { dg-do preprocess } */
-/* { dg-options "-Wall -fshow-column" } */
+/* { dg-options "-Wall" } */
/* Test that -Wall emits the warnings about integer promotion changing
the sign of an operand. */
diff --git a/gcc/testsuite/gcc.dg/cpp/Wtrigraphs-2.c b/gcc/testsuite/gcc.dg/cpp/Wtrigraphs-2.c
index 43bf134842a..8d61f2841f0 100644
--- a/gcc/testsuite/gcc.dg/cpp/Wtrigraphs-2.c
+++ b/gcc/testsuite/gcc.dg/cpp/Wtrigraphs-2.c
@@ -1,5 +1,5 @@
/* { dg-do preprocess } */
-/* { dg-options "-std=c99 -Wtrigraphs -fno-show-column" } */
+/* { dg-options "-std=c99 -Wtrigraphs" } */
/* Test warnings for trigraphs in comments, with trigraphs enabled.
Neil Booth. 4 May 2003. */
diff --git a/gcc/testsuite/gcc.dg/cpp/Wtrigraphs.c b/gcc/testsuite/gcc.dg/cpp/Wtrigraphs.c
index 5ed6c98ad49..d4be2040c18 100644
--- a/gcc/testsuite/gcc.dg/cpp/Wtrigraphs.c
+++ b/gcc/testsuite/gcc.dg/cpp/Wtrigraphs.c
@@ -1,5 +1,5 @@
/* { dg-do preprocess } */
-/* { dg-options "-std=gnu99 -Wtrigraphs -fno-show-column" } */
+/* { dg-options "-std=gnu99 -Wtrigraphs" } */
/* Test we don't double warn for trigraphs immediately after preceding
text. Source Neil Booth. 22 Nov 2000. */
diff --git a/gcc/testsuite/gcc.dg/cpp/arith-1.c b/gcc/testsuite/gcc.dg/cpp/arith-1.c
index 85d5848d800..99e3cd7be2e 100644
--- a/gcc/testsuite/gcc.dg/cpp/arith-1.c
+++ b/gcc/testsuite/gcc.dg/cpp/arith-1.c
@@ -7,7 +7,7 @@
independent of target precision. */
/* { dg-do preprocess } */
-/* { dg-options -fno-show-column } */
+/* { dg-options "" } */
/* Test || operator and its short circuiting. */
#if 0 || 0
diff --git a/gcc/testsuite/gcc.dg/cpp/arith-3.c b/gcc/testsuite/gcc.dg/cpp/arith-3.c
index cc5fd1b3bf7..3015d31657a 100644
--- a/gcc/testsuite/gcc.dg/cpp/arith-3.c
+++ b/gcc/testsuite/gcc.dg/cpp/arith-3.c
@@ -9,7 +9,7 @@
Please keep changes to arith-2.c and arith-3.c in sync. */
/* { dg-do preprocess } */
-/* { dg-options "-std=c99 -fno-show-column" } */
+/* { dg-options "-std=c99" } */
#include <limits.h>
diff --git a/gcc/testsuite/gcc.dg/cpp/assert2.c b/gcc/testsuite/gcc.dg/cpp/assert2.c
index 130f7f5320a..5228bcbb3a9 100644
--- a/gcc/testsuite/gcc.dg/cpp/assert2.c
+++ b/gcc/testsuite/gcc.dg/cpp/assert2.c
@@ -1,6 +1,6 @@
/* Malformed assertion tests. */
/* { dg-do preprocess } */
-/* { dg-options "-fno-show-column -Wno-deprecated" } */
+/* { dg-options "-Wno-deprecated" } */
#assert /* { dg-error "without predicate" "assert w/o predicate" } */
#assert % /* { dg-error "an identifier" "assert punctuation" } */
diff --git a/gcc/testsuite/gcc.dg/cpp/cpp.exp b/gcc/testsuite/gcc.dg/cpp/cpp.exp
index 1dc504e30ba..acf0898407b 100644
--- a/gcc/testsuite/gcc.dg/cpp/cpp.exp
+++ b/gcc/testsuite/gcc.dg/cpp/cpp.exp
@@ -37,7 +37,7 @@ dg-init
# Main loop.
dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{c,S} ]] \
- "-fno-show-column" $DEFAULT_CFLAGS
+ "" $DEFAULT_CFLAGS
# All done.
dg-finish
diff --git a/gcc/testsuite/gcc.dg/cpp/escape-2.c b/gcc/testsuite/gcc.dg/cpp/escape-2.c
index e79fa91cbe9..902fad3a2c2 100644
--- a/gcc/testsuite/gcc.dg/cpp/escape-2.c
+++ b/gcc/testsuite/gcc.dg/cpp/escape-2.c
@@ -1,7 +1,7 @@
/* Copyright (C) 2001 Free Software Foundation, Inc. */
/* { dg-do compile } */
-/* { dg-options "-pedantic -std=c99 -fno-show-column" } */
+/* { dg-options "-pedantic -std=c99" } */
/* This tests various diagnostics with -pedantic about escape
sequences, for both the preprocessor and the compiler.
diff --git a/gcc/testsuite/gcc.dg/cpp/escape.c b/gcc/testsuite/gcc.dg/cpp/escape.c
index c9dd44e43e5..e7d5e08dd49 100644
--- a/gcc/testsuite/gcc.dg/cpp/escape.c
+++ b/gcc/testsuite/gcc.dg/cpp/escape.c
@@ -1,7 +1,7 @@
/* Copyright (C) 2001 Free Software Foundation, Inc. */
/* { dg-do compile } */
-/* { dg-options "-Wtraditional -std=c89 -fno-show-column" } */
+/* { dg-options "-Wtraditional -std=c89" } */
/* This tests various diagnostics with -Wtraditioanl about escape
sequences, for both the preprocessor and the compiler.
diff --git a/gcc/testsuite/gcc.dg/cpp/extratokens.c b/gcc/testsuite/gcc.dg/cpp/extratokens.c
index d3e941bfff0..11d094af572 100644
--- a/gcc/testsuite/gcc.dg/cpp/extratokens.c
+++ b/gcc/testsuite/gcc.dg/cpp/extratokens.c
@@ -1,7 +1,7 @@
/* Copyright (C) 2000, 2008 Free Software Foundation, Inc. */
/* { dg-do preprocess } */
-/* { dg-options "-fno-show-column -Wno-deprecated" } */
+/* { dg-options "-Wno-deprecated" } */
/* Tests all directives that do not permit excess tokens at the end of
the line. */
diff --git a/gcc/testsuite/gcc.dg/cpp/extratokens2.c b/gcc/testsuite/gcc.dg/cpp/extratokens2.c
index fe682bfa59d..8e69a96c5b5 100644
--- a/gcc/testsuite/gcc.dg/cpp/extratokens2.c
+++ b/gcc/testsuite/gcc.dg/cpp/extratokens2.c
@@ -1,7 +1,7 @@
/* Copyright (C) 2002 Free Software Foundation, Inc. */
/* { dg-do preprocess } */
-/* { dg-options "-fno-show-column -Wno-endif-labels" } */
+/* { dg-options "-Wno-endif-labels" } */
/* Tests that -Wno-endif-labels correctly disables the checks done by
default (and tested in extratokens.c). */
diff --git a/gcc/testsuite/gcc.dg/cpp/if-mpar.c b/gcc/testsuite/gcc.dg/cpp/if-mpar.c
index 633cefcb442..45dd78b1e67 100644
--- a/gcc/testsuite/gcc.dg/cpp/if-mpar.c
+++ b/gcc/testsuite/gcc.dg/cpp/if-mpar.c
@@ -4,7 +4,6 @@
missing parenthesis message. */
/* { dg-do preprocess } */
-/* { dg-options "-fshow-column" } */
#if (1 /* { dg-error "5:missing '\\)'" "missing ')' no. 1" } */
#endif
diff --git a/gcc/testsuite/gcc.dg/cpp/include2.c b/gcc/testsuite/gcc.dg/cpp/include2.c
index 67f1065ae8c..de34255ec35 100644
--- a/gcc/testsuite/gcc.dg/cpp/include2.c
+++ b/gcc/testsuite/gcc.dg/cpp/include2.c
@@ -11,5 +11,5 @@
/* These error is No such file or directory, just once. However, this
message is locale-dependent, so don't test for it. */
-/* { dg-error "silly" "" { target *-*-* } 10 } */
+/* { dg-error "silly" "" { target *-*-* } 0 } */
/* { dg-message "terminated" "" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/gcc.dg/cpp/include2a.c b/gcc/testsuite/gcc.dg/cpp/include2a.c
index 974f3f33263..6a11c92cff2 100644
--- a/gcc/testsuite/gcc.dg/cpp/include2a.c
+++ b/gcc/testsuite/gcc.dg/cpp/include2a.c
@@ -11,6 +11,6 @@
/* These error is No such file or directory, just once. However, this
message is locale-dependent, so don't test for it. */
-/* { dg-error "silly" "" { target *-*-* } 10 } */
-/* { dg-error "missing" "" { target *-*-* } 10 } */
+/* { dg-error "silly" "" { target *-*-* } 0 } */
+/* { dg-error "missing" "" { target *-*-* } 0 } */
/* { dg-message "terminated" "" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/gcc.dg/cpp/line3.c b/gcc/testsuite/gcc.dg/cpp/line3.c
index dc5bf818da9..7a1061478d4 100644
--- a/gcc/testsuite/gcc.dg/cpp/line3.c
+++ b/gcc/testsuite/gcc.dg/cpp/line3.c
@@ -14,15 +14,15 @@ main(void)
char *A;
A = "text"; /* { dg-warning "discards qualifiers" "case zero" } */
- A = one("text"
+ A = one("text" /* { dg-warning "discards qualifiers" "case one" } */
"text")
- ; /* { dg-warning "discards qualifiers" "case one" } */
- A = two("text"
+ ;
+ A = two("text" /* { dg-warning "discards qualifiers" "case two" } */
"text")
- ; /* { dg-warning "discards qualifiers" "case two" } */
- A = four("text"
+ ;
+ A = four("text" /* { dg-warning "discards qualifiers" "case four" } */
"text")
- ; /* { dg-warning "discards qualifiers" "case four" } */
+ ;
return 0;
}
diff --git a/gcc/testsuite/gcc.dg/cpp/macspace1.c b/gcc/testsuite/gcc.dg/cpp/macspace1.c
index daf14d2b1f1..d8578448b64 100644
--- a/gcc/testsuite/gcc.dg/cpp/macspace1.c
+++ b/gcc/testsuite/gcc.dg/cpp/macspace1.c
@@ -1,6 +1,6 @@
/* PR preprocessor/19475 */
/* { dg-do preprocess } */
-/* { dg-options "-std=iso9899:1990 -pedantic-errors -fno-show-column" } */
+/* { dg-options "-std=iso9899:1990 -pedantic-errors" } */
#define a! /* { dg-warning "missing whitespace" } */
#define b" /* { dg-warning "missing whitespace" } */
diff --git a/gcc/testsuite/gcc.dg/cpp/macspace2.c b/gcc/testsuite/gcc.dg/cpp/macspace2.c
index 7a81eceeac8..1494fed18c3 100644
--- a/gcc/testsuite/gcc.dg/cpp/macspace2.c
+++ b/gcc/testsuite/gcc.dg/cpp/macspace2.c
@@ -1,6 +1,6 @@
/* PR preprocessor/19475 */
/* { dg-do preprocess } */
-/* { dg-options "-std=iso9899:1999 -pedantic-errors -fno-show-column" } */
+/* { dg-options "-std=iso9899:1999 -pedantic-errors" } */
#define a! /* { dg-error "requires whitespace" } */
#define b" /* { dg-error "requires whitespace" } */
diff --git a/gcc/testsuite/gcc.dg/cpp/missing-header-1.c b/gcc/testsuite/gcc.dg/cpp/missing-header-1.c
index 5445d4c4fec..dbcc2b36167 100644
--- a/gcc/testsuite/gcc.dg/cpp/missing-header-1.c
+++ b/gcc/testsuite/gcc.dg/cpp/missing-header-1.c
@@ -2,7 +2,8 @@
/* { dg-do compile } */
/* { dg-options "" } */
-#include "nonexistent.h" /* { dg-error "nonexistent.h" } */
+#include "nonexistent.h"
+/* { dg-message "nonexistent.h" "" { target *-*-* } 0 } */
/* { dg-message "terminated" "" { target *-*-* } 0 } */
/* This declaration should not receive any diagnostic. */
diff --git a/gcc/testsuite/gcc.dg/cpp/poison.c b/gcc/testsuite/gcc.dg/cpp/poison.c
index d667183de31..f85405c0983 100644
--- a/gcc/testsuite/gcc.dg/cpp/poison.c
+++ b/gcc/testsuite/gcc.dg/cpp/poison.c
@@ -1,5 +1,4 @@
-/* { dg-do preprocess }
- { dg-options "-fno-show-column" } */
+/* { dg-do preprocess } */
#pragma GCC poison foo
foo /* { dg-error "foo" "use of foo" } */
diff --git a/gcc/testsuite/gcc.dg/cpp/pr29612-2.c b/gcc/testsuite/gcc.dg/cpp/pr29612-2.c
index 813eb77af13..fff10a843b4 100644
--- a/gcc/testsuite/gcc.dg/cpp/pr29612-2.c
+++ b/gcc/testsuite/gcc.dg/cpp/pr29612-2.c
@@ -1,6 +1,6 @@
/* PR preprocessor/29612 */
/* { dg-do preprocess } */
-/* { dg-options "-Wtraditional -fno-show-column" } */
+/* { dg-options "-Wtraditional" } */
# 6 "pr29612-2.c"
diff --git a/gcc/testsuite/gcc.dg/cpp/pr36674.i b/gcc/testsuite/gcc.dg/cpp/pr36674.i
new file mode 100644
index 00000000000..9362d5a4080
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/cpp/pr36674.i
@@ -0,0 +1,12 @@
+/* PR cpp/36674 #include location is offset by one row in errors from preprocessed files */
+/* { dg-do compile } */
+/* { dg-options "-fshow-column" } */
+# 1 "gcc/testsuite/gcc.dg/pr36674.c"
+# 1 "<built-in>"
+# 1 "<command-line>"
+# 1 "gcc/testsuite/gcc.dg/pr36674.c"
+# 1 "gcc/testsuite/gcc.dg/pr36674.h" 1
+not_declared_yet();
+# 1 "gcc/testsuite/gcc.dg/pr36674.c" 2
+/* { dg-message "file included from \[^\n\]*pr36674.c:1:" "correct include line" { target *-*-* } 0 } */
+/* { dg-message "pr36674.h:1:1: warning: data definition has no type or storage class" "correct warning" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/gcc.dg/cpp/redef2.c b/gcc/testsuite/gcc.dg/cpp/redef2.c
index 57fa3b1930b..1dbc10033ed 100644
--- a/gcc/testsuite/gcc.dg/cpp/redef2.c
+++ b/gcc/testsuite/gcc.dg/cpp/redef2.c
@@ -1,7 +1,7 @@
/* Test for redefining macros with significant differences. */
/* { dg-do preprocess }
- { dg-options "-ansi -Wall -fno-show-column" } */
+ { dg-options "-ansi -Wall" } */
#define mac(a, b) (a) + (b)
#define mac(a, b) (a) * (b)
diff --git a/gcc/testsuite/gcc.dg/cpp/strify2.c b/gcc/testsuite/gcc.dg/cpp/strify2.c
index 2c768dcd05e..c24220c70e0 100644
--- a/gcc/testsuite/gcc.dg/cpp/strify2.c
+++ b/gcc/testsuite/gcc.dg/cpp/strify2.c
@@ -1,7 +1,7 @@
/* Copyright (C) 2000 Free Software Foundation, Inc. */
/* { dg-do run } */
-/* { dg-options "-std=c99 -pedantic-errors -fno-show-column" } */
+/* { dg-options "-std=c99 -pedantic-errors" } */
/* Tests a whole bunch of things are correctly stringified. */
diff --git a/gcc/testsuite/gcc.dg/cpp/syshdr.c b/gcc/testsuite/gcc.dg/cpp/syshdr.c
index 75137739327..310d5d0d288 100644
--- a/gcc/testsuite/gcc.dg/cpp/syshdr.c
+++ b/gcc/testsuite/gcc.dg/cpp/syshdr.c
@@ -8,5 +8,6 @@
/* { dg-do preprocess } */
/* { dg-error "include_next" "good error" { target *-*-* } 4 } */
-#include "syshdr1.h" /* { dg-message "" "In file included from:" } */
+#include "syshdr1.h"
+/* { dg-message "" "In file included from:" { target *-*-* } 0 } */
#include "syshdr2.h"
diff --git a/gcc/testsuite/gcc.dg/cpp/sysmac2.c b/gcc/testsuite/gcc.dg/cpp/sysmac2.c
index 0d1efabdc07..6d493a9ed1b 100644
--- a/gcc/testsuite/gcc.dg/cpp/sysmac2.c
+++ b/gcc/testsuite/gcc.dg/cpp/sysmac2.c
@@ -1,7 +1,7 @@
/* Copyright (C) 2001 Free Software Foundation, Inc. */
/* { dg-do compile } */
-/* { dg-options "-std=gnu99 -pedantic -Wtraditional -fno-show-column" } */
+/* { dg-options "-std=gnu99 -pedantic -Wtraditional" } */
/* Tests diagnostics are suppressed for some macros defined in system
headers. */
diff --git a/gcc/testsuite/gcc.dg/cpp/tr-warn1.c b/gcc/testsuite/gcc.dg/cpp/tr-warn1.c
index 259f9288253..37b5efe5df1 100644
--- a/gcc/testsuite/gcc.dg/cpp/tr-warn1.c
+++ b/gcc/testsuite/gcc.dg/cpp/tr-warn1.c
@@ -1,6 +1,6 @@
/* Test for warnings about nontraditional directives. */
/* { dg-do preprocess } */
-/* { dg-options "-pedantic -Wtraditional -fno-show-column" } */
+/* { dg-options "-pedantic -Wtraditional" } */
/* Block 1: K+R directives should have the # indented. */
diff --git a/gcc/testsuite/gcc.dg/cpp/tr-warn3.c b/gcc/testsuite/gcc.dg/cpp/tr-warn3.c
index e802b4dd0f7..33517188cd8 100644
--- a/gcc/testsuite/gcc.dg/cpp/tr-warn3.c
+++ b/gcc/testsuite/gcc.dg/cpp/tr-warn3.c
@@ -3,7 +3,7 @@
warnings inside unused clauses because they are often hidden this
way on purpose. However they do still require indentation for K&R. */
/* { dg-do preprocess } */
-/* { dg-options "-pedantic -Wtraditional -fno-show-column" } */
+/* { dg-options "-pedantic -Wtraditional" } */
#if 1
diff --git a/gcc/testsuite/gcc.dg/cpp/tr-warn4.c b/gcc/testsuite/gcc.dg/cpp/tr-warn4.c
index 14dd8a3163e..f5b5779bfd7 100644
--- a/gcc/testsuite/gcc.dg/cpp/tr-warn4.c
+++ b/gcc/testsuite/gcc.dg/cpp/tr-warn4.c
@@ -2,7 +2,7 @@
Note, gcc should omit these warnings in system header files.
By Kaveh R. Ghazi <ghazi@caip.rutgers.edu> 8/22/2000. */
/* { dg-do preprocess } */
-/* { dg-options "-Wtraditional -fno-show-column" } */
+/* { dg-options "-Wtraditional" } */
#if 1U /* { dg-warning "traditional C rejects" "numeric constant suffix" } */
#endif
diff --git a/gcc/testsuite/gcc.dg/cpp/tr-warn5.c b/gcc/testsuite/gcc.dg/cpp/tr-warn5.c
index 16dcf4c0866..6867b88c219 100644
--- a/gcc/testsuite/gcc.dg/cpp/tr-warn5.c
+++ b/gcc/testsuite/gcc.dg/cpp/tr-warn5.c
@@ -2,7 +2,7 @@
Note, gcc should omit these warnings in system header files.
By Kaveh R. Ghazi <ghazi@caip.rutgers.edu> 8/22/2000. */
/* { dg-do preprocess } */
-/* { dg-options "-Wtraditional -fno-show-column" } */
+/* { dg-options "-Wtraditional" } */
#if +1 /* { dg-warning "unary plus operator" "unary plus operator" } */
#endif
diff --git a/gcc/testsuite/gcc.dg/cpp/tr-warn6.c b/gcc/testsuite/gcc.dg/cpp/tr-warn6.c
index e9aa851d041..d95409ef8f9 100644
--- a/gcc/testsuite/gcc.dg/cpp/tr-warn6.c
+++ b/gcc/testsuite/gcc.dg/cpp/tr-warn6.c
@@ -2,7 +2,7 @@
Note, gcc should omit these warnings in system header files.
By Kaveh R. Ghazi <ghazi@caip.rutgers.edu> 9/8/2000. */
/* { dg-do preprocess } */
-/* { dg-options "-Wtraditional -fno-show-column" } */
+/* { dg-options "-Wtraditional" } */
#define foo1(h) sdf "h3" fds "h" /* { dg-warning "macro argument \"h\" would be stringified" "traditional stringification" } */
#define foo2(h2) sdf "h2" fds "h3" /* { dg-warning "macro argument \"h2\" would be stringified" "traditional stringification" } */
diff --git a/gcc/testsuite/gcc.dg/cpp/trad/trad.exp b/gcc/testsuite/gcc.dg/cpp/trad/trad.exp
index 22225e51915..190cfcfdee6 100644
--- a/gcc/testsuite/gcc.dg/cpp/trad/trad.exp
+++ b/gcc/testsuite/gcc.dg/cpp/trad/trad.exp
@@ -37,7 +37,7 @@ dg-init
# Main loop.
dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] \
- "-fno-show-column" $DEFAULT_TRADCPPFLAGS
+ "" $DEFAULT_TRADCPPFLAGS
# All done.
dg-finish
diff --git a/gcc/testsuite/gcc.dg/cpp/unc4.c b/gcc/testsuite/gcc.dg/cpp/unc4.c
index 758e5bbc6d9..10c49e9d4db 100644
--- a/gcc/testsuite/gcc.dg/cpp/unc4.c
+++ b/gcc/testsuite/gcc.dg/cpp/unc4.c
@@ -1,5 +1,4 @@
/* { dg-do preprocess } */
-/* { dg-options "-fno-show-column" } */
/* Tests for un-terminated conditional diagnostics.
Copyright (c) 1999 Free Software Foundation.
diff --git a/gcc/testsuite/gcc.dg/cpp/undef2.c b/gcc/testsuite/gcc.dg/cpp/undef2.c
index 4e6a690dcc9..5614e039b22 100644
--- a/gcc/testsuite/gcc.dg/cpp/undef2.c
+++ b/gcc/testsuite/gcc.dg/cpp/undef2.c
@@ -1,9 +1,7 @@
/* C99 6.10.8 para 4: None of [the predefined macro names] shall be
- the subject of a #define or an #undef preprocessing directive. We
- pass -fno-show-column as otherwise dejagnu gets confused. */
+ the subject of a #define or an #undef preprocessing directive. */
/* { dg-do preprocess } */
-/* { dg-options "-fno-show-column" } */
#undef __DATE__ /* { dg-warning "undefining" "__DATE__" } */
#undef __TIME__ /* { dg-warning "undefining" "__TIME__" } */
diff --git a/gcc/testsuite/gcc.dg/dll-6.c b/gcc/testsuite/gcc.dg/dll-6.c
new file mode 100644
index 00000000000..7907f40d1bd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/dll-6.c
@@ -0,0 +1,52 @@
+/* { dg-do link } */
+/* { dg-require-dll "" } */
+/* { dg-additional-sources "dll-6a.c" } */
+/* { dg-options "-w -O2 -std=gnu89" } */
+
+/* Test that inline functions declared "dllexport" appear in object
+ files, even if they are not called.
+
+ This behavior is required by the ARM C++ ABI:
+
+ Exporting a function that can be inlined should force the
+ creation and export of an out-of-line copy of it.
+
+ and should presumably also apply.
+
+ Visual Studio 2005 also honors that rule. */
+
+__declspec(dllexport) inline void i1() {}
+
+__declspec(dllexport) extern inline void e1() {}
+
+/* It is invalid to declare the function inline after its definition. */
+#if 0
+__declspec(dllexport) void i2() {}
+inline void i2();
+
+__declspec(dllexport) extern void e2() {}
+inline void e2();
+#endif
+
+__declspec(dllexport) inline void i3() {}
+void i3();
+
+__declspec(dllexport) inline void e3() {}
+extern void e3();
+
+__declspec(dllexport) void i4();
+inline void i4() {};
+
+__declspec(dllexport) extern void e4();
+inline void e4() {};
+
+__declspec(dllexport) inline void i5();
+void i5() {};
+
+__declspec(dllexport) inline void e5();
+extern void e5() {};
+
+/* Make sure that just declaring the function -- without defining it
+ -- does not cause errors. */
+__declspec(dllexport) inline void i6();
+__declspec(dllexport) extern inline void e6();
diff --git a/gcc/testsuite/gcc.dg/dll-6a.c b/gcc/testsuite/gcc.dg/dll-6a.c
new file mode 100644
index 00000000000..80caf321742
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/dll-6a.c
@@ -0,0 +1,21 @@
+extern void i1();
+extern void i3();
+extern void i4();
+extern void i5();
+
+extern void e1();
+extern void e3();
+extern void e4();
+extern void e5();
+
+int main () {
+ i1();
+ i3();
+ i4();
+ i5();
+
+ e1();
+ e3();
+ e4();
+ e5();
+}
diff --git a/gcc/testsuite/gcc.dg/dll-7.c b/gcc/testsuite/gcc.dg/dll-7.c
new file mode 100644
index 00000000000..c3a5957ae6b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/dll-7.c
@@ -0,0 +1,52 @@
+/* { dg-do link } */
+/* { dg-require-dll "" } */
+/* { dg-additional-sources "dll-7a.c" } */
+/* { dg-options "-w -O2 -std=gnu99" } */
+
+/* Test that inline functions declared "dllexport" appear in object
+ files, even if they are not called.
+
+ This behavior is required by the ARM C++ ABI:
+
+ Exporting a function that can be inlined should force the
+ creation and export of an out-of-line copy of it.
+
+ and should presumably also apply.
+
+ Visual Studio 2005 also honors that rule. */
+
+__declspec(dllexport) inline void i1() {}
+
+__declspec(dllexport) extern inline void e1() {}
+
+/* It is invalid to declare the function inline after its definition. */
+#if 0
+__declspec(dllexport) void i2() {}
+inline void i2();
+
+__declspec(dllexport) extern void e2() {}
+inline void e2();
+#endif
+
+__declspec(dllexport) inline void i3() {}
+void i3();
+
+__declspec(dllexport) inline void e3() {}
+extern void e3();
+
+__declspec(dllexport) void i4();
+inline void i4() {};
+
+__declspec(dllexport) extern void e4();
+inline void e4() {};
+
+__declspec(dllexport) inline void i5();
+void i5() {};
+
+__declspec(dllexport) inline void e5();
+extern void e5() {};
+
+/* Make sure that just declaring the function -- without defining it
+ -- does not cause errors. */
+__declspec(dllexport) inline void i6();
+__declspec(dllexport) extern inline void e6();
diff --git a/gcc/testsuite/gcc.dg/dll-7a.c b/gcc/testsuite/gcc.dg/dll-7a.c
new file mode 100644
index 00000000000..80caf321742
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/dll-7a.c
@@ -0,0 +1,21 @@
+extern void i1();
+extern void i3();
+extern void i4();
+extern void i5();
+
+extern void e1();
+extern void e3();
+extern void e4();
+extern void e5();
+
+int main () {
+ i1();
+ i3();
+ i4();
+ i5();
+
+ e1();
+ e3();
+ e4();
+ e5();
+}
diff --git a/gcc/testsuite/gcc.dg/dremf-type-compat-2.c b/gcc/testsuite/gcc.dg/dremf-type-compat-2.c
index 61f0ba84fe3..980ead187e7 100644
--- a/gcc/testsuite/gcc.dg/dremf-type-compat-2.c
+++ b/gcc/testsuite/gcc.dg/dremf-type-compat-2.c
@@ -11,8 +11,8 @@ float dremf (float, float); /* { dg-warning "prototype declaration" } */
float
dremf (x, y)
- float x;
- float y;
-{ /* { dg-warning "promoted argument '.' doesn't match prototype" } */
+ float x; /* { dg-warning "promoted argument 'x' doesn't match prototype" } */
+ float y; /* { dg-warning "promoted argument 'y' doesn't match prototype" } */
+{
return x + y;
}
diff --git a/gcc/testsuite/gcc.dg/dremf-type-compat-3.c b/gcc/testsuite/gcc.dg/dremf-type-compat-3.c
index 437e26f65ba..3934a64e19f 100644
--- a/gcc/testsuite/gcc.dg/dremf-type-compat-3.c
+++ b/gcc/testsuite/gcc.dg/dremf-type-compat-3.c
@@ -11,8 +11,8 @@ float dremf (float, float); /* { dg-error "prototype declaration" } */
float
dremf (x, y)
- float x;
- float y;
-{ /* { dg-error "promoted argument '.' doesn't match prototype" } */
+ float x; /* { dg-error "promoted argument 'x' doesn't match prototype" } */
+ float y; /* { dg-error "promoted argument 'y' doesn't match prototype" } */
+{
return x + y;
}
diff --git a/gcc/testsuite/gcc.dg/enum-compat-1.c b/gcc/testsuite/gcc.dg/enum-compat-1.c
index 18d1f7fe715..5fb150cee79 100644
--- a/gcc/testsuite/gcc.dg/enum-compat-1.c
+++ b/gcc/testsuite/gcc.dg/enum-compat-1.c
@@ -12,8 +12,8 @@ enum e2 {c, d};
void f(enum e1); /* { dg-error "prototype" "error at decl" } */
void f(x)
- enum e2 x;
-{ /* { dg-error "doesn't match prototype" "error at defn" } */
+ enum e2 x; /* { dg-error "doesn't match prototype" } */
+{
return;
}
diff --git a/gcc/testsuite/gcc.dg/falign-labels-1.c b/gcc/testsuite/gcc.dg/falign-labels-1.c
new file mode 100644
index 00000000000..be277e4e043
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/falign-labels-1.c
@@ -0,0 +1,39 @@
+/* { dg-do run } */
+/* { dg-options "-falign-labels=8" } */
+
+/* On ARMv7-A CPUs, this test resulted in incorrect code generation.
+ The code generated for the switch statement expected the jump table
+ to immediately follow the jump instruction, but -falign-labels
+ caused the label preceding the table to be aligned. */
+/* M68K and fido only support -falign-labels argument <= 2. */
+
+volatile int x;
+
+int main(void)
+{
+ int y;
+
+ x = 0;
+
+ switch(x)
+ {
+ case 0:
+ y = 2 * x;
+ break;
+ case 1:
+ y = -3 * x;
+ break;
+ case 2:
+ y = x + 5;
+ break;
+ case 3:
+ y = x - 7;
+ break;
+ default:
+ break;
+ }
+
+ x = y;
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/func-ptr-conv-1.c b/gcc/testsuite/gcc.dg/func-ptr-conv-1.c
index 4e42e5fe117..c331fbc88fc 100644
--- a/gcc/testsuite/gcc.dg/func-ptr-conv-1.c
+++ b/gcc/testsuite/gcc.dg/func-ptr-conv-1.c
@@ -9,15 +9,15 @@
void f(void);
-void *v1 = f; /* { dg-warning "pointer" "bad conversion" } */
-void *v2 = &f; /* { dg-warning "pointer" "bad conversion" } */
-void *v3 = (void *)f; /* { dg-warning "pointer" "bad conversion" } */
-void *v4 = (void *)&f; /* { dg-warning "pointer" "bad conversion" } */
+void *v1 = f; /* { dg-warning "12:pointer" "bad conversion" } */
+void *v2 = &f; /* { dg-warning "12:pointer" "bad conversion" } */
+void *v3 = (void *)f; /* { dg-warning "12:pointer" "bad conversion" } */
+void *v4 = (void *)&f; /* { dg-warning "12:pointer" "bad conversion" } */
void *v5;
-char *c1 = f; /* { dg-warning "pointer" "bad conversion" } */
-char *c2 = &f; /* { dg-warning "pointer" "bad conversion" } */
-char *c3 = (char *)f; /* { dg-warning "pointer" "bad conversion" } */
-char *c4 = (char *)&f; /* { dg-warning "pointer" "bad conversion" } */
+char *c1 = f; /* { dg-warning "12:pointer" "bad conversion" } */
+char *c2 = &f; /* { dg-warning "12:pointer" "bad conversion" } */
+char *c3 = (char *)f; /* { dg-warning "12:pointer" "bad conversion" } */
+char *c4 = (char *)&f; /* { dg-warning "12:pointer" "bad conversion" } */
char *c5;
void (*fp)(void);
int a;
@@ -25,20 +25,20 @@ int a;
void
g(void)
{
- v5 = f; /* { dg-warning "pointer" "bad conversion" } */
- v5 = &f; /* { dg-warning "pointer" "bad conversion" } */
- v5 = (void *)f; /* { dg-warning "pointer" "bad conversion" } */
- v5 = (void *)&f; /* { dg-warning "pointer" "bad conversion" } */
- c5 = f; /* { dg-warning "pointer" "bad conversion" } */
- c5 = &f; /* { dg-warning "pointer" "bad conversion" } */
- c5 = (char *)f; /* { dg-warning "pointer" "bad conversion" } */
- c5 = (char *)&f; /* { dg-warning "pointer" "bad conversion" } */
- fp = v5; /* { dg-warning "pointer" "bad conversion" } */
- fp = c5; /* { dg-warning "pointer" "bad conversion" } */
- fp = (void (*)(void))v5; /* { dg-warning "pointer" "bad conversion" } */
- fp = (void (*)(void))c5; /* { dg-warning "pointer" "bad conversion" } */
- (a ? f : v3); /* { dg-warning "pointer" "bad conversion" } */
- (a ? v2 : fp); /* { dg-warning "pointer" "bad conversion" } */
+ v5 = f; /* { dg-warning "6:pointer" "bad conversion" } */
+ v5 = &f; /* { dg-warning "6:pointer" "bad conversion" } */
+ v5 = (void *)f; /* { dg-warning "8:pointer" "bad conversion" } */
+ v5 = (void *)&f; /* { dg-warning "8:pointer" "bad conversion" } */
+ c5 = f; /* { dg-warning "6:pointer" "bad conversion" } */
+ c5 = &f; /* { dg-warning "6:pointer" "bad conversion" } */
+ c5 = (char *)f; /* { dg-warning "8:pointer" "bad conversion" } */
+ c5 = (char *)&f; /* { dg-warning "8:pointer" "bad conversion" } */
+ fp = v5; /* { dg-warning "6:pointer" "bad conversion" } */
+ fp = c5; /* { dg-warning "6:pointer" "bad conversion" } */
+ fp = (void (*)(void))v5; /* { dg-warning "8:pointer" "bad conversion" } */
+ fp = (void (*)(void))c5; /* { dg-warning "8:pointer" "bad conversion" } */
+ (a ? f : v3); /* { dg-warning "6:pointer" "bad conversion" } */
+ (a ? v2 : fp); /* { dg-warning "6:pointer" "bad conversion" } */
/* The following are OK. */
fp = 0;
fp = (void *)0;
diff --git a/gcc/testsuite/gcc.dg/gomp/for-1.c b/gcc/testsuite/gcc.dg/gomp/for-1.c
index 840f9478499..384293e8275 100644
--- a/gcc/testsuite/gcc.dg/gomp/for-1.c
+++ b/gcc/testsuite/gcc.dg/gomp/for-1.c
@@ -44,6 +44,6 @@ void foo (int j, int k)
baz (i);
#pragma omp for
- for (i = 0; i < 10; i-=3, j+=2) /* { dg-error "23:invalid increment expression" } */
+ for (i = 0; i < 10; i-=3, j+=2) /* { dg-error "27:invalid increment expression" } */
baz (i);
}
diff --git a/gcc/testsuite/gcc.dg/gomp/pr27415.c b/gcc/testsuite/gcc.dg/gomp/pr27415.c
index 418eaf678e9..010a6c3e4dd 100644
--- a/gcc/testsuite/gcc.dg/gomp/pr27415.c
+++ b/gcc/testsuite/gcc.dg/gomp/pr27415.c
@@ -15,8 +15,8 @@ void
test2 (void)
{
int i = 0;
-#pragma omp parallel for firstprivate (i)
- for (i = 0; i < 10; i++) /* { dg-error "should not be firstprivate" } */
+#pragma omp parallel for firstprivate (i) /* { dg-error "should not be firstprivate" } */
+ for (i = 0; i < 10; i++)
;
}
@@ -34,8 +34,8 @@ void
test4 (void)
{
int i = 0;
-#pragma omp parallel for reduction (*:i)
- for (i = 0; i < 10; i++) /* { dg-error "should not be reduction" } */
+#pragma omp parallel for reduction (*:i) /* { dg-error "should not be reduction" } */
+ for (i = 0; i < 10; i++)
;
}
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-4.c b/gcc/testsuite/gcc.dg/ipa/ipa-4.c
index 9f716f13936..c162b2385f2 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-4.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-4.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O3 -fipa-cp -fipa-cp-clone -fdump-ipa-cp" } */
+/* { dg-options "-O3 -fipa-cp -fipa-cp-clone -fdump-ipa-cp -fno-early-inlining" } */
/* { dg-skip-if "PR 25442" { "*-*-*" } { "-fpic" "-fPIC" } { "" } } */
#include <stdio.h>
diff --git a/gcc/testsuite/gcc.dg/ipa/ipacost-1.c b/gcc/testsuite/gcc.dg/ipa/ipacost-1.c
index 1c75c6cfde5..d91546899ea 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipacost-1.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipacost-1.c
@@ -46,6 +46,8 @@ i_can_not_be_propagated_fully2 (int *a)
main()
{
i_can_be_propagated_fully2 (array);
+ i_can_be_propagated_fully2 (array);
+ i_can_not_be_propagated_fully2 (array);
i_can_not_be_propagated_fully2 (array);
}
diff --git a/gcc/testsuite/gcc.dg/ipa/ipacost-2.c b/gcc/testsuite/gcc.dg/ipa/ipacost-2.c
index 46db85fde3e..958059c73e6 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipacost-2.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipacost-2.c
@@ -47,6 +47,8 @@ i_can_not_be_propagated_fully2 (int *a)
main()
{
i_can_be_propagated_fully2 (array);
+ i_can_be_propagated_fully2 (array);
+ i_can_not_be_propagated_fully2 (array);
i_can_not_be_propagated_fully2 (array);
}
@@ -54,7 +56,7 @@ main()
/* { dg-final { scan-ipa-dump-times "versioned function i_can_be_propagated_fully " 1 "cp" } } */
/* { dg-final { scan-ipa-dump-times "versioned function i_can_not_be_propagated_fully2" 1 "cp" } } */
/* { dg-final { scan-ipa-dump-times "versioned function i_can_not_be_propagated_fully " 1 "cp" } } */
-/* { dg-final { scan-tree-dump-not "i_can_be_propagated" "optimized" } } */
-/* { dg-final { scan-tree-dump-not "i_can_be_propagated" "optimized" } } */
+/* { dg-final { scan-tree-dump-not "i_can_be_propagated_fully \\(" "optimized" } } */
+/* { dg-final { scan-tree-dump-not "i_can_be_propagated_fully2 \\(" "optimized" } } */
/* { dg-final { cleanup-ipa-dump "cp" } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/modif-1.c b/gcc/testsuite/gcc.dg/ipa/modif-1.c
index bc1706c5650..db6915a9d9e 100644
--- a/gcc/testsuite/gcc.dg/ipa/modif-1.c
+++ b/gcc/testsuite/gcc.dg/ipa/modif-1.c
@@ -15,12 +15,11 @@ void func4 (int *pi);
void the_test (struct whatever u, struct whatever v,
struct whatever w, struct whatever x,
- int i, int j, int k, int l)
+ int i, int k, int l)
{
struct whatever *pw = &w;
int *pk = &k;
- j = l+3;
v.first = 9;
func1 (u);
@@ -28,7 +27,6 @@ void the_test (struct whatever u, struct whatever v,
func2 (pw);
func2 (&x);
func3 (i);
- func3 (j);
func4 (pk);
func4 (&l);
}
@@ -40,5 +38,4 @@ void the_test (struct whatever u, struct whatever v,
/* { dg-final { scan-ipa-dump-not "param 4\[^\\n\]*modified" "inline" } } */
/* { dg-final { scan-ipa-dump "param 5\[^\\n\]*modified" "inline" } } */
/* { dg-final { scan-ipa-dump "param 6\[^\\n\]*modified" "inline" } } */
-/* { dg-final { scan-ipa-dump "param 7\[^\\n\]*modified" "inline" } } */
/* { dg-final { cleanup-ipa-dump "inline" } } */
diff --git a/gcc/testsuite/gcc.dg/label-decl-2.c b/gcc/testsuite/gcc.dg/label-decl-2.c
index 97c453b78b7..6706a706bfe 100644
--- a/gcc/testsuite/gcc.dg/label-decl-2.c
+++ b/gcc/testsuite/gcc.dg/label-decl-2.c
@@ -8,9 +8,8 @@ typedef int b;
void
f (void)
{
- __label__ a, b, c, d;
+ __label__ a, b, c, d; /* { dg-warning "ISO C forbids label declarations" "label decls" { target *-*-* } 11 } */
__extension__ (void)&&d; /* { dg-error "label 'd' used but not defined" } */
- /* { dg-warning "ISO C forbids label declarations" "label decls" { target *-*-* } 11 } */
goto c; /* { dg-error "label 'c' used but not defined" } */
a: (void)0;
b: (void)0;
diff --git a/gcc/testsuite/gcc.dg/memcpy-1.c b/gcc/testsuite/gcc.dg/memcpy-1.c
index cc602423793..2b11098b286 100644
--- a/gcc/testsuite/gcc.dg/memcpy-1.c
+++ b/gcc/testsuite/gcc.dg/memcpy-1.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-optimized --param sra-max-structure-size=32" } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
/* PR36598 AVR fail maybe due to cost metrics */
/* { dg-final { scan-tree-dump-times "nasty_local" 0 "optimized" { xfail { "avr-*-*" } } } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/nofixed-point-2.c b/gcc/testsuite/gcc.dg/nofixed-point-2.c
index 97bbf70225c..5820ded922e 100644
--- a/gcc/testsuite/gcc.dg/nofixed-point-2.c
+++ b/gcc/testsuite/gcc.dg/nofixed-point-2.c
@@ -9,7 +9,7 @@ f1 (void)
}
__typeof (0r) /* { dg-error "not supported" "reject fixed-point" } */
-b2 (void)
+b2 (void) /* { dg-warning "defaults to" } */
{
return 0r; /* { dg-error "not supported" "reject fixed-point" } */
}
@@ -26,5 +26,4 @@ f4 (void) /* { dg-error "not supported" "reject fixed-point" } */
return 0k; /* { dg-error "not supported" "reject fixed-point" } */
}
-/* { dg-warning "defaults to" "" { target *-*-* } 13 } */
/* { dg-error "is used without" "" { target *-*-* } 24 } */
diff --git a/gcc/testsuite/gcc.dg/old-style-prom-2.c b/gcc/testsuite/gcc.dg/old-style-prom-2.c
index 0460facef61..e7e690e1417 100644
--- a/gcc/testsuite/gcc.dg/old-style-prom-2.c
+++ b/gcc/testsuite/gcc.dg/old-style-prom-2.c
@@ -7,8 +7,8 @@ float f (float, float); /* { dg-warning "prototype declaration" } */
float
f (x, y)
- float x;
- float y;
-{ /* { dg-warning "promoted argument '.' doesn't match prototype" } */
+ float x; /* { dg-warning "promoted argument 'x' doesn't match prototype" } */
+ float y; /* { dg-warning "promoted argument 'y' doesn't match prototype" } */
+{
return x + y;
}
diff --git a/gcc/testsuite/gcc.dg/old-style-prom-3.c b/gcc/testsuite/gcc.dg/old-style-prom-3.c
index 931a4a7264b..720367f2e33 100644
--- a/gcc/testsuite/gcc.dg/old-style-prom-3.c
+++ b/gcc/testsuite/gcc.dg/old-style-prom-3.c
@@ -7,8 +7,8 @@ float f (float, float); /* { dg-error "prototype declaration" } */
float
f (x, y)
- float x;
- float y;
-{ /* { dg-error "promoted argument '.' doesn't match prototype" } */
+ float x; /* { dg-error "promoted argument 'x' doesn't match prototype" } */
+ float y; /* { dg-error "promoted argument 'y' doesn't match prototype" } */
+{
return x + y;
}
diff --git a/gcc/testsuite/gcc.dg/optimize-bswapdi-1.c b/gcc/testsuite/gcc.dg/optimize-bswapdi-1.c
new file mode 100644
index 00000000000..45fb2af2b30
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/optimize-bswapdi-1.c
@@ -0,0 +1,28 @@
+/* { dg-do compile { target alpha*-*-* ia64*-*-* x86_64-*-* s390x-*-* } } */
+/* { dg-require-effective-target stdint_types } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-options "-O2 -fdump-tree-bswap" } */
+
+#include <stdint.h>
+#define __const_swab64(x) ((uint64_t)( \
+ (((uint64_t)(x) & (uint64_t)0x00000000000000ffULL) << 56) | \
+ (((uint64_t)(x) & (uint64_t)0x000000000000ff00ULL) << 40) | \
+ (((uint64_t)(x) & (uint64_t)0x0000000000ff0000ULL) << 24) | \
+ (((uint64_t)(x) & (uint64_t)0x00000000ff000000ULL) << 8) | \
+ (((uint64_t)(x) & (uint64_t)0x000000ff00000000ULL) >> 8) | \
+ (((uint64_t)(x) & (uint64_t)0x0000ff0000000000ULL) >> 24) | \
+ (((uint64_t)(x) & (uint64_t)0x00ff000000000000ULL) >> 40) | \
+ (((uint64_t)(x) & (uint64_t)0xff00000000000000ULL) >> 56)))
+
+
+/* This byte swap implementation is used by the Linux kernel and the
+ GNU C library. */
+
+uint64_t
+swap64 (uint64_t in)
+{
+ return __const_swab64 (in);
+}
+
+/* { dg-final { scan-tree-dump-times "64 bit bswap implementation found at" 1 "bswap" } } */
+/* { dg-final { cleanup-tree-dump "bswap" } } */
diff --git a/gcc/testsuite/gcc.dg/optimize-bswapsi-1.c b/gcc/testsuite/gcc.dg/optimize-bswapsi-1.c
new file mode 100644
index 00000000000..fc77296d522
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/optimize-bswapsi-1.c
@@ -0,0 +1,35 @@
+/* { dg-do compile { target alpha*-*-* i?86-*-* powerpc*-*-* rs6000-*-* x86_64-*-* s390*-*-* } } */
+/* { dg-require-effective-target stdint_types } */
+/* { dg-options "-O2 -fdump-tree-bswap" } */
+
+#include <stdint.h>
+
+#define __const_swab32(x) ((uint32_t)( \
+ (((uint32_t)(x) & (uint32_t)0x000000ffUL) << 24) | \
+ (((uint32_t)(x) & (uint32_t)0x0000ff00UL) << 8) | \
+ (((uint32_t)(x) & (uint32_t)0x00ff0000UL) >> 8) | \
+ (((uint32_t)(x) & (uint32_t)0xff000000UL) >> 24)))
+
+/* This byte swap implementation is used by the Linux kernel and the
+ GNU C library. */
+
+uint32_t
+swap32_a (uint32_t in)
+{
+ return __const_swab32 (in);
+}
+
+/* The OpenSSH byte swap implementation. */
+uint32_t
+swap32_b (uint32_t in)
+{
+ uint32_t a;
+
+ a = (in << 16) | (in >> 16);
+ a = ((a & 0x00ff00ff) << 8) | ((a & 0xff00ff00) >> 8);
+
+ return a;
+}
+
+/* { dg-final { scan-tree-dump-times "32 bit bswap implementation found at" 2 "bswap" } } */
+/* { dg-final { cleanup-tree-dump "bswap" } } */
diff --git a/gcc/testsuite/gcc.dg/overflow-warn-1.c b/gcc/testsuite/gcc.dg/overflow-warn-1.c
index 0cf08a3e77f..78909df368b 100644
--- a/gcc/testsuite/gcc.dg/overflow-warn-1.c
+++ b/gcc/testsuite/gcc.dg/overflow-warn-1.c
@@ -12,23 +12,23 @@ enum e {
/* Overflow in an unevaluated part of an expression is OK (example
in the standard). */
E2 = 2 || 1 / 0,
- E3 = 1 / 0, /* { dg-warning "division by zero" } */
- /* { dg-error "enumerator value for 'E3' is not an integer constant" "enum error" { target *-*-* } 15 } */
+ E3 = 1 / 0, /* { dg-warning "10:division by zero" } */
+ /* { dg-error "3:enumerator value for 'E3' is not an integer constant" "enum error" { target *-*-* } 15 } */
/* But as in DR#031, the 1/0 in an evaluated subexpression means the
whole expression violates the constraints. */
- E4 = 0 * (1 / 0), /* { dg-warning "division by zero" } */
+ E4 = 0 * (1 / 0), /* { dg-warning "15:division by zero" } */
/* { dg-error "enumerator value for 'E4' is not an integer constant" "enum error" { target *-*-* } 19 } */
- E5 = INT_MAX + 1, /* { dg-warning "integer overflow in expression" } */
+ E5 = INT_MAX + 1, /* { dg-warning "16:integer overflow in expression" } */
/* Again, overflow in evaluated subexpression. */
- E6 = 0 * (INT_MAX + 1), /* { dg-warning "integer overflow in expression" } */
+ E6 = 0 * (INT_MAX + 1), /* { dg-warning "21:integer overflow in expression" } */
/* A cast does not constitute overflow in conversion. */
E7 = (char) INT_MAX
};
struct s {
int a;
- int : 0 * (1 / 0); /* { dg-warning "division by zero" } */
- /* { dg-error "not an integer constant" "integer constant" { target *-*-* } 30 } */
+ int : 0 * (1 / 0); /* { dg-warning "16:division by zero" } */
+ /* { dg-error "not an integer constant" "22:integer constant" { target *-*-* } 30 } */
int : 0 * (INT_MAX + 1); /* { dg-warning "integer overflow in expression" } */
};
@@ -37,11 +37,11 @@ f (void)
{
/* This expression is not required to be a constant expression, so
it should just involve undefined behavior at runtime. */
- int c = INT_MAX + 1; /* { dg-warning "integer overflow in expression" } */
+ int c = INT_MAX + 1; /* { dg-warning "19:integer overflow in expression" } */
}
/* But this expression does need to be constant. */
-static int sc = INT_MAX + 1; /* { dg-warning "integer overflow in expression" } */
+static int sc = INT_MAX + 1; /* { dg-warning "25:integer overflow in expression" } */
/* The first two of these involve overflow, so are not null pointer
constants. The third has the overflow in an unevaluated
diff --git a/gcc/testsuite/gcc.dg/pch/counter-2.c b/gcc/testsuite/gcc.dg/pch/counter-2.c
index 6dd2245d7d8..14ce24909c8 100644
--- a/gcc/testsuite/gcc.dg/pch/counter-2.c
+++ b/gcc/testsuite/gcc.dg/pch/counter-2.c
@@ -8,7 +8,7 @@
#endif
#include "counter-2.h" /* { dg-warning "not used because `__COUNTER__' is invalid" } */
-/* { dg-error "counter-2.h: No such file or directory" "no such file" { target *-*-* } 10 } */
+/* { dg-error "counter-2.h: No such file or directory" "no such file" { target *-*-* } 0 } */
/* { dg-error "one or more PCH files were found, but they were invalid" "invalid files" { target *-*-* } 10 } */
/* { dg-message "terminated" "" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/gcc.dg/pch/valid-1.c b/gcc/testsuite/gcc.dg/pch/valid-1.c
index 3ee90916591..b7f22d0dc17 100644
--- a/gcc/testsuite/gcc.dg/pch/valid-1.c
+++ b/gcc/testsuite/gcc.dg/pch/valid-1.c
@@ -1,8 +1,8 @@
/* { dg-options "-I. -Winvalid-pch -g" } */
#include "valid-1.h"/* { dg-warning "created with -gnone, but used with -g" } */
-/* { dg-error "No such file" "no such file" { target *-*-* } 3 } */
-/* { dg-error "they were invalid" "invalid files" { target *-*-* } 3 } */
+/* { dg-error "No such file" "no such file" { target *-*-* } 0 } */
+/* { dg-error "they were invalid" "invalid files" { target *-*-* } 0 } */
/* { dg-message "terminated" "" { target *-*-* } 0 } */
int x;
diff --git a/gcc/testsuite/gcc.dg/pch/valid-2.c b/gcc/testsuite/gcc.dg/pch/valid-2.c
index 34269a87960..3d8cb1427f3 100644
--- a/gcc/testsuite/gcc.dg/pch/valid-2.c
+++ b/gcc/testsuite/gcc.dg/pch/valid-2.c
@@ -1,7 +1,7 @@
/* { dg-options "-I. -Winvalid-pch -fexceptions" } */
#include "valid-2.h" /* { dg-warning "settings for -fexceptions do not match" } */
-/* { dg-error "No such file" "no such file" { target *-*-* } 3 } */
-/* { dg-error "they were invalid" "invalid files" { target *-*-* } 3 } */
+/* { dg-error "No such file" "no such file" { target *-*-* } 0 } */
+/* { dg-error "they were invalid" "invalid files" { target *-*-* } 0 } */
/* { dg-message "terminated" "" { target *-*-* } 0 } */
int x;
diff --git a/gcc/testsuite/gcc.dg/pch/warn-1.c b/gcc/testsuite/gcc.dg/pch/warn-1.c
index 64944c776d8..1d31cef0544 100644
--- a/gcc/testsuite/gcc.dg/pch/warn-1.c
+++ b/gcc/testsuite/gcc.dg/pch/warn-1.c
@@ -3,8 +3,8 @@
#define DEFINED_VALUE 3
#include "warn-1.h"/* { dg-warning "not used because .DEFINED_VALUE. is defined" } */
-/* { dg-error "No such file" "no such file" { target *-*-* } 5 } */
-/* { dg-error "they were invalid" "invalid files" { target *-*-* } 5 } */
+/* { dg-error "No such file" "no such file" { target *-*-* } 0 } */
+/* { dg-error "they were invalid" "invalid files" { target *-*-* } 0 } */
/* { dg-message "terminated" "" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/gcc.dg/plugin/ggcplug-test-1.c b/gcc/testsuite/gcc.dg/plugin/ggcplug-test-1.c
new file mode 100644
index 00000000000..74e68bb82ec
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/ggcplug-test-1.c
@@ -0,0 +1,12 @@
+/* Test the ggcplug plugin. */
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+int main()
+{
+ int i=0, j=0;
+ for (i= 0; i<1000; i++)
+ if (i%8 == 0)
+ j++;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/plugin/ggcplug.c b/gcc/testsuite/gcc.dg/plugin/ggcplug.c
new file mode 100644
index 00000000000..f90e77bcf72
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/ggcplug.c
@@ -0,0 +1,112 @@
+/* This plugin tests the GGC related plugin events. */
+/* { dg-options "-O" } */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "toplev.h"
+#include "basic-block.h"
+#include "gimple.h"
+#include "tree.h"
+#include "tree-pass.h"
+#include "intl.h"
+#include "gcc-plugin.h"
+
+
+
+/* our callback is the same for all PLUGIN_GGC_START,
+ PLUGIN_GGC_MARKING, PLUGIN_GGC_END events; it just increments the
+ user_data which is an int */
+static void increment_callback (void *gcc_data, void *user_data);
+
+/* our counters are user_data */
+static int our_ggc_start_counter;
+static int our_ggc_end_counter;
+static int our_ggc_marking_counter;
+
+/* our empty GGC extra root table */
+static const struct ggc_root_tab our_xtratab[] = {
+ LAST_GGC_ROOT_TAB
+};
+
+
+/* The initialization routine exposed to and called by GCC. The spec of this
+ function is defined in gcc/gcc-plugin.h.
+
+ Note that this function needs to be named exactly "plugin_init". */
+int
+plugin_init (struct plugin_name_args *plugin_info,
+ struct plugin_gcc_version *version)
+{
+ const char *plugin_name = plugin_info->base_name;
+ int argc = plugin_info->argc;
+ int i = 0;
+ struct plugin_argument *argv = plugin_info->argv;
+ if (!plugin_default_version_check (version, version))
+ return 1;
+ /* Process the plugin arguments. This plugin takes the following arguments:
+ count-ggc-start count-ggc-end count-ggc-mark */
+ for (i = 0; i < argc; ++i)
+ {
+ if (!strcmp (argv[i].key, "count-ggc-start"))
+ {
+ if (argv[i].value)
+ warning (0, G_ ("option '-fplugin-arg-%s-count-ggc-start=%s'"
+ " ignored (superfluous '=%s')"),
+ plugin_name, argv[i].value, argv[i].value);
+ else
+ register_callback ("ggcplug",
+ PLUGIN_GGC_START,
+ increment_callback,
+ (void *) &our_ggc_start_counter);
+ }
+ else if (!strcmp (argv[i].key, "count-ggc-end"))
+ {
+ if (argv[i].value)
+ warning (0, G_ ("option '-fplugin-arg-%s-count-ggc-end=%s'"
+ " ignored (superfluous '=%s')"),
+ plugin_name, argv[i].value, argv[i].value);
+ else
+ register_callback ("ggcplug",
+ PLUGIN_GGC_END,
+ increment_callback,
+ (void *) &our_ggc_end_counter);
+ }
+ else if (!strcmp (argv[i].key, "count-ggc-mark"))
+ {
+ if (argv[i].value)
+ warning (0, G_ ("option '-fplugin-arg-%s-count-ggc-mark=%s'"
+ " ignored (superfluous '=%s')"),
+ plugin_name, argv[i].value, argv[i].value);
+ else
+ register_callback ("ggcplug",
+ PLUGIN_GGC_MARKING,
+ increment_callback,
+ (void *) &our_ggc_marking_counter);
+ }
+ else if (!strcmp (argv[i].key, "test-extra-root"))
+ {
+ if (argv[i].value)
+ warning (0, G_ ("option '-fplugin-arg-%s-test-extra-root=%s'"
+ " ignored (superfluous '=%s')"),
+ plugin_name, argv[i].value, argv[i].value);
+ else
+ register_callback ("ggcplug",
+ PLUGIN_REGISTER_GGC_ROOTS,
+ NULL,
+ (void *) our_xtratab);
+ }
+ }
+ /* plugin initialization succeeded */
+ return 0;
+ }
+
+static void
+increment_callback (void *gcc_data, void *user_data)
+{
+ int *usercountptr = (int *) user_data;
+ gcc_assert (!gcc_data);
+ gcc_assert (user_data);
+ (*usercountptr)++;
+}
diff --git a/gcc/testsuite/gcc.dg/plugin/one_time-test-1.c b/gcc/testsuite/gcc.dg/plugin/one_time-test-1.c
new file mode 100644
index 00000000000..a49ecb4affe
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/one_time-test-1.c
@@ -0,0 +1,8 @@
+/* Test that pass is inserted and invoked once. */
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+int main (int argc, char **argv)
+{
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/plugin/one_time_plugin.c b/gcc/testsuite/gcc.dg/plugin/one_time_plugin.c
new file mode 100644
index 00000000000..8ae327a68f9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/one_time_plugin.c
@@ -0,0 +1,60 @@
+/* Plugin that prints message if it inserted (and invoked) more than once. */
+#include "config.h"
+#include "gcc-plugin.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "toplev.h"
+#include "gimple.h"
+#include "tree-pass.h"
+#include "intl.h"
+
+static bool one_pass_gate (void)
+{
+ return true;
+}
+
+static unsigned int one_pass_exec (void)
+{
+ static int counter = 0;
+
+ if (counter > 0) {
+ printf ("Executed more than once \n");
+ }
+ counter++;
+}
+
+struct gimple_opt_pass one_pass =
+{
+ {
+ GIMPLE_PASS,
+ "useless", /* name */
+ one_pass_gate, /* gate */
+ one_pass_exec, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ 0, /* tv_id */
+ PROP_gimple_any, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_dump_func /* todo_flags_finish */
+ }
+};
+
+
+int plugin_init (struct plugin_name_args *plugin_info,
+ struct plugin_gcc_version *version)
+{
+ struct plugin_pass p;
+
+ p.pass = &one_pass.pass;
+ p.reference_pass_name = "useless";
+ p.ref_pass_instance_number = 1;
+ p.pos_op = PASS_POS_INSERT_AFTER;
+
+ register_callback ("one_pass", PLUGIN_PASS_MANAGER_SETUP, NULL, &p);
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/plugin/plugin.exp b/gcc/testsuite/gcc.dg/plugin/plugin.exp
index 93c0c5cb848..be6d7ab1243 100644
--- a/gcc/testsuite/gcc.dg/plugin/plugin.exp
+++ b/gcc/testsuite/gcc.dg/plugin/plugin.exp
@@ -47,7 +47,10 @@ load_lib plugin-support.exp
# Specify the plugin source file and the associated test files in a list.
# plugin_test_list={ {plugin1 test1 test2 ...} {plugin2 test1 ...} ... }
set plugin_test_list [list \
- { selfassign.c self-assign-test-1.c self-assign-test-2.c } ]
+ { selfassign.c self-assign-test-1.c self-assign-test-2.c } \
+ { ggcplug.c ggcplug-test-1.c } \
+ { one_time_plugin.c one_time-test-1.c } \
+]
foreach plugin_test $plugin_test_list {
# Replace each source file with its full-path name
diff --git a/gcc/testsuite/gcc.dg/plugin/selfassign.c b/gcc/testsuite/gcc.dg/plugin/selfassign.c
index 6fbce83c01d..2bc1d861358 100644
--- a/gcc/testsuite/gcc.dg/plugin/selfassign.c
+++ b/gcc/testsuite/gcc.dg/plugin/selfassign.c
@@ -2,6 +2,7 @@
self-assignment statements. */
/* { dg-options "-O" } */
+#include "gcc-plugin.h"
#include "config.h"
#include "system.h"
#include "coretypes.h"
@@ -12,7 +13,6 @@
#include "tree.h"
#include "tree-pass.h"
#include "intl.h"
-#include "gcc-plugin.h"
/* Indicate whether to check overloaded operator '=', which is performed by
@@ -294,10 +294,13 @@ static struct gimple_opt_pass pass_warn_self_assign =
Note that this function needs to be named exactly "plugin_init". */
int
-plugin_init (const char *plugin_name, struct plugin_gcc_version *version,
- int argc, struct plugin_argument *argv)
+plugin_init (struct plugin_name_args *plugin_info,
+ struct plugin_gcc_version *version)
{
struct plugin_pass pass_info;
+ const char *plugin_name = plugin_info->base_name;
+ int argc = plugin_info->argc;
+ struct plugin_argument *argv = plugin_info->argv;
bool enabled = true;
int i;
diff --git a/gcc/testsuite/gcc.dg/pr15698-1.c b/gcc/testsuite/gcc.dg/pr15698-1.c
index 6bb001aea7f..5a75a10733f 100644
--- a/gcc/testsuite/gcc.dg/pr15698-1.c
+++ b/gcc/testsuite/gcc.dg/pr15698-1.c
@@ -17,7 +17,7 @@ int foobar ()
}
char *rindex(a, b)
- register char *a, b;
-{ /* { dg-warning "argument 'a' doesn't match built-in prototype" } */
+ register char *a, b; /* { dg-warning "argument 'a' doesn't match built-in prototype" } */
+{
return 0;
}
diff --git a/gcc/testsuite/gcc.dg/pr16302.c b/gcc/testsuite/gcc.dg/pr16302.c
new file mode 100644
index 00000000000..0daa513ffb2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr16302.c
@@ -0,0 +1,76 @@
+/* PR 16302 */
+/* { dg-do compile } */
+/* { dg-options "-Wlogical-op" } */
+void bar (int);
+int
+foo (int argc, char *argv[])
+{
+ if (argc != 1 || argc != 2) return 1; /* { dg-warning "'or' of collectively exhaustive tests is always true" } */
+ if (argc < 0 && argc > 10) return 1; /* { dg-warning "'and' of mutually exclusive tests is always false" } */
+ if (argc || !argc) return 1; /* { dg-warning "'or' of collectively exhaustive tests is always true" } */
+ if (argc && !argc) return 1; /* { dg-warning "'and' of mutually exclusive tests is always false" } */
+ bar (argc != 1 || argc != 2); /* { dg-warning "'or' of collectively exhaustive tests is always true" } */
+ bar (argc < 0 && argc > 10); /* { dg-warning "'and' of mutually exclusive tests is always false" } */
+ bar (argc || !argc); /* { dg-warning "'or' of collectively exhaustive tests is always true" } */
+ bar (argc && !argc); /* { dg-warning "'and' of mutually exclusive tests is always false" } */
+ return (argc != 1 || argc != 2) ? 1 : 0 ; /* { dg-warning "'or' of collectively exhaustive tests is always true" } */
+ return (argc < 0 && argc > 10) ? 1 : 0; /* { dg-warning "'and' of mutually exclusive tests is always false" } */
+ return (argc || !argc) ? 1 : 0; /* { dg-warning "'or' of collectively exhaustive tests is always true" } */
+ return (argc && !argc) ? 1 : 0; /* { dg-warning "'and' of mutually exclusive tests is always false" } */
+
+ if (argc == 2 && argc == 1) return 1; /* { dg-warning "'and' of mutually exclusive tests is always false" } */
+ if (argc < 0 && argc > 10) return 1; /* { dg-warning "'and' of mutually exclusive tests is always false" } */
+ if (argc || !argc) return 1; /* { dg-warning "'or' of collectively exhaustive tests is always true" } */
+ if (argc && !argc) return 1; /* { dg-warning "'and' of mutually exclusive tests is always false" } */
+ bar (argc == 2 && argc == 1); /* { dg-warning "'and' of mutually exclusive tests is always false" } */
+ bar (argc < 0 && argc > 10); /* { dg-warning "'and' of mutually exclusive tests is always false" } */
+ bar (argc || !argc); /* { dg-warning "'or' of collectively exhaustive tests is always true" } */
+ bar (argc && !argc); /* { dg-warning "'and' of mutually exclusive tests is always false" } */
+ return (argc == 2 && argc == 1) ? 1 : 0 ; /* { dg-warning "'and' of mutually exclusive tests is always false" } */
+ return (argc < 0 && argc > 10) ? 1 : 0; /* { dg-warning "'and' of mutually exclusive tests is always false" } */
+ return (argc || !argc) ? 1 : 0; /* { dg-warning "'or' of collectively exhaustive tests is always true" } */
+ return (argc && !argc) ? 1 : 0; /* { dg-warning "'and' of mutually exclusive tests is always false" } */
+
+ if (argc == 2 && argc == 1) return 1; /* { dg-warning "'and' of mutually exclusive tests is always false" } */
+ if (argc < 0 && argc > 10) return 1; /* { dg-warning "'and' of mutually exclusive tests is always false" } */
+ if (!argc || argc) return 1; /* { dg-warning "'or' of collectively exhaustive tests is always true" } */
+ if (!argc && argc) return 1; /* { dg-warning "'and' of mutually exclusive tests is always false" } */
+ bar (argc == 2 && argc == 1); /* { dg-warning "'and' of mutually exclusive tests is always false" } */
+ bar (argc < 0 && argc > 10); /* { dg-warning "'and' of mutually exclusive tests is always false" } */
+ bar (!argc || argc); /* { dg-warning "'or' of collectively exhaustive tests is always true" } */
+ bar (!argc && argc); /* { dg-warning "'and' of mutually exclusive tests is always false" } */
+ return (argc == 2 && argc == 1) ? 1 : 0 ; /* { dg-warning "'and' of mutually exclusive tests is always false" } */
+ return (argc < 0 && argc > 10) ? 1 : 0; /* { dg-warning "'and' of mutually exclusive tests is always false" } */
+ return (!argc || argc) ? 1 : 0; /* { dg-warning "'or' of collectively exhaustive tests is always true" } */
+ return (!argc && argc) ? 1 : 0; /* { dg-warning "'and' of mutually exclusive tests is always false" } */
+
+ return 0;
+}
+
+int
+foo2 (int argc)
+{
+ if (5 != 1 || 5 != 2) return 1;
+ if (5 < 0 && 5 > 10) return 1;
+ if (1 || 0) return 1;
+ if (0 && 1) return 1;
+ if (2 || !2) return 1;
+ if (2 && !2) return 1;
+ if (!(!2) || !(2)) return 1;
+ if (!(!2) && !(2)) return 1;
+ bar (5 != 1 || 5 != 2);
+ bar (5 < 0 && 5 > 10);
+ bar (1 || 0);
+ bar (0 && 1);
+ bar (2 || !2);
+ bar (2 && !2);
+ return (5 != 1 || 5 != 2) ? 1 : 0 ;
+ return (5 < 0 && 5 > 10) ? 1 : 0;
+ return (1 || 0) ? 1 : 0 ;
+ return (0 && 1) ? 1 : 0;
+ return (2 || !2) ? 1 : 0;
+ return (2 && !2) ? 1 : 0;
+
+ return 0;
+}
+
diff --git a/gcc/testsuite/gcc.dg/pr20368-1.c b/gcc/testsuite/gcc.dg/pr20368-1.c
index ac76c16f783..4140397c142 100644
--- a/gcc/testsuite/gcc.dg/pr20368-1.c
+++ b/gcc/testsuite/gcc.dg/pr20368-1.c
@@ -6,7 +6,7 @@
extern __typeof (f) g; /* { dg-error "'f' undeclared here \\(not in a function\\)" } */
int
-f (x)
- float x; /* { dg-warning "function declaration isn't a prototype" } */
+f (x) /* { dg-warning "function declaration isn't a prototype" } */
+ float x;
{
}
diff --git a/gcc/testsuite/gcc.dg/pr33667.c b/gcc/testsuite/gcc.dg/pr33667.c
index d3c039b51df..676c4a46dac 100644
--- a/gcc/testsuite/gcc.dg/pr33667.c
+++ b/gcc/testsuite/gcc.dg/pr33667.c
@@ -1,7 +1,7 @@
/* { dg-do compile } */
/* { dg-options "-O2" } */
-typedef unsigned int size_t;
+__extension__ typedef __SIZE_TYPE__ size_t;
typedef unsigned char uint8_t;
typedef unsigned short int uint16_t;
typedef unsigned long long int uint64_t;
diff --git a/gcc/testsuite/gcc.dg/pr40172-1.c b/gcc/testsuite/gcc.dg/pr40172-1.c
new file mode 100644
index 00000000000..a834a8a998e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr40172-1.c
@@ -0,0 +1,31 @@
+/* PR middle-end/40172 */
+/* { dg-do compile } */
+/* { dg-options "-Wall -W -Werror -Wlogical-op" } */
+
+struct rtx_def;
+typedef struct rtx_def *rtx;
+
+extern int foo;
+extern int bar;
+extern int xxx;
+
+int
+test (void)
+{
+ if (((rtx) 0 != (rtx) 0) && xxx ? foo : bar)
+ return 1;
+ else if ((foo & 0) && xxx)
+ return 2;
+ else if (foo & 0)
+ return 3;
+ else if (0 && xxx)
+ return 4;
+ else if (0)
+ return 5;
+ if (((int) 0 != (int) 0) && bar ? foo : xxx)
+ return 6;
+ else if (0 != 0 && foo ? xxx : bar)
+ return 7;
+ else
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/pr40172-2.c b/gcc/testsuite/gcc.dg/pr40172-2.c
new file mode 100644
index 00000000000..17aabb8b5f3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr40172-2.c
@@ -0,0 +1,16 @@
+/* PR middle-end/40172 */
+/* { dg-do compile } */
+/* { dg-options "-Wall -W -Werror" } */
+
+extern int xxx;
+
+#define XXX xxx
+
+int
+test (void)
+{
+ if (!XXX && xxx)
+ return 4;
+ else
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/pr40172-3.c b/gcc/testsuite/gcc.dg/pr40172-3.c
new file mode 100644
index 00000000000..ea74fce37c6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr40172-3.c
@@ -0,0 +1,17 @@
+/* PR middle-end/40172 */
+/* { dg-do compile */
+/* { dg-xfail-if "" { "*-*-*" } { "*" } { "" } } */
+/* { dg-options "-Wall -W -Werror -Wlogical-op" } */
+
+extern int xxx;
+
+#define XXX xxx
+
+int
+test (void)
+{
+ if (!XXX && xxx)
+ return 4;
+ else
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/pr40340-1.c b/gcc/testsuite/gcc.dg/pr40340-1.c
new file mode 100644
index 00000000000..aae84c63781
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr40340-1.c
@@ -0,0 +1,24 @@
+/* PR middle-end/40340 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wall -Wno-system-headers" } */
+
+#include "pr40340.h"
+
+static inline
+__attribute__ ((always_inline))
+void
+test (char *p)
+{
+ memset (p, 0, 6);
+}
+
+int
+main (void)
+{
+ char buf[4];
+ test (buf);
+ return 0;
+}
+
+/* { dg-warning "will always overflow destination buffer" "" { target *-*-* } 10 } */
+/* { dg-message "file included" "In file included" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/gcc.dg/pr40340-2.c b/gcc/testsuite/gcc.dg/pr40340-2.c
new file mode 100644
index 00000000000..a0d6e084e73
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr40340-2.c
@@ -0,0 +1,16 @@
+/* PR middle-end/40340 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wall -Wno-system-headers" } */
+
+#include "pr40340.h"
+
+int
+main (void)
+{
+ char buf[4];
+ memset (buf, 0, 6);
+ return 0;
+}
+
+/* { dg-warning "will always overflow destination buffer" "" { target *-*-* } 10 } */
+/* { dg-message "file included" "In file included" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/gcc.dg/pr40340-3.c b/gcc/testsuite/gcc.dg/pr40340-3.c
new file mode 100644
index 00000000000..5ef09e073d8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr40340-3.c
@@ -0,0 +1,15 @@
+/* PR middle-end/40340 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wall -Wno-system-headers" } */
+
+#define TEST2
+#include "pr40340.h"
+
+int
+main (void)
+{
+ test2 ();
+ return 0;
+}
+
+/* { dg-bogus "will always overflow destination buffer" "" { target *-*-* } 10 } */
diff --git a/gcc/testsuite/gcc.dg/pr40340-4.c b/gcc/testsuite/gcc.dg/pr40340-4.c
new file mode 100644
index 00000000000..d3f020cada8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr40340-4.c
@@ -0,0 +1,16 @@
+/* PR middle-end/40340 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wall -Wno-system-headers -g" } */
+
+#define TEST3
+#include "pr40340.h"
+
+int
+main (void)
+{
+ char buf[4];
+ test3 (buf);
+ return 0;
+}
+
+/* { dg-bogus "will always overflow destination buffer" "" { target *-*-* } 10 } */
diff --git a/gcc/testsuite/gcc.dg/pr40340-5.c b/gcc/testsuite/gcc.dg/pr40340-5.c
new file mode 100644
index 00000000000..f50514c3ac9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr40340-5.c
@@ -0,0 +1,17 @@
+/* PR middle-end/40340 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wall -Wsystem-headers -g" } */
+
+#define TEST3
+#include "pr40340.h"
+
+int
+main (void)
+{
+ char buf[4];
+ test3 (buf);
+ return 0;
+}
+
+/* { dg-warning "will always overflow destination buffer" "" { target *-*-* } 10 } */
+/* { dg-message "file included" "In file included" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/gcc.dg/pr40340.h b/gcc/testsuite/gcc.dg/pr40340.h
new file mode 100644
index 00000000000..174e076b943
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr40340.h
@@ -0,0 +1,31 @@
+#pragma GCC system_header
+typedef __SIZE_TYPE__ size_t;
+extern void *memset (void *s, int c, size_t n)
+ __attribute__ ((nothrow, nonnull (1)));
+extern inline
+__attribute__ ((always_inline, artificial, gnu_inline, nothrow))
+void *
+memset (void *dest, int ch, size_t len)
+{
+ return __builtin___memset_chk (dest, ch, len,
+ __builtin_object_size (dest, 0));
+}
+
+#ifdef TEST2
+static void
+__attribute__ ((noinline))
+test2 (void)
+{
+ char buf[4];
+ memset (buf, 0, 6);
+}
+#endif
+
+#ifdef TEST3
+static inline void
+__attribute__ ((always_inline))
+test3 (char *p)
+{
+ memset (p, 0, 6);
+}
+#endif
diff --git a/gcc/testsuite/gcc.dg/prefetch-loop-arrays-1.c b/gcc/testsuite/gcc.dg/prefetch-loop-arrays-1.c
index ba91d69650d..59cebc52e96 100644
--- a/gcc/testsuite/gcc.dg/prefetch-loop-arrays-1.c
+++ b/gcc/testsuite/gcc.dg/prefetch-loop-arrays-1.c
@@ -3,7 +3,7 @@
/* { dg-options "-O2 -fprefetch-loop-arrays -w" } */
/* { dg-options "-O2 -fprefetch-loop-arrays -march=i686 -msse -w" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
-typedef unsigned long size_t;
+__extension__ typedef __SIZE_TYPE__ size_t;
struct re_pattern_buffer
{
diff --git a/gcc/testsuite/gcc.dg/sibcall-1.c b/gcc/testsuite/gcc.dg/sibcall-1.c
index 4521ace9e15..e8a95513d9e 100644
--- a/gcc/testsuite/gcc.dg/sibcall-1.c
+++ b/gcc/testsuite/gcc.dg/sibcall-1.c
@@ -37,7 +37,7 @@ recurser_void (int n)
void *trackpoint;
-void
+void __attribute__ ((noinline))
track (int n)
{
char stackpos[1];
diff --git a/gcc/testsuite/gcc.dg/sibcall-2.c b/gcc/testsuite/gcc.dg/sibcall-2.c
index 4c226c496e3..a626273e620 100644
--- a/gcc/testsuite/gcc.dg/sibcall-2.c
+++ b/gcc/testsuite/gcc.dg/sibcall-2.c
@@ -38,7 +38,7 @@ recurser_void (void)
void *trackpoint;
-void
+void __attribute__ ((noinline))
track ()
{
char stackpos[1];
diff --git a/gcc/testsuite/gcc.dg/sibcall-3.c b/gcc/testsuite/gcc.dg/sibcall-3.c
index e085bfbc7a3..e8798cc599f 100644
--- a/gcc/testsuite/gcc.dg/sibcall-3.c
+++ b/gcc/testsuite/gcc.dg/sibcall-3.c
@@ -66,7 +66,7 @@ recurser_void2 (int n)
void *trackpoint;
-void
+void __attribute__ ((noinline))
track (int n)
{
char stackpos[1];
diff --git a/gcc/testsuite/gcc.dg/sibcall-4.c b/gcc/testsuite/gcc.dg/sibcall-4.c
index 11b09d0791b..223c03c1218 100644
--- a/gcc/testsuite/gcc.dg/sibcall-4.c
+++ b/gcc/testsuite/gcc.dg/sibcall-4.c
@@ -67,7 +67,7 @@ recurser_void2 (void)
void *trackpoint;
-void
+void __attribute__ ((noinline))
track ()
{
char stackpos[1];
diff --git a/gcc/testsuite/gcc.dg/sibcall-6.c b/gcc/testsuite/gcc.dg/sibcall-6.c
index 6f2f2188151..3dba764bbfb 100644
--- a/gcc/testsuite/gcc.dg/sibcall-6.c
+++ b/gcc/testsuite/gcc.dg/sibcall-6.c
@@ -8,7 +8,7 @@
/* { dg-do run { target i?86-*-* x86_64-*-* s390*-*-* } } */
/* { dg-skip-if "" { { i?86-*-* x86_64-*-* } && { ilp32 && { ! nonpic } } } { "*" } { "" } } */
-/* { dg-options "-O2 -foptimize-sibling-calls" } */
+/* { dg-options "-O2 -foptimize-sibling-calls -fno-ipa-cp" } */
extern void abort (void);
extern void exit (int);
@@ -27,7 +27,7 @@ main ()
exit (0);
}
-int
+int __attribute__ ((noinline))
bar (b)
int b;
{
@@ -37,7 +37,7 @@ bar (b)
abort ();
}
-int
+int __attribute__ ((noinline))
foo (f)
int f;
{
diff --git a/gcc/testsuite/gcc.dg/simd-1b.c b/gcc/testsuite/gcc.dg/simd-1b.c
index 56d94b91c68..1e2b597b565 100644
--- a/gcc/testsuite/gcc.dg/simd-1b.c
+++ b/gcc/testsuite/gcc.dg/simd-1b.c
@@ -14,7 +14,7 @@ void
hanneke ()
{
/* Operators on compatible SIMD types. */
- a %= b; /* { dg-error "invalid operands to binary %" } */
+ a %= b;
c &= d;
a |= b;
c ^= d;
diff --git a/gcc/testsuite/gcc.dg/stmt-expr-label-1.c b/gcc/testsuite/gcc.dg/stmt-expr-label-1.c
index 57ab34eaab2..a9dd46623f3 100644
--- a/gcc/testsuite/gcc.dg/stmt-expr-label-1.c
+++ b/gcc/testsuite/gcc.dg/stmt-expr-label-1.c
@@ -402,3 +402,6 @@ void f194 (void) { ({ ({0;}); ({0;}); 0;}); ({ ({0;}); ({0;}); 0;}); a:0; goto a
void fa194 (void) { P0A:goto P0A;({ P01A:goto P01A;({P012A:goto P012A;0;}); P01B:goto P01B;({P013A:goto P013A;0;}); P01C:goto P01C;0;}); P0B:goto P0B;({ P02A:goto P02A;({P024A:goto P024A;0;}); P02B:goto P02B;({P025A:goto P025A;0;}); P02C:goto P02C;0;}); a:0;p0D:goto p0D; goto a; P0D:goto P0D; }
void f195 (void) { ({ ({0;}); ({0;}); 0;}); ({ ({0;}); ({0;}); 0;}); 0;a: goto a; }
void fa195 (void) { P0A:goto P0A;({ P01A:goto P01A;({P012A:goto P012A;0;}); P01B:goto P01B;({P013A:goto P013A;0;}); P01C:goto P01C;0;}); P0B:goto P0B;({ P02A:goto P02A;({P024A:goto P024A;0;}); P02B:goto P02B;({P025A:goto P025A;0;}); P02C:goto P02C;0;}); P0C:goto P0C;0;a: goto a; P0D:goto P0D; }
+
+/* Match extra informative notes. */
+/* { dg-message "note: label '\[^\n'\]*' defined here" "note: expected" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/gcc.dg/stmt-expr-label-2.c b/gcc/testsuite/gcc.dg/stmt-expr-label-2.c
index 35b96e830e5..be7aa521000 100644
--- a/gcc/testsuite/gcc.dg/stmt-expr-label-2.c
+++ b/gcc/testsuite/gcc.dg/stmt-expr-label-2.c
@@ -8,13 +8,13 @@
void
f (int a)
{
- switch (a)
+ switch (a) /* { dg-message "here" } */
{
case 0:
case 1:
({
- case 2: /* { dg-error "case label in statement expression not containing enclosing switch statement" } */
- default: /* { dg-error "'default' label in statement expression not containing enclosing switch statement" } */
+ case 2: /* { dg-error "switch jumps into statement expression" } */
+ default: /* { dg-error "switch jumps into statement expression" } */
switch (a)
{
case 3:
diff --git a/gcc/testsuite/gcc.dg/stmt-expr-label-3.c b/gcc/testsuite/gcc.dg/stmt-expr-label-3.c
index 7b1515f89ac..0a6722283f4 100644
--- a/gcc/testsuite/gcc.dg/stmt-expr-label-3.c
+++ b/gcc/testsuite/gcc.dg/stmt-expr-label-3.c
@@ -6,3 +6,6 @@
/* { dg-options "-O2" } */
void f(void) { 1 ? 1 : ({ a : 1; 1; }); goto a; } /* { dg-error "jump into statement expression" } */
+
+/* Match extra informative notes. */
+/* { dg-message "note: label '\[^\n'\]*' defined here" "note: expected" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/gcc.dg/struct/wo_prof_escape_substr_pointer.c b/gcc/testsuite/gcc.dg/struct/wo_prof_escape_substr_pointer.c
index 8e54632454e..4cb94afc5df 100644
--- a/gcc/testsuite/gcc.dg/struct/wo_prof_escape_substr_pointer.c
+++ b/gcc/testsuite/gcc.dg/struct/wo_prof_escape_substr_pointer.c
@@ -24,6 +24,8 @@ typedef struct
int c;
}str_with_substr_t;
+int foo;
+
int
main (void)
{
@@ -37,6 +39,8 @@ main (void)
for (i=0; i < N; i++)
A[i].sub_str->a = 5;
+ foo = A[56].sub_str->a;
+
return 0;
}
diff --git a/gcc/testsuite/gcc.dg/torture/builtin-math-5.c b/gcc/testsuite/gcc.dg/torture/builtin-math-5.c
new file mode 100644
index 00000000000..d266e50aff0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/builtin-math-5.c
@@ -0,0 +1,46 @@
+/* Copyright (C) 2009 Free Software Foundation.
+
+ Test things that should block GCC from optimizing compile-time
+ constants passed to a builtin complex transcendental functions.
+
+ Origin: Kaveh R. Ghazi, January 28, 2009. */
+
+/* { dg-do compile } */
+/* { dg-options "-fdump-tree-original" } */
+
+extern void foof (_Complex float);
+extern void foo (_Complex double);
+extern void fool (_Complex long double);
+
+#define TESTIT(FUNC, ARG) do { \
+ foof (__builtin_##FUNC##f (ARG##F)); \
+ foo (__builtin_##FUNC (ARG)); \
+ fool (__builtin_##FUNC##l (ARG##L)); \
+} while (0)
+
+void bar()
+{
+ /* An argument of NaN is not evaluated at compile-time. */
+#ifndef __SPU__
+ foof (__builtin_csqrtf (__builtin_nanf("")));
+#endif
+ foo (__builtin_csqrt (__builtin_nan("")));
+ fool (__builtin_csqrtl (__builtin_nanl("")));
+
+ /* An argument of Inf/-Inf is not evaluated at compile-time. */
+#ifndef __SPU__
+ foof (__builtin_csqrtf (__builtin_inff()));
+#endif
+ foo (__builtin_csqrt (__builtin_inf()));
+ fool (__builtin_csqrtl (__builtin_infl()));
+#ifndef __SPU__
+ foof (__builtin_csqrtf (-__builtin_inff()));
+#endif
+ foo (__builtin_csqrt (-__builtin_inf()));
+ fool (__builtin_csqrtl (-__builtin_infl()));
+}
+
+/* { dg-final { scan-tree-dump-times "csqrtf" 3 "original" } } */
+/* { dg-final { scan-tree-dump-times "csqrt " 3 "original" } } */
+/* { dg-final { scan-tree-dump-times "csqrtl" 3 "original" } } */
+/* { dg-final { cleanup-tree-dump "original" } } */
diff --git a/gcc/testsuite/gcc.dg/torture/builtin-math-6.c b/gcc/testsuite/gcc.dg/torture/builtin-math-6.c
new file mode 100644
index 00000000000..7fd1f729e2c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/builtin-math-6.c
@@ -0,0 +1,167 @@
+/* Copyright (C) 2009 Free Software Foundation.
+
+ Verify that folding of built-in complex math functions with
+ constant arguments is correctly performed by the compiler.
+
+ Origin: Kaveh R. Ghazi, January 28, 2009. */
+
+/* { dg-do link } */
+/* { dg-require-effective-target mpc } */
+
+/* All references to link_error should go away at compile-time. */
+extern void link_error(int);
+
+/* Return TRUE if the signs of floating point values X and Y are not
+ equal. This is important when comparing signed zeros. */
+#define CKSGN_F(X,Y) \
+ (__builtin_copysignf(1,(X)) != __builtin_copysignf(1,(Y)))
+#define CKSGN(X,Y) \
+ (__builtin_copysign(1,(X)) != __builtin_copysign(1,(Y)))
+#define CKSGN_L(X,Y) \
+ (__builtin_copysignl(1,(X)) != __builtin_copysignl(1,(Y)))
+
+/* Return TRUE if signs of the real parts, and the signs of the
+ imaginary parts, of X and Y are not equal. */
+#define COMPLEX_CKSGN_F(X,Y) \
+ (CKSGN_F(__real__ (X), __real__ (Y)) || CKSGN_F (__imag__ (X), __imag__ (Y)))
+#define COMPLEX_CKSGN(X,Y) \
+ (CKSGN(__real__ (X), __real__ (Y)) || CKSGN (__imag__ (X), __imag__ (Y)))
+#define COMPLEX_CKSGN_L(X,Y) \
+ (CKSGN_L(__real__ (X), __real__ (Y)) || CKSGN_L (__imag__ (X), __imag__ (Y)))
+
+/* For complex numbers, test that FUNC(ARG) == (RES). */
+#define TESTIT_COMPLEX(FUNC, ARG, RES) do { \
+ if (__builtin_##FUNC##f(ARG) != (RES) \
+ || COMPLEX_CKSGN_F(__builtin_##FUNC##f(ARG), (RES))) \
+ link_error(__LINE__); \
+ if (__builtin_##FUNC(ARG) != (RES) \
+ || COMPLEX_CKSGN(__builtin_##FUNC(ARG), (RES))) \
+ link_error(__LINE__); \
+ if (__builtin_##FUNC##l(ARG) != (RES) \
+ || COMPLEX_CKSGN_L(__builtin_##FUNC##l(ARG), (RES))) \
+ link_error(__LINE__); \
+ } while (0)
+
+/* Return TRUE if X differs from EXPECTED by more than 1%. If
+ EXPECTED is zero, then any difference may return TRUE. We don't
+ worry about signed zeros. */
+#define DIFF1PCT_F(X,EXPECTED) \
+ (__builtin_fabsf((X)-(EXPECTED)) * 100 > __builtin_fabsf(EXPECTED))
+#define DIFF1PCT(X,EXPECTED) \
+ (__builtin_fabs((X)-(EXPECTED)) * 100 > __builtin_fabs(EXPECTED))
+#define DIFF1PCT_L(X,EXPECTED) \
+ (__builtin_fabsl((X)-(EXPECTED)) * 100 > __builtin_fabsl(EXPECTED))
+
+/* Return TRUE if complex value X differs from EXPECTED by more than
+ 1% in either the real or imaginary parts. */
+#define COMPLEX_DIFF1PCT_F(X,EXPECTED) \
+ (DIFF1PCT_F(__real__ (X), __real__ (EXPECTED)) \
+ || DIFF1PCT_F(__imag__ (X), __imag__ (EXPECTED)))
+#define COMPLEX_DIFF1PCT(X,EXPECTED) \
+ (DIFF1PCT(__real__ (X), __real__ (EXPECTED)) \
+ || DIFF1PCT(__imag__ (X), __imag__ (EXPECTED)))
+#define COMPLEX_DIFF1PCT_L(X,EXPECTED) \
+ (DIFF1PCT_L(__real__ (X), __real__ (EXPECTED)) \
+ || DIFF1PCT_L(__imag__ (X), __imag__ (EXPECTED)))
+
+/* Range test, for complex numbers check that FUNC(ARG) is within 1%
+ of RES. This is NOT a test for accuracy to the last-bit, we're
+ merely checking that we get relatively sane results. I.e. the GCC
+ builtin is hooked up to the correct MPC function call. We first
+ check the magnitude and then the sign. */
+#define TESTIT_COMPLEX_R(FUNC, ARG, RES) do { \
+ if (COMPLEX_DIFF1PCT_F (__builtin_##FUNC##f(ARG), (RES)) \
+ || COMPLEX_CKSGN_F(__builtin_##FUNC##f(ARG), (RES))) \
+ link_error(__LINE__); \
+ if (COMPLEX_DIFF1PCT (__builtin_##FUNC(ARG), (RES)) \
+ || COMPLEX_CKSGN(__builtin_##FUNC(ARG), (RES))) \
+ link_error(__LINE__); \
+ if (COMPLEX_DIFF1PCT (__builtin_##FUNC(ARG), (RES)) \
+ || COMPLEX_CKSGN(__builtin_##FUNC(ARG), (RES))) \
+ link_error(__LINE__); \
+ } while (0)
+
+int main (void)
+{
+ TESTIT_COMPLEX (csin, 0.0F, 0.0F);
+ TESTIT_COMPLEX (csin, -0.0F, -0.0F);
+ TESTIT_COMPLEX (csin, __builtin_conjf(0.0F), __builtin_conjf(0.0F));
+ TESTIT_COMPLEX (csin, __builtin_conjf(-0.0F), __builtin_conjf(-0.0F));
+
+ TESTIT_COMPLEX_R (csin, 3.45678F + 2.34567FI, -1.633059F - 4.917448FI);
+ TESTIT_COMPLEX_R (csin, 3.45678F - 2.34567FI, -1.633059F + 4.917448FI);
+ TESTIT_COMPLEX_R (csin, -3.45678F + 2.34567FI, 1.633059F - 4.917448FI);
+ TESTIT_COMPLEX_R (csin, -3.45678F - 2.34567FI, 1.633059F + 4.917448FI);
+
+ TESTIT_COMPLEX (ccos, 0.0F, __builtin_conjf(1.0F));
+ TESTIT_COMPLEX (ccos, -0.0F, 1.0F);
+ TESTIT_COMPLEX (ccos, __builtin_conjf(0.0F), 1.0F);
+ TESTIT_COMPLEX (ccos, __builtin_conjf(-0.0F), __builtin_conjf(1.0F));
+
+ TESTIT_COMPLEX_R (ccos, 3.45678F + 2.34567FI, -5.008512F + 1.603367FI);
+ TESTIT_COMPLEX_R (ccos, 3.45678F - 2.34567FI, -5.008512F - 1.603367FI);
+ TESTIT_COMPLEX_R (ccos, -3.45678F + 2.34567FI, -5.008512F - 1.603367FI);
+ TESTIT_COMPLEX_R (ccos, -3.45678F - 2.34567FI, -5.008512F + 1.603367FI);
+
+ TESTIT_COMPLEX (ctan, 0.0F, 0.0F);
+ TESTIT_COMPLEX (ctan, -0.0F, -0.0F);
+ TESTIT_COMPLEX (ctan, __builtin_conjf(0.0F), __builtin_conjf(0.0F));
+ TESTIT_COMPLEX (ctan, __builtin_conjf(-0.0F), __builtin_conjf(-0.0F));
+
+ TESTIT_COMPLEX_R (ctan, 3.45678F + 2.34567FI, 0.010657F + 0.985230FI);
+ TESTIT_COMPLEX_R (ctan, 3.45678F - 2.34567FI, 0.010657F - 0.985230FI);
+ TESTIT_COMPLEX_R (ctan, -3.45678F + 2.34567FI, -0.010657F + 0.985230FI);
+ TESTIT_COMPLEX_R (ctan, -3.45678F - 2.34567FI, -0.010657F - 0.985230FI);
+
+ TESTIT_COMPLEX (csinh, 0.0F, 0.0F);
+ TESTIT_COMPLEX (csinh, -0.0F, -0.0F);
+ TESTIT_COMPLEX (csinh, __builtin_conjf(0.0F), __builtin_conjf(0.0F));
+ TESTIT_COMPLEX (csinh, __builtin_conjf(-0.0F), __builtin_conjf(-0.0F));
+
+ TESTIT_COMPLEX_R (csinh, 3.45678F + 2.34567FI, -11.083178F + 11.341487FI);
+ TESTIT_COMPLEX_R (csinh, 3.45678F - 2.34567FI, -11.083178F - 11.341487FI);
+ TESTIT_COMPLEX_R (csinh, -3.45678F + 2.34567FI, 11.083178F + 11.341487FI);
+ TESTIT_COMPLEX_R (csinh, -3.45678F - 2.34567FI, 11.083178F - 11.341487FI);
+
+ TESTIT_COMPLEX (ccosh, 0.0F, 1.0F);
+ TESTIT_COMPLEX (ccosh, -0.0F, __builtin_conjf(1.0F));
+ TESTIT_COMPLEX (ccosh, __builtin_conjf(0.0F), __builtin_conjf(1.0F));
+ TESTIT_COMPLEX (ccosh, __builtin_conjf(-0.0F), 1.0F);
+
+ TESTIT_COMPLEX_R (ccosh, 3.45678F + 2.34567FI, -11.105238F + 11.318958FI);
+ TESTIT_COMPLEX_R (ccosh, 3.45678F - 2.34567FI, -11.105238F - 11.318958FI);
+ TESTIT_COMPLEX_R (ccosh, -3.45678F + 2.34567FI, -11.105238F - 11.318958FI);
+ TESTIT_COMPLEX_R (ccosh, -3.45678F - 2.34567FI, -11.105238F + 11.318958FI);
+
+ TESTIT_COMPLEX (ctanh, 0.0F, 0.0F);
+ TESTIT_COMPLEX (ctanh, -0.0F, -0.0F);
+ TESTIT_COMPLEX (ctanh, __builtin_conjf(0.0F), __builtin_conjf(0.0F));
+ TESTIT_COMPLEX (ctanh, __builtin_conjf(-0.0F), __builtin_conjf(-0.0F));
+
+ TESTIT_COMPLEX_R (ctanh, 3.45678F + 2.34567FI, 1.000040F - 0.001988FI);
+ TESTIT_COMPLEX_R (ctanh, 3.45678F - 2.34567FI, 1.000040F + 0.001988FI);
+ TESTIT_COMPLEX_R (ctanh, -3.45678F + 2.34567FI, -1.000040F - 0.001988FI);
+ TESTIT_COMPLEX_R (ctanh, -3.45678F - 2.34567FI, -1.000040F + 0.001988FI);
+
+ TESTIT_COMPLEX (clog, 1.0F, 0.0F);
+ TESTIT_COMPLEX_R (clog, -1.0F, 3.141593FI);
+ TESTIT_COMPLEX (clog, __builtin_conjf(1.0F), __builtin_conjf(0.0F)); /* Fails with mpc-0.6. */
+ TESTIT_COMPLEX_R (clog, __builtin_conjf(-1.0F), __builtin_conjf(3.141593FI)); /* Fails with mpc-0.6. */
+
+ TESTIT_COMPLEX_R (clog, 3.45678F + 2.34567FI, 1.429713F + 0.596199FI);
+ TESTIT_COMPLEX_R (clog, 3.45678F - 2.34567FI, 1.429713F - 0.596199FI);
+ TESTIT_COMPLEX_R (clog, -3.45678F + 2.34567FI, 1.429713F + 2.545394FI);
+ TESTIT_COMPLEX_R (clog, -3.45678F - 2.34567FI, 1.429713F - 2.545394FI);
+
+ TESTIT_COMPLEX (csqrt, 0.0F, 0.0F);
+ TESTIT_COMPLEX (csqrt, -0.0F, 0.0F);
+ TESTIT_COMPLEX (csqrt, __builtin_conjf(0.0F), __builtin_conjf(0.0F));
+ TESTIT_COMPLEX (csqrt, __builtin_conjf(-0.0F), __builtin_conjf(0.0F));
+
+ TESTIT_COMPLEX_R (csqrt, 3.45678F + 2.34567FI, 1.953750F + 0.600299FI);
+ TESTIT_COMPLEX_R (csqrt, 3.45678F - 2.34567FI, 1.953750F - 0.600299FI);
+ TESTIT_COMPLEX_R (csqrt, -3.45678F + 2.34567FI, 0.600299F + 1.953750FI);
+ TESTIT_COMPLEX_R (csqrt, -3.45678F - 2.34567FI, 0.600299F - 1.953750FI);
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr39204.c b/gcc/testsuite/gcc.dg/torture/pr39204.c
index 4604b7079d1..1389a52ec58 100644
--- a/gcc/testsuite/gcc.dg/torture/pr39204.c
+++ b/gcc/testsuite/gcc.dg/torture/pr39204.c
@@ -1,7 +1,7 @@
/* { dg-do compile } */
/* { dg-options "-w" } */
-typedef unsigned int size_t;
+__extension__ typedef __SIZE_TYPE__ size_t;
typedef unsigned char __u_char;
typedef unsigned short int __u_short;
typedef unsigned int __u_int;
diff --git a/gcc/testsuite/gcc.dg/torture/pr40328.c b/gcc/testsuite/gcc.dg/torture/pr40328.c
new file mode 100644
index 00000000000..e378e63c00a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr40328.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-fno-tree-sra" } */
+
+_Complex float foo(void)
+{
+ _Complex float a[64] = {};
+ _Complex float x;
+ x = a[1];
+ return x;
+}
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20041122-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20041122-1.c
index d5cabb0bd37..d72d133e154 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/20041122-1.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20041122-1.c
@@ -2,7 +2,7 @@
/* { dg-options "-O1 -fdump-tree-dom2" } */
-typedef unsigned int size_t;
+__extension__ typedef __SIZE_TYPE__ size_t;
extern void *xmalloc (size_t) __attribute__ ((__malloc__));
struct edge_def
{
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/col-1.c b/gcc/testsuite/gcc.dg/tree-ssa/col-1.c
new file mode 100644
index 00000000000..5838134ad21
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/col-1.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-tree-gimple-details-lineno" } */
+
+void foo (int, int);
+
+int
+m(int x)
+{
+ int c, a;
+ a = (c = 5) + 16 + x * 2 ;
+ foo (c, a);
+}
+
+/* { dg-final { scan-tree-dump-times "10:9.*c = 5" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "10:14.*c . 16" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "10:4.*a =" 1 "gimple" } } */
+/* { dg-final { cleanup-tree-dump "gimple" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/flatten-2.c b/gcc/testsuite/gcc.dg/tree-ssa/flatten-2.c
index 52a865dbd7c..ffed23cf454 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/flatten-2.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/flatten-2.c
@@ -1,11 +1,16 @@
/* { dg-do compile } */
-/* { dg-options -O2 } */
+/* { dg-options "-O2 -fno-early-inlining" } */
extern void do_something_usefull();
/* Check that we finish compiling even if instructed to
flatten a cyclic callgraph. Verify we correctly
flatten with another function marked flatten in the
- callgraph. */
+ callgraph.
+
+ Main inline is cureful about indirect calls giving
+ precedence to breaking cycle at indirect call sites.
+ Early inliner can't do similar analysis, so we need
+ to disable it if we want cycles to be broken consistently. */
void __attribute__((flatten)) direct(void)
{
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/flatten-3.c b/gcc/testsuite/gcc.dg/tree-ssa/flatten-3.c
new file mode 100644
index 00000000000..a1edb910e9d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/flatten-3.c
@@ -0,0 +1,79 @@
+/* { dg-do compile } */
+/* { dg-options -O2 } */
+
+extern void do_something_usefull();
+/* Check that we finish compiling even if instructed to
+ flatten a cyclic callgraph. Verify we correctly
+ flatten with another function marked flatten in the
+ callgraph. */
+
+void __attribute__((flatten)) direct(void)
+{
+ direct();
+}
+
+
+void __attribute__((flatten)) indirect(void);
+static void indirect1(void)
+{
+ indirect();
+}
+void __attribute__((flatten)) indirect(void)
+{
+ indirect1();
+}
+
+
+void __attribute__((flatten)) doubleindirect(void);
+static void doubleindirect2(void)
+{
+ doubleindirect();
+ do_something_usefull ();
+}
+static void doubleindirect1(void)
+{
+ doubleindirect2();
+}
+void __attribute__((flatten)) doubleindirect(void)
+{
+ doubleindirect1();
+}
+
+
+static void subcycle1(void);
+static void subcycle2(void)
+{
+ subcycle1();
+ do_something_usefull ();
+}
+static void subcycle1(void)
+{
+ subcycle2();
+}
+void __attribute__((flatten)) subcycle(void)
+{
+ subcycle1();
+}
+
+
+static void doublesubcycle1(void);
+static void doublesubcycle2(void);
+static void doublesubcycle3(void)
+{
+ doublesubcycle1();
+ do_something_usefull ();
+}
+static void doublesubcycle2(void)
+{
+ doublesubcycle3();
+}
+static void doublesubcycle1(void)
+{
+ doublesubcycle2();
+}
+void __attribute__((flatten)) doublesubcycle(void)
+{
+ doublesubcycle1();
+}
+
+/* { dg-final { scan-assembler "cycle\[123\]\[: \t\n\]" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/fre-vce-1.c b/gcc/testsuite/gcc.dg/tree-ssa/fre-vce-1.c
new file mode 100644
index 00000000000..f8c12c8d6c5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/fre-vce-1.c
@@ -0,0 +1,35 @@
+/* { dg-options "-O2 -fdump-tree-fre -w" } */
+/* { dg-do compile } */
+#define vector __attribute__((vector_size(sizeof(int)*4) ))
+struct s { vector int i; };
+vector float f(struct s *sv)
+{
+ sv->i = (vector int){1, 2, 3, 4};
+ return (vector float)sv->i;
+}
+
+
+vector float f1(struct s *sv, vector int a)
+{
+ sv->i = a;
+ return (vector float)sv->i;
+}
+
+struct s1 { int i; };
+
+void g(struct s1 *, float);
+void a1 (struct s1 sv)
+{
+ sv.i = 1;
+ g(&sv, *(float*)&sv.i);
+}
+
+
+void a2 (struct s1 sv, int i)
+{
+ sv.i = i;
+ g(&sv, *(float*)&sv.i);
+}
+
+/* { dg-final { scan-tree-dump-times "sv_\[0-9\]\\\(D\\\)->i" 2 "fre" } } */
+/* { dg-final { scan-tree-dump-times "sv.i" 2 "fre" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/inline-3.c b/gcc/testsuite/gcc.dg/tree-ssa/inline-3.c
new file mode 100644
index 00000000000..f7ebb33d2a5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/inline-3.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-einline2" } */
+extern void inlined ();
+void inline_me_too (void);
+void inline_through_me (void (*ptr)(void));
+void
+inline_me (void)
+{
+ inlined();
+}
+
+void main(void)
+{
+ inline_through_me (inline_me);
+ inline_through_me (inline_me_too);
+}
+void
+inline_through_me (void (*ptr)(void))
+{
+ ptr();
+}
+
+void
+inline_me_too (void)
+{
+ inlined();
+}
+/* { dg-final { scan-tree-dump-times "Inlining inline_me " 1 "einline2"} } */
+/* { dg-final { scan-tree-dump-times "Inlining inline_me_too " 1 "einline2"} } */
+/* { dg-final { cleanup-tree-dump "einline2" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-36.c b/gcc/testsuite/gcc.dg/tree-ssa/loop-36.c
index 0af4d534a7f..9e917376581 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/loop-36.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/loop-36.c
@@ -1,7 +1,7 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-dce2" } */
-struct X { float array[4]; };
+struct X { float array[2]; };
struct X a,b;
@@ -9,9 +9,9 @@ float foobar () {
float s = 0;
unsigned int d;
struct X c;
- for (d=0; d<4; ++d)
+ for (d=0; d<2; ++d)
c.array[d] = a.array[d] * b.array[d];
- for (d=0; d<4; ++d)
+ for (d=0; d<2; ++d)
s+=c.array[d];
return s;
}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr36908.c b/gcc/testsuite/gcc.dg/tree-ssa/pr36908.c
index a135bcff238..8fa2ed2ca1f 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr36908.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr36908.c
@@ -2,7 +2,7 @@
/* { dg-options "-O2 -ftree-loop-distribution" } */
#define NULL ((void *)0)
-typedef unsigned int size_t;
+__extension__ typedef __SIZE_TYPE__ size_t;
extern void *foo(size_t nelem, size_t elsize);
extern void bar (char*, ...);
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr38250.c b/gcc/testsuite/gcc.dg/tree-ssa/pr38250.c
index 79039066808..fac6cd3b806 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr38250.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr38250.c
@@ -1,7 +1,7 @@
/* { dg-do compile } */
/* { dg-options "-O2 -ftree-loop-distribution" } */
-typedef long unsigned int size_t;
+__extension__ typedef __SIZE_TYPE__ size_t;
typedef struct {
long dat[2];
} gsl_complex_long_double;
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr40087.c b/gcc/testsuite/gcc.dg/tree-ssa/pr40087.c
new file mode 100644
index 00000000000..22e2b629ed7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr40087.c
@@ -0,0 +1,30 @@
+/* { dg-do run } */
+/* { dg-options "-O1 " } */
+
+extern void abort (void);
+
+static void __attribute__((always_inline))
+reverse(int *first, int *last)
+{
+ if (first == last--)
+ return;
+ while (first != last)
+ {
+ int t = *first;
+ *first = *last;
+ *last = t;
+ if (++first == last--)
+ break;
+ }
+}
+
+int main()
+{
+ int seq[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
+
+ reverse(seq, seq + 8);
+ if (seq[3] != 5 || seq[4] != 4)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/prefetch-5.c b/gcc/testsuite/gcc.dg/tree-ssa/prefetch-5.c
index 643ac8053e4..19914cabfd0 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/prefetch-5.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/prefetch-5.c
@@ -1,6 +1,6 @@
/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
/* { dg-require-effective-target ilp32 } */
-/* { dg-options "-O2 -fprefetch-loop-arrays -march=athlon -fdump-tree-aprefetch-details" } */
+/* { dg-options "-O2 --param min-insn-to-prefetch-ratio=5 -fprefetch-loop-arrays -march=athlon -fdump-tree-aprefetch-details" } */
/* These are common idioms for writing variable-length arrays at the end
of structures. We should not deduce anything about the number of iterations
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-1.c
new file mode 100644
index 00000000000..ee8a84bd06f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-1.c
@@ -0,0 +1,37 @@
+/* { dg-do run } */
+/* { dg-options "-O -fdump-tree-alias-details" } */
+
+int *i;
+void __attribute__((noinline))
+foo (void)
+{
+ *i = 1;
+}
+int __attribute__((noinline))
+bar(int local_p)
+{
+ int x = 0;
+ int *j;
+ int **p;
+ if (local_p)
+ p = &j;
+ else
+ p = &i;
+ *p = &x; /* This makes x escape. */
+ foo ();
+ return x;
+}
+extern void abort (void);
+int main()
+{
+ int k = 2;
+ i = &k;
+ if (bar (1) != 0 || k != 1)
+ abort ();
+ if (bar (0) != 1)
+ abort ();
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump "ESCAPED, points-to vars: { x }" "alias" } } */
+/* { dg-final { cleanup-tree-dump "alias" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-2.c
new file mode 100644
index 00000000000..ad5ed2e50de
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-2.c
@@ -0,0 +1,38 @@
+/* { dg-do run } */
+/* { dg-options "-O -fdump-tree-alias-details" } */
+
+int *i;
+void __attribute__((noinline))
+foo (void)
+{
+ *i = 1;
+}
+int __attribute__((noinline))
+bar(int local_p, int **q)
+{
+ int x = 0;
+ int *j;
+ int **p;
+ if (local_p)
+ p = &j;
+ else
+ p = q;
+ *p = &x; /* This makes x escape. */
+ foo ();
+ return x;
+}
+extern void abort (void);
+int main()
+{
+ int k = 2;
+ int **q = &i;
+ i = &k;
+ if (bar (1, q) != 0 || k != 1)
+ abort ();
+ if (bar (0, q) != 1)
+ abort ();
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump "ESCAPED, points-to vars: { x }" "alias" } } */
+/* { dg-final { cleanup-tree-dump "alias" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-3.c b/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-3.c
new file mode 100644
index 00000000000..ea11c8a3d7f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-3.c
@@ -0,0 +1,42 @@
+/* { dg-do run } */
+/* { dg-options "-O -fdump-tree-alias-details" } */
+
+int *i;
+void __attribute__((noinline))
+foo (void)
+{
+ *i = 1;
+}
+int **__attribute__((noinline,const))
+foobar (void)
+{
+ return &i;
+}
+int __attribute__((noinline))
+bar(int local_p)
+{
+ int x = 0;
+ int *j;
+ int **p;
+ if (local_p)
+ p = &j;
+ else
+ p = foobar();
+ *p = &x; /* This makes x escape. */
+ foo ();
+ return x;
+}
+extern void abort (void);
+int main()
+{
+ int k = 2;
+ i = &k;
+ if (bar (1) != 0 || k != 1)
+ abort ();
+ if (bar (0) != 1)
+ abort ();
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump "ESCAPED, points-to vars: { x }" "alias" } } */
+/* { dg-final { cleanup-tree-dump "alias" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/sra-1.c b/gcc/testsuite/gcc.dg/tree-ssa/sra-1.c
index c2e45eb1f84..e5af2475115 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/sra-1.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/sra-1.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O1 -fdump-tree-optimized --param sra-max-structure-size=32" } */
+/* { dg-options "-O1 -fdump-tree-optimized" } */
/* Tests for SRA. */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/sra-2.c b/gcc/testsuite/gcc.dg/tree-ssa/sra-2.c
index ec30bc904d7..5682b8afbcf 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/sra-2.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/sra-2.c
@@ -1,5 +1,5 @@
-/* { dg-do compile } */
-/* { dg-options "-O1 -fdump-tree-optimized --param sra-max-structure-size=32" } */
+/* { dg-do compile } */
+/* { dg-options "-O1 -fno-tree-fre -fdump-tree-optimized" } */
/* Test for SRA. */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/sra-3.c b/gcc/testsuite/gcc.dg/tree-ssa/sra-3.c
index 661dc58ff09..d8908152384 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/sra-3.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/sra-3.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O1 -fdump-tree-optimized --param sra-max-structure-size=32" } */
+/* { dg-options "-O1 -fdump-tree-optimized" } */
/* Test for SRA. */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/sra-4.c b/gcc/testsuite/gcc.dg/tree-ssa/sra-4.c
index 6fdf37ffb34..73a68f90043 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/sra-4.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/sra-4.c
@@ -1,6 +1,6 @@
/* { dg-do compile } */
/* { dg-options "-O1 -fdump-tree-optimized -w" } */
-/* Check that SRA does non block copies for structs that just contain vectors. */
+/* Check that SRA replaces strucutres containing vectors. */
#define vector __attribute__((vector_size(16)))
@@ -20,7 +20,5 @@ vector int f(vector int t1, vector int t2)
return st3.t;
}
-/* There should be no references to st as SRA should not have done block copy. */
/* { dg-final { scan-tree-dump-times "st" 0 "optimized" } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */
-
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/sra-5.c b/gcc/testsuite/gcc.dg/tree-ssa/sra-5.c
new file mode 100644
index 00000000000..869d2f55f95
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/sra-5.c
@@ -0,0 +1,74 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-optimized" } */
+
+/* Tests for SRA of unions. */
+
+
+typedef union testunion
+{
+ double d;
+ char f1;
+} testunion;
+
+void
+copyunion1 (testunion param)
+{
+ testunion local;
+ param.f1 = 0;
+ local = param;
+ if (local.f1 != 0)
+ link_error ();
+}
+
+void
+copyunion11 (testunion *param)
+{
+ testunion local;
+ param->f1 = 0;
+ local = *param;
+ if (local.f1 != 0)
+ link_error ();
+}
+
+void
+copyunion111 (testunion param)
+{
+ testunion *local = &param;
+ param.f1 = 0;
+ if (local->f1 != 0)
+ link_error ();
+}
+
+testunion globuf;
+void
+copyunion1111 (void)
+{
+ testunion local;
+ globuf.f1 = 0;
+ local = globuf;
+ if (local.f1 != 0)
+ link_error ();
+}
+
+void
+copyunion11111 (void)
+{
+ testunion *local = &globuf;
+ globuf.f1 = 0;
+ if (local->f1 != 0)
+ link_error ();
+}
+
+void
+copyunion111111 (testunion param)
+{
+ static testunion local;
+ param.f1 = 0;
+ local = param;
+ if (local.f1 != 0)
+ link_error ();
+}
+
+/* There should be no reference to link_error. */
+/* { dg-final { scan-tree-dump-times "link_error" 0 "optimized"} } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/sra-6.c b/gcc/testsuite/gcc.dg/tree-ssa/sra-6.c
new file mode 100644
index 00000000000..e59b536c12d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/sra-6.c
@@ -0,0 +1,40 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-optimized -fdump-tree-esra-details" } */
+
+typedef struct teststruct
+{
+ double d;
+ int i1;
+ char c1;
+ float z;
+ char c2;
+ int i2;
+} teststruct;
+
+
+void cow (int i)
+{
+ teststruct a, b, c, d;
+
+ a.d = 3.2;
+ a.i1 = i;
+
+ b = a;
+ c = b;
+ d = c;
+
+ if (d.i1 != i)
+ link_error ();
+}
+
+
+/* Suaccesses of b and c should have been created. */
+/* { dg-final { scan-tree-dump "expr = b.d" "esra"} } */
+/* { dg-final { scan-tree-dump "expr = b.i1" "esra"} } */
+/* { dg-final { scan-tree-dump "expr = c.d" "esra"} } */
+/* { dg-final { scan-tree-dump "expr = c.i1" "esra"} } */
+/* { dg-final { cleanup-tree-dump "esra" } } */
+
+/* There should be no reference to link_error. */
+/* { dg-final { scan-tree-dump-times "link_error" 0 "optimized"} } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/sra-7.c b/gcc/testsuite/gcc.dg/tree-ssa/sra-7.c
new file mode 100644
index 00000000000..325a329f343
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/sra-7.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-optimized" } */
+
+typedef struct { char f[4]; } __attribute__((aligned (4))) s;
+
+void a(s *s1, s *s2)
+{
+ *s1 = *s2;
+}
+
+/* Struct copies should not be split into members. */
+/* { dg-final { scan-tree-dump "\\\*s1_.\\\(D\\\) = \\\*s2" "optimized"} } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-10.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-10.c
index dd0da7913dc..bce2c315a66 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-10.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-10.c
@@ -1,7 +1,7 @@
/* { dg-do compile } */
/* { dg-options "-O -w -fdump-tree-dse-vops" } */
-typedef unsigned int size_t;
+__extension__ typedef __SIZE_TYPE__ size_t;
typedef struct _IO_FILE FILE;
typedef struct
{
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-14.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-14.c
index 24b58ee941a..81b82fe4880 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-14.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-14.c
@@ -8,6 +8,7 @@ struct Foo
void *data;
double size;
};
+void bar(double *);
void foo(double (*q)[4])
{
struct Foo tmp1;
@@ -23,6 +24,7 @@ void foo(double (*q)[4])
this store to tmp1 here. */
tmp1.size -= 1.0;
}
+ bar(a);
}
/* { dg-final { scan-tree-dump "Inserted .* &a" "fre" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-15.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-15.c
index a557f27f319..d24cd1e4c38 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-15.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-15.c
@@ -8,6 +8,7 @@ struct Foo
void *data;
double size;
};
+void bar(double *);
void foo(double (*q)[4])
{
struct Foo tmp1;
@@ -22,6 +23,7 @@ void foo(double (*q)[4])
this store to tmp1 here. */
tmp1.size -= 1.0;
}
+ bar(a);
}
/* { dg-final { scan-tree-dump "Replaced" "fre" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-24.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-24.c
new file mode 100644
index 00000000000..705993a4fb3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-24.c
@@ -0,0 +1,34 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fno-tree-sra -fdump-tree-fre" } */
+
+int foo(void)
+{
+ int a[16] = {};
+ return a[3];
+}
+
+int bar(void)
+{
+ int a[16];
+ __builtin_memset (a, 0, sizeof(a));
+ return a[3];
+}
+
+struct X { int i; };
+int baz(void)
+{
+ struct X a,b;
+ a.i = 0;
+ b = a;
+ return b.i;
+}
+
+int bazzoo (void)
+{
+ struct X b, a = {};
+ b = a;
+ return b.i;
+}
+
+/* { dg-final { scan-tree-dump-times "= 0;" 5 "fre" } } */
+/* { dg-final { cleanup-tree-dump "fre" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-25.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-25.c
new file mode 100644
index 00000000000..f7f99bf74f5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-25.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fno-tree-sra -fdump-tree-fre" } */
+
+struct X { int i; int j; };
+void bar (struct X *);
+int foo (struct X *p)
+{
+ struct X x;
+ p->i = 1;
+ x = *p;
+ x.j = 2;
+ return p->i - x.i;
+}
+
+/* We should optimize this to return 0. */
+
+/* { dg-final { scan-tree-dump "= 0;" "fre" } } */
+/* { dg-final { cleanup-tree-dump "fre" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-26.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-26.c
new file mode 100644
index 00000000000..144d146b935
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-26.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fno-tree-sra -fdump-tree-fre-details" } */
+
+union U {
+ float f;
+ int i;
+};
+
+int foo (union U *p)
+{
+ union U u;
+ p->f = 0.0;
+ u = *p;
+ return u.i;
+}
+
+/* { dg-final { scan-tree-dump "Replaced u.i with 0 in" "fre" } } */
+/* { dg-final { cleanup-tree-dump "fre" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-27.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-27.c
new file mode 100644
index 00000000000..39368707ce9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-27.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-fre-details" } */
+
+int *q;
+void __attribute__((noinline))
+bar (void)
+{
+ *q = 1;
+}
+int foo(int which_p)
+{
+ int x = 0;
+ int *i,*j;
+ int **p;
+ if (which_p)
+ p = &i;
+ else
+ p = &j;
+ *p = &x;
+ bar ();
+ return x;
+}
+
+/* { dg-final { scan-tree-dump "Replaced x with 0" "fre" } } */
+/* { dg-final { cleanup-tree-dump "fre" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-7.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-7.c
index bd81831eba8..895c05fdf91 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-7.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-7.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O -fdump-tree-fre-details -fdump-tree-optimized" } */
+/* { dg-options "-O -fno-tree-sra -fdump-tree-fre-details -fdump-tree-optimized" } */
#if (__SIZEOF_INT__ == __SIZEOF_FLOAT__)
typedef int intflt;
#elif (__SIZEOF_LONG__ == __SIZEOF_FLOAT__)
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-8.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-8.c
index 6e17bd531b3..bc9f8e3992e 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-8.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-8.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O -fdump-tree-fre-details" } */
+/* { dg-options "-O -fno-tree-sra -fdump-tree-fre-details" } */
#if (__SIZEOF_INT__ == __SIZEOF_FLOAT__)
typedef int intflt;
#elif (__SIZEOF_LONG__ == __SIZEOF_FLOAT__)
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-9.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-9.c
index 18595ed6fe5..c8a434a2bba 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-9.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-9.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O -fdump-tree-fre-stats" } */
+/* { dg-options "-O -fno-tree-sra -fdump-tree-fre-stats" } */
union loc {
unsigned reg;
diff --git a/gcc/testsuite/gcc.dg/va-arg-2.c b/gcc/testsuite/gcc.dg/va-arg-2.c
index 2fd0ed97e3f..e1c915ffc92 100644
--- a/gcc/testsuite/gcc.dg/va-arg-2.c
+++ b/gcc/testsuite/gcc.dg/va-arg-2.c
@@ -5,7 +5,7 @@
#include <varargs.h> /* { dg-bogus "varargs.h" "missing file" } */
-/* { dg-message "" "In file included from" { target *-*-* } 6 } */
+/* { dg-message "file included from" "file included from" { target *-*-* } 0 } */
/* { dg-error "no longer implements" "#error 1" { target *-*-* } 4 } */
/* { dg-error "Revise your code" "#error 2" { target *-*-* } 5 } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-1.c b/gcc/testsuite/gcc.dg/vect/bb-slp-1.c
new file mode 100644
index 00000000000..57e5665247d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-1.c
@@ -0,0 +1,62 @@
+/* { dg-require-effective-target vect_int } */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include "tree-vect.h"
+
+#define N 32
+
+unsigned int out[N*8];
+unsigned int in[N*8] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63};
+
+__attribute__ ((noinline)) int
+main1 (int dummy)
+{
+ int i;
+ unsigned int *pin = &in[0];
+ unsigned int *pout = &out[0];
+
+ for (i = 0; i < N; i++)
+ {
+ *pout++ = *pin++;
+ *pout++ = *pin++;
+ *pout++ = *pin++;
+ *pout++ = *pin++;
+ *pout++ = *pin++;
+ *pout++ = *pin++;
+ *pout++ = *pin++;
+ *pout++ = *pin++;
+ /* Avoid loop vectorization. */
+ if (dummy == 32)
+ abort ();
+ }
+
+ /* check results: */
+ for (i = 0; i < N; i++)
+ {
+ if (out[i*8] != in[i*8]
+ || out[i*8 + 1] != in[i*8 + 1]
+ || out[i*8 + 2] != in[i*8 + 2]
+ || out[i*8 + 3] != in[i*8 + 3]
+ || out[i*8 + 4] != in[i*8 + 4]
+ || out[i*8 + 5] != in[i*8 + 5]
+ || out[i*8 + 6] != in[i*8 + 6]
+ || out[i*8 + 7] != in[i*8 + 7])
+ abort ();
+ }
+
+ return 0;
+}
+
+int main (void)
+{
+ check_vect ();
+
+ main1 (33);
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" } } */
+/* { dg-final { cleanup-tree-dump "slp" } } */
+
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-10.c b/gcc/testsuite/gcc.dg/vect/bb-slp-10.c
new file mode 100644
index 00000000000..1a678ca3677
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-10.c
@@ -0,0 +1,53 @@
+/* { dg-require-effective-target vect_int } */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include "tree-vect.h"
+
+#define N 16
+
+unsigned int out[N];
+unsigned int in[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
+
+__attribute__ ((noinline)) int
+main1 (unsigned int x, unsigned int y)
+{
+ int i;
+ unsigned int *pin = &in[0];
+ unsigned int *pout = &out[1];
+ unsigned int a0, a1, a2, a3;
+
+ /* Misaligned store. */
+ a0 = *pin++ + 23;
+ a1 = *pin++ + 142;
+ a2 = *pin++ + 2;
+ a3 = *pin++ + 31;
+
+ *pout++ = a0 * x;
+ *pout++ = a1 * y;
+ *pout++ = a2 * x;
+ *pout++ = a3 * y;
+
+ /* Check results. */
+ if (out[1] != (in[0] + 23) * x
+ || out[2] != (in[1] + 142) * y
+ || out[3] != (in[2] + 2) * x
+ || out[4] != (in[3] + 31) * y)
+ abort();
+
+ return 0;
+}
+
+int main (void)
+{
+ check_vect ();
+
+ main1 (2, 3);
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 0 "slp" } } */
+/* { dg-final { scan-tree-dump-times "unsupported alignment in basic block." 1 "slp" } } */
+/* { dg-final { cleanup-tree-dump "slp" } } */
+
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-11.c b/gcc/testsuite/gcc.dg/vect/bb-slp-11.c
new file mode 100644
index 00000000000..456f9618139
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-11.c
@@ -0,0 +1,52 @@
+/* { dg-require-effective-target vect_int } */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include "tree-vect.h"
+
+#define N 16
+
+unsigned int out[N];
+unsigned int in[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
+
+__attribute__ ((noinline)) int
+main1 (unsigned int x, unsigned int y)
+{
+ int i;
+ unsigned int *pin = &in[0];
+ unsigned int *pout = &out[0];
+ short a0, a1, a2, a3;
+
+ a0 = *pin++ + 23;
+ a1 = *pin++ + 142;
+ a2 = *pin++ + 2;
+ a3 = *pin++ + 31;
+
+ *pout++ = a0 * x;
+ *pout++ = a1 * y;
+ *pout++ = a2 * x;
+ *pout++ = a3 * y;
+
+ /* Check results. */
+ if (out[0] != (in[0] + 23) * x
+ || out[1] != (in[1] + 142) * y
+ || out[2] != (in[2] + 2) * x
+ || out[3] != (in[3] + 31) * y)
+ abort();
+
+ return 0;
+}
+
+int main (void)
+{
+ check_vect ();
+
+ main1 (2, 3);
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 0 "slp" } } */
+/* { dg-final { scan-tree-dump-times "SLP with multiple types" 1 "slp" } } */
+/* { dg-final { cleanup-tree-dump "slp" } } */
+
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-13.c b/gcc/testsuite/gcc.dg/vect/bb-slp-13.c
new file mode 100644
index 00000000000..5005ae5019f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-13.c
@@ -0,0 +1,49 @@
+/* { dg-require-effective-target vect_int } */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include "tree-vect.h"
+
+#define N 16
+
+unsigned int out[N];
+unsigned int in[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
+
+__attribute__ ((noinline)) int
+main1 (unsigned int x, unsigned int y)
+{
+ int i;
+ unsigned int a0, a1, a2, a3;
+
+ a0 = in[0] + 23;
+ a1 = in[1] + 142;
+ a2 = in[2] + 2;
+ a3 = in[3] + 31;
+
+ out[0] = a0 * x;
+ out[1] = a1 * y;
+ out[2] = a2 * x;
+ out[3] = a3 * y;
+
+ /* Check results. */
+ if (out[0] != (in[0] + 23) * x
+ || out[1] != (in[1] + 142) * y
+ || out[2] != (in[2] + 2) * x
+ || out[3] != (in[3] + 31) * y)
+ abort();
+
+ return 0;
+}
+
+int main (void)
+{
+ check_vect ();
+
+ main1 (2, 3);
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target vect_int_mult } } } */
+/* { dg-final { cleanup-tree-dump "slp" } } */
+
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-14.c b/gcc/testsuite/gcc.dg/vect/bb-slp-14.c
new file mode 100644
index 00000000000..673a163c92f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-14.c
@@ -0,0 +1,50 @@
+/* { dg-require-effective-target vect_int } */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include "tree-vect.h"
+
+#define N 16
+
+unsigned int out[N];
+unsigned int in[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
+
+__attribute__ ((noinline)) int
+main1 (unsigned int x, unsigned int y)
+{
+ int i;
+ unsigned int a0, a1, a2, a3;
+
+ /* Not consecutive load with permutation - not supported. */
+ a0 = in[0] + 23;
+ a1 = in[1] + 142;
+ a2 = in[1] + 2;
+ a3 = in[3] + 31;
+
+ out[0] = a0 * x;
+ out[1] = a1 * y;
+ out[2] = a2 * x;
+ out[3] = a3 * y;
+
+ /* Check results. */
+ if (out[0] != (in[0] + 23) * x
+ || out[1] != (in[1] + 142) * y
+ || out[2] != (in[1] + 2) * x
+ || out[3] != (in[3] + 31) * y)
+ abort();
+
+ return 0;
+}
+
+int main (void)
+{
+ check_vect ();
+
+ main1 (2, 3);
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 0 "slp" } } */
+/* { dg-final { cleanup-tree-dump "slp" } } */
+
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-15.c b/gcc/testsuite/gcc.dg/vect/bb-slp-15.c
new file mode 100644
index 00000000000..ba8bc757e86
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-15.c
@@ -0,0 +1,54 @@
+/* { dg-require-effective-target vect_int } */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include "tree-vect.h"
+
+#define N 16
+
+unsigned int out[N];
+unsigned int in[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
+
+__attribute__ ((noinline)) int
+main1 (unsigned int x, unsigned int y)
+{
+ int i;
+ unsigned int a0, a1, a2, a3;
+
+ if (x > y)
+ x = x + y;
+ else
+ y = x;
+
+ a0 = in[0] + 23;
+ a1 = in[1] + 142;
+ a2 = in[2] + 2;
+ a3 = in[3] + 31;
+
+ out[0] = a0 * x;
+ out[1] = a1 * y;
+ out[2] = a2 * x;
+ out[3] = a3 * y;
+
+ /* Check results. */
+ if (out[0] != (in[0] + 23) * x
+ || out[1] != (in[1] + 142) * y
+ || out[2] != (in[2] + 2) * x
+ || out[3] != (in[3] + 31) * y)
+ abort();
+
+ return 0;
+}
+
+int main (void)
+{
+ check_vect ();
+
+ main1 (2, 3);
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target vect_int_mult } } } */
+/* { dg-final { cleanup-tree-dump "slp" } } */
+
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-16.c b/gcc/testsuite/gcc.dg/vect/bb-slp-16.c
new file mode 100644
index 00000000000..16cd7a18d67
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-16.c
@@ -0,0 +1,71 @@
+/* { dg-require-effective-target vect_int } */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include "tree-vect.h"
+
+#define N 32
+
+unsigned int out[N*8];
+unsigned int in[N*8] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63};
+unsigned int arr[N] = {0,1,2,3,4,5,6,7};
+
+__attribute__ ((noinline)) int
+main1 (int dummy)
+{
+ int i;
+ unsigned int *pin = &in[0];
+ unsigned int *pout = &out[0];
+ unsigned int a = 0;
+
+ for (i = 0; i < N; i++)
+ {
+ *pout++ = *pin++ + a;
+ *pout++ = *pin++ + a;
+ *pout++ = *pin++ + a;
+ *pout++ = *pin++ + a;
+ *pout++ = *pin++ + a;
+ *pout++ = *pin++ + a;
+ *pout++ = *pin++ + a;
+ *pout++ = *pin++ + a;
+ if (arr[i] = i)
+ a = i;
+ else
+ a = 2;
+ }
+
+ a = 0;
+ /* check results: */
+ for (i = 0; i < N; i++)
+ {
+ if (out[i*8] != in[i*8] + a
+ || out[i*8 + 1] != in[i*8 + 1] + a
+ || out[i*8 + 2] != in[i*8 + 2] + a
+ || out[i*8 + 3] != in[i*8 + 3] + a
+ || out[i*8 + 4] != in[i*8 + 4] + a
+ || out[i*8 + 5] != in[i*8 + 5] + a
+ || out[i*8 + 6] != in[i*8 + 6] + a
+ || out[i*8 + 7] != in[i*8 + 7] + a)
+ abort ();
+
+ if (arr[i] = i)
+ a = i;
+ else
+ a = 2;
+ }
+
+ return 0;
+}
+
+int main (void)
+{
+ check_vect ();
+
+ main1 (33);
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" } } */
+/* { dg-final { cleanup-tree-dump "slp" } } */
+
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-17.c b/gcc/testsuite/gcc.dg/vect/bb-slp-17.c
new file mode 100644
index 00000000000..36227391d2e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-17.c
@@ -0,0 +1,60 @@
+/* { dg-require-effective-target vect_int } */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include "tree-vect.h"
+
+#define N 16
+
+unsigned int b[N];
+unsigned int out[N];
+unsigned int in[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
+
+__attribute__ ((noinline)) int
+main1 (unsigned int x, unsigned int y)
+{
+ int i;
+ unsigned int a0, a1, a2, a3;
+
+ if (x > y)
+ x = x + y;
+ else
+ y = x;
+
+ a0 = in[0] + 23;
+ a1 = in[1] + 142;
+ a2 = in[2] + 2;
+ a3 = in[3] + 31;
+
+ b[0] = a0;
+ b[1] = a1;
+
+ out[0] = a0 * x;
+ out[1] = a1 * y;
+ out[2] = a2 * x;
+ out[3] = a3 * y;
+
+ /* Check results. */
+ if (out[0] != (in[0] + 23) * x
+ || out[1] != (in[1] + 142) * y
+ || out[2] != (in[2] + 2) * x
+ || out[3] != (in[3] + 31) * y
+ || b[0] != in[0] + 23
+ || b[1] != in[1] + 142)
+ abort();
+
+ return 0;
+}
+
+int main (void)
+{
+ check_vect ();
+
+ main1 (2, 3);
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target vect_int_mult } } } */
+/* { dg-final { cleanup-tree-dump "slp" } } */
+
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-18.c b/gcc/testsuite/gcc.dg/vect/bb-slp-18.c
new file mode 100644
index 00000000000..ab99f822aff
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-18.c
@@ -0,0 +1,49 @@
+/* { dg-require-effective-target vect_int } */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include "tree-vect.h"
+
+#define N 16
+
+unsigned int out[N];
+unsigned int in[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
+
+__attribute__ ((noinline)) int
+main1 (unsigned int x, unsigned int y)
+{
+ int i;
+ unsigned int a0, a1, a2, a3;
+
+ a0 = in[0] + 23;
+ a1 = in[1] + 142;
+ a2 = in[2] + 2;
+ a3 = in[3] + 31;
+
+ out[0] = a0 * x;
+ out[1] = a1 * y;
+ out[2] = a2 * x;
+ out[3] = a3 * y;
+
+ /* Check results. */
+ if (out[0] != a0 * x
+ || out[1] != a1 * y
+ || out[2] != a2 * x
+ || out[3] != a3 * y)
+ abort();
+
+ return 0;
+}
+
+int main (void)
+{
+ check_vect ();
+
+ main1 (2, 3);
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target vect_int_mult } } } */
+/* { dg-final { cleanup-tree-dump "slp" } } */
+
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-19.c b/gcc/testsuite/gcc.dg/vect/bb-slp-19.c
new file mode 100644
index 00000000000..5ee83a1945e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-19.c
@@ -0,0 +1,56 @@
+/* { dg-require-effective-target vect_int } */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include "tree-vect.h"
+
+#define N 16
+
+unsigned short out[N];
+unsigned short in[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
+
+__attribute__ ((noinline)) int
+main1 ()
+{
+ int i;
+ unsigned short *pin = &in[0];
+ unsigned short *pout = &out[0];
+
+ /* A group of 9 shorts - unsupported for now. */
+ *pout++ = *pin++;
+ *pout++ = *pin++;
+ *pout++ = *pin++;
+ *pout++ = *pin++;
+ *pout++ = *pin++;
+ *pout++ = *pin++;
+ *pout++ = *pin++;
+ *pout++ = *pin++;
+ *pout++ = *pin++;
+
+ /* Check results. */
+ if (out[0] != in[0]
+ || out[1] != in[1]
+ || out[2] != in[2]
+ || out[3] != in[3]
+ || out[4] != in[4]
+ || out[5] != in[5]
+ || out[6] != in[6]
+ || out[7] != in[7]
+ || out[8] != in[8])
+ abort();
+
+ return 0;
+}
+
+int main (void)
+{
+ check_vect ();
+
+ main1 ();
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { xfail *-*-* } } } */
+/* { dg-final { cleanup-tree-dump "slp" } } */
+
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-2.c b/gcc/testsuite/gcc.dg/vect/bb-slp-2.c
new file mode 100644
index 00000000000..1de31986829
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-2.c
@@ -0,0 +1,59 @@
+/* { dg-require-effective-target vect_int } */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include "tree-vect.h"
+
+#define N 16
+
+unsigned int out[N*8];
+unsigned int in[N*8] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63};
+
+__attribute__ ((noinline)) int
+main1 (int dummy)
+{
+ int i;
+ unsigned int *pin = &in[0];
+ unsigned int *pout = &out[0];
+
+ for (i = 0; i < N*2; i++)
+ {
+ *pout++ = *pin++;
+ *pout++ = *pin++;
+ *pout++ = *pin++;
+ *pout++ = *pin++;
+
+ /* Avoid loop vectorization. */
+ if (dummy == 32)
+ abort ();
+ }
+
+ /* check results: */
+ for (i = 0; i < N; i++)
+ {
+ if (out[i*8] != in[i*8]
+ || out[i*8 + 1] != in[i*8 + 1]
+ || out[i*8 + 2] != in[i*8 + 2]
+ || out[i*8 + 3] != in[i*8 + 3]
+ || out[i*8 + 4] != in[i*8 + 4]
+ || out[i*8 + 5] != in[i*8 + 5]
+ || out[i*8 + 6] != in[i*8 + 6]
+ || out[i*8 + 7] != in[i*8 + 7])
+ abort ();
+ }
+
+ return 0;
+}
+
+int main (void)
+{
+ check_vect ();
+
+ main1 (33);
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" } } */
+/* { dg-final { cleanup-tree-dump "slp" } } */
+
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-20.c b/gcc/testsuite/gcc.dg/vect/bb-slp-20.c
new file mode 100644
index 00000000000..a40a629d1e7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-20.c
@@ -0,0 +1,68 @@
+/* { dg-require-effective-target vect_int } */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include "tree-vect.h"
+
+#define N 16
+
+int b[N];
+unsigned int out[N];
+unsigned int in[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
+
+__attribute__ ((noinline)) int
+main1 (unsigned int x, unsigned int y)
+{
+ int i;
+ unsigned int a0, a1, a2, a3;
+
+ if (x > y)
+ x = x + y;
+ else
+ y = x;
+
+ /* Two SLP instances in the basic block, only one is supported for now,
+ the second one contains type conversion. */
+ a0 = in[0] + 23;
+ a1 = in[1] + 142;
+ a2 = in[2] + 2;
+ a3 = in[3] + 31;
+
+ b[0] = -a0;
+ b[1] = -a1;
+ b[2] = -a2;
+ b[3] = -a3;
+
+ out[0] = a0 * x;
+ out[1] = a1 * y;
+ out[2] = a2 * x;
+ out[3] = a3 * y;
+
+ /* Check results. */
+ if (out[0] != (in[0] + 23) * x
+ || out[1] != (in[1] + 142) * y
+ || out[2] != (in[2] + 2) * x
+ || out[3] != (in[3] + 31) * y
+ || b[0] != -(in[0] + 23)
+ || b[1] != -(in[1] + 142)
+ || b[2] != -(in[2] + 2)
+ || b[3] != -(in[3] + 31))
+
+ abort();
+
+ return 0;
+}
+
+int main (void)
+{
+ check_vect ();
+
+ main1 (2, 3);
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target vect_int_mult } } } */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "slp" { target vect_int_mult } } } */
+/* { dg-final { cleanup-tree-dump "slp" } } */
+
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-21.c b/gcc/testsuite/gcc.dg/vect/bb-slp-21.c
new file mode 100644
index 00000000000..f0b4f6b1ac8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-21.c
@@ -0,0 +1,68 @@
+/* { dg-require-effective-target vect_int } */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include "tree-vect.h"
+
+#define N 16
+
+unsigned int b[N];
+unsigned int out[N];
+unsigned int in[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
+
+__attribute__ ((noinline)) int
+main1 (unsigned int x, unsigned int y)
+{
+ int i;
+ unsigned int a0, a1, a2, a3;
+
+ /* Two SLP instances in one basic block. */
+ if (x > y)
+ x = x + y;
+ else
+ y = x;
+
+ a0 = in[0] + 23;
+ a1 = in[1] + 142;
+ a2 = in[2] + 2;
+ a3 = in[3] + 31;
+
+ b[0] = a0;
+ b[1] = a1;
+ b[2] = a2;
+ b[3] = a3;
+
+ out[0] = a0 * x;
+ out[1] = a1 * y;
+ out[2] = a2 * x;
+ out[3] = a3 * y;
+
+ /* Check results. */
+ if (out[0] != (in[0] + 23) * x
+ || out[1] != (in[1] + 142) * y
+ || out[2] != (in[2] + 2) * x
+ || out[3] != (in[3] + 31) * y
+ || b[0] != (in[0] + 23)
+ || b[1] != (in[1] + 142)
+ || b[2] != (in[2] + 2)
+ || b[3] != (in[3] + 31))
+
+ abort();
+
+ return 0;
+}
+
+int main (void)
+{
+ check_vect ();
+
+ main1 (2, 3);
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" } } */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "slp" { target { ! {vect_int_mult } } } } } */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "slp" { target vect_int_mult } } } */
+/* { dg-final { cleanup-tree-dump "slp" } } */
+
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-22.c b/gcc/testsuite/gcc.dg/vect/bb-slp-22.c
new file mode 100644
index 00000000000..3e6e685f118
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-22.c
@@ -0,0 +1,67 @@
+/* { dg-require-effective-target vect_int } */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include "tree-vect.h"
+
+#define N 16
+
+unsigned int b[N];
+unsigned int out[N];
+unsigned int in[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
+
+__attribute__ ((noinline)) int
+main1 (unsigned int x, unsigned int y)
+{
+ int i;
+ unsigned int a0, a1, a2, a3;
+
+ a0 = in[0] + 23;
+ a1 = in[1] + 142;
+ a2 = in[2] + 2;
+ a3 = in[3] + 31;
+
+ if (x > y)
+ {
+ b[0] = a0;
+ b[1] = a1;
+ b[2] = a2;
+ b[3] = a3;
+ }
+ else
+ {
+ out[0] = a0 * x;
+ out[1] = a1 * y;
+ out[2] = a2 * x;
+ out[3] = a3 * y;
+ }
+
+ /* Check results. */
+ if ((x <= y
+ && (out[0] != (in[0] + 23) * x
+ || out[1] != (in[1] + 142) * y
+ || out[2] != (in[2] + 2) * x
+ || out[3] != (in[3] + 31) * y))
+ || (x > y
+ && (b[0] != (in[0] + 23)
+ || b[1] != (in[1] + 142)
+ || b[2] != (in[2] + 2)
+ || b[3] != (in[3] + 31))))
+ abort();
+
+ return 0;
+}
+
+int main (void)
+{
+ check_vect ();
+
+ main1 (2, 3);
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target { ! {vect_int_mult } } } } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 2 "slp" { target vect_int_mult } } } */
+/* { dg-final { cleanup-tree-dump "slp" } } */
+
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-3.c b/gcc/testsuite/gcc.dg/vect/bb-slp-3.c
new file mode 100644
index 00000000000..07ad7129ad7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-3.c
@@ -0,0 +1,45 @@
+/* { dg-require-effective-target vect_int } */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include "tree-vect.h"
+
+#define N 16
+
+unsigned int out[N];
+unsigned int in[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
+
+__attribute__ ((noinline)) int
+main1 ()
+{
+ int i;
+ unsigned int *pin = &in[0];
+ unsigned int *pout = &out[0];
+
+ *pout++ = *pin++;
+ *pout++ = *pin++;
+ *pout++ = *pin++;
+ *pout++ = *pin++;
+
+ /* Check results. */
+ if (out[0] != in[0]
+ || out[1] != in[1]
+ || out[2] != in[2]
+ || out[3] != in[3])
+ abort();
+
+ return 0;
+}
+
+int main (void)
+{
+ check_vect ();
+
+ main1 ();
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" } } */
+/* { dg-final { cleanup-tree-dump "slp" } } */
+
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-4.c b/gcc/testsuite/gcc.dg/vect/bb-slp-4.c
new file mode 100644
index 00000000000..4ed8d7c6b39
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-4.c
@@ -0,0 +1,41 @@
+/* { dg-require-effective-target vect_int } */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include "tree-vect.h"
+
+#define N 16
+
+unsigned short out[N];
+unsigned short in[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
+
+__attribute__ ((noinline)) int
+main1 ()
+{
+ int i;
+ unsigned short *pin = &in[0];
+ unsigned short *pout = &out[0];
+
+ *pout++ = *pin++;
+ *pout++ = *pin++;
+
+ /* Check results. */
+ if (out[0] != in[0]
+ || out[1] != in[1])
+ abort();
+
+ return 0;
+}
+
+int main (void)
+{
+ check_vect ();
+
+ main1 ();
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 0 "slp" } } */
+/* { dg-final { cleanup-tree-dump "slp" } } */
+
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-5.c b/gcc/testsuite/gcc.dg/vect/bb-slp-5.c
new file mode 100644
index 00000000000..0775d998c8d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-5.c
@@ -0,0 +1,53 @@
+/* { dg-require-effective-target vect_int } */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include "tree-vect.h"
+
+#define N 16
+
+unsigned short out[N];
+unsigned short in[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
+
+__attribute__ ((noinline)) int
+main1 ()
+{
+ int i;
+ unsigned short *pin = &in[0];
+ unsigned short *pout = &out[0];
+
+ *pout++ = *pin++;
+ *pout++ = *pin++;
+ *pout++ = *pin++;
+ *pout++ = *pin++;
+ *pout++ = *pin++;
+ *pout++ = *pin++;
+ *pout++ = *pin++;
+ *pout++ = *pin++;
+
+ /* Check results. */
+ if (out[0] != in[0]
+ || out[1] != in[1]
+ || out[2] != in[2]
+ || out[3] != in[3]
+ || out[4] != in[4]
+ || out[5] != in[5]
+ || out[6] != in[6]
+ || out[7] != in[7])
+ abort();
+
+ return 0;
+}
+
+int main (void)
+{
+ check_vect ();
+
+ main1 ();
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" } } */
+/* { dg-final { cleanup-tree-dump "slp" } } */
+
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-6.c b/gcc/testsuite/gcc.dg/vect/bb-slp-6.c
new file mode 100644
index 00000000000..d351691c2fc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-6.c
@@ -0,0 +1,51 @@
+/* { dg-require-effective-target vect_int } */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include "tree-vect.h"
+
+#define N 16
+
+unsigned int out[N];
+unsigned int in[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
+
+__attribute__ ((noinline)) int
+main1 (unsigned int x, unsigned int y)
+{
+ int i;
+ unsigned int *pin = &in[0];
+ unsigned int *pout = &out[0];
+ unsigned int a0, a1, a2, a3;
+
+ a0 = *pin++ + 23;
+ a1 = *pin++ + 142;
+ a2 = *pin++ + 2;
+ a3 = *pin++ + 31;
+
+ *pout++ = a0 * x;
+ *pout++ = a1 * y;
+ *pout++ = a2 * x;
+ *pout++ = a3 * y;
+
+ /* Check results. */
+ if (out[0] != (in[0] + 23) * x
+ || out[1] != (in[1] + 142) * y
+ || out[2] != (in[2] + 2) * x
+ || out[3] != (in[3] + 31) * y)
+ abort();
+
+ return 0;
+}
+
+int main (void)
+{
+ check_vect ();
+
+ main1 (2, 3);
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target vect_int_mult } } } */
+/* { dg-final { cleanup-tree-dump "slp" } } */
+
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-7.c b/gcc/testsuite/gcc.dg/vect/bb-slp-7.c
new file mode 100644
index 00000000000..e3fac8d5dbe
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-7.c
@@ -0,0 +1,52 @@
+/* { dg-require-effective-target vect_int } */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include "tree-vect.h"
+
+#define N 16
+
+unsigned int out[N];
+unsigned int in[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
+
+__attribute__ ((noinline)) int
+main1 (unsigned int x, unsigned int y)
+{
+ int i;
+ unsigned int *pin = &in[0];
+ unsigned int *pout = &out[0];
+ unsigned int a0, a1, a2, a3;
+
+ /* Non isomorphic. */
+ a0 = *pin++ + 23;
+ a1 = *pin++ + 142;
+ a2 = *pin++ + 2;
+ a3 = *pin++ * 31;
+
+ *pout++ = a0 * x;
+ *pout++ = a1 * y;
+ *pout++ = a2 * x;
+ *pout++ = a3 * y;
+
+ /* Check results. */
+ if (out[0] != (in[0] + 23) * x
+ || out[1] != (in[1] + 142) * y
+ || out[2] != (in[2] + 2) * x
+ || out[3] != (in[3] * 31) * y)
+ abort();
+
+ return 0;
+}
+
+int main (void)
+{
+ check_vect ();
+
+ main1 (2, 3);
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 0 "slp" } } */
+/* { dg-final { cleanup-tree-dump "slp" } } */
+
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-8.c b/gcc/testsuite/gcc.dg/vect/bb-slp-8.c
new file mode 100644
index 00000000000..b0c1be77a3e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-8.c
@@ -0,0 +1,50 @@
+/* { dg-require-effective-target vect_int } */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include "tree-vect.h"
+
+#define N 16
+
+unsigned int out[N];
+unsigned int in[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
+
+__attribute__ ((noinline)) int
+main1 (unsigned int x, unsigned int y, unsigned int *pin, unsigned int *pout)
+{
+ int i;
+ unsigned int a0, a1, a2, a3;
+
+ /* pin and pout may alias. */
+ a0 = *pin++ + 23;
+ a1 = *pin++ + 142;
+ a2 = *pin++ + 2;
+ a3 = *pin++ + 31;
+
+ *pout++ = a0 * x;
+ *pout++ = a1 * y;
+ *pout++ = a2 * x;
+ *pout++ = a3 * y;
+
+ /* Check results. */
+ if (out[0] != (in[0] + 23) * x
+ || out[1] != (in[1] + 142) * y
+ || out[2] != (in[2] + 2) * x
+ || out[3] != (in[3] + 31) * y)
+ abort();
+
+ return 0;
+}
+
+int main (void)
+{
+ check_vect ();
+
+ main1 (2, 3, &in[0], &out[0]);
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 0 "slp" } } */
+/* { dg-final { cleanup-tree-dump "slp" } } */
+
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-9.c b/gcc/testsuite/gcc.dg/vect/bb-slp-9.c
new file mode 100644
index 00000000000..e8fe1507365
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-9.c
@@ -0,0 +1,53 @@
+/* { dg-require-effective-target vect_int } */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include "tree-vect.h"
+
+#define N 16
+
+unsigned int out[N];
+unsigned int in[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
+
+__attribute__ ((noinline)) int
+main1 (unsigned int x, unsigned int y)
+{
+ int i;
+ unsigned int *pin = &in[1];
+ unsigned int *pout = &out[0];
+ unsigned int a0, a1, a2, a3;
+
+ /* Misaligned load. */
+ a0 = *pin++ + 23;
+ a1 = *pin++ + 142;
+ a2 = *pin++ + 2;
+ a3 = *pin++ + 31;
+
+ *pout++ = a0 * x;
+ *pout++ = a1 * y;
+ *pout++ = a2 * x;
+ *pout++ = a3 * y;
+
+ /* Check results. */
+ if (out[0] != (in[1] + 23) * x
+ || out[1] != (in[2] + 142) * y
+ || out[2] != (in[3] + 2) * x
+ || out[3] != (in[4] + 31) * y)
+ abort();
+
+ return 0;
+}
+
+int main (void)
+{
+ check_vect ();
+
+ main1 (2, 3);
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 0 "slp" } } */
+/* { dg-final { scan-tree-dump-times "unsupported alignment in basic block." 1 "slp" } } */
+/* { dg-final { cleanup-tree-dump "slp" } } */
+
diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/i386/costmodel-vect-31.c b/gcc/testsuite/gcc.dg/vect/costmodel/i386/costmodel-vect-31.c
index c61517aab42..da7b7c3b3f8 100644
--- a/gcc/testsuite/gcc.dg/vect/costmodel/i386/costmodel-vect-31.c
+++ b/gcc/testsuite/gcc.dg/vect/costmodel/i386/costmodel-vect-31.c
@@ -86,7 +86,8 @@ int main (void)
return main1 ();
}
-/* { dg-final { scan-tree-dump-times "vectorization not profitable" 1 "vect" } }
+/* { dg-final { scan-tree-dump-times "vectorization not profitable" 1 "vect" { xfail vect_hw_misalign } } }
*/
-/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" } } */
+/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" { xfail vect_hw_misalign } } } */
+/* { dg-final { scan-tree-dump-times "vectorized 4 loops" 1 "vect" { target vect_hw_misalign } } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/i386/costmodel-vect-33.c b/gcc/testsuite/gcc.dg/vect/costmodel/i386/costmodel-vect-33.c
index feaf5859130..8a14ededc25 100644
--- a/gcc/testsuite/gcc.dg/vect/costmodel/i386/costmodel-vect-33.c
+++ b/gcc/testsuite/gcc.dg/vect/costmodel/i386/costmodel-vect-33.c
@@ -11,6 +11,7 @@ struct test {
extern struct test s;
+__attribute__ ((noinline))
int main1 ()
{
int i;
@@ -35,5 +36,5 @@ int main (void)
return main1 ();
}
-/* { dg-final { scan-tree-dump-times "vectorization not profitable" 1 "vect" } } */
+/* { dg-final { scan-tree-dump-times "vectorization not profitable" 1 "vect" { xfail vect_hw_misalign } } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-vect-31.c b/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-vect-31.c
index c61517aab42..4490cdc2182 100644
--- a/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-vect-31.c
+++ b/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-vect-31.c
@@ -86,7 +86,7 @@ int main (void)
return main1 ();
}
-/* { dg-final { scan-tree-dump-times "vectorization not profitable" 1 "vect" } }
- */
-/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" } } */
+/* { dg-final { scan-tree-dump-times "vectorization not profitable" 1 "vect" { xfail vect_hw_misalign } } } */
+/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" { target {! vect_hw_misalign} } } } */
+/* { dg-final { scan-tree-dump-times "vectorized 4 loops" 1 "vect" { target {vect_hw_misalign } } } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-vect-33.c b/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-vect-33.c
index feaf5859130..8a14ededc25 100644
--- a/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-vect-33.c
+++ b/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-vect-33.c
@@ -11,6 +11,7 @@ struct test {
extern struct test s;
+__attribute__ ((noinline))
int main1 ()
{
int i;
@@ -35,5 +36,5 @@ int main (void)
return main1 ();
}
-/* { dg-final { scan-tree-dump-times "vectorization not profitable" 1 "vect" } } */
+/* { dg-final { scan-tree-dump-times "vectorization not profitable" 1 "vect" { xfail vect_hw_misalign } } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-8.c b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-8.c
index 629cb94971f..ea67946e505 100644
--- a/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-8.c
+++ b/gcc/testsuite/gcc.dg/vect/no-scevccp-outer-8.c
@@ -46,5 +46,5 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED." 1 "vect" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED." 1 "vect" { xfail { ! { vect_hw_misalign } } } } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-31.c b/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-31.c
index 21b87a39677..6060a418a3d 100644
--- a/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-31.c
+++ b/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-31.c
@@ -87,6 +87,7 @@ int main (void)
}
/* { dg-final { scan-tree-dump-times "vectorized 4 loops" 1 "vect" } } */
-/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" } } */
-/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 2 "vect" } } */
+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" { xfail vect_hw_misalign } } } */
+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { target vect_hw_misalign } } } */
+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 2 "vect" { xfail vect_hw_misalign } } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-64.c b/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-64.c
index 1ce3fa7f23b..2b6f99787c1 100644
--- a/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-64.c
+++ b/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-64.c
@@ -83,6 +83,7 @@ int main (void)
}
/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" } } */
-/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" } } */
-/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 2 "vect" } } */
+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" { xfail vect_hw_misalign } } } */
+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { target vect_hw_misalign } } } */
+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 2 "vect" { xfail vect_hw_misalign } } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-66.c b/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-66.c
index 49a9098f79f..78419fae851 100644
--- a/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-66.c
+++ b/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-66.c
@@ -78,6 +78,7 @@ int main (void)
}
/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" } } */
-/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" } } */
-/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" } } */
+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" { xfail vect_hw_misalign } } } */
+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { target vect_hw_misalign } } } */
+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail vect_hw_misalign } } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-68.c b/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-68.c
index de036e88ebf..19bd4f12d05 100644
--- a/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-68.c
+++ b/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-68.c
@@ -87,6 +87,7 @@ int main (void)
}
/* { dg-final { scan-tree-dump-times "vectorized 4 loops" 1 "vect" } } */
-/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" } } */
-/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 2 "vect" } } */
+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" { xfail vect_hw_misalign } } } */
+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { target vect_hw_misalign } } } */
+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 2 "vect" { xfail vect_hw_misalign } } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-69.c b/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-69.c
index c63ae2fd21b..5f0aeaa9df1 100644
--- a/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-69.c
+++ b/gcc/testsuite/gcc.dg/vect/no-section-anchors-vect-69.c
@@ -113,8 +113,9 @@ int main (void)
}
/* { dg-final { scan-tree-dump-times "vectorized 4 loops" 1 "vect" } } */
-/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" } } */
-/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 2 "vect" { xfail {! vector_alignment_reachable} } } } */
-/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 1 "vect" { target {! vector_alignment_reachable} } } } */
-/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { target {! vector_alignment_reachable} } } } */
+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" { xfail vect_hw_misalign } } } */
+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { target vect_hw_misalign } } } */
+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 2 "vect" { xfail { {! vector_alignment_reachable} || vect_hw_misalign } } } } */
+/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 1 "vect" { target { {! vector_alignment_reachable} && {! vect_hw_misalign} } } } } */
+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { target { {! vector_alignment_reachable} && {! vect_hw_misalign} } } } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/no-tree-reassoc-bb-slp-12.c b/gcc/testsuite/gcc.dg/vect/no-tree-reassoc-bb-slp-12.c
new file mode 100644
index 00000000000..d0b2ed4fff7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/no-tree-reassoc-bb-slp-12.c
@@ -0,0 +1,53 @@
+/* { dg-require-effective-target vect_int } */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include "tree-vect.h"
+
+#define N 16
+
+unsigned int out[N];
+unsigned int in1[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
+unsigned int in2[N] = {10,11,12,13,14,15,16,17,18,19,110,111,112,113,114,115};
+
+__attribute__ ((noinline)) int
+main1 (unsigned int x, unsigned int y)
+{
+ int i;
+ unsigned int *pin1 = &in1[0];
+ unsigned int *pin2 = &in2[0];
+ unsigned int *pout = &out[0];
+ unsigned int a0, a1, a2, a3;
+
+ a0 = *pin2++ - *pin1++ + 23;
+ a1 = *pin2++ - *pin1++ + 142;
+ a2 = *pin2++ - *pin1++ + 2;
+ a3 = *pin2++ - *pin1++ + 31;
+
+ *pout++ = a0 * x;
+ *pout++ = a1 * y;
+ *pout++ = a2 * x;
+ *pout++ = a3 * y;
+
+ /* Check results. */
+ if (out[0] != (in2[0] - in1[0] + 23) * x
+ || out[1] != (in2[1] - in1[1] + 142) * y
+ || out[2] != (in2[2] - in1[2] + 2) * x
+ || out[3] != (in2[3] - in1[3] + 31) * y)
+ abort();
+
+ return 0;
+}
+
+int main (void)
+{
+ check_vect ();
+
+ main1 (2, 3);
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target vect_int_mult } } } */
+/* { dg-final { cleanup-tree-dump "slp" } } */
+
diff --git a/gcc/testsuite/gcc.dg/vect/no-vfa-vect-43.c b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-43.c
index 13fbc82a42f..16a01d1a320 100644
--- a/gcc/testsuite/gcc.dg/vect/no-vfa-vect-43.c
+++ b/gcc/testsuite/gcc.dg/vect/no-vfa-vect-43.c
@@ -22,41 +22,53 @@ void bar (float *pa, float *pb, float *pc)
__attribute__ ((noinline)) int
-main1 (float *pa)
+main1 (float *pa, float *pb, float *pc)
{
int i;
- float pb[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
- float pc[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
+ float b[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__)));
+ float c[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__)));
+
+ for (i = 0; i < N; i++)
+ {
+ b[i] = pb[i];
+ c[i] = pc[i];
+ }
/* Vectorizable: pa may not alias pb and/or pc, even though their
addresses escape. &pa would need to escape to point to escaped memory. */
for (i = 0; i < N; i++)
{
- pa[i] = pb[i] * pc[i];
+ pa[i] = b[i] * c[i];
}
- bar (pa,pb,pc);
+ bar (pa,b,c);
return 0;
}
__attribute__ ((noinline)) int
-main2 (float * pa)
+main2 (float *pa, float *pb, float *pc)
{
int i;
- float pb[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
- float pc[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
+ float b[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__)));
+ float c[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__)));
+
+ for (i = 0; i < N; i++)
+ {
+ b[i] = pb[i];
+ c[i] = pc[i];
+ }
/* Vectorizable: pb and pc addresses do not escape. */
for (i = 0; i < N; i++)
{
- pa[i] = pb[i] * pc[i];
+ pa[i] = b[i] * c[i];
}
/* check results: */
for (i = 0; i < N; i++)
{
- if (pa[i] != (pb[i] * pc[i]))
+ if (pa[i] != (b[i] * c[i]))
abort ();
}
@@ -67,14 +79,16 @@ int main (void)
{
int i;
float a[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__)));
+ float b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
+ float c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
check_vect ();
- main1 (a);
- main2 (a);
+ main1 (a,b,c);
+ main2 (a,b,c);
return 0;
}
-/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" } } */
-/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 2 "vect" { target vect_no_align } } } */
+/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 2 "vect" } } */
+/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 6 "vect" { target vect_no_align } } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/pr18400.c b/gcc/testsuite/gcc.dg/vect/pr18400.c
index 6bc3b5c831b..50971046f62 100644
--- a/gcc/testsuite/gcc.dg/vect/pr18400.c
+++ b/gcc/testsuite/gcc.dg/vect/pr18400.c
@@ -8,6 +8,7 @@
int b[N] = {0,3,6,9,12,15,18,21};
int a[N];
+__attribute__ ((noinline))
int main1 ()
{
int i;
diff --git a/gcc/testsuite/gcc.dg/vect/pr25413.c b/gcc/testsuite/gcc.dg/vect/pr25413.c
index 1cb33e3b9dc..e483732680f 100644
--- a/gcc/testsuite/gcc.dg/vect/pr25413.c
+++ b/gcc/testsuite/gcc.dg/vect/pr25413.c
@@ -33,7 +33,7 @@ int main (void)
}
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vector_alignment_reachable_for_64bit } } } */
-/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" { target { ! vector_alignment_reachable_for_64bit } } } } */
-/* { dg-final { scan-tree-dump-times "vector alignment may not be reachable" 1 "vect" { target { ! vector_alignment_reachable_for_64bit } } } } */
-/* { dg-final { scan-tree-dump-times "not vectorized: unsupported unaligned store" 1 "vect" { target { ! vector_alignment_reachable_for_64bit } } } } */
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" { target { {! vector_alignment_reachable_for_64bit} && {! vect_hw_misalign} } } } } */
+/* { dg-final { scan-tree-dump-times "vector alignment may not be reachable" 1 "vect" { target { {! vector_alignment_reachable_for_64bit} && {! vect_hw_misalign} } } } } */
+/* { dg-final { scan-tree-dump-times "not vectorized: unsupported unaligned store" 1 "vect" { target { {! vector_alignment_reachable_for_64bit} && {! vect_hw_misalign} } } } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/pr31699.c b/gcc/testsuite/gcc.dg/vect/pr31699.c
index cbc596d467f..4f9cf581b58 100644
--- a/gcc/testsuite/gcc.dg/vect/pr31699.c
+++ b/gcc/testsuite/gcc.dg/vect/pr31699.c
@@ -6,6 +6,7 @@
float x[256];
+__attribute__ ((noinline))
void foo(void)
{
double *z = malloc (sizeof(double) * 256);
diff --git a/gcc/testsuite/gcc.dg/vect/pr40238.c b/gcc/testsuite/gcc.dg/vect/pr40238.c
new file mode 100644
index 00000000000..91cf0982439
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr40238.c
@@ -0,0 +1,35 @@
+/* { dg-do compile } */
+
+extern int xdo_rb_ctr_row( int *pos_code);
+
+int xgp_ahd_interpolate (int tile)
+{
+ int p[4];
+
+ switch (tile) {
+ default:
+ case 0:
+ case 1:
+ p[0] = 0; p[1] = 1; p[2] = 2; p[3] = 3;
+ break;
+ case 2:
+ case 3:
+ p[0] = 1; p[1] = 0; p[2] = 3; p[3] = 2;
+ break;
+ case 4:
+ case 5:
+ p[0] = 3; p[1] = 2; p[2] = 1; p[3] = 0;
+ break;
+ case 6:
+ case 7:
+ p[0] = 2; p[1] = 3; p[2] = 0; p[3] = 1;
+ break;
+ }
+
+ xdo_rb_ctr_row(p);
+ xdo_rb_ctr_row(p);
+ return 0;
+}
+
+/* { dg-final { cleanup-tree-dump "vect" } } */
+
diff --git a/gcc/testsuite/gcc.dg/vect/pr40254.c b/gcc/testsuite/gcc.dg/vect/pr40254.c
new file mode 100644
index 00000000000..b890a449312
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr40254.c
@@ -0,0 +1,39 @@
+#include <stdlib.h>
+#include <stdarg.h>
+#include "tree-vect.h"
+
+struct s
+{
+ int *x;
+ int x1;
+ int x2;
+ int x3;
+ int *y;
+};
+
+struct s arr[64] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__)));
+
+__attribute__ ((noinline)) void
+foo (int i, int *in_x, int *in_y)
+{
+ arr[i].x = in_x;
+ arr[i].y = in_y;
+}
+
+int
+main (void)
+{
+ int a, b;
+
+ check_vect ();
+
+ foo (5, &a, &b);
+
+ if (arr[5].x != &a || arr[5].y != &b)
+ abort ();
+
+ return 0;
+}
+
+/* { dg-final { cleanup-tree-dump "vect" } } */
+
diff --git a/gcc/testsuite/gcc.dg/vect/slp-25.c b/gcc/testsuite/gcc.dg/vect/slp-25.c
index 23022fd2b06..d10720e7d84 100644
--- a/gcc/testsuite/gcc.dg/vect/slp-25.c
+++ b/gcc/testsuite/gcc.dg/vect/slp-25.c
@@ -55,6 +55,7 @@ int main (void)
}
/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" } } */
-/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" } } */
-/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 2 "vect" { xfail vect_no_align } } } */
+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" { xfail vect_hw_misalign } } } */
+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { target vect_hw_misalign } } } */
+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 2 "vect" { xfail { vect_no_align || vect_hw_misalign } } } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/slp-3.c b/gcc/testsuite/gcc.dg/vect/slp-3.c
index 1bb9884a644..070715371bb 100644
--- a/gcc/testsuite/gcc.dg/vect/slp-3.c
+++ b/gcc/testsuite/gcc.dg/vect/slp-3.c
@@ -142,8 +142,7 @@ int main (void)
return 0;
}
-/* One of the loops gets complettely unrolled. */
-/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" { xfail vect_no_align } } } */
-/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" { xfail vect_no_align } } } */
+/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" { xfail vect_no_align } } } */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 3 "vect" { xfail vect_no_align } } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-109.c b/gcc/testsuite/gcc.dg/vect/vect-109.c
index d4e017f1f16..173b8c06970 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-109.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-109.c
@@ -73,6 +73,7 @@ int main (void)
}
/* { dg-final { scan-tree-dump-times "vectorized 0 loops" 2 "vect" } } */
-/* { dg-final { scan-tree-dump-times "not vectorized: unsupported unaligned store" 2 "vect" } } */
+/* { dg-final { scan-tree-dump-times "not vectorized: unsupported unaligned store" 2 "vect" { xfail vect_hw_misalign } } } */
+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 3 "vect" { target vect_hw_misalign } } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-26.c b/gcc/testsuite/gcc.dg/vect/vect-26.c
index 3cb9fb674be..268ed05061f 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-26.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-26.c
@@ -36,6 +36,6 @@ int main (void)
}
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
-/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" } } */
-/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" } } */
+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail {! vect_hw_misalign} } } } */
+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail vect_hw_misalign } } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-28.c b/gcc/testsuite/gcc.dg/vect/vect-28.c
index e698eef93a4..ddf1ee3b0ed 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-28.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-28.c
@@ -39,7 +39,7 @@ int main (void)
}
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
-/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" } } */
-/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { target vector_alignment_reachable } } } */
-/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 1 "vect" { target { ! vector_alignment_reachable } } } } */
+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail { ! { vect_hw_misalign } } } } } */
+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { target { vector_alignment_reachable && { ! { vect_hw_misalign } } } } } } */
+/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 1 "vect" { target { {! vector_alignment_reachable} && {! vect_hw_misalign} } } } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-33.c b/gcc/testsuite/gcc.dg/vect/vect-33.c
index c1e89c44cb8..9ee4aecb2ea 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-33.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-33.c
@@ -38,7 +38,7 @@ int main (void)
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
-/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" } } */
-/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { target vector_alignment_reachable } } } */
-/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 1 "vect" { target { ! vector_alignment_reachable } } } } */
+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail { ! { vect_hw_misalign } } } } } */
+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { target { vector_alignment_reachable && {! vect_hw_misalign} } } } } */
+/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 1 "vect" { target { {! vector_alignment_reachable} && {! vect_hw_misalign} } } } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-40.c b/gcc/testsuite/gcc.dg/vect/vect-40.c
index a73d1551643..d2c17d1d97d 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-40.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-40.c
@@ -26,13 +26,16 @@ void bar (float *pa, float *pb, float *pc)
vect-46.c is similar to this one with one difference:
the loop bound is unknown. */
+float b[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__)))
+ = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
+float c[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__)))
+ = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
+
__attribute__ ((noinline)) int
main1 ()
{
int i;
float a[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__)));
- float b[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
- float c[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
float *pa = a;
float *pb = b;
float *pc = c;
diff --git a/gcc/testsuite/gcc.dg/vect/vect-42.c b/gcc/testsuite/gcc.dg/vect/vect-42.c
index f1764e13ecf..482a333d1ef 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-42.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-42.c
@@ -27,15 +27,22 @@ void bar (float *pa, float *pb, float *pc)
No aliasing problems. */
__attribute__ ((noinline)) int
-main1 (float * __restrict__ pa)
+main1 (float * __restrict__ pa, float *pb, float *pc)
{
+ float b[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__)));
+ float c[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__)));
int i;
- float pb[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
- float pc[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
+ /* We also vectorize this loop. */
for (i = 0; i < N; i++)
{
- pa[i] = pb[i] * pc[i];
+ b[i] = pb[i];
+ c[i] = pc[i];
+ }
+
+ for (i = 0; i < N; i++)
+ {
+ pa[i] = b[i] * c[i];
}
return 0;
@@ -45,18 +52,18 @@ int main (void)
{
int i;
float a[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__)));
- float b[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
- float c[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
+ float b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
+ float c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
check_vect ();
- main1 (a);
+ main1 (a,b,c);
bar (a,b,c);
return 0;
}
-/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
-/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 1 "vect" { target { vect_no_align || { ! vector_alignment_reachable } } } } } */
-/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail { vect_no_align || { ! vector_alignment_reachable } } } } } */
-/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail {vect_no_align || { ! vector_alignment_reachable } } } } } */
+/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" } } */
+/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 3 "vect" { target { vect_no_align || { { ! vector_alignment_reachable} && {!vect_hw_misalign} } } } } } */
+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 4 "vect" { xfail { { vect_no_align || vect_hw_misalign } || { ! vector_alignment_reachable } } } } } */
+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail { { vect_no_align || vect_hw_misalign } || { ! vector_alignment_reachable } } } } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-44.c b/gcc/testsuite/gcc.dg/vect/vect-44.c
index 81c6c1b8e87..89d09b36535 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-44.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-44.c
@@ -65,8 +65,9 @@ int main (void)
two loads to be aligned). */
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
-/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail vect_no_align } } } */
-/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail { vect_no_align || {! vector_alignment_reachable} } } } } */
+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 3 "vect" { xfail { ! {vect_hw_misalign } } } } } */
+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail { vect_no_align || vect_hw_misalign } } } } */
+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail { { vect_no_align || vect_hw_misalign } || {! vector_alignment_reachable} } } } } */
/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 3 "vect" { target vect_no_align } } } */
-/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 1 "vect" { target { {! vector_alignment_reachable} && {! vect_no_align} } } } } */
+/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 1 "vect" { target { {! vector_alignment_reachable} && {{! vect_no_align} && {! vect_hw_misalign} } } } } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-46.c b/gcc/testsuite/gcc.dg/vect/vect-46.c
index 2588a7b291e..d506d4329c0 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-46.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-46.c
@@ -26,11 +26,16 @@ void bar (float *pa, float *pb, float *pc)
vect-40.c is similar to this one with one difference:
the loop bound is known. */
+float b[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__)))
+ = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
+float c[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__)))
+ = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
+
__attribute__ ((noinline)) int
main1 (int n)
{
int i;
- float a[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); float b[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57}; float c[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
+ float a[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__)));
float *pa = a;
float *pb = b;
float *pc = c;
diff --git a/gcc/testsuite/gcc.dg/vect/vect-50.c b/gcc/testsuite/gcc.dg/vect/vect-50.c
index ea4d7ff4795..f247679a989 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-50.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-50.c
@@ -56,13 +56,14 @@ int main (void)
return 0;
}
-/* For targets that don't support misaligned loads we version for the
- all three accesses (peeling to align the store will not force the
- two loads to be aligned). */
+/* For targets that don't support misaligned loads and don't support
+ misaligned stores we version for the all three accesses (peeling to
+ align the store will not force the two loads to be aligned). */
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
-/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail vect_no_align } } } */
-/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail { vect_no_align || {! vector_alignment_reachable} } } } } */
+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail { vect_no_align || vect_hw_misalign } } } } */
+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 3 "vect" { target vect_hw_misalign } } } */
+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail { { vect_no_align || vect_hw_misalign } || {! vector_alignment_reachable} } } } } */
/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 3 "vect" { target vect_no_align } } } */
-/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 1 "vect" { target { {! vector_alignment_reachable} && {! vect_no_align} } } } } */
+/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 1 "vect" { target { {! vector_alignment_reachable} && {!vect_no_align && !vect_hw_misalign} } } } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-54.c b/gcc/testsuite/gcc.dg/vect/vect-54.c
index 629e82df59b..85387fa6a34 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-54.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-54.c
@@ -59,6 +59,7 @@ int main (void)
}
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
-/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" } } */
-/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" } } */
+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 3 "vect" { target vect_hw_misalign } } } */
+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" { xfail vect_hw_misalign } } } */
+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail vect_hw_misalign } } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-58.c b/gcc/testsuite/gcc.dg/vect/vect-58.c
index fa8c91b3071..5ceb15627fc 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-58.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-58.c
@@ -58,6 +58,7 @@ int main (void)
}
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
-/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" } } */
-/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" } } */
+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 3 "vect" { target vect_hw_misalign } } } */
+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" { xfail vect_hw_misalign } } } */
+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail vect_hw_misalign } } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-70.c b/gcc/testsuite/gcc.dg/vect/vect-70.c
index 23b1902e54f..bf206874ecd 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-70.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-70.c
@@ -63,7 +63,8 @@ int main (void)
}
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
-/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" } } */
-/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" {target vector_alignment_reachable } } } */
-/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 1 "vect" {target {! vector_alignment_reachable} } } } */
+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" { xfail vect_hw_misalign } } } */
+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { target vect_hw_misalign } } } */
+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" {target { vector_alignment_reachable && { ! {vect_hw_misalign} } } } } } */
+/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 1 "vect" {target {{! vector_alignment_reachable} && {! vect_hw_misalign} } } } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-76.c b/gcc/testsuite/gcc.dg/vect/vect-76.c
index 7097e7a821e..d7713024224 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-76.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-76.c
@@ -11,13 +11,13 @@
more involved than just an ssa_name. */
int ib[N+OFF] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) = {0, 1, 3, 5, 7, 11, 13, 17, 0, 2, 6, 10};
+int ic[N+OFF] = {0, 1, 3, 5, 7, 11, 13, 17, 0, 2, 6, 10};
__attribute__ ((noinline))
int main1 (int *pib)
{
int i;
int ia[N+OFF];
- int ic[N+OFF] = {0, 1, 3, 5, 7, 11, 13, 17, 0, 2, 6, 10};
for (i = OFF; i < N; i++)
{
diff --git a/gcc/testsuite/gcc.dg/vect/vect-87.c b/gcc/testsuite/gcc.dg/vect/vect-87.c
index 151091a065b..e7c5bbc7159 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-87.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-87.c
@@ -50,7 +50,8 @@ int main (void)
/* Fails for targets that don't vectorize PLUS (e.g alpha). */
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
-/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" } } */
-/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" {target vector_alignment_reachable } } } */
-/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 1 "vect" {target {! vector_alignment_reachable} } } } */
+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { target vect_hw_misalign } } } */
+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" { xfail vect_hw_misalign } } } */
+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" {target { vector_alignment_reachable && {! vect_hw_misalign} } } } } */
+/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 1 "vect" {target { {! vector_alignment_reachable} && {! vect_hw_misalign} } } } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-88.c b/gcc/testsuite/gcc.dg/vect/vect-88.c
index a1666334916..3dc5588e92d 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-88.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-88.c
@@ -50,7 +50,8 @@ int main (void)
/* Fails for targets that don't vectorize PLUS (e.g alpha). */
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
-/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" } } */
-/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" {target vector_alignment_reachable } } } */
-/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 1 "vect" {target {! vector_alignment_reachable} } } } */
+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { target vect_hw_misalign } } } */
+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" { xfail vect_hw_misalign } } } */
+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" {target { vector_alignment_reachable && {! vect_hw_misalign} } } } } */
+/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 1 "vect" {target { {! vector_alignment_reachable} && {! vect_hw_misalign} } } } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-89.c b/gcc/testsuite/gcc.dg/vect/vect-89.c
index 131efeab53a..4a6e7ae47f7 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-89.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-89.c
@@ -45,6 +45,7 @@ int main (void)
}
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
-/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" } } */
-/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" } } */
+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { target vect_hw_misalign } } } */
+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" { xfail vect_hw_misalign } } } */
+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail vect_hw_misalign } } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-91.c b/gcc/testsuite/gcc.dg/vect/vect-91.c
index 75073632458..c5aee4403f2 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-91.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-91.c
@@ -58,7 +58,8 @@ main3 ()
}
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 3 "vect" { xfail vect_no_int_add } } } */
+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 6 "vect" { target vect_hw_misalign } } } */
/* { dg-final { scan-tree-dump-times "accesses have the same alignment." 3 "vect" } } */
-/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 3 "vect" {target vector_alignment_reachable } } } */
-/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 3 "vect" {target {! vector_alignment_reachable} } } } */
+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 3 "vect" {target { vector_alignment_reachable && {! vect_hw_misalign} } } } } */
+/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 3 "vect" {target { {! vector_alignment_reachable} && {! vect_hw_misalign} } } } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-92.c b/gcc/testsuite/gcc.dg/vect/vect-92.c
index 3a64e251cb2..62aa97540f2 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-92.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-92.c
@@ -91,6 +91,7 @@ int main (void)
}
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 3 "vect" } } */
-/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" } } */
-/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 3 "vect" } } */
+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 9 "vect" { target vect_hw_misalign } } } */
+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" { xfail vect_hw_misalign } } } */
+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 3 "vect" { xfail vect_hw_misalign } } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-93.c b/gcc/testsuite/gcc.dg/vect/vect-93.c
index 351ab04fe84..4c41e60df0a 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-93.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-93.c
@@ -71,8 +71,9 @@ int main (void)
/* main && main1 together: */
/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 2 "vect" { target powerpc*-*-* i?86-*-* x86_64-*-* } } } */
+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 3 "vect" { target vect_hw_misalign } } } */
/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 2 "vect" { target { vect_no_align && {! vector_alignment_reachable} } } } } */
-/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 3 "vect" { xfail { vect_no_align || {! vector_alignment_reachable} } } } } */
+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 3 "vect" { xfail { { vect_no_align || vect_hw_misalign } || {! vector_alignment_reachable} } } } } */
/* in main1: */
/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" { target !powerpc*-*-* !i?86-*-* !x86_64-*-* } } } */
@@ -80,6 +81,6 @@ int main (void)
/* in main: */
/* { dg-final { scan-tree-dump-times "vectorized 0 loops" 1 "vect" { target vect_no_align } } } */
-/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail vect_no_align } } } */
+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail { vect_no_align || vect_hw_misalign } } } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-95.c b/gcc/testsuite/gcc.dg/vect/vect-95.c
index ea9f32b994a..9f1a2c4b256 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-95.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-95.c
@@ -62,8 +62,9 @@ int main (void)
stores and generate misaligned accesses for the loads. For targets that
don't support unaligned loads we version for all four accesses. */
-/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail vect_no_align } } } */
-/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 2 "vect" { xfail vect_no_align } } } */
+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail { vect_no_align || vect_hw_misalign } } } } */
+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 4 "vect" { target vect_hw_misalign } } } */
+/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 2 "vect" { xfail { vect_no_align || vect_hw_misalign } } } } */
/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" { target vect_no_align } } } */
/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 4 "vect" { target vect_no_align } } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-96.c b/gcc/testsuite/gcc.dg/vect/vect-96.c
index d92b28d5e32..1a6feca71cf 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-96.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-96.c
@@ -44,6 +44,6 @@ int main (void)
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { target { {! vect_no_align} && vector_alignment_reachable } } } } */
-/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail { vect_no_align || {! vector_alignment_reachable} } } } } */
-/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 1 "vect" { target { vect_no_align || {! vector_alignment_reachable} } } } } */
+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail { { vect_no_align || vect_hw_misalign } || {! vector_alignment_reachable} } } } } */
+/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 1 "vect" { target { vect_no_align || { {! vector_alignment_reachable} && {!vect_hw_misalign} } } } } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-align-1.c b/gcc/testsuite/gcc.dg/vect/vect-align-1.c
index f6bf22da93e..099b7fea443 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-align-1.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-align-1.c
@@ -46,6 +46,7 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 1 "vect" } } */
+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { target vect_hw_misalign } } } */
+/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 1 "vect" { xfail vect_hw_misalign} } } */
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-align-2.c b/gcc/testsuite/gcc.dg/vect/vect-align-2.c
index ec2f3eefbb7..08a80112d73 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-align-2.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-align-2.c
@@ -43,6 +43,6 @@ int main (void)
/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 0 "vect" } } */
-/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 1 "vect" } } */
+/* { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 1 "vect" { xfail vect_hw_misalign} } } */
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-iv-10.c b/gcc/testsuite/gcc.dg/vect/vect-iv-10.c
index e4242009b41..7ec487253ac 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-iv-10.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-iv-10.c
@@ -5,6 +5,7 @@
#define N 16
+__attribute__ ((noinline))
int main1 ()
{
int i,j;
diff --git a/gcc/testsuite/gcc.dg/vect/vect-multitypes-1.c b/gcc/testsuite/gcc.dg/vect/vect-multitypes-1.c
index 2ebececc847..1a0375266b0 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-multitypes-1.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-multitypes-1.c
@@ -78,11 +78,11 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" { xfail *-*-* } } } */
-/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail vect_no_align } } } */
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" { xfail {! vect_hw_misalign} } } } */
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail { vect_no_align || vect_hw_misalign } } } } */
/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 2 "vect" { xfail *-*-* } } } */
-/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail vect_no_align } } } */
-/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 4 "vect" { xfail *-*-* } } } */
-/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail vect_no_align } } } */
+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail { vect_no_align || vect_hw_misalign }} } } */
+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 4 "vect" { xfail {! vect_hw_misalign} } } } */
+/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail { vect_no_align || vect_hw_misalign } } } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-multitypes-4.c b/gcc/testsuite/gcc.dg/vect/vect-multitypes-4.c
index 7ac33672353..f1d62f7cd0e 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-multitypes-4.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-multitypes-4.c
@@ -85,10 +85,10 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" { xfail *-*-* } } } */
-/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail vect_no_align } } } */
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" { xfail {! vect_hw_misalign} } } } */
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail { vect_no_align || vect_hw_misalign } } } } */
/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 2 "vect" { xfail *-*-* } } } */
-/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail vect_no_align } } } */
+/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail { vect_no_align || vect_hw_misalign } } } } */
/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 8 "vect" { xfail *-*-* } } } */
/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 4 "vect" { xfail vect_no_align } } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-nest-cycle-1.c b/gcc/testsuite/gcc.dg/vect/vect-nest-cycle-1.c
new file mode 100644
index 00000000000..0cf2ca06d14
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-nest-cycle-1.c
@@ -0,0 +1,48 @@
+/* { dg-require-effective-target vect_float } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 16
+
+float in[N] = {232,132,32,432,532,321,327,323,321,324,322,329,432,832,932,232};
+float out[N];
+float check_res[N] = {112,-4,-120,264,348,121,111,91,73,60,42,33,120,504,588,-128};
+float a[2*N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31};
+
+/* Outer-loop vectorization. */
+
+__attribute__ ((noinline)) void
+foo ()
+{
+ int i, j;
+ float res;
+
+ for (i = 0; i < N; i++)
+ {
+ res = in[i];
+
+ for (j = 0; j < N; j++)
+ res = res - a[i+j];
+
+ out[i] = res;
+ }
+
+ for (i = 0; i < N; i++)
+ if (out[i] != check_res[i])
+ abort ();
+
+}
+
+int main ()
+{
+ check_vect ();
+
+ foo();
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
+
diff --git a/gcc/testsuite/gcc.dg/vect/vect-nest-cycle-2.c b/gcc/testsuite/gcc.dg/vect/vect-nest-cycle-2.c
new file mode 100644
index 00000000000..fd63a785d00
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-nest-cycle-2.c
@@ -0,0 +1,48 @@
+/* { dg-require-effective-target vect_float } */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include "tree-vect.h"
+
+#define N 16
+
+float out[N];
+float check_res[N] = {880,864,848,832,816,800,784,768,752,736,720,704,688,672,656,640};
+float a[2*N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31};
+
+/* Outer-loop vectorization. */
+
+__attribute__ ((noinline)) void
+foo ()
+{
+ int i, j;
+ float res;
+
+ for (i = 0; i < N; i++)
+ {
+ res = 1000;
+
+ for (j = 0; j < N; j++)
+ res = res - a[i+j];
+
+ out[i] = res;
+ }
+
+ for (i = 0; i < N; i++)
+ if (out[i] != check_res[i])
+ abort ();
+
+}
+
+int main ()
+{
+ check_vect ();
+
+ foo();
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
+
diff --git a/gcc/testsuite/gcc.dg/vect/vect-nest-cycle-3.c b/gcc/testsuite/gcc.dg/vect/vect-nest-cycle-3.c
new file mode 100644
index 00000000000..70fa6b84d98
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-nest-cycle-3.c
@@ -0,0 +1,57 @@
+/* { dg-require-effective-target vect_float } */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include "tree-vect.h"
+
+#define N 16
+#define DIFF 82
+
+float c[N][N], b[N][N], a[N];
+
+__attribute__ ((noinline)) int
+main1 ()
+{
+ int i, j;
+ float diff;
+
+ /* In inner loop vectorization -funsafe-math-optimizations is needed to
+ vectorize the summation. But in outer loop vectorization the order of
+ calculation doesn't change, therefore, there is no need in that flag. */
+ for (i = 0; i < N; i++)
+ {
+ diff = 2;
+ for (j = 0; j < N; j++)
+ diff += (b[j][i] - c[j][i]);
+
+ a[i] = diff;
+ }
+
+ /* Check results: */
+ for (i = 0; i < N; i++)
+ if (a[i] != DIFF)
+ abort ();
+
+ return 0;
+}
+
+int main (void)
+{
+ int i, j;
+
+ for (i = 0; i < N; i++)
+ for (j = 0; j < N; j++)
+ {
+ b[i][j] = i+j+5;
+ c[i][j] = i+j;
+ }
+
+ check_vect ();
+
+ main1 ();
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" } } */
+/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-outer-1a.c b/gcc/testsuite/gcc.dg/vect/vect-outer-1a.c
index 3d237b78e72..f88dd21059b 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-outer-1a.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-outer-1a.c
@@ -4,9 +4,7 @@
signed short image[N][N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__)));
signed short block[N][N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__)));
-/* Can't do outer-loop vectorization because of non-consecutive access.
- Currently fails to vectorize because the reduction pattern is not
- recognized. */
+/* Can't do outer-loop vectorization because of non-consecutive access. */
int
foo (){
@@ -22,7 +20,5 @@ foo (){
}
/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" { xfail *-*-* } } } */
-/* FORNOW */
-/* { dg-final { scan-tree-dump-times "strided access in outer loop" 1 "vect" { xfail *-*-* } } } */
-/* { dg-final { scan-tree-dump-times "unexpected pattern" 1 "vect" } } */
+/* { dg-final { scan-tree-dump-times "strided access in outer loop" 1 "vect" } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-outer-4f.c b/gcc/testsuite/gcc.dg/vect/vect-outer-4f.c
index 88d6b7abccd..c6cc4a8d1a4 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-outer-4f.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-outer-4f.c
@@ -66,5 +66,4 @@ int main (void)
}
/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" { xfail *-*-* } } } */
-/* { dg-final { scan-tree-dump-times "vect_recog_widen_sum_pattern: not allowed" 1 "vect" } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-outer-4g.c b/gcc/testsuite/gcc.dg/vect/vect-outer-4g.c
index 88d6b7abccd..c6cc4a8d1a4 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-outer-4g.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-outer-4g.c
@@ -66,5 +66,4 @@ int main (void)
}
/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" { xfail *-*-* } } } */
-/* { dg-final { scan-tree-dump-times "vect_recog_widen_sum_pattern: not allowed" 1 "vect" } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-outer-4k.c b/gcc/testsuite/gcc.dg/vect/vect-outer-4k.c
index 88d6b7abccd..c6cc4a8d1a4 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-outer-4k.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-outer-4k.c
@@ -66,5 +66,4 @@ int main (void)
}
/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" { xfail *-*-* } } } */
-/* { dg-final { scan-tree-dump-times "vect_recog_widen_sum_pattern: not allowed" 1 "vect" } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-outer-4l.c b/gcc/testsuite/gcc.dg/vect/vect-outer-4l.c
index 88d6b7abccd..c6cc4a8d1a4 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-outer-4l.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-outer-4l.c
@@ -66,5 +66,4 @@ int main (void)
}
/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" { xfail *-*-* } } } */
-/* { dg-final { scan-tree-dump-times "vect_recog_widen_sum_pattern: not allowed" 1 "vect" } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect.exp b/gcc/testsuite/gcc.dg/vect/vect.exp
index d9c47f6c1c0..42435eb3130 100644
--- a/gcc/testsuite/gcc.dg/vect/vect.exp
+++ b/gcc/testsuite/gcc.dg/vect/vect.exp
@@ -122,6 +122,8 @@ dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/nodump-*.\[cS\]]] \
"" $DEFAULT_VECTCFLAGS
lappend DEFAULT_VECTCFLAGS "-fdump-tree-vect-details"
+set VECT_SLP_CFLAGS $DEFAULT_VECTCFLAGS
+lappend VECT_SLP_CFLAGS "-fdump-tree-slp-details"
# Main loop.
dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/pr*.\[cS\]]] \
@@ -130,10 +132,14 @@ dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/vect-*.\[cS\]]] \
"" $DEFAULT_VECTCFLAGS
dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/slp-*.\[cS\]]] \
"" $DEFAULT_VECTCFLAGS
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/bb-slp*.\[cS\]]] \
+ "" $VECT_SLP_CFLAGS
+
#### Tests with special options
global SAVED_DEFAULT_VECTCFLAGS
set SAVED_DEFAULT_VECTCFLAGS $DEFAULT_VECTCFLAGS
+set SAVED_VECT_SLP_CFLAGS $VECT_SLP_CFLAGS
# --param vect-max-version-for-alias-checks=0 tests
set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS
@@ -262,6 +268,11 @@ dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/O3-*.\[cS\]]] \
dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/O1-*.\[cS\]]] \
"" $O1_VECTCFLAGS
+# -fno-tree-reassoc
+set VECT_SLP_CFLAGS $SAVED_VECT_SLP_CFLAGS
+lappend VECT_SLP_CFLAGS "-fno-tree-reassoc"
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/no-tree-reassoc-bb-slp-*.\[cS\]]] \
+ "" $VECT_SLP_CFLAGS
# Clean up.
set dg-do-what-default ${save-dg-do-what-default}
diff --git a/gcc/testsuite/gcc.dg/vector-4.c b/gcc/testsuite/gcc.dg/vector-4.c
new file mode 100644
index 00000000000..7964a881f4a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vector-4.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+#define vector __attribute__((vector_size(4*sizeof(int)) ))
+
+vector int a, b, c;
+
+
+/* Test that remainder works for vectors. */
+void f(void)
+{
+ a = b % c;
+}
diff --git a/gcc/testsuite/gcc.dg/vla-8.c b/gcc/testsuite/gcc.dg/vla-8.c
index e4c6ae4157f..6e14a06875e 100644
--- a/gcc/testsuite/gcc.dg/vla-8.c
+++ b/gcc/testsuite/gcc.dg/vla-8.c
@@ -23,8 +23,12 @@ void foo1(int n) {
}
void foo2(int n) {
- goto A; /* { dg-error "jump into scope of identifier with variably modified type" } */
+ goto A; /* { dg-error "jump into scope of identifier with variably modified type" } */
int (*(*bar2)(void))[n];
A:
;
}
+
+/* Match extra informative notes. */
+/* { dg-message "note: label '\[^\n'\]*' defined here" "note: expected" { target *-*-* } 0 } */
+/* { dg-message "note: '\[^\n'\]*' declared here" "note: expected" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/gcc.target/arm/neon-modes-1.c b/gcc/testsuite/gcc.target/arm/neon-modes-1.c
new file mode 100644
index 00000000000..6ee13af0142
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/neon-modes-1.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_neon_ok } */
+/* { dg-options "-O1" } */
+/* { dg-add-options arm_neon } */
+
+#include <arm_neon.h>
+
+void neon_internal_error(int *dst, int *src)
+{
+ uint16x8x4_t sval;
+
+ sval = vld4q_u16((void *)src);
+ vst4q_u16((void *)dst,sval);
+}
diff --git a/gcc/testsuite/gcc.target/arm/neon-vmla-1.c b/gcc/testsuite/gcc.target/arm/neon-vmla-1.c
new file mode 100644
index 00000000000..3592ab979ac
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/neon-vmla-1.c
@@ -0,0 +1,10 @@
+/* { dg-require-effective-target arm_neon_hw } */
+/* { dg-options "-O2 -mfpu=neon -mfloat-abi=softfp -ftree-vectorize" } */
+/* { dg-final { scan-assembler "vmla\\.f32" } } */
+
+/* Verify that VMLA is used. */
+void f1(int n, float a, float x[], float y[]) {
+ int i;
+ for (i = 0; i < n; ++i)
+ y[i] = a * x[i] + y[i];
+}
diff --git a/gcc/testsuite/gcc.target/arm/neon-vmls-1.c b/gcc/testsuite/gcc.target/arm/neon-vmls-1.c
new file mode 100644
index 00000000000..1b3fcbbbbc9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/neon-vmls-1.c
@@ -0,0 +1,10 @@
+/* { dg-require-effective-target arm_neon_hw } */
+/* { dg-options "-O2 -mfpu=neon -mfloat-abi=softfp -ftree-vectorize" } */
+/* { dg-final { scan-assembler "vmls\\.f32" } } */
+
+/* Verify that VMLS is used. */
+void f1(int n, float a, float x[], float y[]) {
+ int i;
+ for (i = 0; i < n; ++i)
+ y[i] = y[i] - a * x[i];
+}
diff --git a/gcc/testsuite/gcc.target/arm/thumb2-mul-space-2.c b/gcc/testsuite/gcc.target/arm/thumb2-mul-space-2.c
new file mode 100644
index 00000000000..b53df2fa12a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/thumb2-mul-space-2.c
@@ -0,0 +1,15 @@
+/* In Thumb-2 mode, when optimizing for size, generate a "muls"
+ instruction and use the resulting condition flags rather than a
+ separate compare instruction. */
+/* { dg-options "-mthumb -Os" } */
+/* { dg-require-effective-target arm_thumb2_ok } */
+/* { dg-final { scan-assembler "muls" } } */
+/* { dg-final { scan-assembler-not "cmp" } } */
+
+int x;
+
+void f(int i, int j)
+{
+ if (i * j < 0)
+ x = 1;
+}
diff --git a/gcc/testsuite/gcc.target/arm/thumb2-mul-space-3.c b/gcc/testsuite/gcc.target/arm/thumb2-mul-space-3.c
new file mode 100644
index 00000000000..143a6deee79
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/thumb2-mul-space-3.c
@@ -0,0 +1,17 @@
+/* In Thumb-2 mode, when optimizing for size, generate a "muls"
+ instruction and use the resulting condition flags rather than a
+ separate compare instruction. */
+/* { dg-options "-mthumb -Os" } */
+/* { dg-require-effective-target arm_thumb2_ok } */
+/* { dg-final { scan-assembler "muls" } } */
+/* { dg-final { scan-assembler-not "cmp" } } */
+
+int x;
+
+int f(int i, int j)
+{
+ i = i * j;
+ if (i < 0)
+ x = 1;
+ return i;
+}
diff --git a/gcc/testsuite/gcc.target/arm/thumb2-mul-space.c b/gcc/testsuite/gcc.target/arm/thumb2-mul-space.c
new file mode 100644
index 00000000000..8cf0cb40f41
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/thumb2-mul-space.c
@@ -0,0 +1,10 @@
+/* Use 16-bit multiply instruction in Thumb-2 mode when optimizing for
+ size. */
+/* { dg-options "-mthumb -Os" } */
+/* { dg-require-effective-target arm_thumb2_ok } */
+/* { dg-final { scan-assembler "muls" } } */
+
+int f(int i, int j)
+{
+ return i * j;
+}
diff --git a/gcc/testsuite/gcc.target/arm/thumb2-mul-speed.c b/gcc/testsuite/gcc.target/arm/thumb2-mul-speed.c
new file mode 100644
index 00000000000..03cccdb654b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/thumb2-mul-speed.c
@@ -0,0 +1,27 @@
+/* Do not use 16-bit multiply instructions in Thumb-2 mode when
+ optimizing for speed. */
+/* { dg-options "-mthumb -O2" } */
+/* { dg-require-effective-target arm_thumb2_ok } */
+/* { dg-final { scan-assembler-not "muls" } } */
+
+int f(int i, int j)
+{
+ return i * j;
+}
+
+int x;
+
+void g(int i, int j)
+{
+ if (i * j < 0)
+ x = 1;
+}
+
+int h(int i, int j)
+{
+ i = i * j;
+ if (i < 0)
+ x = 1;
+ return i;
+}
+
diff --git a/gcc/testsuite/gcc.target/i386/align-main-1.c b/gcc/testsuite/gcc.target/i386/align-main-1.c
index 5bbc101c0c7..699c7f80c5c 100644
--- a/gcc/testsuite/gcc.target/i386/align-main-1.c
+++ b/gcc/testsuite/gcc.target/i386/align-main-1.c
@@ -11,6 +11,7 @@
typedef int aligned __attribute__((aligned(ALIGNMENT)));
extern void abort(void);
+__attribute__ ((noinline))
void check(void * a)
{
if (((ptrdiff_t)a & (ALIGNMENT-1)) != 0)
diff --git a/gcc/testsuite/gcc.target/i386/align-main-2.c b/gcc/testsuite/gcc.target/i386/align-main-2.c
index df45f0e5106..65c49e7f5dd 100644
--- a/gcc/testsuite/gcc.target/i386/align-main-2.c
+++ b/gcc/testsuite/gcc.target/i386/align-main-2.c
@@ -11,6 +11,7 @@
typedef int aligned __attribute__((aligned(ALIGNMENT)));
extern void abort(void);
+__attribute__ ((noinline))
void check(void * a)
{
if (((ptrdiff_t)a & (ALIGNMENT-1)) != 0)
diff --git a/gcc/testsuite/gcc.target/i386/crc32-1.c b/gcc/testsuite/gcc.target/i386/crc32-1.c
new file mode 100644
index 00000000000..b3ed5b6842a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/crc32-1.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mcrc32" } */
+/* { dg-final { scan-assembler "crc32b\[^\\n\]*eax" } } */
+/* { dg-final { scan-assembler "crc32w\[^\\n\]*eax" } } */
+/* { dg-final { scan-assembler "crc32l\[^\\n\]*eax" } } */
+
+unsigned int
+crc32b (unsigned int x, unsigned char y)
+{
+ return __builtin_ia32_crc32qi (x, y);
+}
+
+unsigned int
+crc32w (unsigned int x, unsigned short y)
+{
+ return __builtin_ia32_crc32hi (x, y);
+}
+
+unsigned int
+crc32d (unsigned int x, unsigned int y)
+{
+ return __builtin_ia32_crc32si (x, y);
+}
diff --git a/gcc/testsuite/gcc.target/i386/crc32-2.c b/gcc/testsuite/gcc.target/i386/crc32-2.c
new file mode 100644
index 00000000000..e7af9ab45f0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/crc32-2.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mcrc32" } */
+/* { dg-final { scan-assembler "crc32q\[^\\n\]*rax" { target lp64 } } } */
+
+unsigned long long
+crc32d (unsigned long long x, unsigned long long y)
+{
+ return __builtin_ia32_crc32di (x, y);
+}
diff --git a/gcc/testsuite/gcc.target/i386/excess-precision-1.c b/gcc/testsuite/gcc.target/i386/excess-precision-1.c
index 3d5e7d288f7..bd825d628e1 100644
--- a/gcc/testsuite/gcc.target/i386/excess-precision-1.c
+++ b/gcc/testsuite/gcc.target/i386/excess-precision-1.c
@@ -1,8 +1,7 @@
/* Excess precision tests. Test that excess precision is carried
through various operations. */
/* { dg-do run } */
-/* { dg-require-effective-target ilp32 } */
-/* { dg-options "-O2 -fexcess-precision=standard" } */
+/* { dg-options "-O2 -mfpmath=387 -fexcess-precision=standard" } */
#include <float.h>
diff --git a/gcc/testsuite/gcc.target/i386/excess-precision-2.c b/gcc/testsuite/gcc.target/i386/excess-precision-2.c
index 1075cd0830e..b5035e5a1fe 100644
--- a/gcc/testsuite/gcc.target/i386/excess-precision-2.c
+++ b/gcc/testsuite/gcc.target/i386/excess-precision-2.c
@@ -1,7 +1,6 @@
/* Excess precision tests. Test excess precision of constants. */
/* { dg-do run } */
-/* { dg-require-effective-target ilp32 } */
-/* { dg-options "-O2 -fexcess-precision=standard" } */
+/* { dg-options "-O2 -mfpmath=387 -fexcess-precision=standard" } */
#include <float.h>
diff --git a/gcc/testsuite/gcc.target/i386/excess-precision-3.c b/gcc/testsuite/gcc.target/i386/excess-precision-3.c
index 0cdcb3d37b6..3de61b43923 100644
--- a/gcc/testsuite/gcc.target/i386/excess-precision-3.c
+++ b/gcc/testsuite/gcc.target/i386/excess-precision-3.c
@@ -1,8 +1,7 @@
/* Excess precision tests. Test excess precision is removed when
necessary. */
/* { dg-do run } */
-/* { dg-require-effective-target ilp32 } */
-/* { dg-options "-O2 -fexcess-precision=standard" } */
+/* { dg-options "-O2 -mfpmath=387 -fexcess-precision=standard" } */
#include <float.h>
#include <stdarg.h>
diff --git a/gcc/testsuite/gcc.target/i386/excess-precision-4.c b/gcc/testsuite/gcc.target/i386/excess-precision-4.c
index db44b0f526e..04e88a375ed 100644
--- a/gcc/testsuite/gcc.target/i386/excess-precision-4.c
+++ b/gcc/testsuite/gcc.target/i386/excess-precision-4.c
@@ -1,8 +1,7 @@
/* Excess precision tests. Test diagnostics for excess precision of
constants. */
/* { dg-do compile } */
-/* { dg-require-effective-target ilp32 } */
-/* { dg-options "-fexcess-precision=standard" } */
+/* { dg-options "-mfpmath=387 -fexcess-precision=standard" } */
float f = 0.0f * 1e50f; /* { dg-warning "floating constant exceeds range of 'float'" } */
double d = 0.0 * 1e400; /* { dg-warning "floating constant exceeds range of 'double'" } */
diff --git a/gcc/testsuite/gcc.target/i386/excess-precision-5.c b/gcc/testsuite/gcc.target/i386/excess-precision-5.c
index 9c765922b81..1cc7e589cfa 100644
--- a/gcc/testsuite/gcc.target/i386/excess-precision-5.c
+++ b/gcc/testsuite/gcc.target/i386/excess-precision-5.c
@@ -1,8 +1,7 @@
/* Excess precision tests. Verify excess precision doesn't affect
actual types. */
/* { dg-do compile } */
-/* { dg-require-effective-target ilp32 } */
-/* { dg-options "-fexcess-precision=standard" } */
+/* { dg-options "-mfpmath=387 -fexcess-precision=standard" } */
float f;
double d;
diff --git a/gcc/testsuite/gcc.target/i386/excess-precision-6.c b/gcc/testsuite/gcc.target/i386/excess-precision-6.c
index 1d421c911c4..fb8d5723212 100644
--- a/gcc/testsuite/gcc.target/i386/excess-precision-6.c
+++ b/gcc/testsuite/gcc.target/i386/excess-precision-6.c
@@ -1,8 +1,7 @@
/* Excess precision tests. Make sure sqrt is not inlined for float or
double. */
/* { dg-do compile } */
-/* { dg-require-effective-target ilp32 } */
-/* { dg-options "-O2 -fno-math-errno -fexcess-precision=standard" } */
+/* { dg-options "-mfpmath=387 -O2 -fno-math-errno -fexcess-precision=standard" } */
float f;
double d;
diff --git a/gcc/testsuite/gcc.target/i386/movbe-1.c b/gcc/testsuite/gcc.target/i386/movbe-1.c
new file mode 100644
index 00000000000..391d4ad9814
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/movbe-1.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mmovbe" } */
+
+extern int x;
+
+void
+foo (int i)
+{
+ x = __builtin_bswap32 (i);
+}
+
+int
+bar ()
+{
+ return __builtin_bswap32 (x);
+}
+
+/* { dg-final { scan-assembler-times "movbe\[ \t\]" 2 } } */
diff --git a/gcc/testsuite/gcc.target/i386/movbe-2.c b/gcc/testsuite/gcc.target/i386/movbe-2.c
new file mode 100644
index 00000000000..d898f20dce4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/movbe-2.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mmovbe" } */
+
+extern long long x;
+
+void
+foo (long long i)
+{
+ x = __builtin_bswap64 (i);
+}
+
+long long
+bar ()
+{
+ return __builtin_bswap64 (x);
+}
+
+/* { dg-final { scan-assembler-times "movbe\[ \t\]" 4 { target ilp32 } } } */
+/* { dg-final { scan-assembler-times "movbe\[ \t\]" 2 { target lp64 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr37216.c b/gcc/testsuite/gcc.target/i386/pr37216.c
new file mode 100644
index 00000000000..5c847a70cfb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr37216.c
@@ -0,0 +1,17 @@
+/* { dg-do run } */
+/* { dg-options "-O3 -msse2" } */
+/* { dg-options "-O3 -msse2 -mpe-aligned-commons" { target pe_aligned_commons } } */
+
+#include "sse2-check.h"
+
+int iarr[64];
+int iint = 0;
+
+void
+sse2_test (void)
+{
+ int i;
+
+ for (i = 0; i < 64; i++)
+ iarr[i] = -2;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr39543-2.c b/gcc/testsuite/gcc.target/i386/pr39543-2.c
index c292041a700..04e980efa7a 100644
--- a/gcc/testsuite/gcc.target/i386/pr39543-2.c
+++ b/gcc/testsuite/gcc.target/i386/pr39543-2.c
@@ -1,6 +1,7 @@
/* PR inline-asm/39543 */
/* { dg-do compile } */
/* { dg-options "-O3" } */
+/* { dg-skip-if "" { ilp32 && { ! nonpic } } { "*" } { "" } } */
float __attribute__ ((aligned (16))) s0[128];
const float s1 = 0.707;
diff --git a/gcc/testsuite/gcc.target/i386/stackalign/pr39146.c b/gcc/testsuite/gcc.target/i386/stackalign/pr39146.c
new file mode 100644
index 00000000000..9ae5f03453e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/stackalign/pr39146.c
@@ -0,0 +1,13 @@
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -mavx" } */
+
+typedef long long __m256i __attribute__ ((__vector_size__ (32), __may_alias__));
+
+
+__m256i
+bar (__m256i x)
+{
+ return x;
+}
+
+/* { dg-final { scan-assembler-not "and\[lq\]?\[^\\n\]*-32,\[^\\n\]*sp" } } */
diff --git a/gcc/testsuite/gcc.target/ia64/mfused-madd-vect.c b/gcc/testsuite/gcc.target/ia64/mfused-madd-vect.c
new file mode 100644
index 00000000000..e166e85daed
--- /dev/null
+++ b/gcc/testsuite/gcc.target/ia64/mfused-madd-vect.c
@@ -0,0 +1,33 @@
+/* { dg-do compile */
+/* { dg-options "-O2 -ftree-vectorize" } */
+/* { dg-final { scan-assembler-not "fpmpy" } } */
+
+/* fpma and fpms will show in either way because there are no
+ specific vector add/sub instructions. So we just check for fpmpy. */
+
+#define N 16
+extern bar(float *, float *, float *, float *);
+void foo()
+{
+ int i;
+ float a[N], b[N], c[N], d[N];
+ bar(a,b,c,d);
+ for (i = 0; i < N; i++) {
+ a[i] = b[i] + c[i] * d[i];
+ }
+ bar(a,b,c,d);
+#if 0
+ for (i = 0; i < N; i++) {
+ a[i] = b[i] - c[i] * d[i];
+ }
+ bar(a,b,c,d);
+#endif
+ for (i = 0; i < N; i++) {
+ a[i] = b[i] * c[i] + d[i];
+ }
+ bar(a,b,c,d);
+ for (i = 0; i < N; i++) {
+ a[i] = b[i] * c[i] - d[i];
+ }
+ bar(a,b,c,d);
+}
diff --git a/gcc/testsuite/gcc.target/ia64/mfused-madd.c b/gcc/testsuite/gcc.target/ia64/mfused-madd.c
new file mode 100644
index 00000000000..8ecb31f0dd3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/ia64/mfused-madd.c
@@ -0,0 +1,64 @@
+/* { dg-do compile */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler-not "fmpy" } } */
+/* { dg-final { scan-assembler-not "fadd" } } */
+/* { dg-final { scan-assembler-not "fsub" } } */
+/* { dg-final { scan-assembler "fma" } } */
+/* { dg-final { scan-assembler "fms" } } */
+/* { dg-final { scan-assembler "fnma" } } */
+
+float foo01(float a, float b, float c) {return (a + b * c);}
+float foo02(float a, float b, float c) {return (a - b * c);}
+float foo03(float a, float b, float c) {return (a * b + c);}
+float foo04(float a, float b, float c) {return (a * b - c);}
+
+double foo05(double a, double b, double c) {return (a + b * c);}
+double foo06(double a, double b, double c) {return (a - b * c);}
+double foo07(double a, double b, double c) {return (a * b + c);}
+double foo08(double a, double b, double c) {return (a * b - c);}
+
+__float80 foo09(__float80 a, __float80 b, __float80 c) {return (a + b * c);}
+__float80 foo10(__float80 a, __float80 b, __float80 c) {return (a - b * c);}
+__float80 foo11(__float80 a, __float80 b, __float80 c) {return (a * b + c);}
+__float80 foo12(__float80 a, __float80 b, __float80 c) {return (a * b - c);}
+
+
+
+float foo20(double a, double b, double c) {return (float) (a + b * c);}
+float foo21(double a, double b, double c) {return (float) (a - b * c);}
+float foo22(double a, double b, double c) {return (float) (a * b + c);}
+float foo23(double a, double b, double c) {return (float) (a * b - c);}
+
+float foo24(__float80 a, __float80 b, __float80 c) {return (float) (a + b * c);}
+float foo25(__float80 a, __float80 b, __float80 c) {return (float) (a - b * c);}
+float foo26(__float80 a, __float80 b, __float80 c) {return (float) (a * b + c);}
+float foo27(__float80 a, __float80 b, __float80 c) {return (float) (a * b - c);}
+
+double foo28(__float80 a, __float80 b, __float80 c) {return (double) (a + b * c);}
+double foo29(__float80 a, __float80 b, __float80 c) {return (double) (a - b * c);}
+double foo30(__float80 a, __float80 b, __float80 c) {return (double) (a * b + c);}
+double foo31(__float80 a, __float80 b, __float80 c) {return (double) (a * b - c);}
+
+
+float foo001(float a, float b, double c) { return (a + b * c); }
+float foo002(float a, float b, double c) { return (a - b * c); }
+
+float foo005(float a, double b, double c) { return (a + b * c); }
+float foo006(float a, double b, double c) { return (a - b * c); }
+float foo007(float a, double b, double c) { return (a * b + c); }
+float foo008(float a, double b, double c) { return (a * b - c); }
+
+double foo009(double a, float b, double c) { return (a + b * c); }
+double foo010(double a, float b, double c) { return (a - b * c); }
+double foo011(double a, float b, double c) { return (a * b + c); }
+double foo012(double a, float b, double c) { return (a * b - c); }
+
+float foo013(float a, double b, __float80 c) { return (a + b * c); }
+float foo014(float a, double b, __float80 c) { return (a - b * c); }
+float foo017(double a, float b, __float80 c) { return (a + b * c); }
+float foo018(double a, float b, __float80 c) { return (a - b * c); }
+
+float foo021(float a, __float80 b, double c) { return (a + b * c); }
+float foo022(float a, __float80 b, double c) { return (a - b * c); }
+float foo023(float a, __float80 b, double c) { return (a * b + c); }
+float foo024(float a, __float80 b, double c) { return (a * b - c); }
diff --git a/gcc/testsuite/gcc.target/ia64/mno-fused-madd-vect.c b/gcc/testsuite/gcc.target/ia64/mno-fused-madd-vect.c
new file mode 100644
index 00000000000..0e24bf6cda8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/ia64/mno-fused-madd-vect.c
@@ -0,0 +1,31 @@
+/* { dg-do compile */
+/* { dg-options "-O2 -mno-fused-madd -ftree-vectorize" } */
+/* { dg-final { scan-assembler "fpmpy" } } */
+
+/* fpma and fpms will show in either way because there are no
+ specific vector add/sub instructions. So we just check for fpmpy. */
+
+#define N 16
+extern bar(float *, float *, float *, float *);
+void foo()
+{
+ int i;
+ float a[N], b[N], c[N], d[N];
+ bar(a,b,c,d);
+ for (i = 0; i < N; i++) {
+ a[i] = b[i] + c[i] * d[i];
+ }
+ bar(a,b,c,d);
+ for (i = 0; i < N; i++) {
+ a[i] = b[i] - c[i] * d[i];
+ }
+ bar(a,b,c,d);
+ for (i = 0; i < N; i++) {
+ a[i] = b[i] * c[i] + d[i];
+ }
+ bar(a,b,c,d);
+ for (i = 0; i < N; i++) {
+ a[i] = b[i] * c[i] - d[i];
+ }
+ bar(a,b,c,d);
+}
diff --git a/gcc/testsuite/gcc.target/ia64/mno-fused-madd.c b/gcc/testsuite/gcc.target/ia64/mno-fused-madd.c
new file mode 100644
index 00000000000..d8ccc947681
--- /dev/null
+++ b/gcc/testsuite/gcc.target/ia64/mno-fused-madd.c
@@ -0,0 +1,64 @@
+/* { dg-do compile */
+/* { dg-options "-O2 -mno-fused-madd" } */
+/* { dg-final { scan-assembler-not "fma" } } */
+/* { dg-final { scan-assembler-not "fms" } } */
+/* { dg-final { scan-assembler-not "fnma" } } */
+/* { dg-final { scan-assembler "fmpy" } } */
+/* { dg-final { scan-assembler "fadd" } } */
+/* { dg-final { scan-assembler "fsub" } } */
+
+float foo01(float a, float b, float c) {return (a + b * c);}
+float foo02(float a, float b, float c) {return (a - b * c);}
+float foo03(float a, float b, float c) {return (a * b + c);}
+float foo04(float a, float b, float c) {return (a * b - c);}
+
+double foo05(double a, double b, double c) {return (a + b * c);}
+double foo06(double a, double b, double c) {return (a - b * c);}
+double foo07(double a, double b, double c) {return (a * b + c);}
+double foo08(double a, double b, double c) {return (a * b - c);}
+
+__float80 foo09(__float80 a, __float80 b, __float80 c) {return (a + b * c);}
+__float80 foo10(__float80 a, __float80 b, __float80 c) {return (a - b * c);}
+__float80 foo11(__float80 a, __float80 b, __float80 c) {return (a * b + c);}
+__float80 foo12(__float80 a, __float80 b, __float80 c) {return (a * b - c);}
+
+
+
+float foo20(double a, double b, double c) {return (float) (a + b * c);}
+float foo21(double a, double b, double c) {return (float) (a - b * c);}
+float foo22(double a, double b, double c) {return (float) (a * b + c);}
+float foo23(double a, double b, double c) {return (float) (a * b - c);}
+
+float foo24(__float80 a, __float80 b, __float80 c) {return (float) (a + b * c);}
+float foo25(__float80 a, __float80 b, __float80 c) {return (float) (a - b * c);}
+float foo26(__float80 a, __float80 b, __float80 c) {return (float) (a * b + c);}
+float foo27(__float80 a, __float80 b, __float80 c) {return (float) (a * b - c);}
+
+double foo28(__float80 a, __float80 b, __float80 c) {return (double) (a + b * c);}
+double foo29(__float80 a, __float80 b, __float80 c) {return (double) (a - b * c);}
+double foo30(__float80 a, __float80 b, __float80 c) {return (double) (a * b + c);}
+double foo31(__float80 a, __float80 b, __float80 c) {return (double) (a * b - c);}
+
+
+float foo001(float a, float b, double c) { return (a + b * c); }
+float foo002(float a, float b, double c) { return (a - b * c); }
+
+float foo005(float a, double b, double c) { return (a + b * c); }
+float foo006(float a, double b, double c) { return (a - b * c); }
+float foo007(float a, double b, double c) { return (a * b + c); }
+float foo008(float a, double b, double c) { return (a * b - c); }
+
+double foo009(double a, float b, double c) { return (a + b * c); }
+double foo010(double a, float b, double c) { return (a - b * c); }
+double foo011(double a, float b, double c) { return (a * b + c); }
+double foo012(double a, float b, double c) { return (a * b - c); }
+
+float foo013(float a, double b, __float80 c) { return (a + b * c); }
+float foo014(float a, double b, __float80 c) { return (a - b * c); }
+float foo017(double a, float b, __float80 c) { return (a + b * c); }
+float foo018(double a, float b, __float80 c) { return (a - b * c); }
+
+float foo021(float a, __float80 b, double c) { return (a + b * c); }
+float foo022(float a, __float80 b, double c) { return (a - b * c); }
+float foo023(float a, __float80 b, double c) { return (a * b + c); }
+float foo024(float a, __float80 b, double c) { return (a * b - c); }
diff --git a/gcc/testsuite/gcc.target/m68k/tls-gd-xgot.c b/gcc/testsuite/gcc.target/m68k/tls-gd-xgot.c
new file mode 100644
index 00000000000..2a4900b5a08
--- /dev/null
+++ b/gcc/testsuite/gcc.target/m68k/tls-gd-xgot.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { ! *-linux-* } { "*" } { "" } } */
+/* { dg-options "-O2 -fpic -mxgot" } */
+/* { dg-final { scan-assembler "#foo@TLSGD,\%\[ad\]\[0-7\]" } } */
+/* { dg-final { scan-assembler "bsr.l __tls_get_addr@PLTPC" } } */
+
+extern int __thread foo;
+
+int *
+bar (void)
+{
+ return &foo;
+}
diff --git a/gcc/testsuite/gcc.target/m68k/tls-gd.c b/gcc/testsuite/gcc.target/m68k/tls-gd.c
new file mode 100644
index 00000000000..2b69fbdc1b4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/m68k/tls-gd.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { ! *-linux-* } { "*" } { "" } } */
+/* { dg-options "-O2 -fpic" } */
+/* { dg-final { scan-assembler "foo@TLSGD\\(\%a5\\)" } } */
+/* { dg-final { scan-assembler "bsr.l __tls_get_addr@PLTPC" } } */
+
+extern int __thread foo;
+
+int *
+bar (void)
+{
+ return &foo;
+}
diff --git a/gcc/testsuite/gcc.target/m68k/tls-ie-xgot.c b/gcc/testsuite/gcc.target/m68k/tls-ie-xgot.c
new file mode 100644
index 00000000000..d3fbfdaa4b6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/m68k/tls-ie-xgot.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { ! *-linux-* } { "*" } { "" } } */
+/* { dg-options "-O2 -mxgot" } */
+/* { dg-final { scan-assembler "jsr __m68k_read_tp" } } */
+/* { dg-final { scan-assembler "#foo@TLSIE,\%\[ad\]\[0-7\]" } } */
+
+extern int __thread foo;
+
+int *
+bar (void)
+{
+ return &foo;
+}
diff --git a/gcc/testsuite/gcc.target/m68k/tls-ie.c b/gcc/testsuite/gcc.target/m68k/tls-ie.c
new file mode 100644
index 00000000000..2661f9fc053
--- /dev/null
+++ b/gcc/testsuite/gcc.target/m68k/tls-ie.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { ! *-linux-* } { "*" } { "" } } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler "jsr __m68k_read_tp" } } */
+/* { dg-final { scan-assembler "foo@TLSIE\\(\%a5\\)" } } */
+
+extern int __thread foo;
+
+int *
+bar (void)
+{
+ return &foo;
+}
diff --git a/gcc/testsuite/gcc.target/m68k/tls-ld-xgot-xtls.c b/gcc/testsuite/gcc.target/m68k/tls-ld-xgot-xtls.c
new file mode 100644
index 00000000000..4817de01d44
--- /dev/null
+++ b/gcc/testsuite/gcc.target/m68k/tls-ld-xgot-xtls.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { ! *-linux-* } { "*" } { "" } } */
+/* { dg-options "-O2 -fpic -mxgot -mxtls" } */
+/* { dg-final { scan-assembler "#foo@TLSLDM,\%\[ad\]\[0-7\]" } } */
+/* { dg-final { scan-assembler "bsr.l __tls_get_addr@PLTPC" } } */
+/* { dg-final { scan-assembler "#foo@TLSLDO,\%\[ad\]\[0-7\]" } } */
+
+static int __thread foo;
+
+int *
+bar (void)
+{
+ return &foo;
+}
diff --git a/gcc/testsuite/gcc.target/m68k/tls-ld-xgot.c b/gcc/testsuite/gcc.target/m68k/tls-ld-xgot.c
new file mode 100644
index 00000000000..f95f7192855
--- /dev/null
+++ b/gcc/testsuite/gcc.target/m68k/tls-ld-xgot.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { ! *-linux-* } { "*" } { "" } } */
+/* { dg-options "-O2 -fpic -mxgot" } */
+/* { dg-final { scan-assembler "#foo@TLSLDM,\%\[ad\]\[0-7\]" } } */
+/* { dg-final { scan-assembler "bsr.l __tls_get_addr@PLTPC" } } */
+/* { dg-final { scan-assembler "lea \\(foo@TLSLDO,\%a0\\)" } } */
+
+static int __thread foo;
+
+int *
+bar (void)
+{
+ return &foo;
+}
diff --git a/gcc/testsuite/gcc.target/m68k/tls-ld-xtls.c b/gcc/testsuite/gcc.target/m68k/tls-ld-xtls.c
new file mode 100644
index 00000000000..1bc3eaf7de5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/m68k/tls-ld-xtls.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { ! *-linux-* } { "*" } { "" } } */
+/* { dg-options "-O2 -fpic -mxtls" } */
+/* { dg-final { scan-assembler "foo@TLSLDM\\(\%a5\\)" } } */
+/* { dg-final { scan-assembler "bsr.l __tls_get_addr@PLTPC" } } */
+/* { dg-final { scan-assembler "#foo@TLSLDO,\%\[ad\]\[0-7\]" } } */
+
+static int __thread foo;
+
+int *
+bar (void)
+{
+ return &foo;
+}
diff --git a/gcc/testsuite/gcc.target/m68k/tls-ld.c b/gcc/testsuite/gcc.target/m68k/tls-ld.c
new file mode 100644
index 00000000000..556a11718ca
--- /dev/null
+++ b/gcc/testsuite/gcc.target/m68k/tls-ld.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { ! *-linux-* } { "*" } { "" } } */
+/* { dg-options "-O2 -fpic" } */
+/* { dg-final { scan-assembler "foo@TLSLDM\\(\%a5\\)" } } */
+/* { dg-final { scan-assembler "bsr.l __tls_get_addr@PLTPC" } } */
+/* { dg-final { scan-assembler "lea \\(foo@TLSLDO,\%a0\\)" } } */
+
+static int __thread foo;
+
+int *
+bar (void)
+{
+ return &foo;
+}
diff --git a/gcc/testsuite/gcc.target/m68k/tls-le-xtls.c b/gcc/testsuite/gcc.target/m68k/tls-le-xtls.c
new file mode 100644
index 00000000000..90061153f89
--- /dev/null
+++ b/gcc/testsuite/gcc.target/m68k/tls-le-xtls.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { ! *-linux-* } { "*" } { "" } } */
+/* { dg-options "-O2 -mxtls" } */
+/* { dg-final { scan-assembler "jsr __m68k_read_tp" } } */
+/* { dg-final { scan-assembler "#foo@TLSLE,\%\[ad\]\[0-7\]" } } */
+
+static int __thread foo;
+
+int *
+bar (void)
+{
+ return &foo;
+}
diff --git a/gcc/testsuite/gcc.target/m68k/tls-le.c b/gcc/testsuite/gcc.target/m68k/tls-le.c
new file mode 100644
index 00000000000..1c0eab23886
--- /dev/null
+++ b/gcc/testsuite/gcc.target/m68k/tls-le.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { ! *-linux-* } { "*" } { "" } } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler "jsr __m68k_read_tp" } } */
+/* { dg-final { scan-assembler "lea \\(foo@TLSLE,\%a0\\)" } } */
+
+static int __thread foo;
+
+int *
+bar (void)
+{
+ return &foo;
+}
diff --git a/gcc/testsuite/gcc.target/mips/const-anchor-1.c b/gcc/testsuite/gcc.target/mips/const-anchor-1.c
new file mode 100644
index 00000000000..66981671d02
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/const-anchor-1.c
@@ -0,0 +1,10 @@
+/* Derive a constant (0x1233ffff) from an intermediate value
+ (0x1234000) used to build another constant. */
+/* { dg-options "-O" } */
+/* { dg-final { scan-assembler-not "0x12330000|305332224" } } */
+/* { dg-final { scan-assembler "addiu\t\\\$5,\\\$\[0-9\]*,-1" } } */
+
+NOMIPS16 void f ()
+{
+ g (0x12340001, 0x1233ffff);
+}
diff --git a/gcc/testsuite/gcc.target/mips/const-anchor-2.c b/gcc/testsuite/gcc.target/mips/const-anchor-2.c
new file mode 100644
index 00000000000..ccb89bb766c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/const-anchor-2.c
@@ -0,0 +1,9 @@
+/* Derive a constant (0x30001) from another constant. */
+/* { dg-options "-O" } */
+/* { dg-final { scan-assembler-not "0x300000|196608" } } */
+/* { dg-final { scan-assembler "addiu\t\\\$5,\\\$\[0-9\]*,32763" } } */
+
+NOMIPS16 void f ()
+{
+ g (0x28006, 0x30001);
+}
diff --git a/gcc/testsuite/gcc.target/mips/extend-1.c b/gcc/testsuite/gcc.target/mips/extend-1.c
new file mode 100644
index 00000000000..952d4a0932c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/extend-1.c
@@ -0,0 +1,14 @@
+/* { dg-options "-O -mgp64 isa=!octeon" } */
+/* { dg-final { scan-assembler-times "\tdsll\t" 5 } } */
+/* { dg-final { scan-assembler-times "\tdsra\t" 5 } } */
+/* { dg-final { scan-assembler-not "\tsll\t" } } */
+
+#define TEST_CHAR(T, N) \
+ NOMIPS16 T f##N (long long d, T *a, T *r) { T b = (char) d; *r = b + *a; }
+#define TEST_SHORT(T, N) \
+ NOMIPS16 T g##N (long long d, T *a, T *r) { T b = (short) d; *r = b + *a; }
+#define TEST(T, N) TEST_CHAR (T, N) TEST_SHORT (T, N)
+
+TEST (int, 1);
+TEST (long long, 2);
+TEST_CHAR (short, 3);
diff --git a/gcc/testsuite/gcc.target/mips/octeon-exts-2.c b/gcc/testsuite/gcc.target/mips/octeon-exts-2.c
index fc5df639d02..42f2a3f8586 100644
--- a/gcc/testsuite/gcc.target/mips/octeon-exts-2.c
+++ b/gcc/testsuite/gcc.target/mips/octeon-exts-2.c
@@ -1,6 +1,7 @@
/* { dg-do compile } */
-/* { dg-options "-O -march=octeon -meb" } */
-/* { dg-final { scan-assembler-times "\texts\t" 4 } } */
+/* { dg-options "-O -march=octeon -meb -dp" } */
+/* Don't match exts in sign-extension. */
+/* { dg-final { scan-assembler-times "\texts\t\[^\\n\]*extv" 4 } } */
struct bar
{
diff --git a/gcc/testsuite/gcc.target/mips/octeon-exts-5.c b/gcc/testsuite/gcc.target/mips/octeon-exts-5.c
index e7a4738b96f..6ec7ac7296f 100644
--- a/gcc/testsuite/gcc.target/mips/octeon-exts-5.c
+++ b/gcc/testsuite/gcc.target/mips/octeon-exts-5.c
@@ -1,7 +1,8 @@
/* -mel version of octeon-exts-2.c. */
/* { dg-do compile } */
-/* { dg-options "-O -march=octeon -mel" } */
-/* { dg-final { scan-assembler-times "\texts\t" 4 } } */
+/* { dg-options "-O -march=octeon -mel -dp" } */
+/* Don't match exts in sign-extension. */
+/* { dg-final { scan-assembler-times "\texts\t\[^\\n\]*extv" 4 } } */
struct bar
{
diff --git a/gcc/testsuite/gcc.target/mips/octeon-exts-6.c b/gcc/testsuite/gcc.target/mips/octeon-exts-6.c
new file mode 100644
index 00000000000..d04e27331d9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/octeon-exts-6.c
@@ -0,0 +1,14 @@
+/* { dg-options "-O -march=octeon -mgp64" } */
+/* { dg-final { scan-assembler-times "\texts\t" 5 } } */
+/* { dg-final { scan-assembler-not "\t(dsll|dsra)\t" } } */
+/* { dg-final { scan-assembler-not "\tsll\t" } } */
+
+#define TEST_CHAR(T, N) \
+ NOMIPS16 T f##N (long long d, T *a, T *r) { T b = (char) d; *r = b + *a; }
+#define TEST_SHORT(T, N) \
+ NOMIPS16 T g##N (long long d, T *a, T *r) { T b = (short) d; *r = b + *a; }
+#define TEST(T, N) TEST_CHAR (T, N) TEST_SHORT (T, N)
+
+TEST (int, 1);
+TEST (long long, 2);
+TEST_CHAR (short, 3);
diff --git a/gcc/testsuite/gcc.target/powerpc/altivec-30.c b/gcc/testsuite/gcc.target/powerpc/altivec-30.c
new file mode 100644
index 00000000000..99783191db9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/altivec-30.c
@@ -0,0 +1,32 @@
+/* { dg-do compile { target powerpc*-*-* } } */
+/* { dg-require-effective-target powerpc_altivec_ok } */
+/* { dg-options "-maltivec" } */
+
+#include <stdbool.h>
+#include <altivec.h>
+
+#define f0(type) void x0##type (vector bool type x) { }
+f0 (int)
+
+#define f1(v, type) void x1##type (v bool type x) { }
+f1 (vector, int)
+
+#define f2(b, type) void x2##type (vector b type x) { }
+f2 (bool, int)
+
+#define f3(v, b, type) void x3##type (v b type x) { }
+f3 (vector, bool, int)
+
+#define f4(v, b, type) void x4##type (v type b x) { }
+f4 (vector, bool, int)
+
+#define B bool
+#define I int
+#define BI bool int
+#define VBI vector bool int
+
+vector bool int a;
+vector B int b;
+vector B I c;
+vector BI d;
+VBI e;
diff --git a/gcc/testsuite/gcc.target/powerpc/altivec-31.c b/gcc/testsuite/gcc.target/powerpc/altivec-31.c
new file mode 100644
index 00000000000..233efe1bebb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/altivec-31.c
@@ -0,0 +1,29 @@
+/* { dg-do compile { target powerpc*-*-* } } */
+/* { dg-require-effective-target powerpc_altivec_ok } */
+/* { dg-options "-maltivec" } */
+
+#define f0(type) void x0##type (vector _Bool type x) { }
+f0 (int)
+
+#define f1(v, type) void x1##type (v _Bool type x) { }
+f1 (vector, int)
+
+#define f2(b, type) void x2##type (vector b type x) { }
+f2 (_Bool, int)
+
+#define f3(v, b, type) void x3##type (v b type x) { }
+f3 (vector, _Bool, int)
+
+#define f4(v, b, type) void x4##type (v type b x) { }
+f4 (vector, _Bool, int)
+
+#define B _Bool
+#define I int
+#define BI _Bool int
+#define VBI vector _Bool int
+
+vector _Bool int a;
+vector B int b;
+vector B I c;
+vector BI d;
+VBI e;
diff --git a/gcc/testsuite/gcc.target/powerpc/altivec-types-1.c b/gcc/testsuite/gcc.target/powerpc/altivec-types-1.c
index d293042d64f..41de95225b3 100644
--- a/gcc/testsuite/gcc.target/powerpc/altivec-types-1.c
+++ b/gcc/testsuite/gcc.target/powerpc/altivec-types-1.c
@@ -24,6 +24,7 @@ __vector unsigned vuj;
__vector signed vsj;
__vector __bool vbj;
__vector float vf;
+__vector _Bool vb;
/* These should be rejected as invalid AltiVec types. */
@@ -37,7 +38,6 @@ __vector signed long long int vslli; /* { dg-error "AltiVec types" "" } */
__vector __bool long long int vblli; /* { dg-error "AltiVec types" "" } */
__vector double vd1; /* { dg-error "AltiVec types" "" } */
__vector long double vld; /* { dg-error "AltiVec types" "" } */
-__vector _Bool vb; /* { dg-error "AltiVec types" "" } */
__vector _Complex float vcf; /* { dg-error "AltiVec types" "" } */
__vector _Complex double vcd; /* { dg-error "AltiVec types" "" } */
__vector _Complex long double vcld; /* { dg-error "AltiVec types" "" } */
diff --git a/gcc/testsuite/gcc.target/x86_64/abi/asm-support.S b/gcc/testsuite/gcc.target/x86_64/abi/asm-support.S
index 61b66e1490a..cb1e31ea785 100644
--- a/gcc/testsuite/gcc.target/x86_64/abi/asm-support.S
+++ b/gcc/testsuite/gcc.target/x86_64/abi/asm-support.S
@@ -49,7 +49,9 @@ snapshot:
.type snapshot_ret, @function
snapshot_ret:
movq %rdi, rdi(%rip)
+ subq $8, %rsp
call *callthis(%rip)
+ addq $8, %rsp
movq %rax, rax(%rip)
movq %rdx, rdx(%rip)
movdqu %xmm0, xmm_regs+0(%rip)
diff --git a/gcc/testsuite/gfortran.dg/array_memset_2.f90 b/gcc/testsuite/gfortran.dg/array_memset_2.f90
index 58ce8fe6442..7805f7b9420 100644
--- a/gcc/testsuite/gfortran.dg/array_memset_2.f90
+++ b/gcc/testsuite/gfortran.dg/array_memset_2.f90
@@ -20,8 +20,8 @@ program test
data c /2*1.0/
a(1,:) = 0. ! This can't be optimized to a memset.
- b(1,:) = 0. ! This is optimized to memset.
- c = 0. ! This is optimized to memset.
+ b(1,:) = 0. ! This is optimized to = {}.
+ c = 0. ! This is optimized to = {}.
d(:,1) = 0. ! This can't be otimized to a memset.
call bar(e)
@@ -33,6 +33,6 @@ program test
end program
-! { dg-final { scan-tree-dump-times "memset" 2 "original" } }
+! { dg-final { scan-tree-dump-times "= {}" 2 "original" } }
! { dg-final { cleanup-tree-dump "original" } }
! { dg-final { cleanup-modules "foo" } }
diff --git a/gcc/testsuite/gfortran.dg/backspace_11.f90 b/gcc/testsuite/gfortran.dg/backspace_11.f90
new file mode 100644
index 00000000000..e369b75f67c
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/backspace_11.f90
@@ -0,0 +1,24 @@
+! { dg-do run }
+! PR 40334 backspace regression
+program backspace_11
+ implicit none
+ character(len=5) :: str
+ open(10, access='sequential', status='scratch')
+ write(10,'(A)')'HELLO'
+ rewind(10)
+
+ do
+ read(10,'(A)',end=1) str
+ enddo
+1 backspace 10
+ !the file pointer is now at EOF
+
+ read(10,*,end=2) str
+ call abort
+2 backspace 10
+ !the file pointer is now at EOF
+
+ read(10,'(A)',end=3) str
+ call abort
+3 continue
+end program backspace_11
diff --git a/gcc/testsuite/gfortran.dg/bind_c_usage_18.f90 b/gcc/testsuite/gfortran.dg/bind_c_usage_18.f90
index 30534cca9a9..2bce215af19 100644
--- a/gcc/testsuite/gfortran.dg/bind_c_usage_18.f90
+++ b/gcc/testsuite/gfortran.dg/bind_c_usage_18.f90
@@ -7,7 +7,7 @@ subroutine foo(x,y,z,a) bind(c) ! { dg-warning "but may not be C interoperable"
use iso_c_binding
implicit none
integer(4) :: x
- integer(c_float) :: y ! { dg-error "C kind type parameter is for type REAL" }
+ integer(c_float) :: y ! { dg-warning "C kind type parameter is for type REAL" }
complex(c_float) :: z ! OK, c_float == c_float_complex
real(c_float_complex) :: a ! OK, c_float == c_float_complex
end subroutine foo
@@ -16,8 +16,8 @@ use iso_c_binding
implicit none
integer, parameter :: it = c_int
integer, parameter :: dt = c_double
-complex(c_int), target :: z1 ! { dg-error "C kind type parameter is for type INTEGER" }
-complex(it), target :: z2 ! { dg-error "C kind type parameter is for type INTEGER" }
+complex(c_int), target :: z1 ! { dg-warning "C kind type parameter is for type INTEGER" }
+complex(it), target :: z2 ! { dg-warning "C kind type parameter is for type INTEGER" }
complex(c_double), target :: z3 ! OK
complex(dt), target :: z4 ! OK
type(c_ptr) :: ptr
diff --git a/gcc/testsuite/gfortran.dg/bound_4.f90 b/gcc/testsuite/gfortran.dg/bound_4.f90
index dd934519d53..b63ce9ec6a9 100644
--- a/gcc/testsuite/gfortran.dg/bound_4.f90
+++ b/gcc/testsuite/gfortran.dg/bound_4.f90
@@ -12,14 +12,14 @@ end program test
subroutine ha0020(mf3)
implicit none
- integer xca(1), xda(1), mf3
+ integer xca(2), xda(2), mf3
xca = 1
xda = -1
- xca(1:1) = xda(1:2:mf3)
+ xca(1:2:-1) = xda(1:2:mf3)
- if (any (xca /= -1)) call abort
+ if (any (xca /= 1)) call abort
if (any(xda(1:2:mf3) /= xda(1:0))) call abort
if (size(xda(1:2:mf3)) /= 0) call abort
if (any(shape(xda(1:2:mf3)) /= 0)) call abort
diff --git a/gcc/testsuite/gfortran.dg/bounds_check_14.f90 b/gcc/testsuite/gfortran.dg/bounds_check_14.f90
index 0b7edfe565b..1e5a4aeeee3 100644
--- a/gcc/testsuite/gfortran.dg/bounds_check_14.f90
+++ b/gcc/testsuite/gfortran.dg/bounds_check_14.f90
@@ -13,14 +13,14 @@ end program test
subroutine ha0020(mf3)
implicit none
- integer xca(1), xda(1), mf3
+ integer xca(2), xda(2), mf3
xca = 1
xda = -1
- xca(1:1) = xda(1:2:mf3)
+ xca(1:2:-1) = xda(1:2:mf3)
- if (any (xca /= -1)) call abort
+ if (any (xca /= 1)) call abort
if (any(xda(1:2:mf3) /= xda(1:0))) call abort
if (size(xda(1:2:mf3)) /= 0) call abort
if (any(shape(xda(1:2:mf3)) /= 0)) call abort
diff --git a/gcc/testsuite/gfortran.dg/bounds_check_fail_3.f90 b/gcc/testsuite/gfortran.dg/bounds_check_fail_3.f90
new file mode 100644
index 00000000000..0826b7d5efc
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/bounds_check_fail_3.f90
@@ -0,0 +1,12 @@
+! { dg-do run }
+! { dg-options "-fbounds-check" }
+! { dg-shouldfail "foo" }
+ integer x(10), m, n
+ x = (/ (i, i = 1, 10) /)
+ m = -3
+ n = -2
+ x(7:1:m) = x(6:2:n)
+ if (any(x /= (/ 2, 2, 3, 4, 5, 6, 6, 8, 9, 10 /))) call abort()
+ x(8:1:m) = x(5:2:n)
+ end
+! { dg-output "line 10 .* bound mismatch, .* dimension 1 .* array \'x\' \\\(3/2\\\)" }
diff --git a/gcc/testsuite/gfortran.dg/bounds_check_fail_4.f90 b/gcc/testsuite/gfortran.dg/bounds_check_fail_4.f90
new file mode 100644
index 00000000000..dee3ca8d66e
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/bounds_check_fail_4.f90
@@ -0,0 +1,12 @@
+! { dg-do run }
+! { dg-options "-fbounds-check" }
+! { dg-shouldfail "foo" }
+ integer x(10), m, n
+ x = (/ (i, i = 1, 10) /)
+ m = -3
+ n = -2
+ x(7:1:m) = x(1:3) + x(6:2:n)
+ if (any(x /= (/ 5, 2, 3, 6, 5, 6, 7, 8, 9, 10 /))) call abort()
+ x(8:1:m) = x(1:3) + x(5:2:n)
+ end
+! { dg-output "line 10 .* bound mismatch, .* dimension 1 .* array \'x\' \\\(2/3\\\)" }
diff --git a/gcc/testsuite/gfortran.dg/bounds_check_strlen_8.f90 b/gcc/testsuite/gfortran.dg/bounds_check_strlen_8.f90
new file mode 100644
index 00000000000..c54f14144f8
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/bounds_check_strlen_8.f90
@@ -0,0 +1,40 @@
+! { dg-do run }
+! { dg-options "-fbounds-check" }
+!
+! PR fortran/40383
+! Gave before a bogus out of bounds.
+! Contributed by Joost VandeVondele.
+!
+MODULE M1
+ INTEGER, PARAMETER :: default_string_length=80
+END MODULE M1
+MODULE M2
+ USE M1
+ IMPLICIT NONE
+CONTAINS
+ FUNCTION F1(a,b,c,d) RESULT(RES)
+ CHARACTER(LEN=default_string_length), OPTIONAL :: a,b,c,d
+ LOGICAL :: res
+ END FUNCTION F1
+END MODULE M2
+
+MODULE M3
+ USE M1
+ USE M2
+ IMPLICIT NONE
+CONTAINS
+ SUBROUTINE S1
+ CHARACTER(LEN=default_string_length) :: a,b
+ LOGICAL :: L1
+ INTEGER :: i
+ DO I=1,10
+ L1=F1(a,b)
+ ENDDO
+ END SUBROUTINE
+END MODULE M3
+
+USE M3
+CALL S1
+END
+
+! { dg-final { cleanup-modules "m1 m2 m3" } }
diff --git a/gcc/testsuite/gfortran.dg/c_f_pointer_shape_tests_4.f03 b/gcc/testsuite/gfortran.dg/c_f_pointer_shape_tests_4.f03
new file mode 100644
index 00000000000..89b8666d7ae
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/c_f_pointer_shape_tests_4.f03
@@ -0,0 +1,115 @@
+! { dg-do run }
+! { dg-additional-sources c_f_pointer_shape_tests_2_driver.c }
+! Verify that the optional SHAPE parameter to c_f_pointer can be of any
+! valid integer kind. We don't test all kinds here since it would be
+! difficult to know what kinds are valid for the architecture we're running on.
+! However, testing ones that should be different should be sufficient.
+module c_f_pointer_shape_tests_4
+ use, intrinsic :: iso_c_binding
+ implicit none
+contains
+ subroutine test_long_long_1d(cPtr, num_elems) bind(c)
+ use, intrinsic :: iso_c_binding
+ type(c_ptr), value :: cPtr
+ integer(c_int), value :: num_elems
+ integer, dimension(:), pointer :: myArrayPtr
+ integer(c_long_long), dimension(1) :: shape
+ integer :: i
+
+ shape(1) = num_elems
+ call c_f_pointer(cPtr, myArrayPtr, shape)
+ do i = 1, num_elems
+ if(myArrayPtr(i) /= (i-1)) call abort ()
+ end do
+ end subroutine test_long_long_1d
+
+ subroutine test_long_long_2d(cPtr, num_rows, num_cols) bind(c)
+ use, intrinsic :: iso_c_binding
+ type(c_ptr), value :: cPtr
+ integer(c_int), value :: num_rows
+ integer(c_int), value :: num_cols
+ integer, dimension(:,:), pointer :: myArrayPtr
+ integer(c_long_long), dimension(3) :: shape
+ integer :: i,j
+
+ shape(1) = num_rows
+ shape(2) = -3;
+ shape(3) = num_cols
+ call c_f_pointer(cPtr, myArrayPtr, shape(1:3:2))
+ do j = 1, num_cols
+ do i = 1, num_rows
+ if(myArrayPtr(i,j) /= ((j-1)*num_rows)+(i-1)) call abort ()
+ end do
+ end do
+ end subroutine test_long_long_2d
+
+ subroutine test_long_1d(cPtr, num_elems) bind(c)
+ use, intrinsic :: iso_c_binding
+ type(c_ptr), value :: cPtr
+ integer(c_int), value :: num_elems
+ integer, dimension(:), pointer :: myArrayPtr
+ integer(c_long), dimension(1) :: shape
+ integer :: i
+
+ shape(1) = num_elems
+ call c_f_pointer(cPtr, myArrayPtr, shape)
+ do i = 1, num_elems
+ if(myArrayPtr(i) /= (i-1)) call abort ()
+ end do
+ end subroutine test_long_1d
+
+ subroutine test_int_1d(cPtr, num_elems) bind(c)
+ use, intrinsic :: iso_c_binding
+ type(c_ptr), value :: cPtr
+ integer(c_int), value :: num_elems
+ integer, dimension(:), pointer :: myArrayPtr
+ integer(c_int), dimension(1) :: shape
+ integer :: i
+
+ shape(1) = num_elems
+ call c_f_pointer(cPtr, myArrayPtr, shape)
+ do i = 1, num_elems
+ if(myArrayPtr(i) /= (i-1)) call abort ()
+ end do
+ end subroutine test_int_1d
+
+ subroutine test_short_1d(cPtr, num_elems) bind(c)
+ use, intrinsic :: iso_c_binding
+ type(c_ptr), value :: cPtr
+ integer(c_int), value :: num_elems
+ integer, dimension(:), pointer :: myArrayPtr
+ integer(c_short), dimension(1) :: shape
+ integer :: i
+
+ shape(1) = num_elems
+ call c_f_pointer(cPtr, myArrayPtr, shape)
+ do i = 1, num_elems
+ if(myArrayPtr(i) /= (i-1)) call abort ()
+ end do
+ end subroutine test_short_1d
+
+ subroutine test_mixed(cPtr, num_elems) bind(c)
+ use, intrinsic :: iso_c_binding
+ type(c_ptr), value :: cPtr
+ integer(c_int), value :: num_elems
+ integer, dimension(:), pointer :: myArrayPtr
+ integer(c_int), dimension(1) :: shape1
+ integer(c_long_long), dimension(1) :: shape2
+ integer :: i
+
+ shape1(1) = num_elems
+ call c_f_pointer(cPtr, myArrayPtr, shape1)
+ do i = 1, num_elems
+ if(myArrayPtr(i) /= (i-1)) call abort ()
+ end do
+
+ nullify(myArrayPtr)
+ shape2(1) = num_elems
+ call c_f_pointer(cPtr, myArrayPtr, shape2)
+ do i = 1, num_elems
+ if(myArrayPtr(i) /= (i-1)) call abort ()
+ end do
+ end subroutine test_mixed
+end module c_f_pointer_shape_tests_4
+! { dg-final { cleanup-modules "c_f_pointer_shape_tests_4" } }
+
diff --git a/gcc/testsuite/gfortran.dg/c_f_pointer_shape_tests_4_driver.c b/gcc/testsuite/gfortran.dg/c_f_pointer_shape_tests_4_driver.c
new file mode 100644
index 00000000000..1282beb12d7
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/c_f_pointer_shape_tests_4_driver.c
@@ -0,0 +1,46 @@
+#define NUM_ELEMS 10
+#define NUM_ROWS 2
+#define NUM_COLS 3
+
+void test_long_long_1d(int *array, int num_elems);
+void test_long_long_2d(int *array, int num_rows, int num_cols);
+void test_long_1d(int *array, int num_elems);
+void test_int_1d(int *array, int num_elems);
+void test_short_1d(int *array, int num_elems);
+void test_mixed(int *array, int num_elems);
+
+int main(int argc, char **argv)
+{
+ int my_array[NUM_ELEMS];
+ int my_2d_array[NUM_ROWS][NUM_COLS];
+ int i, j;
+
+ for(i = 0; i < NUM_ELEMS; i++)
+ my_array[i] = i;
+
+ for(i = 0; i < NUM_ROWS; i++)
+ for(j = 0; j < NUM_COLS; j++)
+ my_2d_array[i][j] = (i*NUM_COLS) + j;
+
+ /* Test c_f_pointer where SHAPE is of type integer, kind=c_long_long. */
+ test_long_long_1d(my_array, NUM_ELEMS);
+
+ /* Test c_f_pointer where SHAPE is of type integer, kind=c_long_long.
+ The indices are transposed for Fortran. */
+ test_long_long_2d(my_2d_array[0], NUM_COLS, NUM_ROWS);
+
+ /* Test c_f_pointer where SHAPE is of type integer, kind=c_long. */
+ test_long_1d(my_array, NUM_ELEMS);
+
+ /* Test c_f_pointer where SHAPE is of type integer, kind=c_int. */
+ test_int_1d(my_array, NUM_ELEMS);
+
+ /* Test c_f_pointer where SHAPE is of type integer, kind=c_short. */
+ test_short_1d(my_array, NUM_ELEMS);
+
+ /* Test c_f_pointer where SHAPE is of type integer, kind=c_int and
+ kind=c_long_long. */
+ test_mixed(my_array, NUM_ELEMS);
+
+ return 0;
+}
diff --git a/gcc/testsuite/gfortran.dg/c_kind_int128_test1.f03 b/gcc/testsuite/gfortran.dg/c_kind_int128_test1.f03
index 6be1ac20b64..b1919614b2e 100644
--- a/gcc/testsuite/gfortran.dg/c_kind_int128_test1.f03
+++ b/gcc/testsuite/gfortran.dg/c_kind_int128_test1.f03
@@ -2,7 +2,6 @@
! { dg-options "-std=f2003" }
! { dg-require-effective-target fortran_integer_16 }
!
-! Note: int_fast*_t currently not supported.
subroutine c_kind_int128_1
use, intrinsic :: iso_c_binding
@@ -10,15 +9,16 @@ subroutine c_kind_int128_1
integer(c_int128_t) :: a ! { dg-error "has no IMPLICIT type" }
integer(c_int_least128_t) :: b ! { dg-error "has no IMPLICIT type" }
-! integer(c_int_fast128_t) :: c
-
+ integer(c_int_fast128_t) :: c ! { dg-error "has no IMPLICIT type" }
+
end subroutine c_kind_int128_1
+
subroutine c_kind_int128_2
use, intrinsic :: iso_c_binding
integer(c_int128_t) :: a ! { dg-error "has not been declared or is a variable" }
integer(c_int_least128_t) :: b ! { dg-error "has not been declared or is a variable" }
-! integer(c_int_fast128_t) :: c
-
+ integer(c_int_fast128_t) :: c ! { dg-error "has not been declared or is a variable" }
+
end subroutine c_kind_int128_2
diff --git a/gcc/testsuite/gfortran.dg/c_kind_int128_test2.f03 b/gcc/testsuite/gfortran.dg/c_kind_int128_test2.f03
index 2f22b72d0be..4fe2dac2913 100644
--- a/gcc/testsuite/gfortran.dg/c_kind_int128_test2.f03
+++ b/gcc/testsuite/gfortran.dg/c_kind_int128_test2.f03
@@ -2,7 +2,7 @@
! { dg-options "-std=gnu" }
! { dg-require-effective-target fortran_integer_16 }
!
-! Note: int_fast*_t currently not supported.
+! Note: int_fast128_t currently not supported.
program c_kind_int128
use, intrinsic :: iso_c_binding
diff --git a/gcc/testsuite/gfortran.dg/c_kind_params.f90 b/gcc/testsuite/gfortran.dg/c_kind_params.f90
index 871ae822b56..4176157887a 100644
--- a/gcc/testsuite/gfortran.dg/c_kind_params.f90
+++ b/gcc/testsuite/gfortran.dg/c_kind_params.f90
@@ -5,16 +5,16 @@
! the -w option is needed to make f951 not report a warning for
! the -std=c99 option that the C file needs.
!
-! Note: int_fast*_t currently not supported, cf. PR 448.
module c_kind_params
use, intrinsic :: iso_c_binding
implicit none
contains
subroutine param_test(my_short, my_int, my_long, my_long_long, &
- my_int8_t, my_int_least8_t, my_int16_t, &
- my_int_least16_t, my_int32_t, my_int_least32_t, &
- my_int64_t, my_int_least64_t, &
+ my_int8_t, my_int_least8_t, my_int_fast8_t, &
+ my_int16_t, my_int_least16_t, my_int_fast16_t, &
+ my_int32_t, my_int_least32_t, my_int_fast32_t, &
+ my_int64_t, my_int_least64_t, my_int_fast64_t, &
my_intmax_t, my_intptr_t, my_float, my_double, my_long_double, &
my_char, my_bool) bind(c)
integer(c_short), value :: my_short
@@ -23,16 +23,16 @@ contains
integer(c_long_long), value :: my_long_long
integer(c_int8_t), value :: my_int8_t
integer(c_int_least8_t), value :: my_int_least8_t
-! integer(c_int_fast8_t), value :: my_int_fast8_t
+ integer(c_int_fast8_t), value :: my_int_fast8_t
integer(c_int16_t), value :: my_int16_t
integer(c_int_least16_t), value :: my_int_least16_t
-! integer(c_int_fast16_t), value :: my_int_fast16_t
+ integer(c_int_fast16_t), value :: my_int_fast16_t
integer(c_int32_t), value :: my_int32_t
integer(c_int_least32_t), value :: my_int_least32_t
-! integer(c_int_fast32_t), value :: my_int_fast32_t
+ integer(c_int_fast32_t), value :: my_int_fast32_t
integer(c_int64_t), value :: my_int64_t
integer(c_int_least64_t), value :: my_int_least64_t
-! integer(c_int_fast64_t), value :: my_int_fast64_t
+ integer(c_int_fast64_t), value :: my_int_fast64_t
integer(c_intmax_t), value :: my_intmax_t
integer(c_intptr_t), value :: my_intptr_t
real(c_float), value :: my_float
@@ -48,19 +48,19 @@ contains
if(my_int8_t /= 1_c_int8_t) call abort()
if(my_int_least8_t /= 2_c_int_least8_t ) call abort()
- print *, 'c_int_fast8_t is: ', c_int_fast8_t
+ if(my_int_fast8_t /= 3_c_int_fast8_t ) call abort()
if(my_int16_t /= 1_c_int16_t) call abort()
if(my_int_least16_t /= 2_c_int_least16_t) call abort()
- print *, 'c_int_fast16_t is: ', c_int_fast16_t
+ if(my_int_fast16_t /= 3_c_int_fast16_t ) call abort()
if(my_int32_t /= 1_c_int32_t) call abort()
if(my_int_least32_t /= 2_c_int_least32_t) call abort()
- print *, 'c_int_fast32_t is: ', c_int_fast32_t
+ if(my_int_fast32_t /= 3_c_int_fast32_t ) call abort()
if(my_int64_t /= 1_c_int64_t) call abort()
if(my_int_least64_t /= 2_c_int_least64_t) call abort()
- print *, 'c_int_fast64_t is: ', c_int_fast64_t
+ if(my_int_fast64_t /= 3_c_int_fast64_t ) call abort()
if(my_intmax_t /= 1_c_intmax_t) call abort()
if(my_intptr_t /= 0_c_intptr_t) call abort()
diff --git a/gcc/testsuite/gfortran.dg/c_kind_tests_2.f03 b/gcc/testsuite/gfortran.dg/c_kind_tests_2.f03
index ced31a554ba..aaaee978adc 100644
--- a/gcc/testsuite/gfortran.dg/c_kind_tests_2.f03
+++ b/gcc/testsuite/gfortran.dg/c_kind_tests_2.f03
@@ -4,11 +4,11 @@ module c_kind_tests_2
integer, parameter :: myF = c_float
real(myF), bind(c) :: myCFloat
- integer(myF), bind(c) :: myCInt ! { dg-error "is for type REAL" }
- integer(c_double), bind(c) :: myCInt2 ! { dg-error "is for type REAL" }
+ integer(myF), bind(c) :: myCInt ! { dg-warning "is for type REAL" }
+ integer(c_double), bind(c) :: myCInt2 ! { dg-warning "is for type REAL" }
integer, parameter :: myI = c_int
- real(myI) :: myReal ! { dg-error "is for type INTEGER" }
- real(myI), bind(c) :: myCFloat2 ! { dg-error "is for type INTEGER" }
+ real(myI) :: myReal ! { dg-warning "is for type INTEGER" }
+ real(myI), bind(c) :: myCFloat2 ! { dg-warning "is for type INTEGER" }
real(4), bind(c) :: myFloat ! { dg-warning "may not be a C interoperable" }
end module c_kind_tests_2
diff --git a/gcc/testsuite/gfortran.dg/c_kinds.c b/gcc/testsuite/gfortran.dg/c_kinds.c
index f79a70f7532..8fb658a98e8 100644
--- a/gcc/testsuite/gfortran.dg/c_kinds.c
+++ b/gcc/testsuite/gfortran.dg/c_kinds.c
@@ -3,15 +3,14 @@
#include <stdint.h>
-/* Note: int_fast*_t is currently not supported, cf. PR 448 */
void param_test(short int my_short, int my_int, long int my_long,
long long int my_long_long, int8_t my_int8_t,
- int_least8_t my_int_least8_t, /*int_fast8_t my_int_fast8_t,*/
+ int_least8_t my_int_least8_t, int_fast8_t my_int_fast8_t,
int16_t my_int16_t, int_least16_t my_int_least16_t,
- /*int_fast16_t my_int_fast16_t,*/ int32_t my_int32_t,
- int_least32_t my_int_least32_t, /*int_fast32_t my_int_fast32_t,*/
+ int_fast16_t my_int_fast16_t, int32_t my_int32_t,
+ int_least32_t my_int_least32_t, int_fast32_t my_int_fast32_t,
int64_t my_int64_t, int_least64_t my_int_least64_t,
- /*int_fast64_t my_int_fast64_t,*/ intmax_t my_intmax_t,
+ int_fast64_t my_int_fast64_t, intmax_t my_intmax_t,
intptr_t my_intptr_t, float my_float, double my_double,
long double my_long_double, char my_char, _Bool my_bool);
@@ -43,10 +42,10 @@ int main(int argc, char **argv)
_Bool my_bool = 1;
param_test(my_short, my_int, my_long, my_long_long, my_int8_t,
- my_int_least8_t, /*my_int_fast8_t, */ my_int16_t,
- my_int_least16_t,/* my_int_fast16_t,*/ my_int32_t,
- my_int_least32_t,/* my_int_fast32_t,*/ my_int64_t,
- my_int_least64_t,/* my_int_fast64_t,*/ my_intmax_t,
+ my_int_least8_t, my_int_fast8_t, my_int16_t,
+ my_int_least16_t, my_int_fast16_t, my_int32_t,
+ my_int_least32_t, my_int_fast32_t, my_int64_t,
+ my_int_least64_t, my_int_fast64_t, my_intmax_t,
my_intptr_t, my_float, my_double, my_long_double, my_char,
my_bool);
diff --git a/gcc/testsuite/gfortran.dg/count_init_expr.f03 b/gcc/testsuite/gfortran.dg/count_init_expr.f03
new file mode 100644
index 00000000000..73a8efa9565
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/count_init_expr.f03
@@ -0,0 +1,15 @@
+! { dg-do "run" }
+
+ INTEGER :: i
+ INTEGER, PARAMETER :: m(4,4) = RESHAPE([ (i, i=1, 16) ], [4, 4] )
+ INTEGER, PARAMETER :: sevens = COUNT (m == 7)
+ INTEGER, PARAMETER :: odd(4) = COUNT (MOD(m, 2) == 1, dim=1)
+ INTEGER, PARAMETER :: even = COUNT (MOD(m, 2) == 0)
+
+ IF (sevens /= 1) CALL abort()
+ IF (ANY(odd /= [ 2,2,2,2 ])) CALL abort()
+ IF (even /= 8) CALL abort()
+
+ ! check the kind parameter
+ IF (KIND(COUNT (m == 7, KIND=2)) /= 2) CALL abort()
+END
diff --git a/gcc/testsuite/gfortran.dg/data_value_1.f90 b/gcc/testsuite/gfortran.dg/data_value_1.f90
new file mode 100644
index 00000000000..ea05a91d30d
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/data_value_1.f90
@@ -0,0 +1,14 @@
+! { dg-do compile }
+! Test the fix for PR40402, in which it was not detected that X
+! is not a constant and so the DATA statement did not have
+! a constant value expression.
+!
+! Contributed by Philippe Marguinaud <philippe.marguinaud@meteo.fr>
+!
+ TYPE POINT
+ REAL :: X
+ ENDTYPE
+ TYPE(POINT) :: P
+ DATA P / POINT(1.+X) / ! { dg-error "non-constant DATA value" }
+ print *, p
+ END
diff --git a/gcc/testsuite/gfortran.dg/debug/pr35154-dwarf2.f b/gcc/testsuite/gfortran.dg/debug/pr35154-dwarf2.f
index b7586ea6e18..bfd215d9736 100644
--- a/gcc/testsuite/gfortran.dg/debug/pr35154-dwarf2.f
+++ b/gcc/testsuite/gfortran.dg/debug/pr35154-dwarf2.f
@@ -1,6 +1,7 @@
C Test program for common block debugging. G. Helffrich 11 July 2004.
C { dg-do compile }
C { dg-skip-if "DWARF-2 only" { "*-*-*" } { "*" } { "-gdwarf-2" } }
+C { dg-skip-if "DWARF-2 only" { "*-*-*" } { "-g1" } { "" } }
C { dg-options "-dA" }
common i,j
common /label/l,m
diff --git a/gcc/testsuite/gfortran.dg/debug/pr37738.f b/gcc/testsuite/gfortran.dg/debug/pr37738.f
index b0a787b2e52..48e18841ac2 100644
--- a/gcc/testsuite/gfortran.dg/debug/pr37738.f
+++ b/gcc/testsuite/gfortran.dg/debug/pr37738.f
@@ -1,6 +1,7 @@
C PR debug/37738
C { dg-do compile }
C { dg-skip-if "DWARF-2 only" { "*-*-*" } { "*" } { "-gdwarf-2" } }
+C { dg-skip-if "DWARF-2 only" { "*-*-*" } { "-g1" } { "" } }
C { dg-options "-dA" }
subroutine a
diff --git a/gcc/testsuite/gfortran.dg/default_format_1.f90 b/gcc/testsuite/gfortran.dg/default_format_1.f90
index 1c6e71ebc71..e374f1b895d 100644
--- a/gcc/testsuite/gfortran.dg/default_format_1.f90
+++ b/gcc/testsuite/gfortran.dg/default_format_1.f90
@@ -1,4 +1,4 @@
-! { dg-do run { xfail spu-*-* } }
+! { dg-do run { xfail spu-*-* } }
! Test XFAILed on Darwin because the system's printf() lacks
! proper support for denormals.
!
diff --git a/gcc/testsuite/gfortran.dg/default_format_denormal_1.f90 b/gcc/testsuite/gfortran.dg/default_format_denormal_1.f90
index adecd50c4d0..debc113ffc1 100644
--- a/gcc/testsuite/gfortran.dg/default_format_denormal_1.f90
+++ b/gcc/testsuite/gfortran.dg/default_format_denormal_1.f90
@@ -1,4 +1,4 @@
-! { dg-do run { xfail alpha*-*-* *-*-darwin[89]* *-*-freebsd* *-*-mingw* spu-*-* } }
+! { dg-do run { xfail alpha*-*-* *-*-darwin[89]* *-*-freebsd* *-*-mingw* *-*-cygwin* spu-*-* } }
! Test XFAILed on these platforms because the system's printf() lacks
! proper support for denormals.
!
diff --git a/gcc/testsuite/gfortran.dg/dot_product_1.f03 b/gcc/testsuite/gfortran.dg/dot_product_1.f03
new file mode 100644
index 00000000000..5ba663348b1
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dot_product_1.f03
@@ -0,0 +1,11 @@
+! { dg-do "run" }
+! Transformational intrinsic DOT_PRODUCT as initialization expression.
+
+ INTEGER, PARAMETER :: n = 10
+ INTEGER, PARAMETER :: a(n) = 1
+ INTEGER, PARAMETER :: p = DOT_PRODUCT(a, a)
+ INTEGER, PARAMETER :: e = DOT_PRODUCT(SHAPE(1), SHAPE(1))
+
+ IF (p /= n) CALL abort()
+ IF (e /= 0) CALL abort()
+END
diff --git a/gcc/testsuite/gfortran.dg/dummy_procedure_1.f90 b/gcc/testsuite/gfortran.dg/dummy_procedure_1.f90
index 6d681436125..57d4bc38e9e 100644
--- a/gcc/testsuite/gfortran.dg/dummy_procedure_1.f90
+++ b/gcc/testsuite/gfortran.dg/dummy_procedure_1.f90
@@ -21,6 +21,9 @@ contains
end function f
end interface
end subroutine s1
+ subroutine s2(x)
+ integer :: x
+ end subroutine
end module m1
use m1
@@ -38,6 +41,7 @@ end module m1
call s1(x) ! explicit interface
call s1(y) ! declared external
call s1(z) ! { dg-error "Expected a procedure for argument" }
+ call s2(x) ! { dg-error "Invalid procedure argument" }
contains
integer function w()
w = 1
diff --git a/gcc/testsuite/gfortran.dg/duplicate_type_2.f90 b/gcc/testsuite/gfortran.dg/duplicate_type_2.f90
index 5b86dc6e775..0fd9258fe80 100644
--- a/gcc/testsuite/gfortran.dg/duplicate_type_2.f90
+++ b/gcc/testsuite/gfortran.dg/duplicate_type_2.f90
@@ -7,14 +7,14 @@
INTEGER FUNCTION foo ()
IMPLICIT NONE
- INTEGER :: foo ! { dg-warning "basic type of" }
- INTEGER :: foo ! { dg-warning "basic type of" }
+ INTEGER :: foo ! { dg-error "basic type of" }
+ INTEGER :: foo ! { dg-error "basic type of" }
foo = 42
END FUNCTION foo
INTEGER FUNCTION bar () RESULT (x)
IMPLICIT NONE
- INTEGER :: x ! { dg-warning "basic type of" }
+ INTEGER :: x ! { dg-error "basic type of" }
INTEGER :: y
INTEGER :: y ! { dg-error "basic type of" }
diff --git a/gcc/testsuite/gfortran.dg/duplicate_type_3.f90 b/gcc/testsuite/gfortran.dg/duplicate_type_3.f90
new file mode 100644
index 00000000000..802029db0ca
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/duplicate_type_3.f90
@@ -0,0 +1,48 @@
+! { dg-do compile }
+!
+! PR 39996: Double typing of function results not detected
+!
+! Contributed by Janus Weil <janus@gcc.gnu.org>
+
+ interface
+ real function A ()
+ end function
+ end interface
+ real :: A ! { dg-error "already has basic type of" }
+
+ real :: B
+ interface
+ real function B () ! { dg-error "already has basic type of" }
+ end function ! { dg-error "Expecting END INTERFACE statement" }
+ end interface
+
+ interface
+ function C ()
+ real :: C
+ end function
+ end interface
+ real :: C ! { dg-error "already has basic type of" }
+
+ real :: D
+ interface
+ function D ()
+ real :: D ! { dg-error "already has basic type of" }
+ end function
+ end interface
+
+ interface
+ function E () result (s)
+ real ::s
+ end function
+ end interface
+ real :: E ! { dg-error "already has basic type of" }
+
+ real :: F
+ interface
+ function F () result (s)
+ real ::s ! { dg-error "already has basic type of" }
+ end function F
+ end interface
+
+end
+
diff --git a/gcc/testsuite/gfortran.dg/elemental_dependency_1.f90 b/gcc/testsuite/gfortran.dg/elemental_dependency_1.f90
index 3e1f67b9a71..d76fad642e3 100644
--- a/gcc/testsuite/gfortran.dg/elemental_dependency_1.f90
+++ b/gcc/testsuite/gfortran.dg/elemental_dependency_1.f90
@@ -40,14 +40,14 @@ PROGRAM main
b = a
CALL double((a(1:sz-1)), a(2:sz)) ! paren expression, temporary created
-! { dg-final { scan-tree-dump-times "A\.17\\\[4\\\]" 1 "original" } }
+! { dg-final { scan-tree-dump-times "A\.16\\\[4\\\]" 1 "original" } }
IF (ANY(a /= (/ b(1), (2*b(i), i=1,sz-1) /))) CALL abort
b = a
CALL double(a(1:sz-1)+1, a(2:sz)) ! op expression, temporary created
-! { dg-final { scan-tree-dump-times "A\.26\\\[4\\\]" 1 "original" } }
+! { dg-final { scan-tree-dump-times "A\.25\\\[4\\\]" 1 "original" } }
IF (ANY(a /= (/ b(1), (2*b(i)+2, i=1,sz-1) /))) CALL abort
@@ -59,7 +59,7 @@ PROGRAM main
b = a
CALL double(self(a(1:sz-1)), a(2:sz)) ! function expr, temporary created
-! { dg-final { scan-tree-dump-times "A\.38\\\[4\\\]" 1 "original" } }
+! { dg-final { scan-tree-dump-times "A\.37\\\[4\\\]" 1 "original" } }
IF (ANY(a /= (/ b(1), (2*b(i), i=1,sz-1) /))) CALL abort
diff --git a/gcc/testsuite/gfortran.dg/erf_2.F90 b/gcc/testsuite/gfortran.dg/erf_2.F90
new file mode 100644
index 00000000000..d418d5fccb9
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/erf_2.F90
@@ -0,0 +1,52 @@
+! { dg-do run }
+! { dg-options "-fno-range-check -ffree-line-length-none " }
+! { dg-options "-fno-range-check -ffree-line-length-none -mieee" { target alpha*-*-* } } */
+!
+! Check that simplification functions and runtime library agree on ERF,
+! ERFC and ERFC_SCALED.
+
+program test
+ implicit none
+
+ interface check
+ procedure check_r4
+ procedure check_r8
+ end interface check
+
+ real(kind=4) :: x4
+ real(kind=8) :: x8
+
+#define CHECK(a) \
+ x8 = a ; x4 = a ; \
+ call check(erf(real(a,kind=8)), erf(x8)) ; \
+ call check(erf(real(a,kind=4)), erf(x4)) ; \
+ call check(erfc(real(a,kind=8)), erfc(x8)) ; \
+ call check(erfc(real(a,kind=4)), erfc(x4)) ; \
+ call check(erfc_scaled(real(a,kind=8)), erfc_scaled(x8)) ; \
+ call check(erfc_scaled(real(a,kind=4)), erfc_scaled(x4)) ;
+
+ CHECK(0.0)
+ CHECK(0.9)
+ CHECK(1.9)
+ CHECK(19.)
+ CHECK(190.)
+
+ CHECK(-0.0)
+ CHECK(-0.9)
+ CHECK(-1.9)
+ CHECK(-19.)
+ CHECK(-190.)
+
+contains
+
+ subroutine check_r4 (a, b)
+ real(kind=4), intent(in) :: a, b
+ if (abs(a - b) > 10 * spacing(a)) call abort
+ end subroutine
+
+ subroutine check_r8 (a, b)
+ real(kind=8), intent(in) :: a, b
+ if (abs(a - b) > 10 * spacing(a)) call abort
+ end subroutine
+
+end program test
diff --git a/gcc/testsuite/gfortran.dg/erfc_scaled_2.f90 b/gcc/testsuite/gfortran.dg/erfc_scaled_2.f90
new file mode 100644
index 00000000000..97fa91fb915
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/erfc_scaled_2.f90
@@ -0,0 +1,14 @@
+! { dg-do compile }
+!
+! Check that ERFC_SCALED can be used in initialization expressions
+ real, parameter :: r = 100*erfc_scaled(12.7)
+ integer(kind=int(r)) :: i
+
+ real(kind=8), parameter :: r8 = 100*erfc_scaled(6.77)
+ integer(kind=int(r8)) :: j
+
+ i = 12
+ j = 8
+ print *, i, j
+
+ end
diff --git a/gcc/testsuite/gfortran.dg/func_decl_2.f90 b/gcc/testsuite/gfortran.dg/func_decl_2.f90
index c2cc4403cd6..658883e65e2 100644
--- a/gcc/testsuite/gfortran.dg/func_decl_2.f90
+++ b/gcc/testsuite/gfortran.dg/func_decl_2.f90
@@ -1,8 +1,6 @@
! { dg-do compile }
! Test fix for PR16943 in which the double typing of
-! N caused an error. This is a common extension to the
-! F95 standard, so the error is only thrown for -std=f95
-! or -pedantic.
+! N caused an error.
!
! Contributed by Paul Thomas <pault@gcc.gnu.org>
!
@@ -14,7 +12,7 @@
integer function bugf(M) result (N)
integer, intent (in) :: M
- integer :: N ! { dg-warning "already has basic type of INTEGER" }
+ integer :: N ! { dg-error "already has basic type of INTEGER" }
N = M
return
end function bugf
diff --git a/gcc/testsuite/gfortran.dg/hollerith.f90 b/gcc/testsuite/gfortran.dg/hollerith.f90
index f9836155b57..21cbf66bdf6 100644
--- a/gcc/testsuite/gfortran.dg/hollerith.f90
+++ b/gcc/testsuite/gfortran.dg/hollerith.f90
@@ -99,10 +99,4 @@ end subroutine
! { dg-warning "Non-character in FORMAT tag" "" { target *-*-* } 39 }
-! { dg-warning "Character array in FORMAT tag" "" { target *-*-* } 43 }
-
-! { dg-warning "Character array in FORMAT tag" "" { target *-*-* } 45 }
-
-! { dg-warning "Character array in FORMAT tag" "" { target *-*-* } 47 }
-
! { dg-warning "Hollerith constant" "" { target *-*-* } 51 }
diff --git a/gcc/testsuite/gfortran.dg/hollerith6.f90 b/gcc/testsuite/gfortran.dg/hollerith6.f90
new file mode 100644
index 00000000000..93e857dd511
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/hollerith6.f90
@@ -0,0 +1,35 @@
+! PR fortran/39865
+! { dg-do run }
+
+subroutine foo (a)
+ integer(kind=4) :: a(1, 3)
+ character(len=40) :: t
+ write (t, fmt=a(1,2)) 1, 2, 3, 4, 5, 6, 7, 8
+ if (t .ne. ' 1 2 3 4 5 6 7 8') call abort
+end subroutine foo
+ interface
+ subroutine foo (a)
+ integer(kind=4) :: a(1, 3)
+ end subroutine foo
+ end interface
+ integer(kind=4) :: b(1,3)
+ character(len=40) :: t
+ b(1,1) = 4HXXXX
+ b(1,2) = 4H (8I
+ b(1,3) = 2H4)
+ write (t, fmt=b(1,2)) 1, 2, 3, 4, 5, 6, 7, 8
+ if (t .ne. ' 1 2 3 4 5 6 7 8') call abort
+ call foo (b)
+end
+
+! { dg-warning "Non-character in FORMAT tag" "FMT" { target *-*-* } 7 }
+! { dg-warning "Non-character in FORMAT tag" "FMT" { target *-*-* } 20 }
+
+! { dg-warning "Hollerith constant" "const" { target *-*-* } 17 }
+! { dg-warning "Conversion" "conversion" { target *-*-* } 17 }
+
+! { dg-warning "Hollerith constant" "const" { target *-*-* } 18 }
+! { dg-warning "Conversion" "conversion" { target *-*-* } 18 }
+
+! { dg-warning "Hollerith constant" "const" { target *-*-* } 19 }
+! { dg-warning "Conversion" "conversion" { target *-*-* } 19 }
diff --git a/gcc/testsuite/gfortran.dg/hollerith7.f90 b/gcc/testsuite/gfortran.dg/hollerith7.f90
new file mode 100644
index 00000000000..8e2fb4fec12
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/hollerith7.f90
@@ -0,0 +1,52 @@
+! PR fortran/39865
+! { dg-do compile }
+
+subroutine foo (a)
+ integer(kind=4), target :: a(1:, 1:)
+ integer(kind=4), pointer :: b(:, :)
+ b => a
+ write (*, fmt=a(1,2)) 1, 2, 3, 4, 5, 6, 7, 8
+ write (*, fmt=b(1,2)) 1, 2, 3, 4, 5, 6, 7, 8
+end subroutine foo
+subroutine bar (a, b)
+ character :: b(2,*)
+ integer :: a(*)
+ write (*, fmt=b) 1, 2, 3
+ write (*, fmt=a) 1, 2, 3
+ write (*, fmt=a(2)) 1, 2, 3
+end subroutine
+ interface
+ subroutine foo (a)
+ integer(kind=4), target :: a(:, :)
+ end subroutine foo
+ end interface
+ integer(kind=4) :: a(2, 3)
+ a = 4HXXXX
+ a(2,2) = 4H (8I
+ a(1,3) = 2H4)
+ a(2,3) = 1H
+ call foo (a(2:2,:))
+end
+
+! { dg-warning "Non-character in FORMAT tag" "FMT" { target *-*-* } 8 }
+! { dg-error "Non-character assumed shape array element in FORMAT tag" "element" { target *-*-* } 8 }
+
+! { dg-warning "Non-character in FORMAT tag" "FMT" { target *-*-* } 9 }
+! { dg-error "Non-character pointer array element in FORMAT tag" "element" { target *-*-* } 9 }
+
+! { dg-error "reference to the assumed size array" "assumed-size" { target *-*-* } 14 }
+! { dg-error "reference to the assumed size array" "assumed-size" { target *-*-* } 15 }
+! { dg-warning "Non-character in FORMAT tag" "FMT" { target *-*-* } 16 }
+! { dg-error "Non-character assumed size array element in FORMAT tag" "element" { target *-*-* } 16 }
+
+! { dg-warning "Hollerith constant" "const" { target *-*-* } 24 }
+! { dg-warning "Conversion" "conversion" { target *-*-* } 24 }
+
+! { dg-warning "Hollerith constant" "const" { target *-*-* } 25 }
+! { dg-warning "Conversion" "conversion" { target *-*-* } 25 }
+
+! { dg-warning "Hollerith constant" "const" { target *-*-* } 26 }
+! { dg-warning "Conversion" "conversion" { target *-*-* } 26 }
+
+! { dg-warning "Hollerith constant" "const" { target *-*-* } 27 }
+! { dg-warning "Conversion" "conversion" { target *-*-* } 27 }
diff --git a/gcc/testsuite/gfortran.dg/hollerith_f95.f90 b/gcc/testsuite/gfortran.dg/hollerith_f95.f90
index 1ba74036c26..4d7fda8c72e 100644
--- a/gcc/testsuite/gfortran.dg/hollerith_f95.f90
+++ b/gcc/testsuite/gfortran.dg/hollerith_f95.f90
@@ -91,10 +91,3 @@ end subroutine
! { dg-error "Non-character in FORMAT tag" "" { target *-*-* } 38 }
! { dg-error "Non-character in FORMAT tag" "" { target *-*-* } 40 }
-
-! { dg-error "Character array in FORMAT tag" "" { target *-*-* } 44 }
-
-! { dg-error "Character array in FORMAT tag" "" { target *-*-* } 46 }
-
-! { dg-error "Character array in FORMAT tag" "" { target *-*-* } 48 }
-
diff --git a/gcc/testsuite/gfortran.dg/interface_20.f90 b/gcc/testsuite/gfortran.dg/interface_20.f90
index 2d7df47eb8e..829add2ff9b 100644
--- a/gcc/testsuite/gfortran.dg/interface_20.f90
+++ b/gcc/testsuite/gfortran.dg/interface_20.f90
@@ -16,5 +16,5 @@ end module m
use m
implicit none
intrinsic cos
-call sub(cos) ! { dg-error "Type/rank mismatch in argument" }
+call sub(cos) ! { dg-error "wrong number of arguments" }
end
diff --git a/gcc/testsuite/gfortran.dg/interface_21.f90 b/gcc/testsuite/gfortran.dg/interface_21.f90
index fea6507b05d..e3db771a93d 100644
--- a/gcc/testsuite/gfortran.dg/interface_21.f90
+++ b/gcc/testsuite/gfortran.dg/interface_21.f90
@@ -18,5 +18,5 @@ end module m
use m
implicit none
EXTERNAL foo ! implicit interface is undefined
-call sub(foo) ! { dg-error "Type/rank mismatch in argument" }
+call sub(foo) ! { dg-error "is not a function" }
end
diff --git a/gcc/testsuite/gfortran.dg/interface_26.f90 b/gcc/testsuite/gfortran.dg/interface_26.f90
index 0778345c3e5..c1af6c67d58 100644
--- a/gcc/testsuite/gfortran.dg/interface_26.f90
+++ b/gcc/testsuite/gfortran.dg/interface_26.f90
@@ -37,7 +37,7 @@ CONTAINS
END INTERFACE
INTEGER, EXTERNAL :: UserOp
- res = UserFunction( a,b, UserOp ) ! { dg-error "Type/rank mismatch in argument" }
+ res = UserFunction( a,b, UserOp ) ! { dg-error "Type/kind mismatch in return value" }
if( res .lt. 10 ) then
res = recSum( a, res, UserFunction, UserOp )
diff --git a/gcc/testsuite/gfortran.dg/interface_27.f90 b/gcc/testsuite/gfortran.dg/interface_27.f90
new file mode 100644
index 00000000000..71975b6b7d2
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/interface_27.f90
@@ -0,0 +1,41 @@
+! { dg-do compile }
+!
+! PR 40039: Procedures as actual arguments: Check intent of arguments
+!
+! Contributed by Janus Weil <janus@gcc.gnu.org>
+
+module m
+
+contains
+
+subroutine a(x,f)
+ real :: x
+ interface
+ real function f(y)
+ real,intent(in) :: y
+ end function
+ end interface
+ print *,f(x)
+end subroutine
+
+real function func(z)
+ real,intent(inout) :: z
+ func = z**2
+end function
+
+subroutine caller
+ interface
+ real function p(y)
+ real,intent(in) :: y
+ end function
+ end interface
+ pointer :: p
+
+ call a(4.3,func) ! { dg-error "INTENT mismatch in argument" }
+ p => func ! { dg-error "INTENT mismatch in argument" }
+end subroutine
+
+end module
+
+! { dg-final { cleanup-modules "m" } }
+
diff --git a/gcc/testsuite/gfortran.dg/interface_28.f90 b/gcc/testsuite/gfortran.dg/interface_28.f90
new file mode 100644
index 00000000000..42a8208f4b3
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/interface_28.f90
@@ -0,0 +1,43 @@
+! { dg-do compile }
+!
+! PR 36947: Attributes not fully checked comparing actual vs dummy procedure
+!
+! Original test case by Walter Spector <w6ws@earthlink.net>
+! Modified by Janus Weil <janus@gcc.gnu.org>
+
+module testsub
+ contains
+ subroutine test(sub)
+ interface
+ subroutine sub(x)
+ integer, intent(in), optional:: x
+ end subroutine
+ end interface
+ call sub()
+ end subroutine
+end module
+
+module sub
+ contains
+ subroutine subActual(x)
+ ! actual subroutine's argment is different in intent
+ integer, intent(inout),optional:: x
+ end subroutine
+ subroutine subActual2(x)
+ ! actual subroutine's argment is missing OPTIONAL
+ integer, intent(in):: x
+ end subroutine
+end module
+
+program interfaceCheck
+ use testsub
+ use sub
+
+ integer :: a
+
+ call test(subActual) ! { dg-error "INTENT mismatch in argument" }
+ call test(subActual2) ! { dg-error "OPTIONAL mismatch in argument" }
+end program
+
+! { dg-final { cleanup-modules "sub testsub" } }
+
diff --git a/gcc/testsuite/gfortran.dg/interface_29.f90 b/gcc/testsuite/gfortran.dg/interface_29.f90
new file mode 100644
index 00000000000..e94571f43e1
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/interface_29.f90
@@ -0,0 +1,52 @@
+! { dg-do compile }
+!
+! PR 36947: Attributes not fully checked comparing actual vs dummy procedure
+!
+! Contributed by Tobias Burnus <burnus@net-b.de>
+
+module m
+interface foo
+ module procedure one, two
+end interface foo
+contains
+subroutine one(op,op2)
+ interface
+ subroutine op(x, y)
+ complex, intent(in) :: x(:)
+ complex, intent(out) :: y(:)
+ end subroutine op
+ subroutine op2(x, y)
+ complex, intent(in) :: x(:)
+ complex, intent(out) :: y(:)
+ end subroutine op2
+ end interface
+end subroutine one
+subroutine two(ops,i,j)
+ interface
+ subroutine op(x, y)
+ complex, intent(in) :: x(:)
+ complex, intent(out) :: y(:)
+ end subroutine op
+ end interface
+ real :: i,j
+end subroutine two
+end module m
+
+module test
+contains
+subroutine bar()
+ use m
+ call foo(precond_prop,prop2)
+end subroutine bar
+ subroutine precond_prop(x, y)
+ complex, intent(in) :: x(:)
+ complex, intent(out) :: y(:)
+ end subroutine
+ subroutine prop2(x, y)
+ complex, intent(in) :: x(:)
+ complex, intent(out) :: y(:)
+ end subroutine
+end module test
+
+! { dg-final { cleanup-modules "m" } }
+
diff --git a/gcc/testsuite/gfortran.dg/interop_params.f03 b/gcc/testsuite/gfortran.dg/interop_params.f03
index 96c7d5cef16..ea3dadac040 100644
--- a/gcc/testsuite/gfortran.dg/interop_params.f03
+++ b/gcc/testsuite/gfortran.dg/interop_params.f03
@@ -14,7 +14,7 @@ contains
end subroutine test_0
subroutine test_1(my_f90_real) bind(c)
- real(c_int), value :: my_f90_real ! { dg-error "is for type INTEGER" }
+ real(c_int), value :: my_f90_real ! { dg-warning "is for type INTEGER" }
end subroutine test_1
subroutine test_2(my_type) bind(c) ! { dg-error "is not C interoperable" }
diff --git a/gcc/testsuite/gfortran.dg/intrinsic_argument_conformance_2.f90 b/gcc/testsuite/gfortran.dg/intrinsic_argument_conformance_2.f90
index 44a4b39f742..daff64f8065 100644
--- a/gcc/testsuite/gfortran.dg/intrinsic_argument_conformance_2.f90
+++ b/gcc/testsuite/gfortran.dg/intrinsic_argument_conformance_2.f90
@@ -34,11 +34,11 @@ program main
b2 = eoshift (a2,1,boundary=c2(:,:)) ! { dg-error "have rank 1 or be a scalar" }
b2 = eoshift (a2,(/1/), boundary=c2(:,:)) ! { dg-error "have rank 1 or be a scalar" }
- b = eoshift (a,(/1/), boundary=c(1,:)) ! { dg-error "Different shape in dimension 1" }
+ b = eoshift (a,(/1/), boundary=c(1,:)) ! { dg-error "invalid shape in dimension" }
if (any(eoshift(foo,dim=1,shift=1,boundary=(/42.0,-7.0/))/= 0)) call abort() ! { dg-error "must be a scalar" }
if (any(eoshift(tempn(2:1),dim=1,shift=1,boundary=(/42.0,-7.0/))/= 0)) call abort() ! { dg-error "must be a scalar" }
- if (any(unpack(tempv,tempv(1:0)/=0,tempv) /= -47)) call abort() ! { dg-error "Different shape" }
- if (any(unpack(tempv(5:4),tempv(1:0)/=0,tempv) /= -47)) call abort() ! { dg-error "Different shape" }
+ if (any(unpack(tempv,tempv(1:0)/=0,tempv) /= -47)) call abort() ! { dg-error "must have identical shape" }
+ if (any(unpack(tempv(5:4),tempv(1:0)/=0,tempv) /= -47)) call abort() ! { dg-error "must have identical shape" }
end program main
diff --git a/gcc/testsuite/gfortran.dg/is_iostat_end_eor_2.f90 b/gcc/testsuite/gfortran.dg/is_iostat_end_eor_2.f90
new file mode 100644
index 00000000000..eda9d31df19
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/is_iostat_end_eor_2.f90
@@ -0,0 +1,39 @@
+! Check that we correctly simplify IS_IOSTAT_END and IS_IOSTAT_EOR.
+! Not very useful, but required by the standards
+!
+! This test relies on the error numbers for END and EOR being -1 and -2.
+! This is good to actual
+!
+! { dg-do compile }
+!
+
+ use iso_fortran_env, only : iostat_end, iostat_eor
+ implicit none
+
+ integer(kind=merge(4, 0, is_iostat_end(-1))) :: a
+ integer(kind=merge(4, 0, is_iostat_end(-1_1))) :: b
+ integer(kind=merge(4, 0, is_iostat_end(-1_2))) :: c
+ integer(kind=merge(4, 0, is_iostat_end(-1_4))) :: d
+ integer(kind=merge(4, 0, is_iostat_end(-1_8))) :: e
+
+ integer(kind=merge(4, 0, is_iostat_eor(-2))) :: f
+ integer(kind=merge(4, 0, is_iostat_eor(-2_1))) :: g
+ integer(kind=merge(4, 0, is_iostat_eor(-2_2))) :: h
+ integer(kind=merge(4, 0, is_iostat_eor(-2_4))) :: i
+ integer(kind=merge(4, 0, is_iostat_eor(-2_8))) :: j
+
+ integer(kind=merge(0, 4, is_iostat_eor(-1))) :: k
+ integer(kind=merge(0, 4, is_iostat_end(-2))) :: l
+
+ integer(kind=merge(0, 4, is_iostat_eor(0))) :: m
+ integer(kind=merge(0, 4, is_iostat_end(0))) :: n
+
+ integer(kind=merge(4, 0, is_iostat_end(0))) :: o ! { dg-error "not supported for type" }
+ integer(kind=merge(4, 0, is_iostat_eor(0))) :: p ! { dg-error "not supported for type" }
+
+ integer(kind=merge(4, 0, is_iostat_eor(iostat_eor))) :: q
+ integer(kind=merge(4, 0, is_iostat_end(iostat_end))) :: r
+ integer(kind=merge(0, 4, is_iostat_end(iostat_eor))) :: s
+ integer(kind=merge(0, 4, is_iostat_eor(iostat_end))) :: t
+
+ end
diff --git a/gcc/testsuite/gfortran.dg/leadz_trailz_1.f90 b/gcc/testsuite/gfortran.dg/leadz_trailz_1.f90
new file mode 100644
index 00000000000..a0cd1979225
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/leadz_trailz_1.f90
@@ -0,0 +1,133 @@
+! { dg-do run }
+
+ integer(kind=1) :: i1
+ integer(kind=2) :: i2
+ integer(kind=4) :: i4
+ integer(kind=8) :: i8
+
+ i1 = -1
+ i2 = -1
+ i4 = -1
+ i8 = -1
+
+ if (leadz(i1) /= 0) call abort
+ if (leadz(i2) /= 0) call abort
+ if (leadz(i4) /= 0) call abort
+ if (leadz(i8) /= 0) call abort
+
+ if (trailz(i1) /= 0) call abort
+ if (trailz(i2) /= 0) call abort
+ if (trailz(i4) /= 0) call abort
+ if (trailz(i8) /= 0) call abort
+
+ if (leadz(-1_1) /= 0) call abort
+ if (leadz(-1_2) /= 0) call abort
+ if (leadz(-1_4) /= 0) call abort
+ if (leadz(-1_8) /= 0) call abort
+
+ if (trailz(-1_1) /= 0) call abort
+ if (trailz(-1_2) /= 0) call abort
+ if (trailz(-1_4) /= 0) call abort
+ if (trailz(-1_8) /= 0) call abort
+
+ i1 = -64
+ i2 = -64
+ i4 = -64
+ i8 = -64
+
+ if (leadz(i1) /= 0) call abort
+ if (leadz(i2) /= 0) call abort
+ if (leadz(i4) /= 0) call abort
+ if (leadz(i8) /= 0) call abort
+
+ if (trailz(i1) /= 6) call abort
+ if (trailz(i2) /= 6) call abort
+ if (trailz(i4) /= 6) call abort
+ if (trailz(i8) /= 6) call abort
+
+ if (leadz(-64_1) /= 0) call abort
+ if (leadz(-64_2) /= 0) call abort
+ if (leadz(-64_4) /= 0) call abort
+ if (leadz(-64_8) /= 0) call abort
+
+ if (trailz(-64_1) /= 6) call abort
+ if (trailz(-64_2) /= 6) call abort
+ if (trailz(-64_4) /= 6) call abort
+ if (trailz(-64_8) /= 6) call abort
+
+ i1 = -108
+ i2 = -108
+ i4 = -108
+ i8 = -108
+
+ if (leadz(i1) /= 0) call abort
+ if (leadz(i2) /= 0) call abort
+ if (leadz(i4) /= 0) call abort
+ if (leadz(i8) /= 0) call abort
+
+ if (trailz(i1) /= 2) call abort
+ if (trailz(i2) /= 2) call abort
+ if (trailz(i4) /= 2) call abort
+ if (trailz(i8) /= 2) call abort
+
+ if (leadz(-108_1) /= 0) call abort
+ if (leadz(-108_2) /= 0) call abort
+ if (leadz(-108_4) /= 0) call abort
+ if (leadz(-108_8) /= 0) call abort
+
+ if (trailz(-108_1) /= 2) call abort
+ if (trailz(-108_2) /= 2) call abort
+ if (trailz(-108_4) /= 2) call abort
+ if (trailz(-108_8) /= 2) call abort
+
+ i1 = 1
+ i2 = 1
+ i4 = 1
+ i8 = 1
+
+ if (leadz(i1) /= bit_size(i1) - 1) call abort
+ if (leadz(i2) /= bit_size(i2) - 1) call abort
+ if (leadz(i4) /= bit_size(i4) - 1) call abort
+ if (leadz(i8) /= bit_size(i8) - 1) call abort
+
+ if (trailz(i1) /= 0) call abort
+ if (trailz(i2) /= 0) call abort
+ if (trailz(i4) /= 0) call abort
+ if (trailz(i8) /= 0) call abort
+
+ if (leadz(1_1) /= bit_size(1_1) - 1) call abort
+ if (leadz(1_2) /= bit_size(1_2) - 1) call abort
+ if (leadz(1_4) /= bit_size(1_4) - 1) call abort
+ if (leadz(1_8) /= bit_size(1_8) - 1) call abort
+
+ if (trailz(1_1) /= 0) call abort
+ if (trailz(1_2) /= 0) call abort
+ if (trailz(1_4) /= 0) call abort
+ if (trailz(1_8) /= 0) call abort
+
+ i1 = 64
+ i2 = 64
+ i4 = 64
+ i8 = 64
+
+ if (leadz(i1) /= 1) call abort
+ if (leadz(i2) /= 9) call abort
+ if (leadz(i4) /= 25) call abort
+ if (leadz(i8) /= 57) call abort
+
+ if (trailz(i1) /= 6) call abort
+ if (trailz(i2) /= 6) call abort
+ if (trailz(i4) /= 6) call abort
+ if (trailz(i8) /= 6) call abort
+
+ if (leadz(64_1) /= 1) call abort
+ if (leadz(64_2) /= 9) call abort
+ if (leadz(64_4) /= 25) call abort
+ if (leadz(64_8) /= 57) call abort
+
+ if (trailz(64_1) /= 6) call abort
+ if (trailz(64_2) /= 6) call abort
+ if (trailz(64_4) /= 6) call abort
+ if (trailz(64_8) /= 6) call abort
+
+end
diff --git a/gcc/testsuite/gfortran.dg/leadz_trailz_2.f90 b/gcc/testsuite/gfortran.dg/leadz_trailz_2.f90
new file mode 100644
index 00000000000..08701d8a537
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/leadz_trailz_2.f90
@@ -0,0 +1,36 @@
+! { dg-do run }
+! { dg-require-effective-target fortran_large_int }
+
+ integer(kind=16) :: i16
+
+ i16 = -1
+ if (leadz(i16) /= 0) call abort
+ if (trailz(i16) /= 0) call abort
+ if (leadz(-1_16) /= 0) call abort
+ if (trailz(-1_16) /= 0) call abort
+
+ i16 = -64
+ if (leadz(i16) /= 0) call abort
+ if (trailz(i16) /= 6) call abort
+ if (leadz(-64_16) /= 0) call abort
+ if (trailz(-64_16) /= 6) call abort
+
+ i16 = -108
+ if (leadz(i16) /= 0) call abort
+ if (trailz(i16) /= 2) call abort
+ if (leadz(-108_16) /= 0) call abort
+ if (trailz(-108_16) /= 2) call abort
+
+ i16 = 1
+ if (leadz(i16) /= bit_size(i16) - 1) call abort
+ if (trailz(i16) /= 0) call abort
+ if (leadz(1_16) /= bit_size(1_16) - 1) call abort
+ if (trailz(1_16) /= 0) call abort
+
+ i16 = 64
+ if (leadz(i16) /= 121) call abort
+ if (trailz(i16) /= 6) call abort
+ if (leadz(64_16) /= 121) call abort
+ if (trailz(64_16) /= 6) call abort
+
+end
diff --git a/gcc/testsuite/gfortran.dg/matmul_8.f03 b/gcc/testsuite/gfortran.dg/matmul_8.f03
new file mode 100644
index 00000000000..d73fdcd07bd
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/matmul_8.f03
@@ -0,0 +1,12 @@
+! { dg-do "run" }
+! Transformational intrinsic MATMUL as initialization expression.
+
+ REAL, PARAMETER :: PI = 3.141592654, theta = PI/6.0
+
+ REAL, PARAMETER :: unity(2,2) = RESHAPE([1.0, 0.0, 0.0, 1.0], [2, 2])
+ REAL, PARAMETER :: m1(2,2) = RESHAPE([COS(theta), SIN(theta), -SIN(theta), COS(theta)], [2, 2])
+ REAL, PARAMETER :: m2(2,2) = RESHAPE([COS(theta), -SIN(theta), SIN(theta), COS(theta)], [2, 2])
+ REAL, PARAMETER :: m(2,2) = MATMUL(m1, m2)
+
+ IF (ANY(ABS(m - unity) > EPSILON(0.0))) CALL abort()
+END
diff --git a/gcc/testsuite/gfortran.dg/nan_5.f90 b/gcc/testsuite/gfortran.dg/nan_5.f90
new file mode 100644
index 00000000000..64886bed0cf
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/nan_5.f90
@@ -0,0 +1,28 @@
+! Check that we correctly simplify ISNAN
+!
+! { dg-do compile }
+!
+! { dg-options "-fno-range-check" }
+! { dg-options "-fno-range-check -mieee" { target alpha*-*-* sh*-*-* } }
+! { dg-skip-if "NaN not supported" { spu-*-* } { "*" } { "" } }
+
+ implicit none
+ real, parameter :: inf = 2 * huge(inf)
+ real, parameter :: nan1 = 0. / 0.
+ real, parameter :: nan2 = 1.5 * nan1
+ real, parameter :: nan3 = inf / inf
+ real, parameter :: nan4 = inf - inf
+ real, parameter :: nan5 = 0. * inf
+ real, parameter :: normal = 42.
+
+ integer(kind=merge(4, 0, isnan(nan1))) :: a
+ integer(kind=merge(4, 0, isnan(nan2))) :: b
+ integer(kind=merge(4, 0, isnan(nan3))) :: c
+ integer(kind=merge(4, 0, isnan(nan4))) :: d
+ integer(kind=merge(4, 0, isnan(nan5))) :: e
+
+ integer(kind=merge(0, 4, isnan(inf))) :: f
+ integer(kind=merge(0, 4, isnan(-inf))) :: g
+ integer(kind=merge(0, 4, isnan(normal))) :: h
+
+ end
diff --git a/gcc/testsuite/gfortran.dg/negative_unit.f b/gcc/testsuite/gfortran.dg/negative_unit.f
index 4f942e27e98..f1733a8888f 100644
--- a/gcc/testsuite/gfortran.dg/negative_unit.f
+++ b/gcc/testsuite/gfortran.dg/negative_unit.f
@@ -6,20 +6,19 @@
! Test case update by Jerry DeLisle <jvdelisle@gcc.gnu.org>
!
! Bugs submitted by Walt Brainerd
- integer i
+ integer i,j
logical l
- i = 0
+ i = -1
! gfortran created a 'fort.-1' file and wrote "Hello" in it
- write (unit=-1, fmt=*, iostat=i) "Hello"
- if (i <= 0) call abort
+ write (unit=i, fmt=*, iostat=j) "Hello"
+ if (j <= 0) call abort
- i = 0
- open (unit=-11, file="xxx", iostat=i)
- if (i <= 0) call abort
+ i = -11
+ open (unit=i, file="xxx", iostat=j)
+ if (j <= 0) call abort
- i = 0
- inquire (unit=-42, exist=l)
+ i = -42
+ inquire (unit=i, exist=l)
if (l) call abort
-
end
diff --git a/gcc/testsuite/gfortran.dg/negative_unit_int8.f b/gcc/testsuite/gfortran.dg/negative_unit_int8.f
index 53a7daa8c25..d4c35579f04 100644
--- a/gcc/testsuite/gfortran.dg/negative_unit_int8.f
+++ b/gcc/testsuite/gfortran.dg/negative_unit_int8.f
@@ -13,22 +13,22 @@
integer, parameter ::ERROR_BAD_UNIT = 5005
logical l
- i = 0
+ i = -1
! gfortran created a 'fort.-1' file and wrote "Hello" in it
- write (unit=-1, fmt=*, iostat=i) "Hello"
+ write (unit=i, fmt=*, iostat=i) "Hello"
if (i <= 0) call abort
- i = 0
- open (unit=-11, file="xxx", iostat=i)
+ i = -11
+ open (unit=i, file="xxx", iostat=i)
if (i <= 0) call abort
- i = 0
- inquire (unit=-42, exist=l)
+ i = -42
+ inquire (unit=i, exist=l)
if (l) call abort
- i = 0
+ i = 2_8*huge(0_4)+20_8
! This one is nasty
- inquire (unit=2_8*huge(0_4)+20_8, exist=l, iostat=i)
+ inquire (unit=i, exist=l, iostat=i)
if (l) call abort
if (i.ne.ERROR_BAD_UNIT) call abort
diff --git a/gcc/testsuite/gfortran.dg/newunit_1.f90 b/gcc/testsuite/gfortran.dg/newunit_1.f90
new file mode 100644
index 00000000000..3a0c0b98cbe
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/newunit_1.f90
@@ -0,0 +1,20 @@
+! { dg-do run }
+! PR40008 F2008: Add NEWUNIT= for OPEN statement
+! Contributed by Jerry DeLisle <jvdelisle@gcc.gnu.org>
+program newunit_1
+ character(len=25) :: str
+ integer(1) :: myunit, myunit2
+ myunit = 25
+ str = "bad"
+ open(newunit=myunit, status="scratch")
+ open(newunit = myunit2, file="newunit_1file")
+ write(myunit,'(e24.15e2)') 1.0d0
+ write(myunit2,*) "abcdefghijklmnop"
+ flush(myunit)
+ rewind(myunit)
+ rewind(myunit2)
+ read(myunit2,'(a)') str
+ if (str.ne." abcdefghijklmnop") call abort
+ close(myunit)
+ close(myunit2, status="delete")
+end program newunit_1
diff --git a/gcc/testsuite/gfortran.dg/nullify_4.f90 b/gcc/testsuite/gfortran.dg/nullify_4.f90
new file mode 100644
index 00000000000..48dcf72ca9d
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/nullify_4.f90
@@ -0,0 +1,8 @@
+! { dg-do compile }
+! PR fortran/40246
+!
+! Check error recovery; was crashing before.
+!
+real, pointer :: ptr
+nullify(ptr, mesh%coarser) ! { dg-error "Syntax error in NULLIFY statement" }
+end
diff --git a/gcc/testsuite/gfortran.dg/pack_assign_1.f90 b/gcc/testsuite/gfortran.dg/pack_assign_1.f90
new file mode 100644
index 00000000000..4bab0da940e
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pack_assign_1.f90
@@ -0,0 +1,8 @@
+! { dg-do "compile" }
+! PR32890 - compile-time checks for assigments
+
+INTEGER :: it, neighbrs(42) ! anything but 30
+
+neighbrs = PACK((/ (it, it=1,30) /), (/ (it, it=1,30) /) < 3, (/ (0,it=1,30) /) ) ! { dg-error "Different shape" }
+
+END
diff --git a/gcc/testsuite/gfortran.dg/pack_vector_1.f90 b/gcc/testsuite/gfortran.dg/pack_vector_1.f90
new file mode 100644
index 00000000000..ba3624e7ef5
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pack_vector_1.f90
@@ -0,0 +1,10 @@
+! { dg-do "compile" }
+!
+! Check that the VECTOR argument of the PACK intrinsic has at least
+! as many elements as the MASK has .TRUE. values.
+!
+
+ INTEGER :: res(2)
+ res = PACK ((/ 1, 2, 3 /), (/.TRUE., .TRUE., .FALSE. /), SHAPE(1)) !{ dg-error "must provide at least as many" }
+ res = PACK ((/ 1, 2, 3 /), (/.TRUE., .TRUE., .FALSE. /), (/ -1 /)) !{ dg-error "must provide at least as many" }
+END
diff --git a/gcc/testsuite/gfortran.dg/pr25923.f90 b/gcc/testsuite/gfortran.dg/pr25923.f90
index f075944b92b..b6979ec8896 100644
--- a/gcc/testsuite/gfortran.dg/pr25923.f90
+++ b/gcc/testsuite/gfortran.dg/pr25923.f90
@@ -10,7 +10,7 @@ implicit none
contains
- function baz(arg) result(res) ! { dg-warning "res.yr' may be" }
+ function baz(arg) result(res) ! { dg-warning "res.yr' may be" "" { xfail *-*-* } }
type(bar), intent(in) :: arg
type(bar) :: res
logical, external:: some_func
diff --git a/gcc/testsuite/gfortran.dg/pr39865.f90 b/gcc/testsuite/gfortran.dg/pr39865.f90
new file mode 100644
index 00000000000..fac34367422
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr39865.f90
@@ -0,0 +1,84 @@
+! PR fortran/39865
+! { dg-do run }
+
+subroutine f1 (a)
+ character(len=1) :: a(7:)
+ character(len=12) :: b
+ character(len=1) :: c(2:10)
+ write (b, a) 'Hell', 'o wo', 'rld!'
+ if (b .ne. 'Hello world!') call abort
+ write (b, a(:)) 'hell', 'o Wo', 'rld!'
+ if (b .ne. 'hello World!') call abort
+ write (b, a(8:)) 'Hell', 'o wo', 'rld!'
+ if (b .ne. 'Hello world!') call abort
+ c(2) = ' '
+ c(3) = '('
+ c(4) = '3'
+ c(5) = 'A'
+ c(6) = '4'
+ c(7) = ')'
+ write (b, c) 'hell', 'o Wo', 'rld!'
+ if (b .ne. 'hello World!') call abort
+ write (b, c(:)) 'Hell', 'o wo', 'rld!'
+ if (b .ne. 'Hello world!') call abort
+ write (b, c(3:)) 'hell', 'o Wo', 'rld!'
+ if (b .ne. 'hello World!') call abort
+end subroutine f1
+
+subroutine f2 (a)
+ character(len=1) :: a(10:,20:)
+ character(len=12) :: b
+ write (b, a) 'Hell', 'o wo', 'rld!'
+ if (b .ne. 'Hello world!') call abort
+ write (b, a) 'hell', 'o Wo', 'rld!'
+ if (b .ne. 'hello World!') call abort
+end subroutine f2
+
+function f3 ()
+ character(len=1) :: f3(5)
+ f3(1) = '('
+ f3(2) = '3'
+ f3(3) = 'A'
+ f3(4) = '4'
+ f3(5) = ')'
+end function f3
+
+ interface
+ subroutine f1 (a)
+ character(len=1) :: a(:)
+ end
+ end interface
+ interface
+ subroutine f2 (a)
+ character(len=1) :: a(:,:)
+ end
+ end interface
+ interface
+ function f3 ()
+ character(len=1) :: f3(5)
+ end
+ end interface
+ integer :: i, j
+ character(len=1) :: e (6, 7:9), f (3,2), g (10)
+ character(len=12) :: b
+ e = 'X'
+ e(2,8) = ' '
+ e(3,8) = '('
+ e(4,8) = '3'
+ e(2,9) = 'A'
+ e(3,9) = '4'
+ e(4,9) = ')'
+ f = e(2:4,8:9)
+ g = 'X'
+ g(2) = ' '
+ g(3) = '('
+ g(4) = '3'
+ g(5) = 'A'
+ g(6) = '4'
+ g(7) = ')'
+ call f1 (g(2:7))
+ call f2 (f)
+ call f2 (e(2:4,8:9))
+ write (b, f3 ()) 'Hell', 'o wo', 'rld!'
+ if (b .ne. 'Hello world!') call abort
+end
diff --git a/gcc/testsuite/gfortran.dg/proc_decl_1.f90 b/gcc/testsuite/gfortran.dg/proc_decl_1.f90
index 25c018301f3..c7ec4f2f3fc 100644
--- a/gcc/testsuite/gfortran.dg/proc_decl_1.f90
+++ b/gcc/testsuite/gfortran.dg/proc_decl_1.f90
@@ -57,6 +57,8 @@ program prog
procedure ( ) :: r
procedure ( up ) :: s ! { dg-error "must be explicit" }
+ procedure(t) :: t ! { dg-error "may not be used as its own interface" }
+
call s
contains
diff --git a/gcc/testsuite/gfortran.dg/proc_decl_7.f90 b/gcc/testsuite/gfortran.dg/proc_decl_7.f90
index 79f413754c1..c8c2a81c5c6 100644
--- a/gcc/testsuite/gfortran.dg/proc_decl_7.f90
+++ b/gcc/testsuite/gfortran.dg/proc_decl_7.f90
@@ -16,6 +16,6 @@ end module m
use m
implicit none
intrinsic cos
-call sub(cos) ! { dg-error "Type/rank mismatch in argument" }
+call sub(cos) ! { dg-error "wrong number of arguments" }
end
! { dg-final { cleanup-modules "m" } }
diff --git a/gcc/testsuite/gfortran.dg/proc_decl_8.f90 b/gcc/testsuite/gfortran.dg/proc_decl_8.f90
index 67c1ddb0ee6..2d3514ec896 100644
--- a/gcc/testsuite/gfortran.dg/proc_decl_8.f90
+++ b/gcc/testsuite/gfortran.dg/proc_decl_8.f90
@@ -20,6 +20,6 @@ use m
implicit none
EXTERNAL foo ! interface is undefined
procedure(cos) :: foo ! { dg-error "Duplicate EXTERNAL attribute specified" }
-call sub(foo) ! { dg-error "Type/rank mismatch in argument" }
+call sub(foo) ! { dg-error "is not a function" }
end
! { dg-final { cleanup-modules "m" } }
diff --git a/gcc/testsuite/gfortran.dg/proc_ptr_11.f90 b/gcc/testsuite/gfortran.dg/proc_ptr_11.f90
index 5c39f995d34..469ebd448b1 100644
--- a/gcc/testsuite/gfortran.dg/proc_ptr_11.f90
+++ b/gcc/testsuite/gfortran.dg/proc_ptr_11.f90
@@ -23,10 +23,11 @@ program bsp
interface
function p3(x)
real(8) :: p3,x
+ intent(in) :: x
end function p3
end interface
- pptr => add ! { dg-error "Interfaces don't match" }
+ pptr => add ! { dg-error "is not a subroutine" }
q => add
@@ -39,11 +40,11 @@ program bsp
p2 => p1
p1 => p2
- p1 => abs ! { dg-error "Interfaces don't match" }
- p2 => abs ! { dg-error "Interfaces don't match" }
+ p1 => abs ! { dg-error "Type/kind mismatch in return value" }
+ p2 => abs ! { dg-error "Type/kind mismatch in return value" }
p3 => dsin
- p3 => sin ! { dg-error "Interfaces don't match" }
+ p3 => sin ! { dg-error "Type/kind mismatch in return value" }
contains
diff --git a/gcc/testsuite/gfortran.dg/proc_ptr_15.f90 b/gcc/testsuite/gfortran.dg/proc_ptr_15.f90
index f95d2806217..57269b0ccf0 100644
--- a/gcc/testsuite/gfortran.dg/proc_ptr_15.f90
+++ b/gcc/testsuite/gfortran.dg/proc_ptr_15.f90
@@ -19,10 +19,10 @@ p4 => p2
p6 => p1
! invalid
-p1 => iabs ! { dg-error "Interfaces don't match" }
-p1 => p2 ! { dg-error "Interfaces don't match" }
-p1 => p5 ! { dg-error "Interfaces don't match" }
-p6 => iabs ! { dg-error "Interfaces don't match" }
+p1 => iabs ! { dg-error "Type/kind mismatch in return value" }
+p1 => p2 ! { dg-error "Type/kind mismatch in return value" }
+p1 => p5 ! { dg-error "Type/kind mismatch in return value" }
+p6 => iabs ! { dg-error "Type/kind mismatch in return value" }
contains
diff --git a/gcc/testsuite/gfortran.dg/proc_ptr_18.f90 b/gcc/testsuite/gfortran.dg/proc_ptr_18.f90
new file mode 100644
index 00000000000..79cd68a513f
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/proc_ptr_18.f90
@@ -0,0 +1,25 @@
+! { dg-do run }
+!
+! PR 40176: Fortran 2003: Procedure pointers with array return value
+!
+! Original test case by Barron Bichon <barron.bichon@swri.org>
+! Modified by Janus Weil <janus@gcc.gnu.org>
+
+PROGRAM test_prog
+
+ PROCEDURE(triple), POINTER :: f
+
+ f => triple
+ if (sum(f(2.,4.)-triple(2.,4.))>1E-3) call abort()
+
+CONTAINS
+
+ FUNCTION triple(a,b) RESULT(tre)
+ REAL, INTENT(in) :: a, b
+ REAL :: tre(2)
+ tre(1) = 3.*a
+ tre(2) = 3.*b
+ END FUNCTION triple
+
+END PROGRAM test_prog
+
diff --git a/gcc/testsuite/gfortran.dg/proc_ptr_19.f90 b/gcc/testsuite/gfortran.dg/proc_ptr_19.f90
new file mode 100644
index 00000000000..a78a8d46432
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/proc_ptr_19.f90
@@ -0,0 +1,35 @@
+! { dg-do run }
+!
+! PR 40176: Fortran 2003: Procedure pointers with array return value
+!
+! This example tests for a bug in procedure pointer assignments,
+! where the rhs is a dummy.
+!
+! Original test case by Barron Bichon <barron.bichon@swri.org>
+! Modified by Janus Weil <janus@gcc.gnu.org>
+
+PROGRAM test_prog
+
+ PROCEDURE(add), POINTER :: forig, fset
+
+ forig => add
+
+ CALL set_ptr(forig,fset)
+
+ if (forig(1,2) /= fset(1,2)) call abort()
+
+CONTAINS
+
+ SUBROUTINE set_ptr(f1,f2)
+ PROCEDURE(add), POINTER :: f1, f2
+ f2 => f1
+ END SUBROUTINE set_ptr
+
+ FUNCTION add(a,b)
+ INTEGER :: a,b,add
+ add = a+b
+
+ END FUNCTION add
+
+END PROGRAM test_prog
+
diff --git a/gcc/testsuite/gfortran.dg/proc_ptr_comp_10.f90 b/gcc/testsuite/gfortran.dg/proc_ptr_comp_10.f90
new file mode 100644
index 00000000000..382f4125533
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/proc_ptr_comp_10.f90
@@ -0,0 +1,31 @@
+! { dg-do compile }
+!
+! PR 40176: Fortran 2003: Procedure pointers with array return value
+!
+! Contributed by Janus Weil <janus@gcc.gnu.org>
+
+module m
+
+abstract interface
+ function ai()
+ real, dimension(3) :: ai
+ end function
+end interface
+
+type t
+ procedure(ai), pointer, nopass :: ppc
+end type
+
+procedure(ai), pointer :: pp
+
+end module
+
+program test
+use m
+type(t) :: obj
+obj%ppc => pp
+pp => obj%ppc
+end
+
+! { dg-final { cleanup-modules "m" } }
+
diff --git a/gcc/testsuite/gfortran.dg/proc_ptr_comp_8.f90 b/gcc/testsuite/gfortran.dg/proc_ptr_comp_8.f90
new file mode 100644
index 00000000000..ed06c2bc651
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/proc_ptr_comp_8.f90
@@ -0,0 +1,58 @@
+! { dg-do run }
+!
+! PR 40164: Fortran 2003: "Arrays of procedure pointers" (using PPCs)
+!
+! Original test case by Barron Bichon <barron.bichon@swri.org>
+! Adapted by Janus Weil <janus@gcc.gnu.org>
+
+PROGRAM test_prog
+
+ ABSTRACT INTERFACE
+ FUNCTION fn_template(n,x) RESULT(y)
+ INTEGER, INTENT(in) :: n
+ REAL, INTENT(in) :: x(n)
+ REAL :: y(n)
+ END FUNCTION fn_template
+ END INTERFACE
+
+ TYPE PPA
+ PROCEDURE(fn_template), POINTER, NOPASS :: f
+ END TYPE PPA
+
+ TYPE ProcPointerArray
+ PROCEDURE(add), POINTER, NOPASS :: f
+ END TYPE ProcPointerArray
+
+ TYPE (ProcPointerArray) :: f_array(3)
+ PROCEDURE(add), POINTER :: f
+ real :: r
+
+ f_array(1)%f => add
+ f => f_array(1)%f
+ f_array(2)%f => sub
+ f_array(3)%f => f_array(1)%f
+
+ r = f(1.,2.)
+ if (abs(r-3.)>1E-3) call abort()
+ r = f_array(1)%f(4.,2.)
+ if (abs(r-6.)>1E-3) call abort()
+ r = f_array(2)%f(5.,3.)
+ if (abs(r-2.)>1E-3) call abort()
+ if (abs(f_array(1)%f(1.,3.)-f_array(3)%f(2.,2.))>1E-3) call abort()
+
+CONTAINS
+
+ FUNCTION add(a,b) RESULT(sum)
+ REAL, INTENT(in) :: a, b
+ REAL :: sum
+ sum = a + b
+ END FUNCTION add
+
+ FUNCTION sub(a,b) RESULT(diff)
+ REAL, INTENT(in) :: a, b
+ REAL :: diff
+ diff = a - b
+ END FUNCTION sub
+
+END PROGRAM test_prog
+
diff --git a/gcc/testsuite/gfortran.dg/proc_ptr_comp_9.f90 b/gcc/testsuite/gfortran.dg/proc_ptr_comp_9.f90
new file mode 100644
index 00000000000..951db485fb0
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/proc_ptr_comp_9.f90
@@ -0,0 +1,37 @@
+! { dg-do run }
+!
+! PR 40176: Fortran 2003: Procedure pointers with array return value
+!
+! Original test case by Barron Bichon <barron.bichon@swri.org>
+! Modified by Janus Weil <janus@gcc.gnu.org>
+
+PROGRAM test_prog
+
+ TYPE ProcPointerType
+ PROCEDURE(triple), POINTER, NOPASS :: f
+ END TYPE ProcPointerType
+
+ TYPE (ProcPointerType) :: ppt
+ PROCEDURE(triple), POINTER :: f
+ REAL :: tres(2)
+
+ ppt%f => triple
+ f => ppt%f
+ tres = f(2,[2.,4.])
+ if (abs(tres(1)-6.)>1E-3) call abort()
+ if (abs(tres(2)-12.)>1E-3) call abort()
+ tres = ppt%f(2,[3.,5.])
+ if (abs(tres(1)-9.)>1E-3) call abort()
+ if (abs(tres(2)-15.)>1E-3) call abort()
+
+CONTAINS
+
+ FUNCTION triple(n,x) RESULT(tre)
+ INTEGER, INTENT(in) :: n
+ REAL, INTENT(in) :: x(2)
+ REAL :: tre(2)
+ tre = 3.*x
+ END FUNCTION triple
+
+END PROGRAM test_prog
+
diff --git a/gcc/testsuite/gfortran.dg/proc_ptr_result_1.f90 b/gcc/testsuite/gfortran.dg/proc_ptr_result_1.f90
index 1261791ae73..f3f7252a6ad 100644
--- a/gcc/testsuite/gfortran.dg/proc_ptr_result_1.f90
+++ b/gcc/testsuite/gfortran.dg/proc_ptr_result_1.f90
@@ -114,7 +114,7 @@ contains
pointer :: f
interface
integer function f(x)
- integer :: x
+ integer,intent(in) :: x
end function
end interface
f => iabs
@@ -123,7 +123,7 @@ contains
function g()
interface
integer function g(x)
- integer :: x
+ integer,intent(in) :: x
end function g
end interface
pointer :: g
@@ -133,13 +133,13 @@ contains
function h(arg)
interface
subroutine arg(b)
- integer :: b
+ integer,intent(inout) :: b
end subroutine arg
end interface
pointer :: h
interface
subroutine h(a)
- integer :: a
+ integer,intent(inout) :: a
end subroutine h
end interface
h => arg
@@ -150,6 +150,7 @@ contains
interface
function i(x)
integer :: i,x
+ intent(in) :: x
end function i
end interface
i => iabs
diff --git a/gcc/testsuite/gfortran.dg/product_init_expr.f03 b/gcc/testsuite/gfortran.dg/product_init_expr.f03
new file mode 100644
index 00000000000..6724eb719f6
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/product_init_expr.f03
@@ -0,0 +1,66 @@
+! { dg-do "run" }
+! { dg-options "-fno-inline" }
+!
+! PRODUCT as initialization expression.
+!
+! This test compares results of simplifier of PRODUCT
+! with the corresponding inlined or library routine(s).
+!
+
+ IMPLICIT NONE
+
+ INTEGER, PARAMETER :: imatrix(2,4) = RESHAPE ([ 1, 2, 3, 4, 5, 6, 7, 8 ], [2, 4] )
+ INTEGER, PARAMETER :: imatrix_prod = PRODUCT (imatrix)
+ INTEGER, PARAMETER :: imatrix_prod_d1(4) = PRODUCT (imatrix, dim=1)
+ INTEGER, PARAMETER :: imatrix_prod_d2(2) = PRODUCT (imatrix, dim=2)
+ LOGICAL, PARAMETER :: i_equal_prod = ALL ([PRODUCT( imatrix_prod_d1 ) == PRODUCT ( imatrix_prod_d2 ), &
+ PRODUCT( imatrix_prod_d1 ) == imatrix_prod])
+ LOGICAL, PARAMETER :: i_empty_prod = PRODUCT(imatrix, mask=.FALSE.) == 1
+
+ REAL, PARAMETER :: rmatrix(2,4) = RESHAPE ([ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0 ], [2, 4] )
+ REAL, PARAMETER :: rmatrix_prod = PRODUCT (rmatrix)
+ REAL, PARAMETER :: rmatrix_prod_d1(4) = PRODUCT (rmatrix, dim=1)
+ REAL, PARAMETER :: rmatrix_prod_d2(2) = PRODUCT (rmatrix, dim=2)
+ LOGICAL, PARAMETER :: r_equal_prod = ALL ([PRODUCT( rmatrix_prod_d1 ) == PRODUCT ( rmatrix_prod_d2 ), &
+ PRODUCT( rmatrix_prod_d1 ) == rmatrix_prod])
+ LOGICAL, PARAMETER :: r_empty_prod = PRODUCT(rmatrix, mask=.FALSE.) == 1.0
+
+ IF (.NOT. ALL ([i_equal_prod, i_empty_prod])) CALL abort()
+ IF (.NOT. ALL ([r_equal_prod, r_empty_prod])) CALL abort()
+
+ CALL ilib (imatrix, imatrix_prod)
+ CALL ilib_with_dim (imatrix, 1, imatrix_prod_d1)
+ CALL ilib_with_dim (imatrix, 2, imatrix_prod_d2)
+ CALL rlib (rmatrix, rmatrix_prod)
+ CALL rlib_with_dim (rmatrix, 1, rmatrix_prod_d1)
+ CALL rlib_with_dim (rmatrix, 2, rmatrix_prod_d2)
+
+CONTAINS
+ SUBROUTINE ilib (array, result)
+ INTEGER, DIMENSION(:,:), INTENT(in) :: array
+ INTEGER, INTENT(in) :: result
+ IF (PRODUCT(array) /= result) CALL abort()
+ END SUBROUTINE
+
+ SUBROUTINE ilib_with_dim (array, dim, result)
+ INTEGER, DIMENSION(:,:), INTENT(in) :: array
+ INTEGER, INTENT(iN) :: dim
+ INTEGER, DIMENSION(:), INTENT(in) :: result
+ IF (ANY (PRODUCT (array, dim=dim) /= result)) CALL abort()
+ END SUBROUTINE
+
+ SUBROUTINE rlib (array, result)
+ REAL, DIMENSION(:,:), INTENT(in) :: array
+ REAL, INTENT(in) :: result
+ IF (ABS(PRODUCT(array) - result) > 2e-6) CALL abort()
+ END SUBROUTINE
+
+ SUBROUTINE rlib_with_dim (array, dim, result)
+ REAL, DIMENSION(:,:), INTENT(in) :: array
+ INTEGER, INTENT(iN) :: dim
+ REAL, DIMENSION(:), INTENT(in) :: result
+ IF (ANY (ABS(PRODUCT (array, dim=dim) - result) > 2e-6)) CALL abort()
+ END SUBROUTINE
+END
+
+
diff --git a/gcc/testsuite/gfortran.dg/reshape_order_5.f90 b/gcc/testsuite/gfortran.dg/reshape_order_5.f90
new file mode 100644
index 00000000000..9c76b88839f
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/reshape_order_5.f90
@@ -0,0 +1,16 @@
+! { dg-do "compile" }
+!
+! PR fortran/37203 - check RESHAPE arguments
+!
+
+ integer, dimension(6) :: source1 = (/ 1, 2, 3, 4, 5, 6 /)
+ integer, dimension(2) :: shape1 = (/ 2, 5/)
+ integer, dimension(2) :: pad1 = (/ 0, 0/)
+ integer, dimension(2) :: t(2,5)
+
+ t = reshape(source1, shape1, pad1, (/2, 1/)) ! ok
+ t = reshape(source1, shape1, pad1, (/2.1, 1.2/)) ! { dg-error "must be INTEGER" }
+ t = reshape(source1, shape1, pad1, (/2, 2/)) ! { dg-error "invalid permutation" }
+ t = reshape(source1, shape1, pad1, (/2, 3/)) ! { dg-error "out-of-range dimension" }
+ t = reshape(source1, shape1, pad1, (/2/)) ! { dg-error "wrong number of elements" }
+end
diff --git a/gcc/testsuite/gfortran.dg/reshape_shape_1.f90 b/gcc/testsuite/gfortran.dg/reshape_shape_1.f90
new file mode 100644
index 00000000000..008c9a8e5c1
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/reshape_shape_1.f90
@@ -0,0 +1,14 @@
+! { dg-do "compile" }
+!
+! PR fortran/37203 - check RESHAPE arguments
+!
+
+ integer, dimension(6) :: source1 = (/ 1, 2, 3, 4, 5, 6 /)
+ integer, dimension(2) :: pad1 = (/ 0, 0/)
+ integer, dimension(2) :: t(2,5)
+ integer :: i
+
+ t = reshape(source1, SHAPE(0), pad1, (/2, 1/)) ! { dg-error "is empty" }
+ t = reshape(source1, (/(i,i=1,32)/), pad1, (/2, 1/)) ! { dg-error "has more than" }
+ t = reshape(source1, (/ 2, -5/), pad1, (/2, 1/)) ! { dg-error "negative element" }
+end
diff --git a/gcc/testsuite/gfortran.dg/reshape_zerosize_2.f90 b/gcc/testsuite/gfortran.dg/reshape_zerosize_2.f90
new file mode 100644
index 00000000000..cdbee42aa6c
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/reshape_zerosize_2.f90
@@ -0,0 +1,11 @@
+! { dg-do "run" }
+
+ ! Simplifier of RESHAPE was broken when reshaping an empty array.
+ INTEGER, PARAMETER :: empty(0,0) = RESHAPE(SHAPE(1), (/0, 0/))
+
+ ! same with surplus padding
+ INTEGER, PARAMETER :: empty_padding(0,0) = RESHAPE(SHAPE(1), (/0, 0/), PAD=( (/ 1, 2 /) ))
+
+ ! same with required padding
+ INTEGER, PARAMETER :: non_empty(2,2) = RESHAPE(SHAPE(1), (/2, 2/), PAD=( (/ 1, 2 /) ))
+END
diff --git a/gcc/testsuite/gfortran.dg/spread_init_expr.f03 b/gcc/testsuite/gfortran.dg/spread_init_expr.f03
new file mode 100644
index 00000000000..a8bdc5e19ee
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/spread_init_expr.f03
@@ -0,0 +1,17 @@
+! { dg-do "run" }
+
+ INTEGER, PARAMETER :: n = 5
+ INTEGER, PARAMETER :: a1(n) = SPREAD(1, 1, n)
+ INTEGER, PARAMETER :: a2(n, 3) = SPREAD([1,2,3], DIM=1, NCOPIES=n)
+ INTEGER, PARAMETER :: a3(3, n) = SPREAD([1,2,3], DIM=2, NCOPIES=n)
+
+ IF (ANY(a1 /= [ 1, 1, 1, 1, 1 ])) CALL abort()
+
+ IF (ANY(a2(:, 1) /= 1)) CALL abort()
+ IF (ANY(a2(:, 2) /= 2)) CALL abort()
+ IF (ANY(a2(:, 3) /= 3)) CALL abort()
+
+ IF (ANY(a3(1, :) /= 1)) CALL abort()
+ IF (ANY(a3(2, :) /= 2)) CALL abort()
+ IF (ANY(a3(3, :) /= 3)) CALL abort()
+END
diff --git a/gcc/testsuite/gfortran.dg/string_1.f90 b/gcc/testsuite/gfortran.dg/string_1.f90
new file mode 100644
index 00000000000..11dc5b7a340
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/string_1.f90
@@ -0,0 +1,14 @@
+! { dg-do compile }
+!
+program main
+ implicit none
+ integer(kind=8), parameter :: l1 = 2_8**32_8
+ character (len=2_8**32_8+4_8), parameter :: s = "" ! { dg-error "too large" }
+ character (len=2_8**32_8+4_8) :: ch ! { dg-error "too large" }
+ character (len=l1 + 1_8) :: v ! { dg-error "too large" }
+ character (len=int(huge(0_4),kind=8) + 1_8) :: z ! { dg-error "too large" }
+ character (len=int(huge(0_4),kind=8) + 0_8) :: w
+
+ print *, len(s)
+
+end program main
diff --git a/gcc/testsuite/gfortran.dg/string_2.f90 b/gcc/testsuite/gfortran.dg/string_2.f90
new file mode 100644
index 00000000000..c94c4141bc5
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/string_2.f90
@@ -0,0 +1,12 @@
+! { dg-do compile }
+!
+program main
+ implicit none
+ character(len=10) :: s
+
+ s = ''
+ print *, s(1:2_8**32_8+3_8) ! { dg-error "exceeds the string length" }
+ print *, s(2_8**32_8+3_8:2_8**32_8+4_8) ! { dg-error "exceeds the string length" }
+ print *, len(s(1:2_8**32_8+3_8)) ! { dg-error "exceeds the string length" }
+
+end program main
diff --git a/gcc/testsuite/gfortran.dg/string_3.f90 b/gcc/testsuite/gfortran.dg/string_3.f90
new file mode 100644
index 00000000000..7daf8d31ae6
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/string_3.f90
@@ -0,0 +1,19 @@
+! { dg-do compile }
+!
+subroutine foo(i)
+ implicit none
+ integer, intent(in) :: i
+ character(len=i) :: s
+
+ s = ''
+ print *, s(1:2_8**32_8+3_8) ! { dg-error "too large" }
+ print *, s(2_8**32_8+3_8:2_8**32_8+4_8) ! { dg-error "too large" }
+ print *, len(s(1:2_8**32_8+3_8)) ! { dg-error "too large" }
+ print *, len(s(2_8**32_8+3_8:2_8**32_8+4_8)) ! { dg-error "too large" }
+
+ print *, s(2_8**32_8+3_8:1)
+ print *, s(2_8**32_8+4_8:2_8**32_8+3_8)
+ print *, len(s(2_8**32_8+3_8:1))
+ print *, len(s(2_8**32_8+4_8:2_8**32_8+3_8))
+
+end subroutine
diff --git a/gcc/testsuite/gfortran.dg/sum_init_expr.f03 b/gcc/testsuite/gfortran.dg/sum_init_expr.f03
new file mode 100644
index 00000000000..fc9701ce86d
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/sum_init_expr.f03
@@ -0,0 +1,66 @@
+! { dg-do "run" }
+! { dg-options "-fno-inline" }
+!
+! SUM as initialization expression.
+!
+! This test compares results of simplifier of SUM
+! with the corresponding inlined or library routine(s).
+!
+
+ IMPLICIT NONE
+
+ INTEGER, PARAMETER :: imatrix(2,4) = RESHAPE ([ 1, 2, 3, 4, 5, 6, 7, 8 ], [2, 4] )
+ INTEGER, PARAMETER :: imatrix_sum = SUM (imatrix)
+ INTEGER, PARAMETER :: imatrix_sum_d1(4) = SUM (imatrix, dim=1)
+ INTEGER, PARAMETER :: imatrix_sum_d2(2) = SUM (imatrix, dim=2)
+ LOGICAL, PARAMETER :: i_equal_sum = ALL ([SUM( imatrix_sum_d1 ) == SUM ( imatrix_sum_d2 ), &
+ SUM( imatrix_sum_d1 ) == imatrix_sum])
+ LOGICAL, PARAMETER :: i_empty_sum = SUM(imatrix, mask=.FALSE.) == 0
+
+ REAL, PARAMETER :: rmatrix(2,4) = RESHAPE ([ 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8 ], [2, 4] )
+ REAL, PARAMETER :: rmatrix_sum = SUM (rmatrix)
+ REAL, PARAMETER :: rmatrix_sum_d1(4) = SUM (rmatrix, dim=1)
+ REAL, PARAMETER :: rmatrix_sum_d2(2) = SUM (rmatrix, dim=2)
+ LOGICAL, PARAMETER :: r_equal_sum = ALL ([SUM( rmatrix_sum_d1 ) == SUM ( rmatrix_sum_d2 ), &
+ SUM( rmatrix_sum_d1 ) == rmatrix_sum])
+ LOGICAL, PARAMETER :: r_empty_sum = SUM(rmatrix, mask=.FALSE.) == 0.0
+
+ IF (.NOT. ALL ([i_equal_sum, i_empty_sum])) CALL abort()
+ IF (.NOT. ALL ([r_equal_sum, r_empty_sum])) CALL abort()
+
+ CALL ilib (imatrix, imatrix_sum)
+ CALL ilib_with_dim (imatrix, 1, imatrix_sum_d1)
+ CALL ilib_with_dim (imatrix, 2, imatrix_sum_d2)
+ CALL rlib (rmatrix, rmatrix_sum)
+ CALL rlib_with_dim (rmatrix, 1, rmatrix_sum_d1)
+ CALL rlib_with_dim (rmatrix, 2, rmatrix_sum_d2)
+
+CONTAINS
+ SUBROUTINE ilib (array, result)
+ INTEGER, DIMENSION(:,:), INTENT(in) :: array
+ INTEGER, INTENT(in) :: result
+ IF (SUM(array) /= result) CALL abort()
+ END SUBROUTINE
+
+ SUBROUTINE ilib_with_dim (array, dim, result)
+ INTEGER, DIMENSION(:,:), INTENT(in) :: array
+ INTEGER, INTENT(iN) :: dim
+ INTEGER, DIMENSION(:), INTENT(in) :: result
+ IF (ANY (SUM (array, dim=dim) /= result)) CALL abort()
+ END SUBROUTINE
+
+ SUBROUTINE rlib (array, result)
+ REAL, DIMENSION(:,:), INTENT(in) :: array
+ REAL, INTENT(in) :: result
+ IF (ABS(SUM(array) - result) > 2e-6) CALL abort()
+ END SUBROUTINE
+
+ SUBROUTINE rlib_with_dim (array, dim, result)
+ REAL, DIMENSION(:,:), INTENT(in) :: array
+ INTEGER, INTENT(iN) :: dim
+ REAL, DIMENSION(:), INTENT(in) :: result
+ IF (ANY (ABS(SUM (array, dim=dim) - result) > 2e-6)) CALL abort()
+ END SUBROUTINE
+END
+
+
diff --git a/gcc/testsuite/gfortran.dg/transpose_3.f03 b/gcc/testsuite/gfortran.dg/transpose_3.f03
new file mode 100644
index 00000000000..b24516604c9
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/transpose_3.f03
@@ -0,0 +1,10 @@
+! { dg-do "run" }
+! Transformational intrinsic TRANSPOSE as initialization expression.
+
+ INTEGER, PARAMETER :: n = 10
+ INTEGER, PARAMETER :: a(n,1) = RESHAPE([ (i, i = 1, n) ], [n, 1])
+ INTEGER, PARAMETER :: b(1,n) = TRANSPOSE(a)
+ INTEGER, PARAMETER :: c(n,1) = TRANSPOSE(b)
+
+ IF (ANY(c /= a)) CALL abort()
+END
diff --git a/gcc/testsuite/gfortran.dg/unpack_init_expr.f03 b/gcc/testsuite/gfortran.dg/unpack_init_expr.f03
new file mode 100644
index 00000000000..78460d19a63
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/unpack_init_expr.f03
@@ -0,0 +1,15 @@
+! { dg-do "run" }
+!
+! Example from F2003, sec 13.7.125
+!
+ INTEGER, PARAMETER :: m(3,3) = RESHAPE ([1,0,0,0,1,0,0,0,1], [3,3])
+ INTEGER, PARAMETER :: v(3) = [1,2,3]
+ LOGICAL, PARAMETER :: F = .FALSE., T = .TRUE.
+ LOGICAL, PARAMETER :: q(3,3) = RESHAPE ([F,T,F,T,F,F,F,F,T], [3,3])
+
+ INTEGER, PARAMETER :: r1(3,3) = UNPACK (V, MASK=Q, FIELD=M)
+ INTEGER, PARAMETER :: r2(3,3) = UNPACK (V, MASK=Q, FIELD=0)
+
+ IF (ANY (r1 /= RESHAPE ([1,1,0,2,1,0,0,0,3], [3,3]))) CALL ABORT()
+ IF (ANY (r2 /= RESHAPE ([0,1,0,2,0,0,0,0,3], [3,3]))) CALL ABORT()
+END
diff --git a/gcc/testsuite/gfortran.dg/vect/vect-2.f90 b/gcc/testsuite/gfortran.dg/vect/vect-2.f90
index 53ee74ce461..adc8d9c0b84 100644
--- a/gcc/testsuite/gfortran.dg/vect/vect-2.f90
+++ b/gcc/testsuite/gfortran.dg/vect/vect-2.f90
@@ -15,8 +15,9 @@ END
! support unaligned loads).
! { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" } }
-! { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 3 "vect" { xfail { vect_no_align || {! vector_alignment_reachable} } } } }
-! { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 2 "vect" { target { vect_no_align && {! vector_alignment_reachable} } } } }
-! { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail vect_no_align } } }
-! { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 3 "vect" {target { vect_no_align || {! vector_alignment_reachable} } } } }
+! { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 3 "vect" { xfail { { vect_no_align || vect_hw_misalign } || {! vector_alignment_reachable} } } } }
+! { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 2 "vect" { target { vect_no_align && { {! vector_alignment_reachable } && {! vect_hw_misalign } } } } } }
+! { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { xfail { vect_no_align || vect_hw_misalign} } } }
+! { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 5 "vect" { target vect_hw_misalign } } }
+! { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 3 "vect" {target { vect_no_align || { {! vector_alignment_reachable } && {! vect_hw_misalign }} } } } }
! { dg-final { cleanup-tree-dump "vect" } }
diff --git a/gcc/testsuite/gfortran.dg/vect/vect-3.f90 b/gcc/testsuite/gfortran.dg/vect/vect-3.f90
index 223d2dc175d..c0d7f0001d5 100644
--- a/gcc/testsuite/gfortran.dg/vect/vect-3.f90
+++ b/gcc/testsuite/gfortran.dg/vect/vect-3.f90
@@ -8,11 +8,10 @@ END
! { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 3 "vect" { target vect_no_align } } }
! { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" { target vect_no_align } } }
-
-! { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 1 "vect" { target { {! vect_no_align} && {! vector_alignment_reachable} } } } }
-! { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { target { {! vect_no_align} && {! vector_alignment_reachable} } } } }
-
-! { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail { vect_no_align || {! vector_alignment_reachable} } } } }
-! { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail { vect_no_align || {! vector_alignment_reachable} } } } }
+! { dg-final { scan-tree-dump-times "Alignment of access forced using versioning" 1 "vect" { target { {! vect_no_align} && { {! vector_alignment_reachable} && {! vect_hw_misalign} } } } } }
+! { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { target { {! vect_no_align} && { {! vector_alignment_reachable} && {! vect_hw_misalign} } } } } }
+! { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 3 "vect" {target vect_hw_misalign} } }
+! { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail { { vect_no_align || vect_hw_misalign } || {! vector_alignment_reachable}} } } }
+! { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail { { vect_no_align || vect_hw_misalign } || { ! vector_alignment_reachable} } } } }
! { dg-final { cleanup-tree-dump "vect" } }
diff --git a/gcc/testsuite/gfortran.dg/vect/vect-4.f90 b/gcc/testsuite/gfortran.dg/vect/vect-4.f90
index 5e514f6136c..34047343692 100644
--- a/gcc/testsuite/gfortran.dg/vect/vect-4.f90
+++ b/gcc/testsuite/gfortran.dg/vect/vect-4.f90
@@ -10,8 +10,9 @@ Y = Y + A * X
END
! { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } }
-! { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail { vect_no_align || {! vector_alignment_reachable} } } } }
-! { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail { vect_no_align || {! vector_alignment_reachable} } } } }
-! { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { target {! vector_alignment_reachable} } } }
+! { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail { { vect_no_align || vect_hw_misalign } || {! vector_alignment_reachable} } } } }
+! { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail { { vect_no_align || vect_hw_misalign } || {! vector_alignment_reachable} } } } }
+! { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 3 "vect" { target vect_hw_misalign } } }
+! { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { target { {! vector_alignment_reachable} && {! vect_hw_misalign} } } } }
! { dg-final { scan-tree-dump-times "accesses have the same alignment." 1 "vect" } }
! { dg-final { cleanup-tree-dump "vect" } }
diff --git a/gcc/testsuite/gfortran.dg/vect/vect-5.f90 b/gcc/testsuite/gfortran.dg/vect/vect-5.f90
index acd13de16f7..c562a81bacc 100644
--- a/gcc/testsuite/gfortran.dg/vect/vect-5.f90
+++ b/gcc/testsuite/gfortran.dg/vect/vect-5.f90
@@ -36,8 +36,9 @@
end
! { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } }
-! { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail { vect_no_align || {! vector_alignment_reachable} } } } }
-! { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail { vect_no_align } } } }
+! { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { xfail { { vect_no_align || vect_hw_misalign } || {! vector_alignment_reachable} } } } }
+! { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 1 "vect" { xfail { vect_no_align || vect_hw_misalign } } } }
+! { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 2 "vect" { target { vect_hw_misalign } } } }
! { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 2 "vect" { target { vect_no_align } } } }
-! { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 1 "vect" { target {! vector_alignment_reachable} } } }
+! { dg-final { scan-tree-dump-times "Alignment of access forced using versioning." 1 "vect" { target { {! vector_alignment_reachable} && {! vect_hw_misalign} } } } }
! { dg-final { cleanup-tree-dump "vect" } }
diff --git a/gcc/testsuite/gfortran.dg/vector_subscript_4.f90 b/gcc/testsuite/gfortran.dg/vector_subscript_4.f90
index 204468456e1..5c341dab4a5 100644
--- a/gcc/testsuite/gfortran.dg/vector_subscript_4.f90
+++ b/gcc/testsuite/gfortran.dg/vector_subscript_4.f90
@@ -9,5 +9,5 @@
integer :: i(-1:1) = 1, j(3) = 1, k(3)
k = j((/1,1,1/)+i)
end
-! { dg-final { scan-tree-dump-times "A\.3\\\[3\\\]" 1 "original" } }
+! { dg-final { scan-tree-dump-times "A\.2\\\[3\\\]" 1 "original" } }
! { dg-final { cleanup-tree-dump "original" } }
diff --git a/gcc/testsuite/gfortran.dg/zero_sized_1.f90 b/gcc/testsuite/gfortran.dg/zero_sized_1.f90
index 5461fb1a7f0..85167fcca3e 100644
--- a/gcc/testsuite/gfortran.dg/zero_sized_1.f90
+++ b/gcc/testsuite/gfortran.dg/zero_sized_1.f90
@@ -15,9 +15,6 @@ subroutine test_cshift
if (any(cshift(gee,shift=(/1,-1/),dim=1)/= 0)) call abort
if (any(cshift(gee,shift=(/1,-1/),dim=2)/= 0)) call abort
if (any(cshift(tempm(5:4,:),shift=(/1,-1/),dim=1)/= 0)) call abort
- if (any(cshift(tempm(5:4,:),shift=(/1,-1/),dim=2)/= 0)) call abort
- if (any(cshift(tempm(:,5:4),shift=(/1,-1/),dim=1)/= 0)) call abort
- if (any(cshift(tempm(:,5:4),shift=(/1,-1/),dim=2)/= 0)) call abort
deallocate(foo,bar,gee)
end
@@ -34,9 +31,6 @@ subroutine test_eoshift
if (any(eoshift(gee,shift=(/1,-1/),dim=1)/= 0)) call abort
if (any(eoshift(gee,shift=(/1,-1/),dim=2)/= 0)) call abort
if (any(eoshift(tempm(5:4,:),shift=(/1,-1/),dim=1)/= 0)) call abort
- if (any(eoshift(tempm(5:4,:),shift=(/1,-1/),dim=2)/= 0)) call abort
- if (any(eoshift(tempm(:,5:4),shift=(/1,-1/),dim=1)/= 0)) call abort
- if (any(eoshift(tempm(:,5:4),shift=(/1,-1/),dim=2)/= 0)) call abort
if (any(eoshift(foo,dim=1,shift=1,boundary=42.0)/= 0)) call abort
if (any(eoshift(tempn(2:1),dim=1,shift=1,boundary=42.0)/= 0)) call abort
@@ -45,9 +39,6 @@ subroutine test_eoshift
if (any(eoshift(gee,shift=(/1,-1/),dim=1,boundary=42.0)/= 0)) call abort
if (any(eoshift(gee,shift=(/1,-1/),dim=2,boundary=42.0)/= 0)) call abort
if (any(eoshift(tempm(5:4,:),shift=(/1,-1/),dim=1,boundary=42.0)/= 0)) call abort
- if (any(eoshift(tempm(5:4,:),shift=(/1,-1/),dim=2,boundary=42.0)/= 0)) call abort
- if (any(eoshift(tempm(:,5:4),shift=(/1,-1/),dim=1,boundary=42.0)/= 0)) call abort
- if (any(eoshift(tempm(:,5:4),shift=(/1,-1/),dim=2,boundary=42.0)/= 0)) call abort
if (any(eoshift(foo,dim=1,shift=1,boundary=42.0)/= 0)) call abort
if (any(eoshift(tempn(2:1),dim=1,shift=1,boundary=-7.0)/= 0)) call abort
@@ -56,9 +47,6 @@ subroutine test_eoshift
if (any(eoshift(gee,shift=(/1,-1/),dim=1,boundary=(/42.0,-7.0/))/= 0)) call abort
if (any(eoshift(gee,shift=(/1,-1/),dim=2,boundary=(/42.0,-7.0/))/= 0)) call abort
if (any(eoshift(tempm(5:4,:),shift=(/1,-1/),dim=1,boundary=(/42.0,-7.0/))/= 0)) call abort
- if (any(eoshift(tempm(5:4,:),shift=(/1,-1/),dim=2,boundary=(/42.0,-7.0/))/= 0)) call abort
- if (any(eoshift(tempm(:,5:4),shift=(/1,-1/),dim=1,boundary=(/42.0,-7.0/))/= 0)) call abort
- if (any(eoshift(tempm(:,5:4),shift=(/1,-1/),dim=2,boundary=(/42.0,-7.0/))/= 0)) call abort
deallocate(foo,bar,gee)
end
diff --git a/gcc/testsuite/gfortran.dg/zero_sized_5.f90 b/gcc/testsuite/gfortran.dg/zero_sized_5.f90
index 30ca8bf8199..49a5d548df0 100644
--- a/gcc/testsuite/gfortran.dg/zero_sized_5.f90
+++ b/gcc/testsuite/gfortran.dg/zero_sized_5.f90
@@ -8,8 +8,6 @@ program main
b = cshift (a,1)
b = cshift (a,j)
b = eoshift (a,1)
- b = eoshift (a,(/1/))
b = eoshift (a,1,boundary=c(1,:))
b = eoshift (a, j, boundary=c(1,:))
-
end program main
diff --git a/gcc/testsuite/gfortran.fortran-torture/compile/pr40413.f90 b/gcc/testsuite/gfortran.fortran-torture/compile/pr40413.f90
new file mode 100644
index 00000000000..d8fa73d6991
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/compile/pr40413.f90
@@ -0,0 +1,46 @@
+module state_matrices
+
+ implicit none
+ private
+
+ public :: state_matrix_copy
+ public :: state_matrix_t
+ public :: matrix_element_t
+
+ type :: matrix_element_t
+ private
+ integer, dimension(:), allocatable :: f
+ end type matrix_element_t
+
+ type :: state_matrix_t
+ private
+ type(matrix_element_t), dimension(:), allocatable :: me
+ end type state_matrix_t
+
+ type :: polarization_t
+ logical :: polarized = .false.
+ integer :: spin_type = 0
+ integer :: multiplicity = 0
+ type(state_matrix_t) :: state
+ end type polarization_t
+
+contains
+
+ function polarization_copy (pol_in) result (pol)
+ type(polarization_t) :: pol
+ type(polarization_t), intent(in) :: pol_in
+ !!! type(state_matrix_t) :: state_dummy
+ pol%polarized = pol_in%polarized
+ pol%spin_type = pol_in%spin_type
+ pol%multiplicity = pol_in%multiplicity
+ !!! state_dummy = state_matrix_copy (pol_in%state)
+ !!! pol%state = state_dummy
+ pol%state = state_matrix_copy (pol_in%state)
+ end function polarization_copy
+
+ function state_matrix_copy (state_in) result (state)
+ type(state_matrix_t) :: state
+ type(state_matrix_t), intent(in), target :: state_in
+ end function state_matrix_copy
+
+end module state_matrices
diff --git a/gcc/testsuite/gfortran.fortran-torture/compile/pr40421.f b/gcc/testsuite/gfortran.fortran-torture/compile/pr40421.f
new file mode 100644
index 00000000000..de7664ce6b3
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/compile/pr40421.f
@@ -0,0 +1,18 @@
+ SUBROUTINE VROT2(N,DIS)
+ IMPLICIT DOUBLE PRECISION (A-H,O-Z)
+ PARAMETER(ZERO=0.0D+00)
+ COMMON /SYMSPD/ PTR(3,144)
+ DIMENSION DIS(3,2),TMP(3,2)
+ DO I = 1,3
+ TMP1 = ZERO
+ DO J = 1,3
+ TMP1 = TMP1 + PTR(I,N+J)
+ END DO
+ TMP(I,1) = TMP1
+ END DO
+ DO I = 1,3
+ DIS(I,1) = TMP(I,1)
+ END DO
+ RETURN
+ END
+
diff --git a/gcc/testsuite/gnat.dg/addr6.adb b/gcc/testsuite/gnat.dg/addr6.adb
new file mode 100644
index 00000000000..e357132d66f
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/addr6.adb
@@ -0,0 +1,31 @@
+-- { dg-do compile }
+
+procedure Addr6 is
+
+ type Byte is mod 2**8;
+
+ type Byte_Arr1 is array (Positive range <>) of Byte;
+ for Byte_Arr1'Alignment use 4;
+
+ type Byte_Arr2 is array (Positive range <>) of Byte;
+
+ function Length return Natural is
+ begin
+ return 1;
+ end;
+
+ function Empty return Byte_Arr2 is
+ Null_Arr : Byte_Arr2 (1 .. 0);
+ begin
+ return Null_Arr;
+ end;
+
+ A1 : Byte_Arr1 (1 .. Length);
+
+ A2 : Byte_Arr2 (A1'Range);
+ for A2'Alignment use 4;
+ for A2'Address use A1'Address;
+
+begin
+ A2 := Empty;
+end;
diff --git a/gcc/testsuite/gnat.dg/align_max.adb b/gcc/testsuite/gnat.dg/align_max.adb
new file mode 100644
index 00000000000..26597ea9661
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/align_max.adb
@@ -0,0 +1,137 @@
+-- { dg-do run }
+
+with System.Storage_Elements; use System.Storage_Elements;
+with Ada.Unchecked_Deallocation;
+
+procedure Align_MAX is
+
+ Align : constant := Standard'Maximum_Alignment;
+
+ generic
+ type Data_Type (<>) is private;
+ type Access_Type is access Data_Type;
+ with function Allocate return Access_Type;
+ with function Address (Ptr : Access_Type) return System.Address;
+ package Check is
+ -- The hooks below just force asm generation that helps associating
+ -- obscure nested function names with their package instance name.
+ Hook_Allocate : System.Address := Allocate'Address;
+ Hook_Address : System.Address := Address'Address;
+ pragma Volatile (Hook_Allocate);
+ pragma Volatile (Hook_Address);
+
+ procedure Run (Announce : String);
+ end;
+
+ package body Check is
+
+ procedure Free is new
+ Ada.Unchecked_Deallocation (Data_Type, Access_Type);
+
+ procedure Run (Announce : String) is
+ Addr : System.Address;
+ Blocks : array (1 .. 1024) of Access_Type;
+ begin
+ for J in Blocks'Range loop
+ Blocks (J) := Allocate;
+ Addr := Address (Blocks (J));
+ if Addr mod Data_Type'Alignment /= 0 then
+ raise Program_Error;
+ end if;
+ end loop;
+
+ for J in Blocks'Range loop
+ Free (Blocks (J));
+ end loop;
+ end;
+ end;
+
+begin
+ declare
+ type Array_Type is array (Integer range <>) of Integer;
+ for Array_Type'Alignment use Align;
+
+ type FAT_Array_Access is access all Array_Type;
+
+ function Allocate return FAT_Array_Access is
+ begin
+ return new Array_Type (1 .. 1);
+ end;
+
+ function Address (Ptr : FAT_Array_Access) return System.Address is
+ begin
+ return Ptr(1)'Address;
+ end;
+ package Check_FAT is new
+ Check (Array_Type, FAT_Array_Access, Allocate, Address);
+ begin
+ Check_FAT.Run ("Checking FAT pointer to UNC array");
+ end;
+
+ declare
+ type Array_Type is array (Integer range <>) of Integer;
+ for Array_Type'Alignment use Align;
+
+ type THIN_Array_Access is access all Array_Type;
+ for THIN_Array_Access'Size use Standard'Address_Size;
+
+ function Allocate return THIN_Array_Access is
+ begin
+ return new Array_Type (1 .. 1);
+ end;
+
+ function Address (Ptr : THIN_Array_Access) return System.Address is
+ begin
+ return Ptr(1)'Address;
+ end;
+ package Check_THIN is new
+ Check (Array_Type, THIN_Array_Access, Allocate, Address);
+ begin
+ Check_THIN.Run ("Checking THIN pointer to UNC array");
+ end;
+
+ declare
+ type Array_Type is array (Integer range 1 .. 1) of Integer;
+ for Array_Type'Alignment use Align;
+
+ type Array_Access is access all Array_Type;
+
+ function Allocate return Array_Access is
+ begin
+ return new Array_Type;
+ end;
+
+ function Address (Ptr : Array_Access) return System.Address is
+ begin
+ return Ptr(1)'Address;
+ end;
+ package Check_Array is new
+ Check (Array_Type, Array_Access, Allocate, Address);
+ begin
+ Check_Array.Run ("Checking pointer to constrained array");
+ end;
+
+ declare
+ type Record_Type is record
+ Value : Integer;
+ end record;
+ for Record_Type'Alignment use Align;
+
+ type Record_Access is access all Record_Type;
+
+ function Allocate return Record_Access is
+ begin
+ return new Record_Type;
+ end;
+
+ function Address (Ptr : Record_Access) return System.Address is
+ begin
+ return Ptr.all'Address;
+ end;
+ package Check_Record is new
+ Check (Record_Type, Record_Access, Allocate, Address);
+ begin
+ Check_Record.Run ("Checking pointer to record");
+ end;
+end;
+
diff --git a/gcc/testsuite/gnat.dg/alignment6.adb b/gcc/testsuite/gnat.dg/alignment6.adb
index 548574f5cc9..f2889a50ecf 100644
--- a/gcc/testsuite/gnat.dg/alignment6.adb
+++ b/gcc/testsuite/gnat.dg/alignment6.adb
@@ -28,5 +28,5 @@ begin
B_REC := A_REC;
end;
--- { dg-final { scan-tree-dump-not "VIEW_CONVERT_EXPR" "gimple" { xfail *-*-* } } }
+-- { dg-final { scan-tree-dump-not "VIEW_CONVERT_EXPR" "gimple" } }
-- { dg-final { cleanup-tree-dump "gimple" } }
diff --git a/gcc/testsuite/gnat.dg/loop_optimization6.adb b/gcc/testsuite/gnat.dg/loop_optimization6.adb
new file mode 100644
index 00000000000..42f1717f1ad
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/loop_optimization6.adb
@@ -0,0 +1,25 @@
+-- { dg-do compile }
+-- { dg-options "-O -gnatp -fdump-tree-optimized" }
+
+package body Loop_Optimization6 is
+ procedure Foo is
+ begin
+ for I in 1 .. 1_000_000 loop
+ A := A + 1;
+ end loop;
+ end Foo;
+
+ procedure Bar is
+ begin
+ for J in 1 .. 1_000 loop
+ Foo;
+ end loop;
+ end Bar;
+
+ procedure Main is
+ begin
+ Bar;
+ end;
+end Loop_Optimization6;
+
+-- { dg-final { scan-tree-dump-not "goto" "optimized"} }
diff --git a/gcc/testsuite/gnat.dg/loop_optimization6.ads b/gcc/testsuite/gnat.dg/loop_optimization6.ads
new file mode 100644
index 00000000000..9b8a2670322
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/loop_optimization6.ads
@@ -0,0 +1,4 @@
+package Loop_Optimization6 is
+ A : Integer := 0;
+ procedure Main;
+end Loop_Optimization6;
diff --git a/gcc/testsuite/gnat.dg/misaligned_nest.adb b/gcc/testsuite/gnat.dg/misaligned_nest.adb
new file mode 100644
index 00000000000..3b6fd845da4
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/misaligned_nest.adb
@@ -0,0 +1,26 @@
+-- { dg-do run }
+-- { dg-options "-gnatp" }
+
+procedure Misaligned_Nest is
+
+ type Int is record
+ V : Integer;
+ end record;
+
+ type Block is record
+ B : Boolean;
+ I : Int;
+ end record;
+ pragma Pack (Block);
+ for Block'Alignment use 1;
+
+ type Pair is array (1 .. 2) of Block;
+
+ P : Pair;
+begin
+ for K in P'Range loop
+ P(K).I.V := 1;
+ end loop;
+end;
+
+
diff --git a/gcc/testsuite/gnat.dg/nested_float_packed.ads b/gcc/testsuite/gnat.dg/nested_float_packed.ads
new file mode 100644
index 00000000000..ae7f5239068
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/nested_float_packed.ads
@@ -0,0 +1,24 @@
+-- { dg-do compile }
+
+package Nested_Float_Packed is
+
+ type Float_Type is record
+ Value : Float;
+ Valid : Boolean;
+ end record;
+
+ type Data_Type is record
+ Data : Float_Type;
+ end record;
+
+ Default_Data : constant Data_Type :=
+ (Data => (Value => 1.0, Valid => False));
+
+ type Range_Type is (RV1, RV2, RV3);
+ for Range_Type use (1, 2, 3);
+
+ Data_Block : array (Range_Type)
+ of Data_Type := (others => Default_Data);
+end;
+
+
diff --git a/gcc/testsuite/gnat.dg/oconst1.adb b/gcc/testsuite/gnat.dg/oconst1.adb
new file mode 100644
index 00000000000..1e97ad8f2eb
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/oconst1.adb
@@ -0,0 +1,18 @@
+-- { dg-do compile }
+-- { dg-final { scan-assembler-not "elabs" } }
+
+package body OCONST1 is
+
+ procedure check (arg : R) is
+ begin
+ if arg.u /= 1
+ or else arg.b.i1 /= 2
+ or else arg.b.i2 /= 3
+ or else arg.b.i3 /= 4
+ then
+ raise Program_Error;
+ end if;
+ end;
+
+end;
+
diff --git a/gcc/testsuite/gnat.dg/oconst1.ads b/gcc/testsuite/gnat.dg/oconst1.ads
new file mode 100644
index 00000000000..93b35f79bae
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/oconst1.ads
@@ -0,0 +1,25 @@
+package OCONST1 is
+
+ type u8 is mod 2**8;
+
+ type Base is record
+ i1 : Integer;
+ i2 : Integer;
+ i3 : Integer;
+ end Record;
+
+ type R is record
+ u : u8;
+ b : Base;
+ end record;
+
+ for R use record
+ u at 0 range 0 .. 7;
+ b at 1 range 0 .. 95; -- BLKmode bitfield
+ end record;
+
+ My_R : constant R := (u=>1, b=>(2, 3, 4));
+
+ procedure check (arg : R);
+
+end;
diff --git a/gcc/testsuite/gnat.dg/oconst2.adb b/gcc/testsuite/gnat.dg/oconst2.adb
new file mode 100644
index 00000000000..d4f45ad5d04
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/oconst2.adb
@@ -0,0 +1,15 @@
+-- { dg-do compile }
+-- { dg-final { scan-assembler-not "elabs" } }
+
+package body OCONST2 is
+
+ procedure check (arg : R) is
+ begin
+ if arg.u /= 1
+ or else arg.b.i1 /= 2
+ then
+ raise Program_Error;
+ end if;
+ end;
+
+end;
diff --git a/gcc/testsuite/gnat.dg/oconst2.ads b/gcc/testsuite/gnat.dg/oconst2.ads
new file mode 100644
index 00000000000..23e57a74cc2
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/oconst2.ads
@@ -0,0 +1,23 @@
+package OCONST2 is
+
+ type u8 is mod 2**8;
+
+ type Base is record
+ i1 : Integer;
+ end Record;
+
+ type R is record
+ u : u8;
+ b : Base;
+ end record;
+
+ for R use record
+ u at 0 range 0 .. 7;
+ b at 1 range 0 .. 31; -- aligned SImode bitfield
+ end record;
+
+ My_R : constant R := (u=>1, b=>(i1=>2));
+
+ procedure check (arg : R);
+
+end;
diff --git a/gcc/testsuite/gnat.dg/oconst3.adb b/gcc/testsuite/gnat.dg/oconst3.adb
new file mode 100644
index 00000000000..c9a94d4f491
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/oconst3.adb
@@ -0,0 +1,16 @@
+-- { dg-do compile }
+-- { dg-final { scan-assembler-not "elabs" } }
+
+package body OCONST3 is
+
+ procedure check (arg : R) is
+ begin
+ if arg.u /= 1
+ or else arg.f /= one
+ or else arg.b.i1 /= 3
+ then
+ raise Program_Error;
+ end if;
+ end;
+
+end;
diff --git a/gcc/testsuite/gnat.dg/oconst3.ads b/gcc/testsuite/gnat.dg/oconst3.ads
new file mode 100644
index 00000000000..6a0094b57e9
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/oconst3.ads
@@ -0,0 +1,26 @@
+package OCONST3 is
+
+ type bit is (zero, one);
+ type u8 is mod 2**8;
+
+ type Base is record
+ i1 : Integer;
+ end Record;
+
+ type R is record
+ u : u8;
+ f : bit;
+ b : Base;
+ end record;
+
+ for R use record
+ u at 0 range 0 .. 7;
+ f at 1 range 0 .. 0;
+ b at 1 range 1 .. 32; -- unaligned SImode bitfield
+ end record;
+
+ My_R : constant R := (u=>1, f=>one, b=>(i1=>3));
+
+ procedure check (arg : R);
+
+end;
diff --git a/gcc/testsuite/gnat.dg/oconst4.adb b/gcc/testsuite/gnat.dg/oconst4.adb
new file mode 100644
index 00000000000..f97f217b3da
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/oconst4.adb
@@ -0,0 +1,24 @@
+-- { dg-do compile }
+-- { dg-final { scan-assembler-not "elabs" } }
+
+package body OCONST4 is
+
+ procedure check (arg : R) is
+ begin
+ if arg.u /= 1
+ or else arg.d.f1 /= 17
+ or else arg.d.b.f1 /= one
+ or else arg.d.b.f2 /= 2
+ or else arg.d.b.f3 /= 17
+ or else arg.d.b.f4 /= 42
+ or else arg.d.f2 /= one
+ or else arg.d.f3 /= 1
+ or else arg.d.f4 /= 111
+ or else arg.d.i1 /= 2
+ or else arg.d.i2 /= 3
+ then
+ raise Program_Error;
+ end if;
+ end;
+
+end;
diff --git a/gcc/testsuite/gnat.dg/oconst4.ads b/gcc/testsuite/gnat.dg/oconst4.ads
new file mode 100644
index 00000000000..cde0935fe8d
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/oconst4.ads
@@ -0,0 +1,66 @@
+package OCONST4 is
+
+ type bit is (zero, one);
+ type u2 is mod 2**2;
+ type u5 is mod 2**5;
+ type u8 is mod 2**8;
+
+ type Base is record
+ f1 : bit;
+ f2 : u2;
+ f3 : u5;
+ f4 : u8;
+ end record;
+
+ for Base use record
+ f1 at 0 range 0 .. 0;
+ f2 at 0 range 1 .. 2;
+ f3 at 0 range 3 .. 7;
+ f4 at 1 range 0 .. 7;
+ end record;
+
+ type Derived is record
+ f1 : u5;
+ b : Base;
+ f2 : bit;
+ f3 : u2;
+ f4 : u8;
+ i1 : Integer;
+ i2 : Integer;
+ end record;
+
+ for Derived use record
+ f1 at 0 range 0 .. 4;
+ b at 0 range 5 .. 20; -- unaligned HImode bitfield
+ f2 at 0 range 21 .. 21;
+ f3 at 0 range 22 .. 23;
+ f4 at 0 range 24 .. 31;
+ i1 at 4 range 0 .. 31;
+ i2 at 8 range 0 .. 31;
+ end record;
+
+ type R is record
+ u : u8;
+ d : Derived;
+ end record;
+
+ for R use record
+ u at 0 range 0 .. 7;
+ d at 1 range 0 .. 95; -- BLKmode bitfield
+ end record;
+
+ My_R : constant R := (u=>1,
+ d=>(f1=>17,
+ b=>(f1=>one,
+ f2=>2,
+ f3=>17,
+ f4=>42),
+ f2=>one,
+ f3=>1,
+ f4=>111,
+ i1=>2,
+ i2=>3));
+
+ procedure check (arg : R);
+
+end;
diff --git a/gcc/testsuite/gnat.dg/oconst5.adb b/gcc/testsuite/gnat.dg/oconst5.adb
new file mode 100644
index 00000000000..4d4896aea58
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/oconst5.adb
@@ -0,0 +1,15 @@
+-- { dg-do compile }
+-- { dg-final { scan-assembler-not "elabs" } }
+
+package body OCONST5 is
+
+ procedure Check (Arg : R; Bit : U1) is
+ begin
+ if Arg.Bit /= Bit
+ or else Arg.Agg.A /= 3
+ or else Arg.Agg.B /= 7
+ then
+ raise Program_Error;
+ end if;
+ end;
+end;
diff --git a/gcc/testsuite/gnat.dg/oconst5.ads b/gcc/testsuite/gnat.dg/oconst5.ads
new file mode 100644
index 00000000000..f12a265d0d3
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/oconst5.ads
@@ -0,0 +1,27 @@
+package OCONST5 is
+
+ type u1 is mod 2**1;
+ type u8 is mod 2**8;
+
+ type HI_Record is record
+ A, B : U8;
+ end record;
+ pragma Suppress_Initialization (HI_Record);
+
+ type R is record
+ Bit : U1;
+ Agg : HI_Record;
+ end record;
+ pragma Suppress_Initialization (R);
+
+ for R use record
+ Bit at 0 range 0 .. 0;
+ Agg at 0 range 1 .. 16;
+ end record;
+
+ My_R0 : R := (Bit => 0, Agg => (A => 3, B => 7));
+ My_R1 : R := (Bit => 1, Agg => (A => 3, B => 7));
+
+ procedure Check (Arg : R; Bit : U1);
+
+end;
diff --git a/gcc/testsuite/gnat.dg/oconst6.ads b/gcc/testsuite/gnat.dg/oconst6.ads
new file mode 100644
index 00000000000..e4c3c50eb0d
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/oconst6.ads
@@ -0,0 +1,18 @@
+-- { dg-do compile }
+-- { dg-final { scan-assembler-not "elabs" } }
+
+package OCONST6 is
+
+ type Sequence is array (1 .. 1) of Natural;
+
+ type Message is record
+ Data : Sequence;
+ end record;
+
+ for Message'Alignment use 1;
+ pragma PACK (Message);
+
+ ACK : Message := (Data => (others => 1));
+
+end;
+
diff --git a/gcc/testsuite/gnat.dg/pack9.adb b/gcc/testsuite/gnat.dg/pack9.adb
index 64d71b11cc9..232904ac1e1 100644
--- a/gcc/testsuite/gnat.dg/pack9.adb
+++ b/gcc/testsuite/gnat.dg/pack9.adb
@@ -1,5 +1,5 @@
-- { dg-do compile }
--- { dg-options "-O2 -gnatp -cargs --param sra-max-structure-size=24 --param sra-max-structure-count=6 -fdump-tree-optimized" }
+-- { dg-options "-O2 -gnatp -cargs -fdump-tree-optimized" }
package body Pack9 is
diff --git a/gcc/testsuite/gnat.dg/specs/rep_clause3.ads b/gcc/testsuite/gnat.dg/specs/rep_clause3.ads
new file mode 100644
index 00000000000..438c6046868
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/specs/rep_clause3.ads
@@ -0,0 +1,36 @@
+package Rep_Clause3 is
+
+ type Record1 is
+ record
+ Page_Handle : Integer range 0 .. 255;
+ Page_Owner : Integer range 0 .. 15;
+ end record;
+ for Record1 use
+ record
+ Page_Handle at 0 range 0 .. 15;
+ Page_Owner at 0 range 16 .. 19;
+ end record;
+ for Record1'Size use 20;
+
+ type Range_A is range 1 .. 7;
+ for Range_A'Size use 16;
+
+ type Array_Type is array (Range_A) of Record1;
+ pragma Pack (Array_Type);
+ for Array_Type'Size use 7 * 20;
+-- for array_Type'alignment use 1;
+
+ type Record2 is
+ record
+ Page_Tree_Index : Range_A;
+ Page_Tree : Array_Type;
+ end record;
+
+ for Record2 use
+ record
+ Page_Tree_Index at 0 range 0 .. 15;
+ Page_Tree at 0 range 16 .. 15 + (7 * 20);
+ end record;
+ for Record2'Size use 16 + (7 * 20);
+
+end Rep_Clause3;
diff --git a/gcc/testsuite/gnat.dg/specs/root-level_1-level_2.ads b/gcc/testsuite/gnat.dg/specs/root-level_1-level_2.ads
new file mode 100644
index 00000000000..9687208e082
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/specs/root-level_1-level_2.ads
@@ -0,0 +1,7 @@
+package Root.Level_1.Level_2 is
+
+ type Level_2_Type (First : Natural;
+ Second : Natural) is new
+ Level_1.Level_1_Type (First => First, Second => Second) with null record;
+
+end Root.Level_1.Level_2;
diff --git a/gcc/testsuite/gnat.dg/specs/root-level_1.ads b/gcc/testsuite/gnat.dg/specs/root-level_1.ads
new file mode 100644
index 00000000000..6bcb1251f2b
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/specs/root-level_1.ads
@@ -0,0 +1,14 @@
+package Root.Level_1 is
+
+ type Level_1_Type (First : Natural;
+ Second : Natural) is new Root_Type with private;
+
+private
+
+ type Level_1_Type (First : Natural;
+ Second : Natural) is new Root_Type (First => First)
+ with record
+ Buffer_1 : Buffer_Type (1 .. Second);
+ end record;
+
+end Root.Level_1;
diff --git a/gcc/testsuite/gnat.dg/specs/root-level_2.ads b/gcc/testsuite/gnat.dg/specs/root-level_2.ads
new file mode 100644
index 00000000000..c4f812ecfb6
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/specs/root-level_2.ads
@@ -0,0 +1,9 @@
+with Root.Level_1;
+
+package Root.Level_2 is
+
+ type Level_2_Type (First : Natural;
+ Second : Natural) is new
+ Level_1.Level_1_Type (First => First, Second => Second) with null record;
+
+end Root.Level_2;
diff --git a/gcc/testsuite/gnat.dg/specs/root.ads b/gcc/testsuite/gnat.dg/specs/root.ads
new file mode 100644
index 00000000000..e80ab880401
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/specs/root.ads
@@ -0,0 +1,9 @@
+package Root is
+
+ type Buffer_Type is array (Positive range <>) of Natural;
+
+ type Root_Type (First : Natural) is abstract tagged record
+ Buffer_Root : Buffer_Type (1 .. First);
+ end record;
+
+end Root;
diff --git a/gcc/testsuite/gnat.dg/test_oconst.adb b/gcc/testsuite/gnat.dg/test_oconst.adb
new file mode 100644
index 00000000000..23e5a97d537
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/test_oconst.adb
@@ -0,0 +1,13 @@
+-- { dg-do run }
+
+with OCONST1, OCONST2, OCONST3, OCONST4, OCONST5;
+
+procedure Test_Oconst is
+begin
+ OCONST1.check (OCONST1.My_R);
+ OCONST2.check (OCONST2.My_R);
+ OCONST3.check (OCONST3.My_R);
+ OCONST4.check (OCONST4.My_R);
+ OCONST5.check (OCONST5.My_R0, 0);
+ OCONST5.check (OCONST5.My_R1, 1);
+end;
diff --git a/gcc/testsuite/lib/gcc-dg.exp b/gcc/testsuite/lib/gcc-dg.exp
index 93df820e27f..3fd4381827f 100644
--- a/gcc/testsuite/lib/gcc-dg.exp
+++ b/gcc/testsuite/lib/gcc-dg.exp
@@ -1,4 +1,4 @@
-# Copyright (C) 1997, 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2008
+# Copyright (C) 1997, 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2008, 2009
# Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
@@ -289,10 +289,18 @@ proc gcc-dg-debug-runtest { target_compile trivial opt_opts testcases } {
$comp_output] } {
remove-build-file "trivial.S"
foreach level {1 "" 3} {
- lappend DEBUG_TORTURE_OPTIONS [list "${type}${level}"]
- foreach opt $opt_opts {
- lappend DEBUG_TORTURE_OPTIONS \
- [list "${type}${level}" "$opt" ]
+ if { ($type == "-gdwarf-2") && ($level != "") } {
+ lappend DEBUG_TORTURE_OPTIONS [list "${type}" "-g${level}"]
+ foreach opt $opt_opts {
+ lappend DEBUG_TORTURE_OPTIONS \
+ [list "${type}" "-g${level}" "$opt" ]
+ }
+ } else {
+ lappend DEBUG_TORTURE_OPTIONS [list "${type}${level}"]
+ foreach opt $opt_opts {
+ lappend DEBUG_TORTURE_OPTIONS \
+ [list "${type}${level}" "$opt" ]
+ }
}
}
}
@@ -320,7 +328,8 @@ proc gcc-dg-debug-runtest { target_compile trivial opt_opts testcases } {
if { ([string match {*/debug-[126].c} "$nshort"] \
|| [string match {*/enum-1.c} "$nshort"] \
|| [string match {*/enum-[12].C} "$nshort"]) \
- && [string match "*1" [lindex "$flags" 0] ] } {
+ && ([string match "*1" [lindex "$flags" 0] ]
+ || [lindex "$flags" 1] == "-g1") } {
set doit 0
}
@@ -628,6 +637,17 @@ if { [info procs saved-dg-error] == [list] \
process-message saved-dg-error "$gcc_error_prefix" "$args"
}
+
+ # Override dg-bogus at the same time. It doesn't handle a prefix
+ # but its expression should include a column number. Otherwise the
+ # line number can match the column number for other messages, leading
+ # to insanity.
+ rename dg-bogus saved-dg-bogus
+
+ proc dg-bogus { args } {
+ upvar dg-messages dg-messages
+ process-message saved-dg-bogus "" $args
+ }
}
# Modify the regular expression saved by a DejaGnu message directive to
@@ -649,20 +669,26 @@ proc process-message { msgproc msgprefix dgargs } {
return;
}
- # Prepend the message prefix to the regular expression and make
- # it match a single line.
+ # Get the entry for the new message. Prepend the message prefix to
+ # the regular expression and make it match a single line.
set newentry [lindex ${dg-messages} end]
set expmsg [lindex $newentry 2]
- # If we have a column...
+ # Handle column numbers from the specified expression (if there is
+ # one) and set up the search expression that will be used by DejaGnu.
if [regexp "^(\[0-9\]+):" $expmsg "" column] {
- # Remove "COLUMN:"
+ # The expression in the directive included a column number.
+ # Remove "COLUMN:" from the original expression and move it
+ # to the proper place in the search expression.
regsub "^\[0-9\]+:" $expmsg "" expmsg
-
- # Include the column in the search expression.
- set expmsg "$column: $msgprefix\[^\n]*$expmsg"
+ set expmsg "$column: $msgprefix\[^\n\]*$expmsg"
+ } elseif [string match "" [lindex $newentry 0]] {
+ # The specified line number is 0; don't expect a column number.
+ set expmsg "$msgprefix\[^\n\]*$expmsg"
} else {
- set expmsg "$msgprefix\[^\n]*$expmsg"
+ # There is no column number in the search expression, but we
+ # should expect one in the message itself.
+ set expmsg "\[0-9\]+: $msgprefix\[^\n\]*$expmsg"
}
set newentry [lreplace $newentry 2 2 $expmsg]
diff --git a/gcc/testsuite/lib/gfortran-dg.exp b/gcc/testsuite/lib/gfortran-dg.exp
index 55d6d400c40..70a0888a0a4 100644
--- a/gcc/testsuite/lib/gfortran-dg.exp
+++ b/gcc/testsuite/lib/gfortran-dg.exp
@@ -135,10 +135,18 @@ proc gfortran-dg-debug-runtest { target_compile trivial opt_opts testcases } {
}
remove-build-file "trivial.S"
foreach level {1 "" 3} {
- lappend DEBUG_TORTURE_OPTIONS [list "${type}${level}"]
- foreach opt $opt_opts {
- lappend DEBUG_TORTURE_OPTIONS [list "${type}${level}" \
- "$opt" ]
+ if { ($type == "-gdwarf-2") && ($level != "") } {
+ lappend DEBUG_TORTURE_OPTIONS [list "${type}" "-g${level}"]
+ foreach opt $opt_opts {
+ lappend DEBUG_TORTURE_OPTIONS \
+ [list "${type}" "-g${level}" "$opt" ]
+ }
+ } else {
+ lappend DEBUG_TORTURE_OPTIONS [list "${type}${level}"]
+ foreach opt $opt_opts {
+ lappend DEBUG_TORTURE_OPTIONS \
+ [list "${type}${level}" "$opt" ]
+ }
}
}
}
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 92bde7886a9..24d81489409 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -466,6 +466,11 @@ proc check_profiling_available { test_what } {
return 0
}
+ # cygwin does not support -p.
+ if { [istarget *-*-cygwin*] && [lindex $test_what 1] == "-p" } {
+ return 0
+ }
+
# uClibc does not have gcrt1.o.
if { [check_effective_target_uclibc]
&& ([lindex $test_what 1] == "-p"
@@ -494,6 +499,7 @@ proc check_profiling_available { test_what } {
|| [istarget m68k-*-elf]
|| [istarget m68k-*-uclinux*]
|| [istarget mips*-*-elf*]
+ || [istarget moxie-*-elf*]
|| [istarget xstormy16-*]
|| [istarget xtensa*-*-elf]
|| [istarget *-*-rtems*]
@@ -606,6 +612,18 @@ proc check_effective_target_pthread {} {
} "-pthread"]
}
+# Return 1 if compilation with -mpe-aligned-commons is error-free
+# for trivial code, 0 otherwise.
+
+proc check_effective_target_pe_aligned_commons {} {
+ if { [istarget *-*-cygwin*] || [istarget *-*-mingw*] } {
+ return [check_no_compiler_messages pe_aligned_commons object {
+ int foo;
+ } "-mpe-aligned-commons"]
+ }
+ return 0
+}
+
# Return 1 if the target supports -fstack-protector
proc check_effective_target_fstack_protector {} {
return [check_runtime fstack_protector {
@@ -1472,6 +1490,17 @@ proc check_effective_target_arm_thumb1_ok { } {
} "-mthumb"]
}
+# Return 1 is this is an ARM target where -mthumb causes Thumb-2 to be
+# used.
+
+proc check_effective_target_arm_thumb2_ok { } {
+ return [check_no_compiler_messages arm_thumb2_ok assembly {
+ #if !defined(__thumb2__)
+ #error FOO
+ #endif
+ } "-mthumb"]
+}
+
# Return 1 if the target supports executing NEON instructions, 0
# otherwise. Cache the result.
@@ -2192,6 +2221,27 @@ proc check_effective_target_vect_no_align { } {
return $et_vect_no_align_saved
}
+# Return 1 if the target supports a vector misalign access, 0 otherwise.
+#
+# This won't change for different subtargets so cache the result.
+
+proc check_effective_target_vect_hw_misalign { } {
+ global et_vect_hw_misalign_saved
+
+ if [info exists et_vect_hw_misalign_saved] {
+ verbose "check_effective_target_vect_hw_misalign: using cached result" 2
+ } else {
+ set et_vect_hw_misalign_saved 0
+ if { ([istarget x86_64-*-*]
+ || [istarget i?86-*-*]) } {
+ set et_vect_hw_misalign_saved 1
+ }
+ }
+ verbose "check_effective_target_vect_hw_misalign: returning $et_vect_hw_misalign_saved" 2
+ return $et_vect_hw_misalign_saved
+}
+
+
# Return 1 if arrays are aligned to the vector alignment
# boundary, 0 otherwise.
#
@@ -2925,3 +2975,16 @@ proc check_effective_target_correct_iso_cpp_string_wchar_protos { } {
#endif
}]
}
+
+# Return 1 if the MPC library is integrated with GCC, 0 otherwise.
+
+proc check_effective_target_mpc { } {
+ return [check_no_compiler_messages mpc executable {
+ extern void link_error(void);
+ int main ()
+ {
+ if (__builtin_csin(0) != 0)
+ link_error();
+ }
+ }]
+}
diff --git a/gcc/timevar.def b/gcc/timevar.def
index e6853756e66..ea392c0920c 100644
--- a/gcc/timevar.def
+++ b/gcc/timevar.def
@@ -121,6 +121,7 @@ DEFTIMEVAR (TV_TREE_LOOP_UNSWITCH , "tree loop unswitching")
DEFTIMEVAR (TV_COMPLETE_UNROLL , "complete unrolling")
DEFTIMEVAR (TV_TREE_PARALLELIZE_LOOPS, "tree parallelize loops")
DEFTIMEVAR (TV_TREE_VECTORIZATION , "tree vectorization")
+DEFTIMEVAR (TV_TREE_SLP_VECTORIZATION, "tree slp vectorization")
DEFTIMEVAR (TV_GRAPHITE_TRANSFORMS , "GRAPHITE loop transforms")
DEFTIMEVAR (TV_TREE_LINEAR_TRANSFORM , "tree loop linear")
DEFTIMEVAR (TV_TREE_LOOP_DISTRIBUTION, "tree loop distribution")
@@ -180,6 +181,7 @@ DEFTIMEVAR (TV_SEQABSTR , "sequence abstraction")
DEFTIMEVAR (TV_GCSE_AFTER_RELOAD , "load CSE after reload")
DEFTIMEVAR (TV_THREAD_PROLOGUE_AND_EPILOGUE, "thread pro- & epilogue")
DEFTIMEVAR (TV_IFCVT2 , "if-conversion 2")
+DEFTIMEVAR (TV_COMBINE_STACK_ADJUST , "combine stack adjustments")
DEFTIMEVAR (TV_PEEPHOLE2 , "peephole 2")
DEFTIMEVAR (TV_RENAME_REGISTERS , "rename registers")
DEFTIMEVAR (TV_CPROP_REGISTERS , "hard reg cprop")
diff --git a/gcc/toplev.c b/gcc/toplev.c
index 63afc9fc29c..12ce6420f3a 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -544,11 +544,11 @@ read_integral_parameter (const char *p, const char *pname, const int defval)
return atoi (p);
}
-/* When compiling with a recent enough GCC, we use the GNU C "extern inline"
- for floor_log2 and exact_log2; see toplev.h. That construct, however,
- conflicts with the ISO C++ One Definition Rule. */
+#if GCC_VERSION < 3004
-#if GCC_VERSION < 3004 || !defined (__cplusplus)
+/* The functions floor_log2 and exact_log2 are defined as inline
+ functions in toplev.h if GCC_VERSION >= 3004. The definitions here
+ are used for older versions of gcc. */
/* Given X, an unsigned number, return the largest int Y such that 2**Y <= X.
If X is 0, return -1. */
@@ -561,9 +561,6 @@ floor_log2 (unsigned HOST_WIDE_INT x)
if (x == 0)
return -1;
-#ifdef CLZ_HWI
- t = HOST_BITS_PER_WIDE_INT - 1 - (int) CLZ_HWI (x);
-#else
if (HOST_BITS_PER_WIDE_INT > 64)
if (x >= (unsigned HOST_WIDE_INT) 1 << (t + 64))
t += 64;
@@ -580,7 +577,6 @@ floor_log2 (unsigned HOST_WIDE_INT x)
t += 2;
if (x >= ((unsigned HOST_WIDE_INT) 1) << (t + 1))
t += 1;
-#endif
return t;
}
@@ -593,14 +589,10 @@ exact_log2 (unsigned HOST_WIDE_INT x)
{
if (x != (x & -x))
return -1;
-#ifdef CTZ_HWI
- return x ? CTZ_HWI (x) : -1;
-#else
return floor_log2 (x);
-#endif
}
-#endif /* GCC_VERSION < 3004 || !defined (__cplusplus) */
+#endif /* GCC_VERSION < 3004 */
/* Handler for fatal signals, such as SIGSEGV. These are transformed
into ICE messages, which is much more user friendly. In case the
@@ -1182,8 +1174,13 @@ print_version (FILE *file, const char *indent)
N_("%s%s%s %sversion %s (%s) compiled by CC, ")
#endif
;
+#ifdef HAVE_mpc
+ static const char fmt2[] =
+ N_("GMP version %s, MPFR version %s, MPC version %s\n");
+#else
static const char fmt2[] =
- N_("GMP version %s, MPFR version %s.\n");
+ N_("GMP version %s, MPFR version %s\n");
+#endif
static const char fmt3[] =
N_("%s%swarning: %s header version %s differs from library version %s.\n");
static const char fmt4[] =
@@ -1215,7 +1212,11 @@ print_version (FILE *file, const char *indent)
#endif
fprintf (file,
file == stderr ? _(fmt2) : fmt2,
- GCC_GMP_STRINGIFY_VERSION, MPFR_VERSION_STRING);
+ GCC_GMP_STRINGIFY_VERSION, MPFR_VERSION_STRING
+#ifdef HAVE_mpc
+ , MPC_VERSION_STRING
+#endif
+ );
if (strcmp (GCC_GMP_STRINGIFY_VERSION, gmp_version))
fprintf (file,
file == stderr ? _(fmt3) : fmt3,
@@ -1226,6 +1227,13 @@ print_version (FILE *file, const char *indent)
file == stderr ? _(fmt3) : fmt3,
indent, *indent != 0 ? " " : "",
"MPFR", MPFR_VERSION_STRING, mpfr_get_version ());
+#ifdef HAVE_mpc
+ if (strcmp (MPC_VERSION_STRING, mpc_get_version ()))
+ fprintf (file,
+ file == stderr ? _(fmt3) : fmt3,
+ indent, *indent != 0 ? " " : "",
+ "MPC", MPC_VERSION_STRING, mpc_get_version ());
+#endif
fprintf (file,
file == stderr ? _(fmt4) : fmt4,
indent, *indent != 0 ? " " : "",
@@ -2379,14 +2387,14 @@ toplev_main (int argc, char **argv)
{
expandargv (&argc, &argv);
- save_argv = (const char **) argv;
+ save_argv = CONST_CAST2 (const char **, char **, argv);
/* Initialization of GCC's environment, and diagnostics. */
general_init (argv[0]);
/* Parse the options and do minimal processing; basically just
enough to default flags appropriately. */
- decode_options (argc, (const char **) argv);
+ decode_options (argc, CONST_CAST2 (const char **, char **, argv));
init_local_tick ();
diff --git a/gcc/toplev.h b/gcc/toplev.h
index 08a89eab034..cca68675f87 100644
--- a/gcc/toplev.h
+++ b/gcc/toplev.h
@@ -21,6 +21,7 @@ along with GCC; see the file COPYING3. If not see
#ifndef GCC_TOPLEV_H
#define GCC_TOPLEV_H
#include "input.h"
+#include "bversion.h"
/* If non-NULL, return one past-the-end of the matching SUBPART of
the WHOLE string. */
@@ -49,7 +50,7 @@ extern void _fatal_insn (const char *, const_rtx, const char *, int, const char
/* None of these functions are suitable for ATTRIBUTE_PRINTF, because
each language front end can extend them with its own set of format
specifiers. We must use custom format checks. */
-#if GCC_VERSION >= 4001
+#if (ENABLE_CHECKING && GCC_VERSION >= 4001) || GCC_VERSION == BUILDING_GCC_VERSION
#define ATTRIBUTE_GCC_DIAG(m, n) __attribute__ ((__format__ (GCC_DIAG_STYLE, m, n))) ATTRIBUTE_NONNULL(m)
#else
#define ATTRIBUTE_GCC_DIAG(m, n) ATTRIBUTE_NONNULL(m)
@@ -168,14 +169,17 @@ extern void decode_d_option (const char *);
extern bool fast_math_flags_set_p (void);
extern bool fast_math_flags_struct_set_p (struct cl_optimization *);
+/* Inline versions of the above for speed. */
+#if GCC_VERSION < 3004
+
/* Return log2, or -1 if not exact. */
extern int exact_log2 (unsigned HOST_WIDE_INT);
/* Return floor of log2, with -1 for zero. */
extern int floor_log2 (unsigned HOST_WIDE_INT);
-/* Inline versions of the above for speed. */
-#if GCC_VERSION >= 3004
+#else /* GCC_VERSION >= 3004 */
+
# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
# define CLZ_HWI __builtin_clzl
# define CTZ_HWI __builtin_ctzl
@@ -187,17 +191,18 @@ extern int floor_log2 (unsigned HOST_WIDE_INT);
# define CTZ_HWI __builtin_ctz
# endif
-extern inline int
+static inline int
floor_log2 (unsigned HOST_WIDE_INT x)
{
return x ? HOST_BITS_PER_WIDE_INT - 1 - (int) CLZ_HWI (x) : -1;
}
-extern inline int
+static inline int
exact_log2 (unsigned HOST_WIDE_INT x)
{
return x == (x & -x) && x ? (int) CTZ_HWI (x) : -1;
}
+
#endif /* GCC_VERSION >= 3004 */
/* Functions used to get and set GCC's notion of in what directory
diff --git a/gcc/tree-call-cdce.c b/gcc/tree-call-cdce.c
index 698ec2f483e..b71978016c5 100644
--- a/gcc/tree-call-cdce.c
+++ b/gcc/tree-call-cdce.c
@@ -779,7 +779,7 @@ shrink_wrap_one_built_in_call (gimple bi_call)
gcc_assert (cond_expr && gimple_code (cond_expr) == GIMPLE_COND);
/* Now the label. */
- bi_call_label_decl = create_artificial_label ();
+ bi_call_label_decl = create_artificial_label (gimple_location (bi_call));
bi_call_label = gimple_build_label (bi_call_label_decl);
gsi_insert_before (&bi_call_bsi, bi_call_label, GSI_SAME_STMT);
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 30ec6edd86f..9ec165e82f6 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -82,6 +82,14 @@ static struct cfg_stats_d cfg_stats;
/* Nonzero if we found a computed goto while building basic blocks. */
static bool found_computed_goto;
+/* Hash table to store last discriminator assigned for each locus. */
+struct locus_discrim_map
+{
+ location_t locus;
+ int discriminator;
+};
+static htab_t discriminator_per_locus;
+
/* Basic blocks and flowgraphs. */
static void make_blocks (gimple_seq);
static void factor_computed_gotos (void);
@@ -91,6 +99,9 @@ static void make_edges (void);
static void make_cond_expr_edges (basic_block);
static void make_gimple_switch_edges (basic_block);
static void make_goto_expr_edges (basic_block);
+static unsigned int locus_map_hash (const void *);
+static int locus_map_eq (const void *, const void *);
+static void assign_discriminator (location_t, basic_block);
static edge gimple_redirect_edge_and_branch (edge, basic_block);
static edge gimple_try_redirect_by_replacing_jump (edge, basic_block);
static unsigned int split_critical_edges (void);
@@ -100,6 +111,7 @@ static inline bool stmt_starts_bb_p (gimple, gimple);
static int gimple_verify_flow_info (void);
static void gimple_make_forwarder_block (edge);
static void gimple_cfg2vcg (FILE *);
+static gimple first_non_label_stmt (basic_block);
/* Flowgraph optimization and cleanup. */
static void gimple_merge_blocks (basic_block, basic_block);
@@ -193,8 +205,11 @@ build_gimple_cfg (gimple_seq seq)
group_case_labels ();
/* Create the edges of the flowgraph. */
+ discriminator_per_locus = htab_create (13, locus_map_hash, locus_map_eq,
+ free);
make_edges ();
cleanup_dead_labels ();
+ htab_delete (discriminator_per_locus);
/* Debugging dumps. */
@@ -314,7 +329,7 @@ factor_computed_gotos (void)
/* Build a label for the new block which will contain the
factored computed goto. */
- factored_label_decl = create_artificial_label ();
+ factored_label_decl = create_artificial_label (UNKNOWN_LOCATION);
factored_computed_goto_label
= gimple_build_label (factored_label_decl);
gsi_insert_after (&new_gsi, factored_computed_goto_label,
@@ -650,7 +665,11 @@ make_edges (void)
fallthru = true;
if (fallthru)
- make_edge (bb, bb->next_bb, EDGE_FALLTHRU);
+ {
+ make_edge (bb, bb->next_bb, EDGE_FALLTHRU);
+ if (last)
+ assign_discriminator (gimple_location (last), bb->next_bb);
+ }
}
if (root_omp_region)
@@ -660,6 +679,91 @@ make_edges (void)
fold_cond_expr_cond ();
}
+/* Trivial hash function for a location_t. ITEM is a pointer to
+ a hash table entry that maps a location_t to a discriminator. */
+
+static unsigned int
+locus_map_hash (const void *item)
+{
+ return ((const struct locus_discrim_map *) item)->locus;
+}
+
+/* Equality function for the locus-to-discriminator map. VA and VB
+ point to the two hash table entries to compare. */
+
+static int
+locus_map_eq (const void *va, const void *vb)
+{
+ const struct locus_discrim_map *a = (const struct locus_discrim_map *) va;
+ const struct locus_discrim_map *b = (const struct locus_discrim_map *) vb;
+ return a->locus == b->locus;
+}
+
+/* Find the next available discriminator value for LOCUS. The
+ discriminator distinguishes among several basic blocks that
+ share a common locus, allowing for more accurate sample-based
+ profiling. */
+
+static int
+next_discriminator_for_locus (location_t locus)
+{
+ struct locus_discrim_map item;
+ struct locus_discrim_map **slot;
+
+ item.locus = locus;
+ item.discriminator = 0;
+ slot = (struct locus_discrim_map **)
+ htab_find_slot_with_hash (discriminator_per_locus, (void *) &item,
+ (hashval_t) locus, INSERT);
+ gcc_assert (slot);
+ if (*slot == HTAB_EMPTY_ENTRY)
+ {
+ *slot = XNEW (struct locus_discrim_map);
+ gcc_assert (*slot);
+ (*slot)->locus = locus;
+ (*slot)->discriminator = 0;
+ }
+ (*slot)->discriminator++;
+ return (*slot)->discriminator;
+}
+
+/* Return TRUE if LOCUS1 and LOCUS2 refer to the same source line. */
+
+static bool
+same_line_p (location_t locus1, location_t locus2)
+{
+ expanded_location from, to;
+
+ if (locus1 == locus2)
+ return true;
+
+ from = expand_location (locus1);
+ to = expand_location (locus2);
+
+ if (from.line != to.line)
+ return false;
+ if (from.file == to.file)
+ return true;
+ return (from.file != NULL
+ && to.file != NULL
+ && strcmp (from.file, to.file) == 0);
+}
+
+/* Assign a unique discriminator value to block BB if it begins at the same
+ LOCUS as its predecessor block. */
+
+static void
+assign_discriminator (location_t locus, basic_block bb)
+{
+ gimple to_stmt;
+
+ if (locus == 0 || bb->discriminator != 0)
+ return;
+
+ to_stmt = first_non_label_stmt (bb);
+ if (to_stmt && same_line_p (locus, gimple_location (to_stmt)))
+ bb->discriminator = next_discriminator_for_locus (locus);
+}
/* Create the edges for a GIMPLE_COND starting at block BB. */
@@ -671,10 +775,13 @@ make_cond_expr_edges (basic_block bb)
basic_block then_bb, else_bb;
tree then_label, else_label;
edge e;
+ location_t entry_locus;
gcc_assert (entry);
gcc_assert (gimple_code (entry) == GIMPLE_COND);
+ entry_locus = gimple_location (entry);
+
/* Entry basic blocks for each component. */
then_label = gimple_cond_true_label (entry);
else_label = gimple_cond_false_label (entry);
@@ -684,12 +791,14 @@ make_cond_expr_edges (basic_block bb)
else_stmt = first_stmt (else_bb);
e = make_edge (bb, then_bb, EDGE_TRUE_VALUE);
+ assign_discriminator (entry_locus, then_bb);
e->goto_locus = gimple_location (then_stmt);
if (e->goto_locus)
e->goto_block = gimple_block (then_stmt);
e = make_edge (bb, else_bb, EDGE_FALSE_VALUE);
if (e)
{
+ assign_discriminator (entry_locus, else_bb);
e->goto_locus = gimple_location (else_stmt);
if (e->goto_locus)
e->goto_block = gimple_block (else_stmt);
@@ -799,8 +908,11 @@ static void
make_gimple_switch_edges (basic_block bb)
{
gimple entry = last_stmt (bb);
+ location_t entry_locus;
size_t i, n;
+ entry_locus = gimple_location (entry);
+
n = gimple_switch_num_labels (entry);
for (i = 0; i < n; ++i)
@@ -808,6 +920,7 @@ make_gimple_switch_edges (basic_block bb)
tree lab = CASE_LABEL (gimple_switch_label (entry, i));
basic_block label_bb = label_to_block (lab);
make_edge (bb, label_bb, 0);
+ assign_discriminator (entry_locus, label_bb);
}
}
@@ -880,8 +993,10 @@ make_goto_expr_edges (basic_block bb)
if (simple_goto_p (goto_t))
{
tree dest = gimple_goto_dest (goto_t);
- edge e = make_edge (bb, label_to_block (dest), EDGE_FALLTHRU);
+ basic_block label_bb = label_to_block (dest);
+ edge e = make_edge (bb, label_bb, EDGE_FALLTHRU);
e->goto_locus = gimple_location (goto_t);
+ assign_discriminator (e->goto_locus, label_bb);
if (e->goto_locus)
e->goto_block = gimple_block (goto_t);
gsi_remove (&last, true);
@@ -917,7 +1032,7 @@ static struct label_record
/* Callback for for_each_eh_region. Helper for cleanup_dead_labels. */
static void
-update_eh_label (struct eh_region *region)
+update_eh_label (struct eh_region_d *region)
{
tree old_label = get_eh_region_tree_label (region);
if (old_label)
@@ -1289,9 +1404,6 @@ replace_uses_by (tree name, tree val)
FOR_EACH_IMM_USE_STMT (stmt, imm_iter, name)
{
- if (gimple_code (stmt) != GIMPLE_PHI)
- push_stmt_changes (&stmt);
-
FOR_EACH_IMM_USE_ON_STMT (use, imm_iter)
{
replace_exp (use, val);
@@ -1318,7 +1430,7 @@ replace_uses_by (tree name, tree val)
if (cfgcleanup_altered_bbs)
bitmap_set_bit (cfgcleanup_altered_bbs, gimple_bb (stmt)->index);
- /* FIXME. This should go in pop_stmt_changes. */
+ /* FIXME. This should go in update_stmt. */
for (i = 0; i < gimple_num_ops (stmt); i++)
{
tree op = gimple_op (stmt, i);
@@ -1330,8 +1442,7 @@ replace_uses_by (tree name, tree val)
}
maybe_clean_or_replace_eh_stmt (stmt, stmt);
-
- pop_stmt_changes (&stmt);
+ update_stmt (stmt);
}
}
@@ -1460,7 +1571,7 @@ gimple_merge_blocks (basic_block a, basic_block b)
/* Return the one of two successors of BB that is not reachable by a
- reached by a complex edge, if there is one. Else, return BB. We use
+ complex edge, if there is one. Else, return BB. We use
this in optimizations that use post-dominators for their heuristics,
to catch the cases in C++ where function calls are involved. */
@@ -2045,18 +2156,6 @@ remove_useless_stmts_1 (gimple_stmt_iterator *gsi, struct rus_data *data)
}
break;
- case GIMPLE_CHANGE_DYNAMIC_TYPE:
- /* If we do not optimize remove GIMPLE_CHANGE_DYNAMIC_TYPE as
- expansion is confused about them and we only remove them
- during alias computation otherwise. */
- if (!optimize)
- {
- data->last_was_goto = false;
- gsi_remove (gsi, false);
- break;
- }
- /* Fallthru. */
-
default:
data->last_was_goto = false;
gsi_next (gsi);
@@ -2713,6 +2812,17 @@ first_stmt (basic_block bb)
return stmt;
}
+/* Return the first non-label statement in basic block BB. */
+
+static gimple
+first_non_label_stmt (basic_block bb)
+{
+ gimple_stmt_iterator i = gsi_start_bb (bb);
+ while (!gsi_end_p (i) && gimple_code (gsi_stmt (i)) == GIMPLE_LABEL)
+ gsi_next (&i);
+ return !gsi_end_p (i) ? gsi_stmt (i) : NULL;
+}
+
/* Return the last statement in basic block BB. */
gimple
@@ -4063,10 +4173,6 @@ verify_types_in_gimple_stmt (gimple stmt)
case GIMPLE_ASM:
return false;
- case GIMPLE_CHANGE_DYNAMIC_TYPE:
- return (!is_gimple_val (gimple_cdt_location (stmt))
- || !POINTER_TYPE_P (TREE_TYPE (gimple_cdt_location (stmt))));
-
case GIMPLE_PHI:
return verify_gimple_phi (stmt);
@@ -4196,7 +4302,7 @@ verify_stmt (gimple_stmt_iterator *gsi)
if (addr)
{
debug_generic_expr (addr);
- inform (input_location, "in statement");
+ inform (gimple_location (gsi_stmt (*gsi)), "in statement");
debug_gimple_stmt (stmt);
return true;
}
@@ -4392,6 +4498,7 @@ verify_stmts (void)
if (gimple_bb (stmt) != bb)
{
error ("gimple_bb (stmt) is set to a wrong basic block");
+ debug_gimple_stmt (stmt);
err |= true;
}
@@ -4801,7 +4908,7 @@ gimple_block_label (basic_block bb)
}
}
- label = create_artificial_label ();
+ label = create_artificial_label (UNKNOWN_LOCATION);
stmt = gimple_build_label (label);
gsi_insert_before (&s, stmt, GSI_NEW_STMT);
return label;
@@ -5960,7 +6067,7 @@ new_label_mapper (tree decl, void *data)
m = XNEW (struct tree_map);
m->hash = DECL_UID (decl);
m->base.from = decl;
- m->to = create_artificial_label ();
+ m->to = create_artificial_label (UNKNOWN_LOCATION);
LABEL_DECL_UID (m->to) = LABEL_DECL_UID (decl);
if (LABEL_DECL_UID (m->to) >= cfun->cfg->last_label_uid)
cfun->cfg->last_label_uid = LABEL_DECL_UID (m->to) + 1;
diff --git a/gcc/tree-chrec.c b/gcc/tree-chrec.c
index 82c1fbefacf..495f95a8be7 100644
--- a/gcc/tree-chrec.c
+++ b/gcc/tree-chrec.c
@@ -1100,21 +1100,6 @@ nb_vars_in_chrec (tree chrec)
}
}
-/* Returns true if TYPE is a type in that we cannot directly perform
- arithmetics, even though it is a scalar type. */
-
-static bool
-avoid_arithmetics_in_type_p (const_tree type)
-{
- /* Ada frontend uses subtypes -- an arithmetic cannot be directly performed
- in the subtype, but a base type must be used, and the result then can
- be casted to the subtype. */
- if (TREE_CODE (type) == INTEGER_TYPE && TREE_TYPE (type) != NULL_TREE)
- return true;
-
- return false;
-}
-
static tree chrec_convert_1 (tree, tree, gimple, bool);
/* Converts BASE and STEP of affine scev to TYPE. LOOP is the loop whose iv
@@ -1136,10 +1121,6 @@ convert_affine_scev (struct loop *loop, tree type,
tree new_base, new_step;
tree step_type = POINTER_TYPE_P (type) ? sizetype : type;
- /* If we cannot perform arithmetic in TYPE, avoid creating an scev. */
- if (avoid_arithmetics_in_type_p (type))
- return false;
-
/* In general,
(TYPE) (BASE + STEP * i) = (TYPE) BASE + (TYPE -- sign extend) STEP * i,
but we must check some assumptions.
@@ -1342,10 +1323,6 @@ chrec_convert_aggressive (tree type, tree chrec)
if (TYPE_PRECISION (type) > TYPE_PRECISION (inner_type))
return NULL_TREE;
- /* If we cannot perform arithmetic in TYPE, avoid creating an scev. */
- if (avoid_arithmetics_in_type_p (type))
- return NULL_TREE;
-
rtype = POINTER_TYPE_P (type) ? sizetype : type;
left = CHREC_LEFT (chrec);
diff --git a/gcc/tree-complex.c b/gcc/tree-complex.c
index 2835220c206..3f1992b716b 100644
--- a/gcc/tree-complex.c
+++ b/gcc/tree-complex.c
@@ -604,6 +604,7 @@ extract_component (gimple_stmt_iterator *gsi, tree t, bool imagpart_p,
case INDIRECT_REF:
case COMPONENT_REF:
case ARRAY_REF:
+ case VIEW_CONVERT_EXPR:
{
tree inner_type = TREE_TYPE (TREE_TYPE (t));
diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c
index de2ad5f921b..2181f469ca0 100644
--- a/gcc/tree-data-ref.c
+++ b/gcc/tree-data-ref.c
@@ -668,8 +668,9 @@ canonicalize_base_object_address (tree addr)
return build_fold_addr_expr (TREE_OPERAND (addr, 0));
}
-/* Analyzes the behavior of the memory reference DR in the innermost loop that
- contains it. Returns true if analysis succeed or false otherwise. */
+/* Analyzes the behavior of the memory reference DR in the innermost loop or
+ basic block that contains it. Returns true if analysis succeed or false
+ otherwise. */
bool
dr_analyze_innermost (struct data_reference *dr)
@@ -683,6 +684,7 @@ dr_analyze_innermost (struct data_reference *dr)
int punsignedp, pvolatilep;
affine_iv base_iv, offset_iv;
tree init, dinit, step;
+ bool in_loop = (loop && loop->num);
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "analyze_innermost: ");
@@ -699,23 +701,43 @@ dr_analyze_innermost (struct data_reference *dr)
}
base = build_fold_addr_expr (base);
- if (!simple_iv (loop, loop_containing_stmt (stmt), base, &base_iv, false))
+ if (in_loop)
{
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "failed: evolution of base is not affine.\n");
- return false;
+ if (!simple_iv (loop, loop_containing_stmt (stmt), base, &base_iv,
+ false))
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "failed: evolution of base is not affine.\n");
+ return false;
+ }
}
+ else
+ {
+ base_iv.base = base;
+ base_iv.step = ssize_int (0);
+ base_iv.no_overflow = true;
+ }
+
if (!poffset)
{
offset_iv.base = ssize_int (0);
offset_iv.step = ssize_int (0);
}
- else if (!simple_iv (loop, loop_containing_stmt (stmt),
- poffset, &offset_iv, false))
+ else
{
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "failed: evolution of offset is not affine.\n");
- return false;
+ if (!in_loop)
+ {
+ offset_iv.base = poffset;
+ offset_iv.step = ssize_int (0);
+ }
+ else if (!simple_iv (loop, loop_containing_stmt (stmt),
+ poffset, &offset_iv, false))
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "failed: evolution of offset is not"
+ " affine.\n");
+ return false;
+ }
}
init = ssize_int (pbitpos / BITS_PER_UNIT);
@@ -752,17 +774,23 @@ dr_analyze_indices (struct data_reference *dr, struct loop *nest)
struct loop *loop = loop_containing_stmt (stmt);
VEC (tree, heap) *access_fns = NULL;
tree ref = unshare_expr (DR_REF (dr)), aref = ref, op;
- tree base, off, access_fn;
- basic_block before_loop = block_before_loop (nest);
-
+ tree base, off, access_fn = NULL_TREE;
+ basic_block before_loop = NULL;
+
+ if (nest)
+ before_loop = block_before_loop (nest);
+
while (handled_component_p (aref))
{
if (TREE_CODE (aref) == ARRAY_REF)
{
op = TREE_OPERAND (aref, 1);
- access_fn = analyze_scalar_evolution (loop, op);
- access_fn = instantiate_scev (before_loop, loop, access_fn);
- VEC_safe_push (tree, heap, access_fns, access_fn);
+ if (nest)
+ {
+ access_fn = analyze_scalar_evolution (loop, op);
+ access_fn = instantiate_scev (before_loop, loop, access_fn);
+ VEC_safe_push (tree, heap, access_fns, access_fn);
+ }
TREE_OPERAND (aref, 1) = build_int_cst (TREE_TYPE (op), 0);
}
@@ -770,7 +798,7 @@ dr_analyze_indices (struct data_reference *dr, struct loop *nest)
aref = TREE_OPERAND (aref, 0);
}
- if (INDIRECT_REF_P (aref))
+ if (nest && INDIRECT_REF_P (aref))
{
op = TREE_OPERAND (aref, 0);
access_fn = analyze_scalar_evolution (loop, op);
@@ -1223,7 +1251,17 @@ dr_may_alias_p (const struct data_reference *a, const struct data_reference *b)
return false;
/* Query the alias oracle. */
- if (!refs_may_alias_p (DR_REF (a), DR_REF (b)))
+ if (!DR_IS_READ (a) && !DR_IS_READ (b))
+ {
+ if (!refs_output_dependent_p (DR_REF (a), DR_REF (b)))
+ return false;
+ }
+ else if (DR_IS_READ (a) && !DR_IS_READ (b))
+ {
+ if (!refs_anti_dependent_p (DR_REF (a), DR_REF (b)))
+ return false;
+ }
+ else if (!refs_may_alias_p (DR_REF (a), DR_REF (b)))
return false;
if (!addr_a || !addr_b)
@@ -1322,8 +1360,9 @@ initialize_data_dependence_relation (struct data_reference *a,
/* If the base of the object is not invariant in the loop nest, we cannot
analyze it. TODO -- in fact, it would suffice to record that there may
be arbitrary dependences in the loops where the base object varies. */
- if (!object_address_invariant_in_loop_p (VEC_index (loop_p, loop_nest, 0),
- DR_BASE_OBJECT (a)))
+ if (loop_nest
+ && !object_address_invariant_in_loop_p (VEC_index (loop_p, loop_nest, 0),
+ DR_BASE_OBJECT (a)))
{
DDR_ARE_DEPENDENT (res) = chrec_dont_know;
return res;
@@ -3993,7 +4032,8 @@ compute_all_dependences (VEC (data_reference_p, heap) *datarefs,
{
ddr = initialize_data_dependence_relation (a, b, loop_nest);
VEC_safe_push (ddr_p, heap, *dependence_relations, ddr);
- compute_affine_dependence (ddr, VEC_index (loop_p, loop_nest, 0));
+ if (loop_nest)
+ compute_affine_dependence (ddr, VEC_index (loop_p, loop_nest, 0));
}
if (compute_self_and_rr)
@@ -4100,9 +4140,10 @@ find_data_references_in_stmt (struct loop *nest, gimple stmt,
dr = create_data_ref (nest, *ref->pos, stmt, ref->is_read);
gcc_assert (dr != NULL);
- /* FIXME -- data dependence analysis does not work correctly for objects with
- invariant addresses. Let us fail here until the problem is fixed. */
- if (dr_address_invariant_p (dr))
+ /* FIXME -- data dependence analysis does not work correctly for objects
+ with invariant addresses in loop nests. Let us fail here until the
+ problem is fixed. */
+ if (dr_address_invariant_p (dr) && nest)
{
free_data_ref (dr);
if (dump_file && (dump_flags & TDF_DETAILS))
@@ -4119,6 +4160,33 @@ find_data_references_in_stmt (struct loop *nest, gimple stmt,
/* Search the data references in LOOP, and record the information into
DATAREFS. Returns chrec_dont_know when failing to analyze a
+ difficult case, returns NULL_TREE otherwise. */
+
+static tree
+find_data_references_in_bb (struct loop *loop, basic_block bb,
+ VEC (data_reference_p, heap) **datarefs)
+{
+ gimple_stmt_iterator bsi;
+
+ for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
+ {
+ gimple stmt = gsi_stmt (bsi);
+
+ if (!find_data_references_in_stmt (loop, stmt, datarefs))
+ {
+ struct data_reference *res;
+ res = XCNEW (struct data_reference);
+ VEC_safe_push (data_reference_p, heap, *datarefs, res);
+
+ return chrec_dont_know;
+ }
+ }
+
+ return NULL_TREE;
+}
+
+/* Search the data references in LOOP, and record the information into
+ DATAREFS. Returns chrec_dont_know when failing to analyze a
difficult case, returns NULL_TREE otherwise.
TODO: This function should be made smarter so that it can handle address
@@ -4130,7 +4198,6 @@ find_data_references_in_loop (struct loop *loop,
{
basic_block bb, *bbs;
unsigned int i;
- gimple_stmt_iterator bsi;
bbs = get_loop_body_in_dom_order (loop);
@@ -4138,20 +4205,11 @@ find_data_references_in_loop (struct loop *loop,
{
bb = bbs[i];
- for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
- {
- gimple stmt = gsi_stmt (bsi);
-
- if (!find_data_references_in_stmt (loop, stmt, datarefs))
- {
- struct data_reference *res;
- res = XCNEW (struct data_reference);
- VEC_safe_push (data_reference_p, heap, *datarefs, res);
-
- free (bbs);
- return chrec_dont_know;
- }
- }
+ if (find_data_references_in_bb (loop, bb, datarefs) == chrec_dont_know)
+ {
+ free (bbs);
+ return chrec_dont_know;
+ }
}
free (bbs);
@@ -4288,6 +4346,26 @@ compute_data_dependences_for_loop (struct loop *loop,
return res;
}
+/* Returns true when the data dependences for the basic block BB have been
+ computed, false otherwise.
+ DATAREFS is initialized to all the array elements contained in this basic
+ block, DEPENDENCE_RELATIONS contains the relations between the data
+ references. Compute read-read and self relations if
+ COMPUTE_SELF_AND_READ_READ_DEPENDENCES is TRUE. */
+bool
+compute_data_dependences_for_bb (basic_block bb,
+ bool compute_self_and_read_read_dependences,
+ VEC (data_reference_p, heap) **datarefs,
+ VEC (ddr_p, heap) **dependence_relations)
+{
+ if (find_data_references_in_bb (NULL, bb, datarefs) == chrec_dont_know)
+ return false;
+
+ compute_all_dependences (*datarefs, dependence_relations, NULL,
+ compute_self_and_read_read_dependences);
+ return true;
+}
+
/* Entry point (for testing only). Analyze all the data references
and the dependence relations in LOOP.
diff --git a/gcc/tree-data-ref.h b/gcc/tree-data-ref.h
index 690301a6f94..dfce23309f5 100644
--- a/gcc/tree-data-ref.h
+++ b/gcc/tree-data-ref.h
@@ -383,6 +383,9 @@ bool dr_analyze_innermost (struct data_reference *);
extern bool compute_data_dependences_for_loop (struct loop *, bool,
VEC (data_reference_p, heap) **,
VEC (ddr_p, heap) **);
+extern bool compute_data_dependences_for_bb (basic_block, bool,
+ VEC (data_reference_p, heap) **,
+ VEC (ddr_p, heap) **);
extern tree find_data_references_in_loop (struct loop *,
VEC (data_reference_p, heap) **);
extern void print_direction_vector (FILE *, lambda_vector, int);
diff --git a/gcc/tree-dfa.c b/gcc/tree-dfa.c
index 4f0cd847195..bc826d01513 100644
--- a/gcc/tree-dfa.c
+++ b/gcc/tree-dfa.c
@@ -656,11 +656,7 @@ get_virtual_var (tree var)
return var;
}
-/* Mark all the naked symbols in STMT for SSA renaming.
-
- NOTE: This function should only be used for brand new statements.
- If the caller is modifying an existing statement, it should use the
- combination push_stmt_changes/pop_stmt_changes. */
+/* Mark all the naked symbols in STMT for SSA renaming. */
void
mark_symbols_for_renaming (gimple stmt)
@@ -759,7 +755,7 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
switch (TREE_CODE (exp))
{
case BIT_FIELD_REF:
- bit_offset += tree_low_cst (TREE_OPERAND (exp, 2), 0);
+ bit_offset += TREE_INT_CST_LOW (TREE_OPERAND (exp, 2));
break;
case COMPONENT_REF:
@@ -770,13 +766,14 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
if (TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == UNION_TYPE)
seen_union = true;
- if (this_offset && TREE_CODE (this_offset) == INTEGER_CST)
+ if (this_offset
+ && TREE_CODE (this_offset) == INTEGER_CST
+ && host_integerp (this_offset, 0))
{
- HOST_WIDE_INT hthis_offset = tree_low_cst (this_offset, 0);
-
+ HOST_WIDE_INT hthis_offset = TREE_INT_CST_LOW (this_offset);
hthis_offset *= BITS_PER_UNIT;
bit_offset += hthis_offset;
- bit_offset += tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 0);
+ bit_offset += TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (field));
}
else
{
@@ -796,18 +793,20 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
case ARRAY_RANGE_REF:
{
tree index = TREE_OPERAND (exp, 1);
- tree low_bound = array_ref_low_bound (exp);
- tree unit_size = array_ref_element_size (exp);
+ tree low_bound, unit_size;
/* If the resulting bit-offset is constant, track it. */
- if (host_integerp (index, 0)
- && host_integerp (low_bound, 0)
- && host_integerp (unit_size, 1))
+ if (TREE_CODE (index) == INTEGER_CST
+ && host_integerp (index, 0)
+ && (low_bound = array_ref_low_bound (exp),
+ host_integerp (low_bound, 0))
+ && (unit_size = array_ref_element_size (exp),
+ host_integerp (unit_size, 1)))
{
- HOST_WIDE_INT hindex = tree_low_cst (index, 0);
+ HOST_WIDE_INT hindex = TREE_INT_CST_LOW (index);
- hindex -= tree_low_cst (low_bound, 0);
- hindex *= tree_low_cst (unit_size, 1);
+ hindex -= TREE_INT_CST_LOW (low_bound);
+ hindex *= TREE_INT_CST_LOW (unit_size);
hindex *= BITS_PER_UNIT;
bit_offset += hindex;
diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c
index 56490f8e3c8..d9baf711379 100644
--- a/gcc/tree-eh.c
+++ b/gcc/tree-eh.c
@@ -87,7 +87,7 @@ struct_ptr_hash (const void *a)
of space by only allocating memory for those that can throw. */
static void
-record_stmt_eh_region (struct eh_region *region, gimple t)
+record_stmt_eh_region (struct eh_region_d *region, gimple t)
{
if (!region)
return;
@@ -371,7 +371,7 @@ struct leh_state
/* What's "current" while constructing the eh region tree. These
correspond to variables of the same name in cfun->eh, which we
don't have easy access to. */
- struct eh_region *cur_region;
+ struct eh_region_d *cur_region;
/* Processing of TRY_FINALLY requires a bit more state. This is
split out into a separate structure so that we don't have to
@@ -395,7 +395,7 @@ struct leh_tf_state
struct leh_state *outer;
/* The exception region created for it. */
- struct eh_region *region;
+ struct eh_region_d *region;
/* The goto queue. */
struct goto_queue_node *goto_queue;
@@ -486,6 +486,7 @@ replace_goto_queue_cond_clause (tree *tp, struct leh_tf_state *tf,
tree label;
gimple_seq new_seq;
treemple temp;
+ location_t loc = gimple_location (gsi_stmt (*gsi));
temp.tp = tp;
new_seq = find_goto_replacement (tf, temp);
@@ -499,7 +500,7 @@ replace_goto_queue_cond_clause (tree *tp, struct leh_tf_state *tf,
return;
}
- label = create_artificial_label ();
+ label = create_artificial_label (loc);
/* Set the new label for the GIMPLE_COND */
*tp = label;
@@ -832,6 +833,7 @@ frob_into_branch_around (gimple tp, tree lab, tree over)
{
gimple x;
gimple_seq cleanup, result;
+ location_t loc = gimple_location (tp);
cleanup = gimple_try_cleanup (tp);
result = gimple_try_eval (tp);
@@ -839,7 +841,7 @@ frob_into_branch_around (gimple tp, tree lab, tree over)
if (gimple_seq_may_fallthru (result))
{
if (!over)
- over = create_artificial_label ();
+ over = create_artificial_label (loc);
x = gimple_build_goto (over);
gimple_seq_add_stmt (&result, x);
}
@@ -890,7 +892,7 @@ lower_try_finally_fallthru_label (struct leh_tf_state *tf)
if (!label)
{
- label = create_artificial_label ();
+ label = create_artificial_label (gimple_location (tf->try_finally_expr));
tf->fallthru_label = label;
if (tf->outer->tf)
{
@@ -1082,7 +1084,7 @@ lower_try_finally_nofallthru (struct leh_state *state,
if (tf->may_throw)
lab = tf->eh_label;
else
- lab = create_artificial_label ();
+ lab = create_artificial_label (gimple_location (tf->try_finally_expr));
/* We expect that tf->top_p is a GIMPLE_TRY. */
finally = gimple_try_cleanup (tf->top_p);
@@ -1117,6 +1119,7 @@ lower_try_finally_onedest (struct leh_state *state, struct leh_tf_state *tf)
gimple x;
gimple_seq finally;
tree finally_label;
+ location_t loc = gimple_location (tf->try_finally_expr);
finally = gimple_try_cleanup (tf->top_p);
tf->top_p_seq = gimple_try_eval (tf->top_p);
@@ -1148,7 +1151,7 @@ lower_try_finally_onedest (struct leh_state *state, struct leh_tf_state *tf)
return;
}
- finally_label = create_artificial_label ();
+ finally_label = create_artificial_label (loc);
x = gimple_build_label (finally_label);
gimple_seq_add_stmt (&tf->top_p_seq, x);
@@ -1201,6 +1204,7 @@ lower_try_finally_copy (struct leh_state *state, struct leh_tf_state *tf)
gimple_seq seq;
gimple x;
tree tmp;
+ location_t tf_loc = gimple_location (tf->try_finally_expr);
finally = gimple_try_cleanup (tf->top_p);
tf->top_p_seq = gimple_try_eval (tf->top_p);
@@ -1262,7 +1266,8 @@ lower_try_finally_copy (struct leh_state *state, struct leh_tf_state *tf)
if (! q)
continue;
- lab = labels[index].label = create_artificial_label ();
+ lab = labels[index].label
+ = create_artificial_label (tf_loc);
if (index == return_index)
do_return_redirection (q, lab, NULL, &return_val);
@@ -1327,6 +1332,10 @@ lower_try_finally_switch (struct leh_state *state, struct leh_tf_state *tf)
gimple switch_stmt;
gimple_seq finally;
struct pointer_map_t *cont_map = NULL;
+ /* The location of the TRY_FINALLY stmt. */
+ location_t tf_loc = gimple_location (tf->try_finally_expr);
+ /* The location of the finally block. */
+ location_t finally_loc;
switch_body = gimple_seq_alloc ();
@@ -1334,6 +1343,12 @@ lower_try_finally_switch (struct leh_state *state, struct leh_tf_state *tf)
finally = gimple_try_cleanup (tf->top_p);
tf->top_p_seq = gimple_try_eval (tf->top_p);
+ /* The location of the finally is either the last stmt in the finally
+ block or the location of the TRY_FINALLY itself. */
+ finally_loc = gimple_seq_last_stmt (tf->top_p_seq) != NULL ?
+ gimple_location (gimple_seq_last_stmt (tf->top_p_seq))
+ : tf_loc;
+
/* Lower the finally block itself. */
lower_eh_constructs_1 (state, finally);
@@ -1345,7 +1360,7 @@ lower_try_finally_switch (struct leh_state *state, struct leh_tf_state *tf)
ndests = fallthru_index + tf->may_fallthru;
finally_tmp = create_tmp_var (integer_type_node, "finally_tmp");
- finally_label = create_artificial_label ();
+ finally_label = create_artificial_label (finally_loc);
/* We use VEC_quick_push on case_label_vec throughout this function,
since we know the size in advance and allocate precisely as muce
@@ -1373,7 +1388,7 @@ lower_try_finally_switch (struct leh_state *state, struct leh_tf_state *tf)
last_case = build3 (CASE_LABEL_EXPR, void_type_node,
build_int_cst (NULL_TREE, fallthru_index), NULL,
- create_artificial_label ());
+ create_artificial_label (tf_loc));
VEC_quick_push (tree, case_label_vec, last_case);
last_case_index++;
@@ -1396,7 +1411,7 @@ lower_try_finally_switch (struct leh_state *state, struct leh_tf_state *tf)
last_case = build3 (CASE_LABEL_EXPR, void_type_node,
build_int_cst (NULL_TREE, eh_index), NULL,
- create_artificial_label ());
+ create_artificial_label (tf_loc));
VEC_quick_push (tree, case_label_vec, last_case);
last_case_index++;
@@ -1480,7 +1495,7 @@ lower_try_finally_switch (struct leh_state *state, struct leh_tf_state *tf)
gcc_assert (slot);
cont_stmt = *(gimple *) slot;
- label = create_artificial_label ();
+ label = create_artificial_label (tf_loc);
CASE_LABEL (last_case) = label;
x = gimple_build_label (label);
@@ -1502,6 +1517,7 @@ lower_try_finally_switch (struct leh_state *state, struct leh_tf_state *tf)
label. */
switch_stmt = gimple_build_switch_vec (finally_tmp, last_case,
case_label_vec);
+ gimple_set_location (switch_stmt, finally_loc);
/* Need to link SWITCH_STMT after running replace_goto_queue
due to not wanting to process the same goto stmts twice. */
@@ -1561,6 +1577,7 @@ lower_try_finally (struct leh_state *state, gimple tp)
struct leh_tf_state this_tf;
struct leh_state this_state;
int ndests;
+ location_t tf_loc = gimple_location (tp);
/* Process the try block. */
@@ -1587,7 +1604,7 @@ lower_try_finally (struct leh_state *state, gimple tp)
this_tf.may_throw = get_eh_region_may_contain_throw (this_tf.region);
if (this_tf.may_throw)
{
- this_tf.eh_label = create_artificial_label ();
+ this_tf.eh_label = create_artificial_label (tf_loc);
set_eh_region_tree_label (this_tf.region, this_tf.eh_label);
honor_protect_cleanup_actions (state, &this_state, &this_tf);
}
@@ -1646,10 +1663,11 @@ lower_try_finally (struct leh_state *state, gimple tp)
static gimple_seq
lower_catch (struct leh_state *state, gimple tp)
{
- struct eh_region *try_region;
+ struct eh_region_d *try_region;
struct leh_state this_state;
gimple_stmt_iterator gsi;
tree out_label;
+ location_t try_catch_loc = gimple_location (tp);
try_region = gen_eh_region_try (state->cur_region);
this_state.cur_region = try_region;
@@ -1665,7 +1683,7 @@ lower_catch (struct leh_state *state, gimple tp)
out_label = NULL;
for (gsi = gsi_start (gimple_try_cleanup (tp)); !gsi_end_p (gsi); )
{
- struct eh_region *catch_region;
+ struct eh_region_d *catch_region;
tree eh_label;
gimple x, gcatch;
@@ -1676,7 +1694,7 @@ lower_catch (struct leh_state *state, gimple tp)
this_state.cur_region = catch_region;
lower_eh_constructs_1 (&this_state, gimple_catch_handler (gcatch));
- eh_label = create_artificial_label ();
+ eh_label = create_artificial_label (try_catch_loc);
set_eh_region_tree_label (catch_region, eh_label);
x = gimple_build_label (eh_label);
@@ -1685,7 +1703,7 @@ lower_catch (struct leh_state *state, gimple tp)
if (gimple_seq_may_fallthru (gimple_catch_handler (gcatch)))
{
if (!out_label)
- out_label = create_artificial_label ();
+ out_label = create_artificial_label (try_catch_loc);
x = gimple_build_goto (out_label);
gimple_seq_add_stmt (gimple_catch_handler_ptr (gcatch), x);
@@ -1707,7 +1725,7 @@ static gimple_seq
lower_eh_filter (struct leh_state *state, gimple tp)
{
struct leh_state this_state;
- struct eh_region *this_region;
+ struct eh_region_d *this_region;
gimple inner;
tree eh_label;
@@ -1731,7 +1749,7 @@ lower_eh_filter (struct leh_state *state, gimple tp)
lower_eh_constructs_1 (state, gimple_eh_filter_failure (inner));
gimple_try_set_cleanup (tp, gimple_eh_filter_failure (inner));
- eh_label = create_artificial_label ();
+ eh_label = create_artificial_label (gimple_location (inner));
set_eh_region_tree_label (this_region, eh_label);
return frob_into_branch_around (tp, eh_label, NULL);
@@ -1744,7 +1762,7 @@ static gimple_seq
lower_cleanup (struct leh_state *state, gimple tp)
{
struct leh_state this_state;
- struct eh_region *this_region;
+ struct eh_region_d *this_region;
struct leh_tf_state fake_tf;
gimple_seq result;
@@ -1770,13 +1788,13 @@ lower_cleanup (struct leh_state *state, gimple tp)
/* Build enough of a try-finally state so that we can reuse
honor_protect_cleanup_actions. */
memset (&fake_tf, 0, sizeof (fake_tf));
- fake_tf.top_p = tp;
+ fake_tf.top_p = fake_tf.try_finally_expr = tp;
fake_tf.outer = state;
fake_tf.region = this_region;
fake_tf.may_fallthru = gimple_seq_may_fallthru (gimple_try_eval (tp));
fake_tf.may_throw = true;
- fake_tf.eh_label = create_artificial_label ();
+ fake_tf.eh_label = create_artificial_label (gimple_location (tp));
set_eh_region_tree_label (this_region, fake_tf.eh_label);
honor_protect_cleanup_actions (state, NULL, &fake_tf);
@@ -1947,7 +1965,7 @@ struct gimple_opt_pass pass_lower_eh =
/* Construct EH edges for STMT. */
static void
-make_eh_edge (struct eh_region *region, void *data)
+make_eh_edge (struct eh_region_d *region, void *data)
{
gimple stmt;
tree lab;
@@ -2026,7 +2044,7 @@ redirect_eh_edge (edge e, basic_block new_bb)
bool is_resx;
bool inlinable = false;
tree label = gimple_block_label (new_bb);
- struct eh_region *r;
+ struct eh_region_d *r;
if (gimple_code (stmt) == GIMPLE_RESX)
{
@@ -2066,7 +2084,7 @@ static bool mark_eh_edge_found_error;
field, output error if something goes wrong. */
static void
-mark_eh_edge (struct eh_region *region, void *data)
+mark_eh_edge (struct eh_region_d *region, void *data)
{
gimple stmt;
tree lab;
@@ -2958,7 +2976,7 @@ struct update_info
operands from DATA->bb_to_remove. */
static void
-make_eh_edge_and_update_phi (struct eh_region *region, void *data)
+make_eh_edge_and_update_phi (struct eh_region_d *region, void *data)
{
struct update_info *info = (struct update_info *) data;
edge e, e2;
diff --git a/gcc/tree-flow-inline.h b/gcc/tree-flow-inline.h
index 9c31eff2a04..f95052bf12e 100644
--- a/gcc/tree-flow-inline.h
+++ b/gcc/tree-flow-inline.h
@@ -1198,6 +1198,21 @@ ref_contains_array_ref (const_tree ref)
return false;
}
+/* Return true if REF has an VIEW_CONVERT_EXPR somewhere in it. */
+
+static inline bool
+contains_view_convert_expr_p (const_tree ref)
+{
+ while (handled_component_p (ref))
+ {
+ if (TREE_CODE (ref) == VIEW_CONVERT_EXPR)
+ return true;
+ ref = TREE_OPERAND (ref, 0);
+ }
+
+ return false;
+}
+
/* Return true, if the two ranges [POS1, SIZE1] and [POS2, SIZE2]
overlap. SIZE1 and/or SIZE2 can be (unsigned)-1 in which case the
range is open-ended. Otherwise return false. */
diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h
index b8d89ff7679..86dd641c06d 100644
--- a/gcc/tree-flow.h
+++ b/gcc/tree-flow.h
@@ -684,7 +684,6 @@ int loop_depth_of_name (tree);
tree degenerate_phi_result (gimple);
/* In tree-ssa-copy.c */
-extern void merge_alias_info (tree, tree);
extern void propagate_value (use_operand_p, tree);
extern void propagate_tree_value (tree *, tree);
extern void propagate_tree_value_into_stmt (gimple_stmt_iterator *, tree);
@@ -867,32 +866,9 @@ void add_to_value (unsigned int, struct pre_expr_d *);
void debug_value_expressions (unsigned int);
void print_value_expressions (FILE *, unsigned int);
-
-/* In tree-vn.c */
-tree make_value_handle (tree);
-void set_value_handle (tree, tree);
-bool expressions_equal_p (tree, tree);
-void sort_vuses (VEC (tree, gc) *);
-void sort_vuses_heap (VEC (tree, heap) *);
-tree vn_lookup_or_add (tree);
-tree vn_lookup_or_add_with_stmt (tree, gimple);
-tree vn_lookup_or_add_with_vuses (tree, VEC (tree, gc) *);
-void vn_add (tree, tree);
-void vn_add_with_vuses (tree, tree, VEC (tree, gc) *);
-tree vn_lookup_with_stmt (tree, gimple);
-tree vn_lookup (tree);
-tree vn_lookup_with_vuses (tree, VEC (tree, gc) *);
-
/* In tree-ssa-sink.c */
bool is_hidden_global_store (gimple);
-/* In tree-sra.c */
-void insert_edge_copies_seq (gimple_seq, basic_block);
-void sra_insert_before (gimple_stmt_iterator *, gimple_seq);
-void sra_insert_after (gimple_stmt_iterator *, gimple_seq);
-void sra_init_cache (void);
-bool sra_type_can_be_decomposed_p (tree);
-
/* In tree-loop-linear.c */
extern void linear_transform_loops (void);
extern unsigned perfect_loop_nest_depth (struct loop *);
@@ -923,6 +899,7 @@ void mark_addressable (tree);
/* In tree-ssa-live.c */
extern void remove_unused_locals (void);
extern void dump_scope_blocks (FILE *, int);
+extern void debug_scope_blocks (int);
/* In tree-ssa-address.c */
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index eaf39802b02..e0bbea17985 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -1011,7 +1011,7 @@ copy_tree_body_r (tree *tp, int *walk_subtrees, void *data)
STRIP_TYPE_NOPS (value);
if (TREE_CONSTANT (value) || TREE_READONLY (value))
{
- *tp = build_empty_stmt ();
+ *tp = build_empty_stmt (EXPR_LOCATION (*tp));
return copy_tree_body_r (tp, walk_subtrees, data);
}
}
@@ -1558,11 +1558,14 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
gcc_unreachable ();
}
+ edge = cgraph_edge (id->src_node, orig_stmt);
/* Constant propagation on argument done during inlining
may create new direct call. Produce an edge for it. */
- if (!edge && is_gimple_call (stmt)
- && (fn = gimple_call_fndecl (stmt)) != NULL
- && !cgraph_edge (id->dst_node, stmt))
+ if ((!edge
+ || (edge->indirect_call
+ && id->transform_call_graph_edges == CB_CGE_MOVE_CLONES))
+ && is_gimple_call (stmt)
+ && (fn = gimple_call_fndecl (stmt)) != NULL)
{
struct cgraph_node *dest = cgraph_node (fn);
@@ -2817,7 +2820,6 @@ inline_forbidden_p_2 (tree *nodep, int *walk_subtrees,
static bool
inline_forbidden_p (tree fndecl)
{
- location_t saved_loc = input_location;
struct function *fun = DECL_STRUCT_FUNCTION (fndecl);
tree step;
struct walk_stmt_info wi;
@@ -2860,7 +2862,6 @@ inline_forbidden_p (tree fndecl)
egress:
pointer_set_destroy (visited_nodes);
- input_location = saved_loc;
return forbidden_p;
}
@@ -2955,7 +2956,8 @@ estimate_move_cost (tree type)
/* Returns cost of operation CODE, according to WEIGHTS */
static int
-estimate_operator_cost (enum tree_code code, eni_weights *weights)
+estimate_operator_cost (enum tree_code code, eni_weights *weights,
+ tree op1 ATTRIBUTE_UNUSED, tree op2)
{
switch (code)
{
@@ -3065,7 +3067,9 @@ estimate_operator_cost (enum tree_code code, eni_weights *weights)
case FLOOR_MOD_EXPR:
case ROUND_MOD_EXPR:
case RDIV_EXPR:
- return weights->div_mod_cost;
+ if (TREE_CODE (op2) != INTEGER_CST)
+ return weights->div_mod_cost;
+ return 1;
default:
/* We expect a copy assignment with no operator. */
@@ -3102,6 +3106,7 @@ estimate_num_insns (gimple stmt, eni_weights *weights)
unsigned cost, i;
enum gimple_code code = gimple_code (stmt);
tree lhs;
+ tree rhs;
switch (code)
{
@@ -3125,16 +3130,35 @@ estimate_num_insns (gimple stmt, eni_weights *weights)
of moving something into "a", which we compute using the function
estimate_move_cost. */
lhs = gimple_assign_lhs (stmt);
+ rhs = gimple_assign_rhs1 (stmt);
+
+ /* EH magic stuff is most probably going to be optimized out.
+ We rarely really need to save EH info for unwinding
+ nested exceptions. */
+ if (TREE_CODE (lhs) == FILTER_EXPR
+ || TREE_CODE (lhs) == EXC_PTR_EXPR
+ || TREE_CODE (rhs) == FILTER_EXPR
+ || TREE_CODE (rhs) == EXC_PTR_EXPR)
+ return 0;
if (is_gimple_reg (lhs))
cost = 0;
else
cost = estimate_move_cost (TREE_TYPE (lhs));
- cost += estimate_operator_cost (gimple_assign_rhs_code (stmt), weights);
+ if (!is_gimple_reg (rhs) && !is_gimple_min_invariant (rhs))
+ cost += estimate_move_cost (TREE_TYPE (rhs));
+
+ cost += estimate_operator_cost (gimple_assign_rhs_code (stmt), weights,
+ gimple_assign_rhs1 (stmt),
+ get_gimple_rhs_class (gimple_assign_rhs_code (stmt))
+ == GIMPLE_BINARY_RHS
+ ? gimple_assign_rhs2 (stmt) : NULL);
break;
case GIMPLE_COND:
- cost = 1 + estimate_operator_cost (gimple_cond_code (stmt), weights);
+ cost = 1 + estimate_operator_cost (gimple_cond_code (stmt), weights,
+ gimple_op (stmt, 0),
+ gimple_op (stmt, 1));
break;
case GIMPLE_SWITCH:
@@ -3143,7 +3167,10 @@ estimate_num_insns (gimple stmt, eni_weights *weights)
TODO: once the switch expansion logic is sufficiently separated, we can
do better job on estimating cost of the switch. */
- cost = gimple_switch_num_labels (stmt) * 2;
+ if (weights->time_based)
+ cost = floor_log2 (gimple_switch_num_labels (stmt)) * 2;
+ else
+ cost = gimple_switch_num_labels (stmt) * 2;
break;
case GIMPLE_CALL:
@@ -3166,8 +3193,7 @@ estimate_num_insns (gimple stmt, eni_weights *weights)
case BUILT_IN_CONSTANT_P:
return 0;
case BUILT_IN_EXPECT:
- cost = 0;
- break;
+ return 0;
/* Prefetch instruction is not expensive. */
case BUILT_IN_PREFETCH:
@@ -3181,6 +3207,8 @@ estimate_num_insns (gimple stmt, eni_weights *weights)
if (decl)
funtype = TREE_TYPE (decl);
+ if (!VOID_TYPE_P (TREE_TYPE (funtype)))
+ cost += estimate_move_cost (TREE_TYPE (funtype));
/* Our cost must be kept in sync with
cgraph_estimate_size_after_inlining that does use function
declaration to figure out the arguments. */
@@ -3217,7 +3245,6 @@ estimate_num_insns (gimple stmt, eni_weights *weights)
case GIMPLE_NOP:
case GIMPLE_PHI:
case GIMPLE_RETURN:
- case GIMPLE_CHANGE_DYNAMIC_TYPE:
case GIMPLE_PREDICT:
case GIMPLE_DEBUG:
return 0;
@@ -3302,15 +3329,11 @@ estimate_num_insns_fn (tree fndecl, eni_weights *weights)
void
init_inline_once (void)
{
- eni_inlining_weights.call_cost = PARAM_VALUE (PARAM_INLINE_CALL_COST);
- eni_inlining_weights.target_builtin_call_cost = 1;
- eni_inlining_weights.div_mod_cost = 10;
- eni_inlining_weights.omp_cost = 40;
-
eni_size_weights.call_cost = 1;
eni_size_weights.target_builtin_call_cost = 1;
eni_size_weights.div_mod_cost = 1;
eni_size_weights.omp_cost = 40;
+ eni_size_weights.time_based = false;
/* Estimating time for call is difficult, since we have no idea what the
called function does. In the current uses of eni_time_weights,
@@ -3320,6 +3343,7 @@ init_inline_once (void)
eni_time_weights.target_builtin_call_cost = 10;
eni_time_weights.div_mod_cost = 10;
eni_time_weights.omp_cost = 40;
+ eni_time_weights.time_based = true;
}
/* Estimate the number of instructions in a gimple_seq. */
@@ -3574,13 +3598,6 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
/* Declare the return variable for the function. */
retvar = declare_return_variable (id, return_slot, modify_dest, &use_retvar);
- if (DECL_IS_OPERATOR_NEW (fn))
- {
- gcc_assert (TREE_CODE (retvar) == VAR_DECL
- && POINTER_TYPE_P (TREE_TYPE (retvar)));
- DECL_NO_TBAA_P (retvar) = 1;
- }
-
/* Add local vars in this inlined callee to caller. */
t_step = id->src_cfun->local_decls;
for (; t_step; t_step = TREE_CHAIN (t_step))
@@ -3604,6 +3621,13 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
duplicate our body before altering anything. */
copy_body (id, bb->count, bb->frequency, bb, return_block);
+ /* Reset the escaped and callused solutions. */
+ if (cfun->gimple_df)
+ {
+ pt_solution_reset (&cfun->gimple_df->escaped);
+ pt_solution_reset (&cfun->gimple_df->callused);
+ }
+
/* Clean up. */
if (id->debug_map)
{
@@ -4345,12 +4369,12 @@ copy_decl_to_var (tree decl, copy_body_data *id)
type = TREE_TYPE (decl);
- copy = build_decl (VAR_DECL, DECL_NAME (decl), type);
+ copy = build_decl (DECL_SOURCE_LOCATION (id->dst_fn),
+ VAR_DECL, DECL_NAME (decl), type);
TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (decl);
TREE_READONLY (copy) = TREE_READONLY (decl);
TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (decl);
DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (decl);
- DECL_NO_TBAA_P (copy) = DECL_NO_TBAA_P (decl);
return copy_decl_for_dup_finish (id, decl, copy);
}
@@ -4370,14 +4394,14 @@ copy_result_decl_to_var (tree decl, copy_body_data *id)
if (DECL_BY_REFERENCE (decl))
type = TREE_TYPE (type);
- copy = build_decl (VAR_DECL, DECL_NAME (decl), type);
+ copy = build_decl (DECL_SOURCE_LOCATION (id->dst_fn),
+ VAR_DECL, DECL_NAME (decl), type);
TREE_READONLY (copy) = TREE_READONLY (decl);
TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (decl);
if (!DECL_BY_REFERENCE (decl))
{
TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (decl);
DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (decl);
- DECL_NO_TBAA_P (copy) = DECL_NO_TBAA_P (decl);
}
return copy_decl_for_dup_finish (id, decl, copy);
diff --git a/gcc/tree-inline.h b/gcc/tree-inline.h
index 069fb30855a..034ed359976 100644
--- a/gcc/tree-inline.h
+++ b/gcc/tree-inline.h
@@ -139,6 +139,11 @@ typedef struct eni_weights_d
/* Cost for omp construct. */
unsigned omp_cost;
+
+ /* True when time of statemnt should be estimated. Thus i.e
+ cost of switch statement is logarithmic rather than linear in number
+ of cases. */
+ bool time_based;
} eni_weights;
/* Weights that estimate_num_insns uses for heuristics in inlining. */
diff --git a/gcc/tree-mudflap.c b/gcc/tree-mudflap.c
index 0c07b97c873..cfba33d9c66 100644
--- a/gcc/tree-mudflap.c
+++ b/gcc/tree-mudflap.c
@@ -295,7 +295,8 @@ static GTY (()) tree mf_set_options_fndecl;
static inline tree
mf_make_builtin (enum tree_code category, const char *name, tree type)
{
- tree decl = mf_mark (build_decl (category, get_identifier (name), type));
+ tree decl = mf_mark (build_decl (UNKNOWN_LOCATION,
+ category, get_identifier (name), type));
TREE_PUBLIC (decl) = 1;
DECL_EXTERNAL (decl) = 1;
lang_hooks.decls.pushdecl (decl);
@@ -315,8 +316,10 @@ mf_make_mf_cache_struct_type (tree field_type)
/* There is, abominably, no language-independent way to construct a
RECORD_TYPE. So we have to call the basic type construction
primitives by hand. */
- tree fieldlo = build_decl (FIELD_DECL, get_identifier ("low"), field_type);
- tree fieldhi = build_decl (FIELD_DECL, get_identifier ("high"), field_type);
+ tree fieldlo = build_decl (UNKNOWN_LOCATION,
+ FIELD_DECL, get_identifier ("low"), field_type);
+ tree fieldhi = build_decl (UNKNOWN_LOCATION,
+ FIELD_DECL, get_identifier ("high"), field_type);
tree struct_type = make_node (RECORD_TYPE);
DECL_CONTEXT (fieldlo) = struct_type;
@@ -447,6 +450,26 @@ execute_mudflap_function_ops (void)
return 0;
}
+/* Insert a gimple_seq SEQ on all the outgoing edges out of BB. Note that
+ if BB has more than one edge, STMT will be replicated for each edge.
+ Also, abnormal edges will be ignored. */
+
+static void
+insert_edge_copies_seq (gimple_seq seq, basic_block bb)
+{
+ edge e;
+ edge_iterator ei;
+ unsigned n_copies = -1;
+
+ FOR_EACH_EDGE (e, ei, bb->succs)
+ if (!(e->flags & EDGE_ABNORMAL))
+ n_copies++;
+
+ FOR_EACH_EDGE (e, ei, bb->succs)
+ if (!(e->flags & EDGE_ABNORMAL))
+ gsi_insert_seq_on_edge (e, n_copies-- > 0 ? gimple_seq_copy (seq) : seq);
+}
+
/* Create and initialize local shadow variables for the lookup cache
globals. Put their decls in the *_l globals for use by
mf_build_check_statement_for. */
diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c
index 14a7d950ea5..80041ec66a7 100644
--- a/gcc/tree-nested.c
+++ b/gcc/tree-nested.c
@@ -1,5 +1,5 @@
/* Nested function decomposition for GIMPLE.
- Copyright (C) 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
This file is part of GCC.
@@ -314,7 +314,8 @@ get_chain_decl (struct nesting_info *info)
Note also that it's represented as a parameter. This is more
close to the truth, since the initial value does come from
the caller. */
- decl = build_decl (PARM_DECL, create_tmp_var_name ("CHAIN"), type);
+ decl = build_decl (DECL_SOURCE_LOCATION (info->context),
+ PARM_DECL, create_tmp_var_name ("CHAIN"), type);
DECL_ARTIFICIAL (decl) = 1;
DECL_IGNORED_P (decl) = 1;
TREE_USED (decl) = 1;
@@ -427,7 +428,7 @@ save_tmp_var (struct nesting_info *info, tree exp, gimple_stmt_iterator *gsi)
static GTY(()) tree trampoline_type;
static tree
-get_trampoline_type (void)
+get_trampoline_type (struct nesting_info *info)
{
unsigned align, size;
tree t;
@@ -448,7 +449,8 @@ get_trampoline_type (void)
t = build_index_type (build_int_cst (NULL_TREE, size - 1));
t = build_array_type (char_type_node, t);
- t = build_decl (FIELD_DECL, get_identifier ("__data"), t);
+ t = build_decl (DECL_SOURCE_LOCATION (info->context),
+ FIELD_DECL, get_identifier ("__data"), t);
DECL_ALIGN (t) = align;
DECL_USER_ALIGN (t) = 1;
@@ -481,7 +483,7 @@ lookup_tramp_for_decl (struct nesting_info *info, tree decl,
{
tree field = make_node (FIELD_DECL);
DECL_NAME (field) = DECL_NAME (decl);
- TREE_TYPE (field) = get_trampoline_type ();
+ TREE_TYPE (field) = get_trampoline_type (info);
TREE_ADDRESSABLE (field) = 1;
insert_field_into_struct (get_frame_type (info), field);
@@ -818,9 +820,9 @@ get_nonlocal_debug_decl (struct nesting_info *info, tree decl)
x = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (x)), x);
/* ??? We should be remapping types as well, surely. */
- new_decl = build_decl (VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
+ new_decl = build_decl (DECL_SOURCE_LOCATION (decl),
+ VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
DECL_CONTEXT (new_decl) = info->context;
- DECL_SOURCE_LOCATION (new_decl) = DECL_SOURCE_LOCATION (decl);
DECL_ARTIFICIAL (new_decl) = DECL_ARTIFICIAL (decl);
DECL_IGNORED_P (new_decl) = DECL_IGNORED_P (decl);
TREE_THIS_VOLATILE (new_decl) = TREE_THIS_VOLATILE (decl);
@@ -1209,7 +1211,8 @@ convert_nonlocal_reference_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p,
{
tree c, decl;
decl = get_chain_decl (info);
- c = build_omp_clause (OMP_CLAUSE_FIRSTPRIVATE);
+ c = build_omp_clause (gimple_location (stmt),
+ OMP_CLAUSE_FIRSTPRIVATE);
OMP_CLAUSE_DECL (c) = decl;
OMP_CLAUSE_CHAIN (c) = gimple_omp_taskreg_clauses (stmt);
gimple_omp_taskreg_set_clauses (stmt, c);
@@ -1302,9 +1305,9 @@ get_local_debug_decl (struct nesting_info *info, tree decl, tree field)
x = info->frame_decl;
x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE);
- new_decl = build_decl (VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
+ new_decl = build_decl (DECL_SOURCE_LOCATION (decl),
+ VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
DECL_CONTEXT (new_decl) = info->context;
- DECL_SOURCE_LOCATION (new_decl) = DECL_SOURCE_LOCATION (decl);
DECL_ARTIFICIAL (new_decl) = DECL_ARTIFICIAL (decl);
DECL_IGNORED_P (new_decl) = DECL_IGNORED_P (decl);
TREE_THIS_VOLATILE (new_decl) = TREE_THIS_VOLATILE (decl);
@@ -1616,7 +1619,8 @@ convert_local_reference_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p,
{
tree c;
(void) get_frame_type (info);
- c = build_omp_clause (OMP_CLAUSE_SHARED);
+ c = build_omp_clause (gimple_location (stmt),
+ OMP_CLAUSE_SHARED);
OMP_CLAUSE_DECL (c) = info->frame_decl;
OMP_CLAUSE_CHAIN (c) = gimple_omp_taskreg_clauses (stmt);
gimple_omp_taskreg_set_clauses (stmt, c);
@@ -1728,7 +1732,7 @@ convert_nl_goto_reference (gimple_stmt_iterator *gsi, bool *handled_ops_p,
slot = pointer_map_insert (i->var_map, label);
if (*slot == NULL)
{
- new_label = create_artificial_label ();
+ new_label = create_artificial_label (UNKNOWN_LOCATION);
DECL_NONLOCAL (new_label) = 1;
*slot = new_label;
}
@@ -1960,8 +1964,9 @@ convert_gimple_call (gimple_stmt_iterator *gsi, bool *handled_ops_p,
break;
if (c == NULL)
{
- c = build_omp_clause (i ? OMP_CLAUSE_FIRSTPRIVATE
- : OMP_CLAUSE_SHARED);
+ c = build_omp_clause (gimple_location (stmt),
+ i ? OMP_CLAUSE_FIRSTPRIVATE
+ : OMP_CLAUSE_SHARED);
OMP_CLAUSE_DECL (c) = decl;
OMP_CLAUSE_CHAIN (c) = gimple_omp_taskreg_clauses (stmt);
gimple_omp_taskreg_set_clauses (stmt, c);
@@ -2186,7 +2191,7 @@ finalize_nesting_tree_1 (struct nesting_info *root)
warn_padded = save_warn_padded;
layout_decl (root->frame_decl, 0);
- /* Remove root->frame_decl from root->new_local_var_chain, such
+ /* Remove root->frame_decl from root->new_local_var_chain, so
that we can declare it also in the lexical blocks, which
helps ensure virtual regs that end up appearing in its RTL
expression get substituted in instantiate_virtual_regs(). */
diff --git a/gcc/tree-nomudflap.c b/gcc/tree-nomudflap.c
index 1021b31757a..96b58f37c5a 100644
--- a/gcc/tree-nomudflap.c
+++ b/gcc/tree-nomudflap.c
@@ -132,6 +132,6 @@ struct gimple_opt_pass pass_mudflap_2 =
We prepare a little dummy struct here.
*/
-const struct ggc_root_tab gt_ggc_r_gt_tree_mudflap_h[] = {
+EXPORTED_CONST struct ggc_root_tab gt_ggc_r_gt_tree_mudflap_h[] = {
LAST_GGC_ROOT_TAB
};
diff --git a/gcc/tree-object-size.c b/gcc/tree-object-size.c
index 18e62e860fd..ebef69c1ad3 100644
--- a/gcc/tree-object-size.c
+++ b/gcc/tree-object-size.c
@@ -43,7 +43,8 @@ struct object_size_info
static unsigned HOST_WIDE_INT unknown[4] = { -1, -1, 0, 0 };
static tree compute_object_offset (const_tree, const_tree);
-static unsigned HOST_WIDE_INT addr_object_size (const_tree, int);
+static unsigned HOST_WIDE_INT addr_object_size (struct object_size_info *,
+ const_tree, int);
static unsigned HOST_WIDE_INT alloc_object_size (const_gimple, int);
static tree pass_through_call (const_gimple);
static void collect_object_sizes_for (struct object_size_info *, tree);
@@ -152,9 +153,10 @@ compute_object_offset (const_tree expr, const_tree var)
If unknown, return unknown[object_size_type]. */
static unsigned HOST_WIDE_INT
-addr_object_size (const_tree ptr, int object_size_type)
+addr_object_size (struct object_size_info *osi, const_tree ptr,
+ int object_size_type)
{
- tree pt_var;
+ tree pt_var, pt_var_size = NULL_TREE, var_size, bytes;
gcc_assert (TREE_CODE (ptr) == ADDR_EXPR);
@@ -163,58 +165,170 @@ addr_object_size (const_tree ptr, int object_size_type)
pt_var = get_base_address (pt_var);
if (pt_var
- && (SSA_VAR_P (pt_var) || TREE_CODE (pt_var) == STRING_CST)
- && TYPE_SIZE_UNIT (TREE_TYPE (pt_var))
- && host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (pt_var)), 1)
- && (unsigned HOST_WIDE_INT)
- tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (pt_var)), 1) < offset_limit)
+ && TREE_CODE (pt_var) == INDIRECT_REF
+ && TREE_CODE (TREE_OPERAND (pt_var, 0)) == SSA_NAME
+ && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (pt_var, 0))))
{
- tree bytes;
+ unsigned HOST_WIDE_INT sz;
- if (pt_var != TREE_OPERAND (ptr, 0))
+ if (!osi)
+ sz = compute_builtin_object_size (TREE_OPERAND (pt_var, 0),
+ object_size_type);
+ else
{
- tree var;
+ tree var = TREE_OPERAND (pt_var, 0);
+ if (osi->pass == 0)
+ collect_object_sizes_for (osi, var);
+ if (bitmap_bit_p (computed[object_size_type],
+ SSA_NAME_VERSION (var)))
+ sz = object_sizes[object_size_type][SSA_NAME_VERSION (var)];
+ else
+ sz = unknown[object_size_type];
+ }
+
+ if (sz != unknown[object_size_type] && sz < offset_limit)
+ pt_var_size = size_int (sz);
+ }
+ else if (pt_var
+ && (SSA_VAR_P (pt_var) || TREE_CODE (pt_var) == STRING_CST)
+ && TYPE_SIZE_UNIT (TREE_TYPE (pt_var))
+ && host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (pt_var)), 1)
+ && (unsigned HOST_WIDE_INT)
+ tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (pt_var)), 1)
+ < offset_limit)
+ pt_var_size = TYPE_SIZE_UNIT (TREE_TYPE (pt_var));
+ else
+ return unknown[object_size_type];
+
+ if (pt_var != TREE_OPERAND (ptr, 0))
+ {
+ tree var;
- if (object_size_type & 1)
+ if (object_size_type & 1)
+ {
+ var = TREE_OPERAND (ptr, 0);
+
+ while (var != pt_var
+ && TREE_CODE (var) != BIT_FIELD_REF
+ && TREE_CODE (var) != COMPONENT_REF
+ && TREE_CODE (var) != ARRAY_REF
+ && TREE_CODE (var) != ARRAY_RANGE_REF
+ && TREE_CODE (var) != REALPART_EXPR
+ && TREE_CODE (var) != IMAGPART_EXPR)
+ var = TREE_OPERAND (var, 0);
+ if (var != pt_var && TREE_CODE (var) == ARRAY_REF)
+ var = TREE_OPERAND (var, 0);
+ if (! TYPE_SIZE_UNIT (TREE_TYPE (var))
+ || ! host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (var)), 1)
+ || (pt_var_size
+ && tree_int_cst_lt (pt_var_size,
+ TYPE_SIZE_UNIT (TREE_TYPE (var)))))
+ var = pt_var;
+ else if (var != pt_var && TREE_CODE (pt_var) == INDIRECT_REF)
{
- var = TREE_OPERAND (ptr, 0);
-
- while (var != pt_var
- && TREE_CODE (var) != BIT_FIELD_REF
- && TREE_CODE (var) != COMPONENT_REF
- && TREE_CODE (var) != ARRAY_REF
- && TREE_CODE (var) != ARRAY_RANGE_REF
- && TREE_CODE (var) != REALPART_EXPR
- && TREE_CODE (var) != IMAGPART_EXPR)
- var = TREE_OPERAND (var, 0);
- if (var != pt_var && TREE_CODE (var) == ARRAY_REF)
- var = TREE_OPERAND (var, 0);
- if (! TYPE_SIZE_UNIT (TREE_TYPE (var))
- || ! host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (var)), 1)
- || tree_int_cst_lt (TYPE_SIZE_UNIT (TREE_TYPE (pt_var)),
- TYPE_SIZE_UNIT (TREE_TYPE (var))))
+ tree v = var;
+ /* For &X->fld, compute object size only if fld isn't the last
+ field, as struct { int i; char c[1]; } is often used instead
+ of flexible array member. */
+ while (v && v != pt_var)
+ switch (TREE_CODE (v))
+ {
+ case ARRAY_REF:
+ if (TYPE_SIZE_UNIT (TREE_TYPE (TREE_OPERAND (v, 0)))
+ && TREE_CODE (TREE_OPERAND (v, 1)) == INTEGER_CST)
+ {
+ tree domain
+ = TYPE_DOMAIN (TREE_TYPE (TREE_OPERAND (v, 0)));
+ if (domain
+ && TYPE_MAX_VALUE (domain)
+ && TREE_CODE (TYPE_MAX_VALUE (domain))
+ == INTEGER_CST
+ && tree_int_cst_lt (TREE_OPERAND (v, 1),
+ TYPE_MAX_VALUE (domain)))
+ {
+ v = NULL_TREE;
+ break;
+ }
+ }
+ v = TREE_OPERAND (v, 0);
+ break;
+ case REALPART_EXPR:
+ case IMAGPART_EXPR:
+ v = NULL_TREE;
+ break;
+ case COMPONENT_REF:
+ if ((TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0)))
+ == RECORD_TYPE
+ && TREE_CHAIN (TREE_OPERAND (v, 1)))
+ || TREE_CODE (TREE_TYPE (v)) != ARRAY_TYPE)
+ v = NULL_TREE;
+ else
+ {
+ if (TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0)))
+ == RECORD_TYPE)
+ v = TREE_OPERAND (v, 0);
+ while (v && v != pt_var && TREE_CODE (v) == COMPONENT_REF)
+ if (TREE_CODE (TREE_TYPE (v)) != UNION_TYPE
+ && TREE_CODE (TREE_TYPE (v)) != QUAL_UNION_TYPE)
+ break;
+ else
+ v = TREE_OPERAND (v, 0);
+ if (v && v != pt_var)
+ v = NULL_TREE;
+ else
+ v = pt_var;
+ }
+ break;
+ default:
+ v = pt_var;
+ break;
+ }
+ if (v == pt_var)
var = pt_var;
}
- else
- var = pt_var;
+ }
+ else
+ var = pt_var;
- bytes = compute_object_offset (TREE_OPERAND (ptr, 0), var);
- if (bytes != error_mark_node)
+ if (var != pt_var)
+ var_size = TYPE_SIZE_UNIT (TREE_TYPE (var));
+ else if (!pt_var_size)
+ return unknown[object_size_type];
+ else
+ var_size = pt_var_size;
+ bytes = compute_object_offset (TREE_OPERAND (ptr, 0), var);
+ if (bytes != error_mark_node)
+ {
+ if (TREE_CODE (bytes) == INTEGER_CST
+ && tree_int_cst_lt (var_size, bytes))
+ bytes = size_zero_node;
+ else
+ bytes = size_binop (MINUS_EXPR, var_size, bytes);
+ }
+ if (var != pt_var
+ && pt_var_size
+ && TREE_CODE (pt_var) == INDIRECT_REF
+ && bytes != error_mark_node)
+ {
+ tree bytes2 = compute_object_offset (TREE_OPERAND (ptr, 0), pt_var);
+ if (bytes2 != error_mark_node)
{
- if (TREE_CODE (bytes) == INTEGER_CST
- && tree_int_cst_lt (TYPE_SIZE_UNIT (TREE_TYPE (var)), bytes))
- bytes = size_zero_node;
+ if (TREE_CODE (bytes2) == INTEGER_CST
+ && tree_int_cst_lt (pt_var_size, bytes2))
+ bytes2 = size_zero_node;
else
- bytes = size_binop (MINUS_EXPR,
- TYPE_SIZE_UNIT (TREE_TYPE (var)), bytes);
+ bytes2 = size_binop (MINUS_EXPR, pt_var_size, bytes2);
+ bytes = size_binop (MIN_EXPR, bytes, bytes2);
}
}
- else
- bytes = TYPE_SIZE_UNIT (TREE_TYPE (pt_var));
-
- if (host_integerp (bytes, 1))
- return tree_low_cst (bytes, 1);
}
+ else if (!pt_var_size)
+ return unknown[object_size_type];
+ else
+ bytes = pt_var_size;
+
+ if (host_integerp (bytes, 1))
+ return tree_low_cst (bytes, 1);
return unknown[object_size_type];
}
@@ -332,11 +446,11 @@ compute_builtin_object_size (tree ptr, int object_size_type)
init_offset_limit ();
if (TREE_CODE (ptr) == ADDR_EXPR)
- return addr_object_size (ptr, object_size_type);
+ return addr_object_size (NULL, ptr, object_size_type);
if (TREE_CODE (ptr) == SSA_NAME
- && POINTER_TYPE_P (TREE_TYPE (ptr))
- && object_sizes[object_size_type] != NULL)
+ && POINTER_TYPE_P (TREE_TYPE (ptr))
+ && object_sizes[object_size_type] != NULL)
{
if (!bitmap_bit_p (computed[object_size_type], SSA_NAME_VERSION (ptr)))
{
@@ -477,7 +591,7 @@ expr_object_size (struct object_size_info *osi, tree ptr, tree value)
|| !POINTER_TYPE_P (TREE_TYPE (value)));
if (TREE_CODE (value) == ADDR_EXPR)
- bytes = addr_object_size (value, object_size_type);
+ bytes = addr_object_size (osi, value, object_size_type);
else
bytes = unknown[object_size_type];
@@ -633,7 +747,7 @@ plus_stmt_object_size (struct object_size_info *osi, tree var, gimple stmt)
unsigned HOST_WIDE_INT off = tree_low_cst (op1, 1);
/* op0 will be ADDR_EXPR here. */
- bytes = compute_builtin_object_size (op0, object_size_type);
+ bytes = addr_object_size (osi, op0, object_size_type);
if (bytes == unknown[object_size_type])
;
else if (off > offset_limit)
diff --git a/gcc/tree-outof-ssa.c b/gcc/tree-outof-ssa.c
index bfcf76a8bd3..9291f0826d8 100644
--- a/gcc/tree-outof-ssa.c
+++ b/gcc/tree-outof-ssa.c
@@ -856,6 +856,67 @@ remove_ssa_form (bool perform_ter, struct ssaexpand *sa)
}
+/* If not already done so for basic block BB, assign increasing uids
+ to each of its instructions. */
+
+static void
+maybe_renumber_stmts_bb (basic_block bb)
+{
+ unsigned i = 0;
+ gimple_stmt_iterator gsi;
+
+ if (!bb->aux)
+ return;
+ bb->aux = NULL;
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ gimple stmt = gsi_stmt (gsi);
+ gimple_set_uid (stmt, i);
+ i++;
+ }
+}
+
+
+/* Return true if we can determine that the SSA_NAMEs RESULT (a result
+ of a PHI node) and ARG (one of its arguments) conflict. Return false
+ otherwise, also when we simply aren't sure. */
+
+static bool
+trivially_conflicts_p (basic_block bb, tree result, tree arg)
+{
+ use_operand_p use;
+ imm_use_iterator imm_iter;
+ gimple defa = SSA_NAME_DEF_STMT (arg);
+
+ /* If ARG isn't defined in the same block it's too complicated for
+ our little mind. */
+ if (gimple_bb (defa) != bb)
+ return false;
+
+ FOR_EACH_IMM_USE_FAST (use, imm_iter, result)
+ {
+ gimple use_stmt = USE_STMT (use);
+ /* Now, if there's a use of RESULT that lies outside this basic block,
+ then there surely is a conflict with ARG. */
+ if (gimple_bb (use_stmt) != bb)
+ return true;
+ if (gimple_code (use_stmt) == GIMPLE_PHI)
+ continue;
+ /* The use now is in a real stmt of BB, so if ARG was defined
+ in a PHI node (like RESULT) both conflict. */
+ if (gimple_code (defa) == GIMPLE_PHI)
+ return true;
+ maybe_renumber_stmts_bb (bb);
+ /* If the use of RESULT occurs after the definition of ARG,
+ the two conflict too. */
+ if (gimple_uid (defa) < gimple_uid (use_stmt))
+ return true;
+ }
+
+ return false;
+}
+
+
/* Search every PHI node for arguments associated with backedges which
we can trivially determine will need a copy (the argument is either
not an SSA_NAME or the argument has a different underlying variable
@@ -873,6 +934,9 @@ insert_backedge_copies (void)
FOR_EACH_BB (bb)
{
+ /* Mark block as possibly needing calculation of UIDs. */
+ bb->aux = &bb->aux;
+
for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
gimple phi = gsi_stmt (gsi);
@@ -895,7 +959,8 @@ insert_backedge_copies (void)
needed. */
if ((e->flags & EDGE_DFS_BACK)
&& (TREE_CODE (arg) != SSA_NAME
- || SSA_NAME_VAR (arg) != result_var))
+ || SSA_NAME_VAR (arg) != result_var
+ || trivially_conflicts_p (bb, result, arg)))
{
tree name;
gimple stmt, last = NULL;
@@ -939,6 +1004,9 @@ insert_backedge_copies (void)
}
}
}
+
+ /* Unmark this block again. */
+ bb->aux = NULL;
}
}
diff --git a/gcc/tree-parloops.c b/gcc/tree-parloops.c
index 0d27eccf279..7128ff24548 100644
--- a/gcc/tree-parloops.c
+++ b/gcc/tree-parloops.c
@@ -290,7 +290,7 @@ loop_parallel_p (struct loop *loop, htab_t reduction_list,
if (!is_gimple_reg (PHI_RESULT (phi)))
continue;
if (simple_loop_info)
- reduc_stmt = vect_is_simple_reduction (simple_loop_info, phi);
+ reduc_stmt = vect_is_simple_reduction (simple_loop_info, phi, true);
/* Create a reduction_info struct, initialize it and insert it to
the reduction list. */
@@ -545,7 +545,8 @@ initialize_reductions (void **slot, void *data)
bvar = create_tmp_var (type, "reduction");
add_referenced_var (bvar);
- c = build_omp_clause (OMP_CLAUSE_REDUCTION);
+ c = build_omp_clause (gimple_location (reduc->reduc_stmt),
+ OMP_CLAUSE_REDUCTION);
OMP_CLAUSE_REDUCTION_CODE (c) = reduc->reduction_code;
OMP_CLAUSE_DECL (c) = SSA_NAME_VAR (gimple_assign_lhs (reduc->reduc_stmt));
@@ -903,7 +904,8 @@ add_field_for_reduction (void **slot, void *data)
struct reduction_info *const red = (struct reduction_info *) *slot;
tree const type = (tree) data;
tree var = SSA_NAME_VAR (gimple_assign_lhs (red->reduc_stmt));
- tree field = build_decl (FIELD_DECL, DECL_NAME (var), TREE_TYPE (var));
+ tree field = build_decl (gimple_location (red->reduc_stmt),
+ FIELD_DECL, DECL_NAME (var), TREE_TYPE (var));
insert_field_into_struct (type, field);
@@ -922,7 +924,8 @@ add_field_for_name (void **slot, void *data)
tree type = (tree) data;
tree name = ssa_name (elt->version);
tree var = SSA_NAME_VAR (name);
- tree field = build_decl (FIELD_DECL, DECL_NAME (var), TREE_TYPE (var));
+ tree field = build_decl (DECL_SOURCE_LOCATION (var),
+ FIELD_DECL, DECL_NAME (var), TREE_TYPE (var));
insert_field_into_struct (type, field);
elt->field = field;
@@ -1288,7 +1291,8 @@ separate_decls_in_region (edge entry, edge exit, htab_t reduction_list,
{
/* Create the type for the structure to store the ssa names to. */
type = lang_hooks.types.make_type (RECORD_TYPE);
- type_name = build_decl (TYPE_DECL, create_tmp_var_name (".paral_data"),
+ type_name = build_decl (BUILTINS_LOCATION,
+ TYPE_DECL, create_tmp_var_name (".paral_data"),
type);
TYPE_NAME (type) = type_name;
@@ -1368,7 +1372,8 @@ create_loop_fn (void)
name = get_identifier (tname);
type = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
- decl = build_decl (FUNCTION_DECL, name, type);
+ decl = build_decl (BUILTINS_LOCATION,
+ FUNCTION_DECL, name, type);
if (!parallelized_functions)
parallelized_functions = BITMAP_GGC_ALLOC ();
bitmap_set_bit (parallelized_functions, DECL_UID (decl));
@@ -1383,12 +1388,14 @@ create_loop_fn (void)
DECL_CONTEXT (decl) = NULL_TREE;
DECL_INITIAL (decl) = make_node (BLOCK);
- t = build_decl (RESULT_DECL, NULL_TREE, void_type_node);
+ t = build_decl (BUILTINS_LOCATION,
+ RESULT_DECL, NULL_TREE, void_type_node);
DECL_ARTIFICIAL (t) = 1;
DECL_IGNORED_P (t) = 1;
DECL_RESULT (decl) = t;
- t = build_decl (PARM_DECL, get_identifier (".paral_data_param"),
+ t = build_decl (BUILTINS_LOCATION,
+ PARM_DECL, get_identifier (".paral_data_param"),
ptr_type_node);
DECL_ARTIFICIAL (t) = 1;
DECL_ARG_TYPE (t) = ptr_type_node;
@@ -1650,7 +1657,7 @@ create_parallel_loop (struct loop *loop, tree loop_fn, tree data,
paral_bb = single_pred (bb);
gsi = gsi_last_bb (paral_bb);
- t = build_omp_clause (OMP_CLAUSE_NUM_THREADS);
+ t = build_omp_clause (BUILTINS_LOCATION, OMP_CLAUSE_NUM_THREADS);
OMP_CLAUSE_NUM_THREADS_EXPR (t)
= build_int_cst (integer_type_node, n_threads);
stmt = gimple_build_omp_parallel (NULL, t, loop_fn, data);
@@ -1721,7 +1728,7 @@ create_parallel_loop (struct loop *loop, tree loop_fn, tree data,
/* Emit GIMPLE_OMP_FOR. */
gimple_cond_set_lhs (cond_stmt, cvar_base);
type = TREE_TYPE (cvar);
- t = build_omp_clause (OMP_CLAUSE_SCHEDULE);
+ t = build_omp_clause (BUILTINS_LOCATION, OMP_CLAUSE_SCHEDULE);
OMP_CLAUSE_SCHEDULE_KIND (t) = OMP_CLAUSE_SCHEDULE_STATIC;
for_stmt = gimple_build_omp_for (NULL, t, 1, NULL);
@@ -1970,6 +1977,16 @@ parallelize_loops (void)
free_stmt_vec_info_vec ();
htab_delete (reduction_list);
+
+ /* Parallelization will cause new function calls to be inserted through
+ which local variables will escape. Reset the points-to solutions
+ for ESCAPED and CALLUSED. */
+ if (changed)
+ {
+ pt_solution_reset (&cfun->gimple_df->escaped);
+ pt_solution_reset (&cfun->gimple_df->callused);
+ }
+
return changed;
}
diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h
index 0237bcef188..1268e35609f 100644
--- a/gcc/tree-pass.h
+++ b/gcc/tree-pass.h
@@ -164,7 +164,7 @@ struct cgraph_node_set_def;
/* Description of IPA pass with generate summary, write, execute, read and
transform stages. */
-struct ipa_opt_pass
+struct ipa_opt_pass_d
{
struct opt_pass pass;
@@ -297,6 +297,7 @@ struct dump_file_info
/* Rebuild the addressable-vars bitmap and do register promotion. */
#define TODO_update_address_taken (1 << 21)
+/* Internally used in execute_function_todo(). */
#define TODO_update_ssa_any \
(TODO_update_ssa \
| TODO_update_ssa_no_phi \
@@ -338,6 +339,7 @@ extern struct gimple_opt_pass pass_graphite_transforms;
extern struct gimple_opt_pass pass_if_conversion;
extern struct gimple_opt_pass pass_loop_distribution;
extern struct gimple_opt_pass pass_vectorize;
+extern struct gimple_opt_pass pass_slp_vectorize;
extern struct gimple_opt_pass pass_complete_unroll;
extern struct gimple_opt_pass pass_complete_unrolli;
extern struct gimple_opt_pass pass_parallelize_loops;
@@ -349,6 +351,7 @@ extern struct gimple_opt_pass pass_ccp;
extern struct gimple_opt_pass pass_phi_only_cprop;
extern struct gimple_opt_pass pass_build_ssa;
extern struct gimple_opt_pass pass_build_alias;
+extern struct gimple_opt_pass pass_build_ealias;
extern struct gimple_opt_pass pass_dominator;
extern struct gimple_opt_pass pass_dce;
extern struct gimple_opt_pass pass_dce_loop;
@@ -374,6 +377,7 @@ extern struct gimple_opt_pass pass_late_warn_uninitialized;
extern struct gimple_opt_pass pass_cse_reciprocals;
extern struct gimple_opt_pass pass_cse_sincos;
extern struct gimple_opt_pass pass_convert_to_rsqrt;
+extern struct gimple_opt_pass pass_optimize_bswap;
extern struct gimple_opt_pass pass_warn_function_return;
extern struct gimple_opt_pass pass_warn_function_noreturn;
extern struct gimple_opt_pass pass_cselim;
@@ -401,10 +405,10 @@ extern struct gimple_opt_pass pass_local_pure_const;
extern struct gimple_opt_pass pass_tracer;
/* IPA Passes */
-extern struct ipa_opt_pass pass_ipa_inline;
-extern struct ipa_opt_pass pass_ipa_cp;
-extern struct ipa_opt_pass pass_ipa_reference;
-extern struct ipa_opt_pass pass_ipa_pure_const;
+extern struct ipa_opt_pass_d pass_ipa_inline;
+extern struct ipa_opt_pass_d pass_ipa_cp;
+extern struct ipa_opt_pass_d pass_ipa_reference;
+extern struct ipa_opt_pass_d pass_ipa_pure_const;
extern struct simple_ipa_opt_pass pass_ipa_matrix_reorg;
extern struct simple_ipa_opt_pass pass_ipa_early_inline;
diff --git a/gcc/tree-predcom.c b/gcc/tree-predcom.c
index a5d4dcd5da6..5d8bf4d2704 100644
--- a/gcc/tree-predcom.c
+++ b/gcc/tree-predcom.c
@@ -1,5 +1,5 @@
/* Predictive commoning.
- Copyright (C) 2005, 2007, 2008 Free Software Foundation, Inc.
+ Copyright (C) 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
This file is part of GCC.
@@ -210,7 +210,7 @@ along with GCC; see the file COPYING3. If not see
/* Data references (or phi nodes that carry data reference values across
loop iterations). */
-typedef struct dref
+typedef struct dref_d
{
/* The reference itself. */
struct data_reference *ref;
@@ -775,7 +775,7 @@ split_data_refs_to_components (struct loop *loop,
comps[ca] = comp;
}
- dataref = XCNEW (struct dref);
+ dataref = XCNEW (struct dref_d);
dataref->ref = dr;
dataref->stmt = DR_STMT (dr);
dataref->offset = double_int_zero;
@@ -1126,7 +1126,7 @@ find_looparound_phi (struct loop *loop, dref ref, dref root)
static void
insert_looparound_copy (chain_p chain, dref ref, gimple phi)
{
- dref nw = XCNEW (struct dref), aref;
+ dref nw = XCNEW (struct dref_d), aref;
unsigned i;
nw->stmt = phi;
@@ -1870,43 +1870,6 @@ execute_pred_commoning_cbck (struct loop *loop, void *data)
execute_pred_commoning (loop, dta->chains, dta->tmp_vars);
}
-/* Returns true if we can and should unroll LOOP FACTOR times. Number
- of iterations of the loop is returned in NITER. */
-
-static bool
-should_unroll_loop_p (struct loop *loop, unsigned factor,
- struct tree_niter_desc *niter)
-{
- edge exit;
-
- if (factor == 1)
- return false;
-
- /* Check whether unrolling is possible. We only want to unroll loops
- for that we are able to determine number of iterations. We also
- want to split the extra iterations of the loop from its end,
- therefore we require that the loop has precisely one
- exit. */
-
- exit = single_dom_exit (loop);
- if (!exit)
- return false;
-
- if (!number_of_iterations_exit (loop, exit, niter, false))
- return false;
-
- /* And of course, we must be able to duplicate the loop. */
- if (!can_duplicate_loop_p (loop))
- return false;
-
- /* The final loop should be small enough. */
- if (tree_num_loop_insns (loop, &eni_size_weights) * factor
- > (unsigned) PARAM_VALUE (PARAM_MAX_UNROLLED_INSNS))
- return false;
-
- return true;
-}
-
/* Base NAME and all the names in the chain of phi nodes that use it
on variable VAR. The phi nodes are recognized by being in the copies of
the header of the LOOP. */
@@ -2339,7 +2302,7 @@ combine_chains (chain_p ch1, chain_p ch2)
for (i = 0; (VEC_iterate (dref, ch1->refs, i, r1)
&& VEC_iterate (dref, ch2->refs, i, r2)); i++)
{
- nw = XCNEW (struct dref);
+ nw = XCNEW (struct dref_d);
nw->stmt = stmt_combining_refs (r1, r2);
nw->distance = r1->distance;
@@ -2544,7 +2507,8 @@ tree_predictive_commoning_loop (struct loop *loop)
that its number of iterations is divisible by the factor. */
unroll_factor = determine_unroll_factor (chains);
scev_reset ();
- unroll = should_unroll_loop_p (loop, unroll_factor, &desc);
+ unroll = (unroll_factor > 1
+ && can_unroll_loop_p (loop, unroll_factor, &desc));
exit = single_dom_exit (loop);
/* Execute the predictive commoning transformations, and possibly unroll the
diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c
index d9d31eee79b..0599e3c4897 100644
--- a/gcc/tree-pretty-print.c
+++ b/gcc/tree-pretty-print.c
@@ -40,7 +40,6 @@ along with GCC; see the file COPYING3. If not see
/* Local functions, macros and variables. */
static const char *op_symbol (const_tree);
static void pretty_print_string (pretty_printer *, const char*);
-static void print_call_name (pretty_printer *, const_tree);
static void newline_and_indent (pretty_printer *, int);
static void maybe_init_pretty_print (FILE *);
static void print_struct_decl (pretty_printer *, const_tree, int, int);
@@ -423,6 +422,135 @@ dump_omp_clauses (pretty_printer *buffer, tree clause, int spc, int flags)
}
+/* Dump location LOC to BUFFER. */
+
+static void
+dump_location (pretty_printer *buffer, location_t loc)
+{
+ expanded_location xloc = expand_location (loc);
+
+ pp_character (buffer, '[');
+ if (xloc.file)
+ {
+ pp_string (buffer, xloc.file);
+ pp_string (buffer, " : ");
+ }
+ pp_decimal_int (buffer, xloc.line);
+ pp_string (buffer, "] ");
+}
+
+
+/* Dump lexical block BLOCK. BUFFER, SPC and FLAGS are as in
+ dump_generic_node. */
+
+static void
+dump_block_node (pretty_printer *buffer, tree block, int spc, int flags)
+{
+ tree t;
+
+ pp_printf (buffer, "BLOCK #%d ", BLOCK_NUMBER (block));
+
+ if (flags & TDF_ADDRESS)
+ pp_printf (buffer, "[%p] ", (void *) block);
+
+ if (BLOCK_ABSTRACT (block))
+ pp_string (buffer, "[abstract] ");
+
+ if (TREE_ASM_WRITTEN (block))
+ pp_string (buffer, "[written] ");
+
+ if (flags & TDF_SLIM)
+ return;
+
+ if (BLOCK_SOURCE_LOCATION (block))
+ dump_location (buffer, BLOCK_SOURCE_LOCATION (block));
+
+ newline_and_indent (buffer, spc + 2);
+
+ if (BLOCK_SUPERCONTEXT (block))
+ {
+ pp_string (buffer, "SUPERCONTEXT: ");
+ dump_generic_node (buffer, BLOCK_SUPERCONTEXT (block), 0,
+ flags | TDF_SLIM, false);
+ newline_and_indent (buffer, spc + 2);
+ }
+
+ if (BLOCK_SUBBLOCKS (block))
+ {
+ pp_string (buffer, "SUBBLOCKS: ");
+ for (t = BLOCK_SUBBLOCKS (block); t; t = BLOCK_CHAIN (t))
+ {
+ dump_generic_node (buffer, t, 0, flags | TDF_SLIM, false);
+ pp_string (buffer, " ");
+ }
+ newline_and_indent (buffer, spc + 2);
+ }
+
+ if (BLOCK_CHAIN (block))
+ {
+ pp_string (buffer, "SIBLINGS: ");
+ for (t = BLOCK_CHAIN (block); t; t = BLOCK_CHAIN (t))
+ {
+ dump_generic_node (buffer, t, 0, flags | TDF_SLIM, false);
+ pp_string (buffer, " ");
+ }
+ newline_and_indent (buffer, spc + 2);
+ }
+
+ if (BLOCK_VARS (block))
+ {
+ pp_string (buffer, "VARS: ");
+ for (t = BLOCK_VARS (block); t; t = TREE_CHAIN (t))
+ {
+ dump_generic_node (buffer, t, 0, flags, false);
+ pp_string (buffer, " ");
+ }
+ newline_and_indent (buffer, spc + 2);
+ }
+
+ if (VEC_length (tree, BLOCK_NONLOCALIZED_VARS (block)) > 0)
+ {
+ unsigned i;
+ VEC(tree,gc) *nlv = BLOCK_NONLOCALIZED_VARS (block);
+
+ pp_string (buffer, "NONLOCALIZED_VARS: ");
+ for (i = 0; VEC_iterate (tree, nlv, i, t); i++)
+ {
+ dump_generic_node (buffer, t, 0, flags, false);
+ pp_string (buffer, " ");
+ }
+ newline_and_indent (buffer, spc + 2);
+ }
+
+ if (BLOCK_ABSTRACT_ORIGIN (block))
+ {
+ pp_string (buffer, "ABSTRACT_ORIGIN: ");
+ dump_generic_node (buffer, BLOCK_ABSTRACT_ORIGIN (block), 0,
+ flags | TDF_SLIM, false);
+ newline_and_indent (buffer, spc + 2);
+ }
+
+ if (BLOCK_FRAGMENT_ORIGIN (block))
+ {
+ pp_string (buffer, "FRAGMENT_ORIGIN: ");
+ dump_generic_node (buffer, BLOCK_FRAGMENT_ORIGIN (block), 0,
+ flags | TDF_SLIM, false);
+ newline_and_indent (buffer, spc + 2);
+ }
+
+ if (BLOCK_FRAGMENT_CHAIN (block))
+ {
+ pp_string (buffer, "FRAGMENT_CHAIN: ");
+ for (t = BLOCK_FRAGMENT_CHAIN (block); t; t = BLOCK_FRAGMENT_CHAIN (t))
+ {
+ dump_generic_node (buffer, t, 0, flags | TDF_SLIM, false);
+ pp_string (buffer, " ");
+ }
+ newline_and_indent (buffer, spc + 2);
+ }
+}
+
+
/* Dump the node NODE on the pretty_printer BUFFER, SPC spaces of
indent. FLAGS specifies details to show in the dump (see TDF_* in
tree-pass.h). If IS_STMT is true, the object printed is considered
@@ -446,17 +574,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
pp_printf (buffer, "<&%p> ", (void *)node);
if ((flags & TDF_LINENO) && EXPR_HAS_LOCATION (node))
- {
- expanded_location xloc = expand_location (EXPR_LOCATION (node));
- pp_character (buffer, '[');
- if (xloc.file)
- {
- pp_string (buffer, xloc.file);
- pp_string (buffer, " : ");
- }
- pp_decimal_int (buffer, xloc.line);
- pp_string (buffer, "] ");
- }
+ dump_location (buffer, EXPR_LOCATION (node));
switch (TREE_CODE (node))
{
@@ -1210,7 +1328,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
break;
case CALL_EXPR:
- print_call_name (buffer, node);
+ print_call_name (buffer, CALL_EXPR_FN (node));
/* Print parameters. */
pp_space (buffer);
@@ -1544,17 +1662,6 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
is_expr = false;
break;
- case CHANGE_DYNAMIC_TYPE_EXPR:
- pp_string (buffer, "<<<change_dynamic_type (");
- dump_generic_node (buffer, CHANGE_DYNAMIC_TYPE_NEW_TYPE (node), spc + 2,
- flags, false);
- pp_string (buffer, ") ");
- dump_generic_node (buffer, CHANGE_DYNAMIC_TYPE_LOCATION (node), spc + 2,
- flags, false);
- pp_string (buffer, ")>>>");
- is_expr = false;
- break;
-
case LABEL_EXPR:
op0 = TREE_OPERAND (node, 0);
/* If this is for break or continue, don't bother printing it. */
@@ -2013,62 +2120,8 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
break;
case BLOCK:
- {
- tree t;
- pp_string (buffer, "BLOCK");
-
- if (BLOCK_ABSTRACT (node))
- pp_string (buffer, " [abstract]");
-
- if (TREE_ASM_WRITTEN (node))
- pp_string (buffer, " [written]");
-
- newline_and_indent (buffer, spc + 2);
-
- if (BLOCK_SUPERCONTEXT (node))
- {
- pp_string (buffer, "SUPERCONTEXT: ");
- if (TREE_CODE (BLOCK_SUPERCONTEXT (node)) == BLOCK)
- pp_printf (buffer, "BLOCK %p",
- (void *)BLOCK_SUPERCONTEXT (node));
- else
- dump_generic_node (buffer, BLOCK_SUPERCONTEXT (node), 0, flags,
- false);
- newline_and_indent (buffer, spc + 2);
- }
-
- if (BLOCK_SUBBLOCKS (node))
- {
- pp_string (buffer, "SUBBLOCKS: ");
- for (t = BLOCK_SUBBLOCKS (node); t; t = BLOCK_CHAIN (t))
- pp_printf (buffer, "%p ", (void *)t);
- newline_and_indent (buffer, spc + 2);
- }
-
- if (BLOCK_VARS (node))
- {
- pp_string (buffer, "VARS: ");
- for (t = BLOCK_VARS (node); t; t = TREE_CHAIN (t))
- {
- dump_generic_node (buffer, t, 0, flags, false);
- pp_string (buffer, " ");
- }
- newline_and_indent (buffer, spc + 2);
- }
-
- if (BLOCK_ABSTRACT_ORIGIN (node))
- {
- pp_string (buffer, "ABSTRACT_ORIGIN: ");
- if (TREE_CODE (BLOCK_ABSTRACT_ORIGIN (node)) == BLOCK)
- pp_printf (buffer, "BLOCK %p",
- (void *)BLOCK_ABSTRACT_ORIGIN (node));
- else
- dump_generic_node (buffer, BLOCK_ABSTRACT_ORIGIN (node), 0, flags,
- false);
- newline_and_indent (buffer, spc + 2);
- }
- }
- break;
+ dump_block_node (buffer, node, spc, flags);
+ break;
case VEC_EXTRACT_EVEN_EXPR:
pp_string (buffer, " VEC_EXTRACT_EVEN_EXPR < ");
@@ -2608,32 +2661,31 @@ op_symbol (const_tree op)
return op_symbol_code (TREE_CODE (op));
}
-/* Prints the name of a CALL_EXPR. */
+/* Prints the name of a call. NODE is the CALL_EXPR_FN of a CALL_EXPR or
+ the gimple_call_fn of a GIMPLE_CALL. */
-static void
-print_call_name (pretty_printer *buffer, const_tree node)
+void
+print_call_name (pretty_printer *buffer, tree node)
{
- tree op0;
-
- gcc_assert (TREE_CODE (node) == CALL_EXPR);
-
- op0 = CALL_EXPR_FN (node);
+ tree op0 = node;
if (TREE_CODE (op0) == NON_LVALUE_EXPR)
op0 = TREE_OPERAND (op0, 0);
+ again:
switch (TREE_CODE (op0))
{
case VAR_DECL:
case PARM_DECL:
+ case FUNCTION_DECL:
dump_function_name (buffer, op0);
break;
case ADDR_EXPR:
case INDIRECT_REF:
case NOP_EXPR:
- dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, 0, false);
- break;
+ op0 = TREE_OPERAND (op0, 0);
+ goto again;
case COND_EXPR:
pp_string (buffer, "(");
diff --git a/gcc/tree-profile.c b/gcc/tree-profile.c
index 8ffedf1823e..95ab49a7543 100644
--- a/gcc/tree-profile.c
+++ b/gcc/tree-profile.c
@@ -75,7 +75,7 @@ tree_init_ic_make_global_vars (void)
ptr_void = build_pointer_type (void_type_node);
ic_void_ptr_var
- = build_decl (VAR_DECL,
+ = build_decl (UNKNOWN_LOCATION, VAR_DECL,
get_identifier ("__gcov_indirect_call_callee"),
ptr_void);
TREE_STATIC (ic_void_ptr_var) = 1;
@@ -86,7 +86,7 @@ tree_init_ic_make_global_vars (void)
gcov_type_ptr = build_pointer_type (get_gcov_type ());
ic_gcov_type_ptr_var
- = build_decl (VAR_DECL,
+ = build_decl (UNKNOWN_LOCATION, VAR_DECL,
get_identifier ("__gcov_indirect_call_counters"),
gcov_type_ptr);
TREE_STATIC (ic_gcov_type_ptr_var) = 1;
diff --git a/gcc/tree-scalar-evolution.c b/gcc/tree-scalar-evolution.c
index b3990c6bfe1..bac6e594d8f 100644
--- a/gcc/tree-scalar-evolution.c
+++ b/gcc/tree-scalar-evolution.c
@@ -1141,11 +1141,10 @@ static t_bool
follow_ssa_edge_expr (struct loop *loop, gimple at_stmt, tree expr,
gimple halting_phi, tree *evolution_of_loop, int limit)
{
- t_bool res = t_false;
- tree rhs0, rhs1;
- tree type = TREE_TYPE (expr);
- enum tree_code code;
-
+ enum tree_code code = TREE_CODE (expr);
+ tree type = TREE_TYPE (expr), rhs0, rhs1;
+ t_bool res;
+
/* The EXPR is one of the following cases:
- an SSA_NAME,
- an INTEGER_CST,
@@ -1154,10 +1153,10 @@ follow_ssa_edge_expr (struct loop *loop, gimple at_stmt, tree expr,
- a MINUS_EXPR,
- an ASSERT_EXPR,
- other cases are not yet handled. */
- code = TREE_CODE (expr);
+
switch (code)
{
- case NOP_EXPR:
+ CASE_CONVERT:
/* This assignment is under the form "a_1 = (cast) rhs. */
res = follow_ssa_edge_expr (loop, at_stmt, TREE_OPERAND (expr, 0),
halting_phi, evolution_of_loop, limit);
@@ -1168,43 +1167,42 @@ follow_ssa_edge_expr (struct loop *loop, gimple at_stmt, tree expr,
/* This assignment is under the form "a_1 = 7". */
res = t_false;
break;
-
+
case SSA_NAME:
/* This assignment is under the form: "a_1 = b_2". */
res = follow_ssa_edge
(loop, SSA_NAME_DEF_STMT (expr), halting_phi, evolution_of_loop, limit);
break;
-
+
case POINTER_PLUS_EXPR:
case PLUS_EXPR:
case MINUS_EXPR:
/* This case is under the form "rhs0 +- rhs1". */
rhs0 = TREE_OPERAND (expr, 0);
rhs1 = TREE_OPERAND (expr, 1);
- STRIP_TYPE_NOPS (rhs0);
- STRIP_TYPE_NOPS (rhs1);
- return follow_ssa_edge_binary (loop, at_stmt, type, rhs0, code, rhs1,
- halting_phi, evolution_of_loop, limit);
+ type = TREE_TYPE (rhs0);
+ STRIP_USELESS_TYPE_CONVERSION (rhs0);
+ STRIP_USELESS_TYPE_CONVERSION (rhs1);
+ res = follow_ssa_edge_binary (loop, at_stmt, type, rhs0, code, rhs1,
+ halting_phi, evolution_of_loop, limit);
+ break;
case ASSERT_EXPR:
- {
- /* This assignment is of the form: "a_1 = ASSERT_EXPR <a_2, ...>"
- It must be handled as a copy assignment of the form a_1 = a_2. */
- tree op0 = ASSERT_EXPR_VAR (expr);
- if (TREE_CODE (op0) == SSA_NAME)
- res = follow_ssa_edge (loop, SSA_NAME_DEF_STMT (op0),
- halting_phi, evolution_of_loop, limit);
- else
- res = t_false;
- break;
- }
-
+ /* This assignment is of the form: "a_1 = ASSERT_EXPR <a_2, ...>"
+ It must be handled as a copy assignment of the form a_1 = a_2. */
+ rhs0 = ASSERT_EXPR_VAR (expr);
+ if (TREE_CODE (rhs0) == SSA_NAME)
+ res = follow_ssa_edge (loop, SSA_NAME_DEF_STMT (rhs0),
+ halting_phi, evolution_of_loop, limit);
+ else
+ res = t_false;
+ break;
default:
res = t_false;
break;
}
-
+
return res;
}
@@ -1215,34 +1213,39 @@ static t_bool
follow_ssa_edge_in_rhs (struct loop *loop, gimple stmt,
gimple halting_phi, tree *evolution_of_loop, int limit)
{
- tree type = TREE_TYPE (gimple_assign_lhs (stmt));
enum tree_code code = gimple_assign_rhs_code (stmt);
+ tree type = gimple_expr_type (stmt), rhs1, rhs2;
+ t_bool res;
- switch (get_gimple_rhs_class (code))
+ switch (code)
{
- case GIMPLE_BINARY_RHS:
- return follow_ssa_edge_binary (loop, stmt, type,
- gimple_assign_rhs1 (stmt), code,
- gimple_assign_rhs2 (stmt),
- halting_phi, evolution_of_loop, limit);
- case GIMPLE_SINGLE_RHS:
- return follow_ssa_edge_expr (loop, stmt, gimple_assign_rhs1 (stmt),
- halting_phi, evolution_of_loop, limit);
- case GIMPLE_UNARY_RHS:
- if (code == NOP_EXPR)
- {
- /* This assignment is under the form "a_1 = (cast) rhs. */
- t_bool res
- = follow_ssa_edge_expr (loop, stmt, gimple_assign_rhs1 (stmt),
+ CASE_CONVERT:
+ /* This assignment is under the form "a_1 = (cast) rhs. */
+ res = follow_ssa_edge_expr (loop, stmt, gimple_assign_rhs1 (stmt),
+ halting_phi, evolution_of_loop, limit);
+ *evolution_of_loop = chrec_convert (type, *evolution_of_loop, stmt);
+ break;
+
+ case POINTER_PLUS_EXPR:
+ case PLUS_EXPR:
+ case MINUS_EXPR:
+ rhs1 = gimple_assign_rhs1 (stmt);
+ rhs2 = gimple_assign_rhs2 (stmt);
+ type = TREE_TYPE (rhs1);
+ res = follow_ssa_edge_binary (loop, stmt, type, rhs1, code, rhs2,
halting_phi, evolution_of_loop, limit);
- *evolution_of_loop = chrec_convert (type, *evolution_of_loop, stmt);
- return res;
- }
- /* FALLTHRU */
+ break;
default:
- return t_false;
+ if (get_gimple_rhs_class (code) == GIMPLE_SINGLE_RHS)
+ res = follow_ssa_edge_expr (loop, stmt, gimple_assign_rhs1 (stmt),
+ halting_phi, evolution_of_loop, limit);
+ else
+ res = t_false;
+ break;
}
+
+ return res;
}
/* Checks whether the I-th argument of a PHI comes from a backedge. */
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index 626a253d152..a2f783afaed 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -1,19 +1,18 @@
/* Scalar Replacement of Aggregates (SRA) converts some structure
references into scalar references, exposing them to the scalar
optimizers.
- Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009
- Free Software Foundation, Inc.
- Contributed by Diego Novillo <dnovillo@redhat.com>
+ Copyright (C) 2008, 2009 Free Software Foundation, Inc.
+ Contributed by Martin Jambor <mjambor@suse.cz>
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 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
+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.
@@ -21,3660 +20,2305 @@ 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/>. */
+/* This file implements Scalar Reduction of Aggregates (SRA). SRA is run
+ twice, once in the early stages of compilation (early SRA) and once in the
+ late stages (late SRA). The aim of both is to turn references to scalar
+ parts of aggregates into uses of independent scalar variables.
+
+ The two passes are nearly identical, the only difference is that early SRA
+ does not scalarize unions which are used as the result in a GIMPLE_RETURN
+ statement because together with inlining this can lead to weird type
+ conversions.
+
+ Both passes operate in four stages:
+
+ 1. The declarations that have properties which make them candidates for
+ scalarization are identified in function find_var_candidates(). The
+ candidates are stored in candidate_bitmap.
+
+ 2. The function body is scanned. In the process, declarations which are
+ used in a manner that prevent their scalarization are removed from the
+ candidate bitmap. More importantly, for every access into an aggregate,
+ an access structure (struct access) is created by create_access() and
+ stored in a vector associated with the aggregate. Among other
+ information, the aggregate declaration, the offset and size of the access
+ and its type are stored in the structure.
+
+ On a related note, assign_link structures are created for every assign
+ statement between candidate aggregates and attached to the related
+ accesses.
+
+ 3. The vectors of accesses are analyzed. They are first sorted according to
+ their offset and size and then scanned for partially overlapping accesses
+ (i.e. those which overlap but one is not entirely within another). Such
+ an access disqualifies the whole aggregate from being scalarized.
+
+ If there is no such inhibiting overlap, a representative access structure
+ is chosen for every unique combination of offset and size. Afterwards,
+ the pass builds a set of trees from these structures, in which children
+ of an access are within their parent (in terms of offset and size).
+
+ Then accesses are propagated whenever possible (i.e. in cases when it
+ does not create a partially overlapping access) across assign_links from
+ the right hand side to the left hand side.
+
+ Then the set of trees for each declaration is traversed again and those
+ accesses which should be replaced by a scalar are identified.
+
+ 4. The function is traversed again, and for every reference into an
+ aggregate that has some component which is about to be scalarized,
+ statements are amended and new statements are created as necessary.
+ Finally, if a parameter got scalarized, the scalar replacements are
+ initialized with values from respective parameter aggregates. */
+
#include "config.h"
#include "system.h"
#include "coretypes.h"
+#include "alloc-pool.h"
#include "tm.h"
-#include "ggc.h"
#include "tree.h"
-
-/* These RTL headers are needed for basic-block.h. */
-#include "rtl.h"
-#include "tm_p.h"
-#include "hard-reg-set.h"
-#include "basic-block.h"
-#include "diagnostic.h"
-#include "langhooks.h"
-#include "tree-inline.h"
-#include "tree-flow.h"
#include "gimple.h"
+#include "tree-flow.h"
+#include "diagnostic.h"
#include "tree-dump.h"
-#include "tree-pass.h"
#include "timevar.h"
-#include "flags.h"
-#include "bitmap.h"
-#include "obstack.h"
-#include "target.h"
-/* expr.h is needed for MOVE_RATIO. */
-#include "expr.h"
#include "params.h"
+#include "target.h"
+#include "flags.h"
+/* Enumeration of all aggregate reductions we can do. */
+enum sra_mode { SRA_MODE_EARLY_INTRA, /* early intraprocedural SRA */
+ SRA_MODE_INTRA }; /* late intraprocedural SRA */
-/* This object of this pass is to replace a non-addressable aggregate with a
- set of independent variables. Most of the time, all of these variables
- will be scalars. But a secondary objective is to break up larger
- aggregates into smaller aggregates. In the process we may find that some
- bits of the larger aggregate can be deleted as unreferenced.
-
- This substitution is done globally. More localized substitutions would
- be the purvey of a load-store motion pass.
-
- The optimization proceeds in phases:
-
- (1) Identify variables that have types that are candidates for
- decomposition.
-
- (2) Scan the function looking for the ways these variables are used.
- In particular we're interested in the number of times a variable
- (or member) is needed as a complete unit, and the number of times
- a variable (or member) is copied.
-
- (3) Based on the usage profile, instantiate substitution variables.
-
- (4) Scan the function making replacements.
-*/
-
+/* Global variable describing which aggregate reduction we are performing at
+ the moment. */
+static enum sra_mode sra_mode;
-/* True if this is the "early" pass, before inlining. */
-static bool early_sra;
+struct assign_link;
-/* The set of aggregate variables that are candidates for scalarization. */
-static bitmap sra_candidates;
+/* ACCESS represents each access to an aggregate variable (as a whole or a
+ part). It can also represent a group of accesses that refer to exactly the
+ same fragment of an aggregate (i.e. those that have exactly the same offset
+ and size). Such representatives for a single aggregate, once determined,
+ are linked in a linked list and have the group fields set.
-/* Set of scalarizable PARM_DECLs that need copy-in operations at the
- beginning of the function. */
-static bitmap needs_copy_in;
+ Moreover, when doing intraprocedural SRA, a tree is built from those
+ representatives (by the means of first_child and next_sibling pointers), in
+ which all items in a subtree are "within" the root, i.e. their offset is
+ greater or equal to offset of the root and offset+size is smaller or equal
+ to offset+size of the root. Children of an access are sorted by offset.
-/* Sets of bit pairs that cache type decomposition and instantiation. */
-static bitmap sra_type_decomp_cache;
-static bitmap sra_type_inst_cache;
+ Note that accesses to parts of vector and complex number types always
+ represented by an access to the whole complex number or a vector. It is a
+ duty of the modifying functions to replace them appropriately. */
-/* One of these structures is created for each candidate aggregate and
- each (accessed) member or group of members of such an aggregate. */
-struct sra_elt
+struct access
{
- /* A tree of the elements. Used when we want to traverse everything. */
- struct sra_elt *parent;
- struct sra_elt *groups;
- struct sra_elt *children;
- struct sra_elt *sibling;
-
- /* If this element is a root, then this is the VAR_DECL. If this is
- a sub-element, this is some token used to identify the reference.
- In the case of COMPONENT_REF, this is the FIELD_DECL. In the case
- of an ARRAY_REF, this is the (constant) index. In the case of an
- ARRAY_RANGE_REF, this is the (constant) RANGE_EXPR. In the case
- of a complex number, this is a zero or one. */
- tree element;
-
- /* The type of the element. */
- tree type;
+ /* Values returned by `get_ref_base_and_extent' for each component reference
+ If EXPR isn't a component reference just set `BASE = EXPR', `OFFSET = 0',
+ `SIZE = TREE_SIZE (TREE_TYPE (expr))'. */
+ HOST_WIDE_INT offset;
+ HOST_WIDE_INT size;
+ tree base;
- /* A VAR_DECL, for any sub-element we've decided to replace. */
- tree replacement;
+ /* Expression. */
+ tree expr;
+ /* Type. */
+ tree type;
- /* The number of times the element is referenced as a whole. I.e.
- given "a.b.c", this would be incremented for C, but not for A or B. */
- unsigned int n_uses;
+ /* Next group representative for this aggregate. */
+ struct access *next_grp;
+
+ /* Pointer to the group representative. Pointer to itself if the struct is
+ the representative. */
+ struct access *group_representative;
+
+ /* If this access has any children (in terms of the definition above), this
+ points to the first one. */
+ struct access *first_child;
+
+ /* Pointer to the next sibling in the access tree as described above. */
+ struct access *next_sibling;
+
+ /* Pointers to the first and last element in the linked list of assign
+ links. */
+ struct assign_link *first_link, *last_link;
+
+ /* Pointer to the next access in the work queue. */
+ struct access *next_queued;
+
+ /* Replacement variable for this access "region." Never to be accessed
+ directly, always only by the means of get_access_replacement() and only
+ when grp_to_be_replaced flag is set. */
+ tree replacement_decl;
+
+ /* Is this particular access write access? */
+ unsigned write : 1;
+
+ /* Is this access currently in the work queue? */
+ unsigned grp_queued : 1;
+ /* Does this group contain a write access? This flag is propagated down the
+ access tree. */
+ unsigned grp_write : 1;
+ /* Does this group contain a read access? This flag is propagated down the
+ access tree. */
+ unsigned grp_read : 1;
+ /* Is the subtree rooted in this access fully covered by scalar
+ replacements? */
+ unsigned grp_covered : 1;
+ /* If set to true, this access and all below it in an access tree must not be
+ scalarized. */
+ unsigned grp_unscalarizable_region : 1;
+ /* Whether data have been written to parts of the aggregate covered by this
+ access which is not to be scalarized. This flag is propagated up in the
+ access tree. */
+ unsigned grp_unscalarized_data : 1;
+ /* Does this access and/or group contain a write access through a
+ BIT_FIELD_REF? */
+ unsigned grp_partial_lhs : 1;
+
+ /* Set when a scalar replacement should be created for this variable. We do
+ the decision and creation at different places because create_tmp_var
+ cannot be called from within FOR_EACH_REFERENCED_VAR. */
+ unsigned grp_to_be_replaced : 1;
+};
- /* The number of times the element is copied to or from another
- scalarizable element. */
- unsigned int n_copies;
+typedef struct access *access_p;
- /* True if TYPE is scalar. */
- bool is_scalar;
+DEF_VEC_P (access_p);
+DEF_VEC_ALLOC_P (access_p, heap);
- /* True if this element is a group of members of its parent. */
- bool is_group;
+/* Alloc pool for allocating access structures. */
+static alloc_pool access_pool;
- /* True if we saw something about this element that prevents scalarization,
- such as non-constant indexing. */
- bool cannot_scalarize;
+/* A structure linking lhs and rhs accesses from an aggregate assignment. They
+ are used to propagate subaccesses from rhs to lhs as long as they don't
+ conflict with what is already there. */
+struct assign_link
+{
+ struct access *lacc, *racc;
+ struct assign_link *next;
+};
- /* True if we've decided that structure-to-structure assignment
- should happen via memcpy and not per-element. */
- bool use_block_copy;
+/* Alloc pool for allocating assign link structures. */
+static alloc_pool link_pool;
- /* True if everything under this element has been marked TREE_NO_WARNING. */
- bool all_no_warning;
+/* Base (tree) -> Vector (VEC(access_p,heap) *) map. */
+static struct pointer_map_t *base_access_vec;
- /* A flag for use with/after random access traversals. */
- bool visited;
+/* Bitmap of bases (candidates). */
+static bitmap candidate_bitmap;
+/* Obstack for creation of fancy names. */
+static struct obstack name_obstack;
- /* True if there is BIT_FIELD_REF on the lhs with a vector. */
- bool is_vector_lhs;
+/* Head of a linked list of accesses that need to have its subaccesses
+ propagated to their assignment counterparts. */
+static struct access *work_queue_head;
- /* 1 if the element is a field that is part of a block, 2 if the field
- is the block itself, 0 if it's neither. */
- char in_bitfld_block;
-};
+/* Dump contents of ACCESS to file F in a human friendly way. If GRP is true,
+ representative fields are dumped, otherwise those which only describe the
+ individual access are. */
-#define IS_ELEMENT_FOR_GROUP(ELEMENT) (TREE_CODE (ELEMENT) == RANGE_EXPR)
+static void
+dump_access (FILE *f, struct access *access, bool grp)
+{
+ fprintf (f, "access { ");
+ fprintf (f, "base = (%d)'", DECL_UID (access->base));
+ print_generic_expr (f, access->base, 0);
+ fprintf (f, "', offset = " HOST_WIDE_INT_PRINT_DEC, access->offset);
+ fprintf (f, ", size = " HOST_WIDE_INT_PRINT_DEC, access->size);
+ fprintf (f, ", expr = ");
+ print_generic_expr (f, access->expr, 0);
+ fprintf (f, ", type = ");
+ print_generic_expr (f, access->type, 0);
+ if (grp)
+ fprintf (f, ", grp_write = %d, grp_read = %d, grp_covered = %d, "
+ "grp_unscalarizable_region = %d, grp_unscalarized_data = %d, "
+ "grp_partial_lhs = %d, grp_to_be_replaced = %d\n",
+ access->grp_write, access->grp_read, access->grp_covered,
+ access->grp_unscalarizable_region, access->grp_unscalarized_data,
+ access->grp_partial_lhs, access->grp_to_be_replaced);
+ else
+ fprintf (f, ", write = %d, grp_partial_lhs = %d\n", access->write,
+ access->grp_partial_lhs);
+}
-#define FOR_EACH_ACTUAL_CHILD(CHILD, ELT) \
- for ((CHILD) = (ELT)->is_group \
- ? next_child_for_group (NULL, (ELT)) \
- : (ELT)->children; \
- (CHILD); \
- (CHILD) = (ELT)->is_group \
- ? next_child_for_group ((CHILD), (ELT)) \
- : (CHILD)->sibling)
+/* Dump a subtree rooted in ACCESS to file F, indent by LEVEL. */
-/* Helper function for above macro. Return next child in group. */
-static struct sra_elt *
-next_child_for_group (struct sra_elt *child, struct sra_elt *group)
+static void
+dump_access_tree_1 (FILE *f, struct access *access, int level)
{
- gcc_assert (group->is_group);
-
- /* Find the next child in the parent. */
- if (child)
- child = child->sibling;
- else
- child = group->parent->children;
-
- /* Skip siblings that do not belong to the group. */
- while (child)
+ do
{
- tree g_elt = group->element;
- if (TREE_CODE (g_elt) == RANGE_EXPR)
- {
- if (!tree_int_cst_lt (child->element, TREE_OPERAND (g_elt, 0))
- && !tree_int_cst_lt (TREE_OPERAND (g_elt, 1), child->element))
- break;
- }
- else
- gcc_unreachable ();
-
- child = child->sibling;
- }
-
- return child;
-}
+ int i;
-/* Random access to the child of a parent is performed by hashing.
- This prevents quadratic behavior, and allows SRA to function
- reasonably on larger records. */
-static htab_t sra_map;
+ for (i = 0; i < level; i++)
+ fputs ("* ", dump_file);
-/* All structures are allocated out of the following obstack. */
-static struct obstack sra_obstack;
+ dump_access (f, access, true);
-/* Debugging functions. */
-static void dump_sra_elt_name (FILE *, struct sra_elt *);
-extern void debug_sra_elt_name (struct sra_elt *);
+ if (access->first_child)
+ dump_access_tree_1 (f, access->first_child, level + 1);
-/* Forward declarations. */
-static tree generate_element_ref (struct sra_elt *);
-static gimple_seq sra_build_assignment (tree dst, tree src);
-static void mark_all_v_defs_seq (gimple_seq);
+ access = access->next_sibling;
+ }
+ while (access);
+}
-
-/* Return true if DECL is an SRA candidate. */
+/* Dump all access trees for a variable, given the pointer to the first root in
+ ACCESS. */
-static bool
-is_sra_candidate_decl (tree decl)
+static void
+dump_access_tree (FILE *f, struct access *access)
{
- return DECL_P (decl) && bitmap_bit_p (sra_candidates, DECL_UID (decl));
+ for (; access; access = access->next_grp)
+ dump_access_tree_1 (f, access, 0);
}
-/* Return true if TYPE is a scalar type. */
+/* Return true iff ACC is non-NULL and has subaccesses. */
-static bool
-is_sra_scalar_type (tree type)
+static inline bool
+access_has_children_p (struct access *acc)
{
- enum tree_code code = TREE_CODE (type);
- return (code == INTEGER_TYPE || code == REAL_TYPE || code == VECTOR_TYPE
- || code == FIXED_POINT_TYPE
- || code == ENUMERAL_TYPE || code == BOOLEAN_TYPE
- || code == POINTER_TYPE || code == OFFSET_TYPE
- || code == REFERENCE_TYPE);
+ return acc && acc->first_child;
}
-/* Return true if TYPE can be decomposed into a set of independent variables.
-
- Note that this doesn't imply that all elements of TYPE can be
- instantiated, just that if we decide to break up the type into
- separate pieces that it can be done. */
+/* Return a vector of pointers to accesses for the variable given in BASE or
+ NULL if there is none. */
-bool
-sra_type_can_be_decomposed_p (tree type)
+static VEC (access_p, heap) *
+get_base_access_vector (tree base)
{
- unsigned int cache = TYPE_UID (TYPE_MAIN_VARIANT (type)) * 2;
- tree t;
+ void **slot;
- /* Avoid searching the same type twice. */
- if (bitmap_bit_p (sra_type_decomp_cache, cache+0))
- return true;
- if (bitmap_bit_p (sra_type_decomp_cache, cache+1))
- return false;
+ slot = pointer_map_contains (base_access_vec, base);
+ if (!slot)
+ return NULL;
+ else
+ return *(VEC (access_p, heap) **) slot;
+}
- /* The type must have a definite nonzero size. */
- if (TYPE_SIZE (type) == NULL || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST
- || integer_zerop (TYPE_SIZE (type)))
- goto fail;
+/* Find an access with required OFFSET and SIZE in a subtree of accesses rooted
+ in ACCESS. Return NULL if it cannot be found. */
- /* The type must be a non-union aggregate. */
- switch (TREE_CODE (type))
+static struct access *
+find_access_in_subtree (struct access *access, HOST_WIDE_INT offset,
+ HOST_WIDE_INT size)
+{
+ while (access && (access->offset != offset || access->size != size))
{
- case RECORD_TYPE:
- {
- bool saw_one_field = false;
-
- for (t = TYPE_FIELDS (type); t ; t = TREE_CHAIN (t))
- if (TREE_CODE (t) == FIELD_DECL)
- {
- /* Reject incorrectly represented bit fields. */
- if (DECL_BIT_FIELD (t)
- && INTEGRAL_TYPE_P (TREE_TYPE (t))
- && (tree_low_cst (DECL_SIZE (t), 1)
- != TYPE_PRECISION (TREE_TYPE (t))))
- goto fail;
-
- /* And volatile fields. */
- if (TREE_THIS_VOLATILE (t))
- goto fail;
-
- saw_one_field = true;
- }
+ struct access *child = access->first_child;
- /* Record types must have at least one field. */
- if (!saw_one_field)
- goto fail;
- }
- break;
+ while (child && (child->offset + child->size <= offset))
+ child = child->next_sibling;
+ access = child;
+ }
- case ARRAY_TYPE:
- /* Array types must have a fixed lower and upper bound. */
- t = TYPE_DOMAIN (type);
- if (t == NULL)
- goto fail;
- if (TYPE_MIN_VALUE (t) == NULL || !TREE_CONSTANT (TYPE_MIN_VALUE (t)))
- goto fail;
- if (TYPE_MAX_VALUE (t) == NULL || !TREE_CONSTANT (TYPE_MAX_VALUE (t)))
- goto fail;
- break;
+ return access;
+}
- case COMPLEX_TYPE:
- break;
+/* Return the first group representative for DECL or NULL if none exists. */
- default:
- goto fail;
- }
+static struct access *
+get_first_repr_for_decl (tree base)
+{
+ VEC (access_p, heap) *access_vec;
- bitmap_set_bit (sra_type_decomp_cache, cache+0);
- return true;
+ access_vec = get_base_access_vector (base);
+ if (!access_vec)
+ return NULL;
- fail:
- bitmap_set_bit (sra_type_decomp_cache, cache+1);
- return false;
+ return VEC_index (access_p, access_vec, 0);
}
-/* Returns true if the TYPE is one of the available va_list types.
- Otherwise it returns false.
- Note, that for multiple calling conventions there can be more
- than just one va_list type present. */
+/* Find an access representative for the variable BASE and given OFFSET and
+ SIZE. Requires that access trees have already been built. Return NULL if
+ it cannot be found. */
-static bool
-is_va_list_type (tree type)
+static struct access *
+get_var_base_offset_size_access (tree base, HOST_WIDE_INT offset,
+ HOST_WIDE_INT size)
{
- tree h;
+ struct access *access;
- if (type == NULL_TREE)
- return false;
- h = targetm.canonical_va_list_type (type);
- if (h == NULL_TREE)
- return false;
- if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (h))
- return true;
- return false;
-}
+ access = get_first_repr_for_decl (base);
+ while (access && (access->offset + access->size <= offset))
+ access = access->next_grp;
+ if (!access)
+ return NULL;
-/* Return true if DECL can be decomposed into a set of independent
- (though not necessarily scalar) variables. */
+ return find_access_in_subtree (access, offset, size);
+}
-static bool
-decl_can_be_decomposed_p (tree var)
+/* Add LINK to the linked list of assign links of RACC. */
+static void
+add_link_to_rhs (struct access *racc, struct assign_link *link)
{
- /* Early out for scalars. */
- if (is_sra_scalar_type (TREE_TYPE (var)))
- return false;
+ gcc_assert (link->racc == racc);
- /* The variable must not be aliased. */
- if (!is_gimple_non_addressable (var))
+ if (!racc->first_link)
{
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "Cannot scalarize variable ");
- print_generic_expr (dump_file, var, dump_flags);
- fprintf (dump_file, " because it must live in memory\n");
- }
- return false;
+ gcc_assert (!racc->last_link);
+ racc->first_link = link;
}
+ else
+ racc->last_link->next = link;
+
+ racc->last_link = link;
+ link->next = NULL;
+}
- /* The variable must not be volatile. */
- if (TREE_THIS_VOLATILE (var))
+/* Move all link structures in their linked list in OLD_RACC to the linked list
+ in NEW_RACC. */
+static void
+relink_to_new_repr (struct access *new_racc, struct access *old_racc)
+{
+ if (!old_racc->first_link)
{
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "Cannot scalarize variable ");
- print_generic_expr (dump_file, var, dump_flags);
- fprintf (dump_file, " because it is declared volatile\n");
- }
- return false;
+ gcc_assert (!old_racc->last_link);
+ return;
}
- /* We must be able to decompose the variable's type. */
- if (!sra_type_can_be_decomposed_p (TREE_TYPE (var)))
+ if (new_racc->first_link)
{
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "Cannot scalarize variable ");
- print_generic_expr (dump_file, var, dump_flags);
- fprintf (dump_file, " because its type cannot be decomposed\n");
- }
- return false;
- }
+ gcc_assert (!new_racc->last_link->next);
+ gcc_assert (!old_racc->last_link || !old_racc->last_link->next);
- /* HACK: if we decompose a va_list_type_node before inlining, then we'll
- confuse tree-stdarg.c, and we won't be able to figure out which and
- how many arguments are accessed. This really should be improved in
- tree-stdarg.c, as the decomposition is truly a win. This could also
- be fixed if the stdarg pass ran early, but this can't be done until
- we've aliasing information early too. See PR 30791. */
- if (early_sra && is_va_list_type (TREE_TYPE (var)))
- return false;
+ new_racc->last_link->next = old_racc->first_link;
+ new_racc->last_link = old_racc->last_link;
+ }
+ else
+ {
+ gcc_assert (!new_racc->last_link);
- return true;
+ new_racc->first_link = old_racc->first_link;
+ new_racc->last_link = old_racc->last_link;
+ }
+ old_racc->first_link = old_racc->last_link = NULL;
}
-/* Return true if TYPE can be *completely* decomposed into scalars. */
+/* Add ACCESS to the work queue (which is actually a stack). */
-static bool
-type_can_instantiate_all_elements (tree type)
+static void
+add_access_to_work_queue (struct access *access)
{
- if (is_sra_scalar_type (type))
- return true;
- if (!sra_type_can_be_decomposed_p (type))
- return false;
-
- switch (TREE_CODE (type))
+ if (!access->grp_queued)
{
- case RECORD_TYPE:
- {
- unsigned int cache = TYPE_UID (TYPE_MAIN_VARIANT (type)) * 2;
- tree f;
+ gcc_assert (!access->next_queued);
+ access->next_queued = work_queue_head;
+ access->grp_queued = 1;
+ work_queue_head = access;
+ }
+}
- if (bitmap_bit_p (sra_type_inst_cache, cache+0))
- return true;
- if (bitmap_bit_p (sra_type_inst_cache, cache+1))
- return false;
+/* Pop an access from the work queue, and return it, assuming there is one. */
- for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
- if (TREE_CODE (f) == FIELD_DECL)
- {
- if (!type_can_instantiate_all_elements (TREE_TYPE (f)))
- {
- bitmap_set_bit (sra_type_inst_cache, cache+1);
- return false;
- }
- }
+static struct access *
+pop_access_from_work_queue (void)
+{
+ struct access *access = work_queue_head;
- bitmap_set_bit (sra_type_inst_cache, cache+0);
- return true;
- }
+ work_queue_head = access->next_queued;
+ access->next_queued = NULL;
+ access->grp_queued = 0;
+ return access;
+}
- case ARRAY_TYPE:
- return type_can_instantiate_all_elements (TREE_TYPE (type));
- case COMPLEX_TYPE:
- return true;
+/* Allocate necessary structures. */
- default:
- gcc_unreachable ();
- }
+static void
+sra_initialize (void)
+{
+ candidate_bitmap = BITMAP_ALLOC (NULL);
+ gcc_obstack_init (&name_obstack);
+ access_pool = create_alloc_pool ("SRA accesses", sizeof (struct access), 16);
+ link_pool = create_alloc_pool ("SRA links", sizeof (struct assign_link), 16);
+ base_access_vec = pointer_map_create ();
}
-/* Test whether ELT or some sub-element cannot be scalarized. */
+/* Hook fed to pointer_map_traverse, deallocate stored vectors. */
static bool
-can_completely_scalarize_p (struct sra_elt *elt)
+delete_base_accesses (const void *key ATTRIBUTE_UNUSED, void **value,
+ void *data ATTRIBUTE_UNUSED)
{
- struct sra_elt *c;
-
- if (elt->cannot_scalarize)
- return false;
-
- for (c = elt->children; c; c = c->sibling)
- if (!can_completely_scalarize_p (c))
- return false;
-
- for (c = elt->groups; c; c = c->sibling)
- if (!can_completely_scalarize_p (c))
- return false;
+ VEC (access_p, heap) *access_vec;
+ access_vec = (VEC (access_p, heap) *) *value;
+ VEC_free (access_p, heap, access_vec);
return true;
}
-
-/* A simplified tree hashing algorithm that only handles the types of
- trees we expect to find in sra_elt->element. */
+/* Deallocate all general structures. */
-static hashval_t
-sra_hash_tree (tree t)
+static void
+sra_deinitialize (void)
{
- hashval_t h;
+ BITMAP_FREE (candidate_bitmap);
+ free_alloc_pool (access_pool);
+ free_alloc_pool (link_pool);
+ obstack_free (&name_obstack, NULL);
- switch (TREE_CODE (t))
- {
- case VAR_DECL:
- case PARM_DECL:
- case RESULT_DECL:
- h = DECL_UID (t);
- break;
-
- case INTEGER_CST:
- h = TREE_INT_CST_LOW (t) ^ TREE_INT_CST_HIGH (t);
- break;
-
- case RANGE_EXPR:
- h = iterative_hash_expr (TREE_OPERAND (t, 0), 0);
- h = iterative_hash_expr (TREE_OPERAND (t, 1), h);
- break;
-
- case FIELD_DECL:
- /* We can have types that are compatible, but have different member
- lists, so we can't hash fields by ID. Use offsets instead. */
- h = iterative_hash_expr (DECL_FIELD_OFFSET (t), 0);
- h = iterative_hash_expr (DECL_FIELD_BIT_OFFSET (t), h);
- break;
+ pointer_map_traverse (base_access_vec, delete_base_accesses, NULL);
+ pointer_map_destroy (base_access_vec);
+}
- case BIT_FIELD_REF:
- /* Don't take operand 0 into account, that's our parent. */
- h = iterative_hash_expr (TREE_OPERAND (t, 1), 0);
- h = iterative_hash_expr (TREE_OPERAND (t, 2), h);
- break;
+/* Remove DECL from candidates for SRA and write REASON to the dump file if
+ there is one. */
+static void
+disqualify_candidate (tree decl, const char *reason)
+{
+ bitmap_clear_bit (candidate_bitmap, DECL_UID (decl));
- default:
- gcc_unreachable ();
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "! Disqualifying ");
+ print_generic_expr (dump_file, decl, 0);
+ fprintf (dump_file, " - %s\n", reason);
}
-
- return h;
}
-/* Hash function for type SRA_PAIR. */
+/* Return true iff the type contains a field or an element which does not allow
+ scalarization. */
-static hashval_t
-sra_elt_hash (const void *x)
+static bool
+type_internals_preclude_sra_p (tree type)
{
- const struct sra_elt *const e = (const struct sra_elt *) x;
- const struct sra_elt *p;
- hashval_t h;
-
- h = sra_hash_tree (e->element);
-
- /* Take into account everything except bitfield blocks back up the
- chain. Given that chain lengths are rarely very long, this
- should be acceptable. If we truly identify this as a performance
- problem, it should work to hash the pointer value
- "e->parent". */
- for (p = e->parent; p ; p = p->parent)
- if (!p->in_bitfld_block)
- h = (h * 65521) ^ sra_hash_tree (p->element);
-
- return h;
-}
-
-/* Equality function for type SRA_PAIR. */
+ tree fld;
+ tree et;
-static int
-sra_elt_eq (const void *x, const void *y)
-{
- const struct sra_elt *const a = (const struct sra_elt *) x;
- const struct sra_elt *const b = (const struct sra_elt *) y;
- tree ae, be;
- const struct sra_elt *ap = a->parent;
- const struct sra_elt *bp = b->parent;
-
- if (ap)
- while (ap->in_bitfld_block)
- ap = ap->parent;
- if (bp)
- while (bp->in_bitfld_block)
- bp = bp->parent;
-
- if (ap != bp)
- return false;
+ switch (TREE_CODE (type))
+ {
+ case RECORD_TYPE:
+ case UNION_TYPE:
+ case QUAL_UNION_TYPE:
+ for (fld = TYPE_FIELDS (type); fld; fld = TREE_CHAIN (fld))
+ if (TREE_CODE (fld) == FIELD_DECL)
+ {
+ tree ft = TREE_TYPE (fld);
- ae = a->element;
- be = b->element;
+ if (TREE_THIS_VOLATILE (fld)
+ || !DECL_FIELD_OFFSET (fld) || !DECL_SIZE (fld)
+ || !host_integerp (DECL_FIELD_OFFSET (fld), 1)
+ || !host_integerp (DECL_SIZE (fld), 1))
+ return true;
- if (ae == be)
- return true;
- if (TREE_CODE (ae) != TREE_CODE (be))
- return false;
+ if (AGGREGATE_TYPE_P (ft)
+ && type_internals_preclude_sra_p (ft))
+ return true;
+ }
- switch (TREE_CODE (ae))
- {
- case VAR_DECL:
- case PARM_DECL:
- case RESULT_DECL:
- /* These are all pointer unique. */
return false;
- case INTEGER_CST:
- /* Integers are not pointer unique, so compare their values. */
- return tree_int_cst_equal (ae, be);
-
- case RANGE_EXPR:
- return
- tree_int_cst_equal (TREE_OPERAND (ae, 0), TREE_OPERAND (be, 0))
- && tree_int_cst_equal (TREE_OPERAND (ae, 1), TREE_OPERAND (be, 1));
+ case ARRAY_TYPE:
+ et = TREE_TYPE (type);
- case FIELD_DECL:
- /* Fields are unique within a record, but not between
- compatible records. */
- if (DECL_FIELD_CONTEXT (ae) == DECL_FIELD_CONTEXT (be))
+ if (AGGREGATE_TYPE_P (et))
+ return type_internals_preclude_sra_p (et);
+ else
return false;
- return fields_compatible_p (ae, be);
-
- case BIT_FIELD_REF:
- return
- tree_int_cst_equal (TREE_OPERAND (ae, 1), TREE_OPERAND (be, 1))
- && tree_int_cst_equal (TREE_OPERAND (ae, 2), TREE_OPERAND (be, 2));
default:
- gcc_unreachable ();
+ return false;
}
}
-/* Create or return the SRA_ELT structure for CHILD in PARENT. PARENT
- may be null, in which case CHILD must be a DECL. */
+/* Create and insert access for EXPR. Return created access, or NULL if it is
+ not possible. */
-static struct sra_elt *
-lookup_element (struct sra_elt *parent, tree child, tree type,
- enum insert_option insert)
+static struct access *
+create_access (tree expr, bool write)
{
- struct sra_elt dummy;
- struct sra_elt **slot;
- struct sra_elt *elt;
+ struct access *access;
+ void **slot;
+ VEC (access_p,heap) *vec;
+ HOST_WIDE_INT offset, size, max_size;
+ tree base = expr;
+ bool unscalarizable_region = false;
- if (parent)
- dummy.parent = parent->is_group ? parent->parent : parent;
- else
- dummy.parent = NULL;
- dummy.element = child;
+ base = get_ref_base_and_extent (expr, &offset, &size, &max_size);
- slot = (struct sra_elt **) htab_find_slot (sra_map, &dummy, insert);
- if (!slot && insert == NO_INSERT)
+ if (!DECL_P (base) || !bitmap_bit_p (candidate_bitmap, DECL_UID (base)))
return NULL;
- elt = *slot;
- if (!elt && insert == INSERT)
+ if (size != max_size)
{
- *slot = elt = XOBNEW (&sra_obstack, struct sra_elt);
- memset (elt, 0, sizeof (*elt));
-
- elt->parent = parent;
- elt->element = child;
- elt->type = type;
- elt->is_scalar = is_sra_scalar_type (type);
-
- if (parent)
- {
- if (IS_ELEMENT_FOR_GROUP (elt->element))
- {
- elt->is_group = true;
- elt->sibling = parent->groups;
- parent->groups = elt;
- }
- else
- {
- elt->sibling = parent->children;
- parent->children = elt;
- }
- }
-
- /* If this is a parameter, then if we want to scalarize, we have
- one copy from the true function parameter. Count it now. */
- if (TREE_CODE (child) == PARM_DECL)
- {
- elt->n_copies = 1;
- bitmap_set_bit (needs_copy_in, DECL_UID (child));
- }
+ size = max_size;
+ unscalarizable_region = true;
}
- return elt;
-}
-
-/* Create or return the SRA_ELT structure for EXPR if the expression
- refers to a scalarizable variable. */
-
-static struct sra_elt *
-maybe_lookup_element_for_expr (tree expr)
-{
- struct sra_elt *elt;
- tree child;
-
- switch (TREE_CODE (expr))
+ if (size < 0)
{
- case VAR_DECL:
- case PARM_DECL:
- case RESULT_DECL:
- if (is_sra_candidate_decl (expr))
- return lookup_element (NULL, expr, TREE_TYPE (expr), INSERT);
- return NULL;
-
- case ARRAY_REF:
- /* We can't scalarize variable array indices. */
- if (in_array_bounds_p (expr))
- child = TREE_OPERAND (expr, 1);
- else
- return NULL;
- break;
-
- case ARRAY_RANGE_REF:
- /* We can't scalarize variable array indices. */
- if (range_in_array_bounds_p (expr))
- {
- tree domain = TYPE_DOMAIN (TREE_TYPE (expr));
- child = build2 (RANGE_EXPR, integer_type_node,
- TYPE_MIN_VALUE (domain), TYPE_MAX_VALUE (domain));
- }
- else
- return NULL;
- break;
-
- case COMPONENT_REF:
- {
- tree type = TREE_TYPE (TREE_OPERAND (expr, 0));
- /* Don't look through unions. */
- if (TREE_CODE (type) != RECORD_TYPE)
- return NULL;
- /* Neither through variable-sized records. */
- if (TYPE_SIZE (type) == NULL_TREE
- || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
- return NULL;
- child = TREE_OPERAND (expr, 1);
- }
- break;
-
- case REALPART_EXPR:
- child = integer_zero_node;
- break;
- case IMAGPART_EXPR:
- child = integer_one_node;
- break;
-
- default:
+ disqualify_candidate (base, "Encountered an unconstrained access.");
return NULL;
}
- elt = maybe_lookup_element_for_expr (TREE_OPERAND (expr, 0));
- if (elt)
- return lookup_element (elt, child, TREE_TYPE (expr), INSERT);
- return NULL;
-}
+ access = (struct access *) pool_alloc (access_pool);
+ memset (access, 0, sizeof (struct access));
-
-/* Functions to walk just enough of the tree to see all scalarizable
- references, and categorize them. */
+ access->base = base;
+ access->offset = offset;
+ access->size = size;
+ access->expr = expr;
+ access->type = TREE_TYPE (expr);
+ access->write = write;
+ access->grp_unscalarizable_region = unscalarizable_region;
-/* A set of callbacks for phases 2 and 4. They'll be invoked for the
- various kinds of references seen. In all cases, *GSI is an iterator
- pointing to the statement being processed. */
-struct sra_walk_fns
-{
- /* Invoked when ELT is required as a unit. Note that ELT might refer to
- a leaf node, in which case this is a simple scalar reference. *EXPR_P
- points to the location of the expression. IS_OUTPUT is true if this
- is a left-hand-side reference. USE_ALL is true if we saw something we
- couldn't quite identify and had to force the use of the entire object. */
- void (*use) (struct sra_elt *elt, tree *expr_p,
- gimple_stmt_iterator *gsi, bool is_output, bool use_all);
-
- /* Invoked when we have a copy between two scalarizable references. */
- void (*copy) (struct sra_elt *lhs_elt, struct sra_elt *rhs_elt,
- gimple_stmt_iterator *gsi);
-
- /* Invoked when ELT is initialized from a constant. VALUE may be NULL,
- in which case it should be treated as an empty CONSTRUCTOR. */
- void (*init) (struct sra_elt *elt, tree value, gimple_stmt_iterator *gsi);
-
- /* Invoked when we have a copy between one scalarizable reference ELT
- and one non-scalarizable reference OTHER without side-effects.
- IS_OUTPUT is true if ELT is on the left-hand side. */
- void (*ldst) (struct sra_elt *elt, tree other,
- gimple_stmt_iterator *gsi, bool is_output);
-
- /* True during phase 2, false during phase 4. */
- /* ??? This is a hack. */
- bool initial_scan;
-};
-
-#ifdef ENABLE_CHECKING
-/* Invoked via walk_tree, if *TP contains a candidate decl, return it. */
+ slot = pointer_map_contains (base_access_vec, base);
+ if (slot)
+ vec = (VEC (access_p, heap) *) *slot;
+ else
+ vec = VEC_alloc (access_p, heap, 32);
-static tree
-sra_find_candidate_decl (tree *tp, int *walk_subtrees,
- void *data ATTRIBUTE_UNUSED)
-{
- tree t = *tp;
- enum tree_code code = TREE_CODE (t);
+ VEC_safe_push (access_p, heap, vec, access);
- if (code == VAR_DECL || code == PARM_DECL || code == RESULT_DECL)
- {
- *walk_subtrees = 0;
- if (is_sra_candidate_decl (t))
- return t;
- }
- else if (TYPE_P (t))
- *walk_subtrees = 0;
+ *((struct VEC (access_p,heap) **)
+ pointer_map_insert (base_access_vec, base)) = vec;
- return NULL;
+ return access;
}
-#endif
-
-/* Walk most expressions looking for a scalarizable aggregate.
- If we find one, invoke FNS->USE. */
-
-static void
-sra_walk_expr (tree *expr_p, gimple_stmt_iterator *gsi, bool is_output,
- const struct sra_walk_fns *fns)
-{
- tree expr = *expr_p;
- tree inner = expr;
- bool disable_scalarization = false;
- bool use_all_p = false;
-
- /* We're looking to collect a reference expression between EXPR and INNER,
- such that INNER is a scalarizable decl and all other nodes through EXPR
- are references that we can scalarize. If we come across something that
- we can't scalarize, we reset EXPR. This has the effect of making it
- appear that we're referring to the larger expression as a whole. */
-
- while (1)
- switch (TREE_CODE (inner))
- {
- case VAR_DECL:
- case PARM_DECL:
- case RESULT_DECL:
- /* If there is a scalarizable decl at the bottom, then process it. */
- if (is_sra_candidate_decl (inner))
- {
- struct sra_elt *elt = maybe_lookup_element_for_expr (expr);
- if (disable_scalarization)
- elt->cannot_scalarize = true;
- else
- fns->use (elt, expr_p, gsi, is_output, use_all_p);
- }
- return;
-
- case ARRAY_REF:
- /* Non-constant index means any member may be accessed. Prevent the
- expression from being scalarized. If we were to treat this as a
- reference to the whole array, we can wind up with a single dynamic
- index reference inside a loop being overridden by several constant
- index references during loop setup. It's possible that this could
- be avoided by using dynamic usage counts based on BB trip counts
- (based on loop analysis or profiling), but that hardly seems worth
- the effort. */
- /* ??? Hack. Figure out how to push this into the scan routines
- without duplicating too much code. */
- if (!in_array_bounds_p (inner))
- {
- disable_scalarization = true;
- goto use_all;
- }
- /* ??? Are we assured that non-constant bounds and stride will have
- the same value everywhere? I don't think Fortran will... */
- if (TREE_OPERAND (inner, 2) || TREE_OPERAND (inner, 3))
- goto use_all;
- inner = TREE_OPERAND (inner, 0);
- break;
-
- case ARRAY_RANGE_REF:
- if (!range_in_array_bounds_p (inner))
- {
- disable_scalarization = true;
- goto use_all;
- }
- /* ??? See above non-constant bounds and stride . */
- if (TREE_OPERAND (inner, 2) || TREE_OPERAND (inner, 3))
- goto use_all;
- inner = TREE_OPERAND (inner, 0);
- break;
-
- case COMPONENT_REF:
- {
- tree type = TREE_TYPE (TREE_OPERAND (inner, 0));
- /* Don't look through unions. */
- if (TREE_CODE (type) != RECORD_TYPE)
- goto use_all;
- /* Neither through variable-sized records. */
- if (TYPE_SIZE (type) == NULL_TREE
- || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
- goto use_all;
- inner = TREE_OPERAND (inner, 0);
- }
- break;
-
- case REALPART_EXPR:
- case IMAGPART_EXPR:
- inner = TREE_OPERAND (inner, 0);
- break;
- case BIT_FIELD_REF:
- /* A bit field reference to a specific vector is scalarized but for
- ones for inputs need to be marked as used on the left hand size so
- when we scalarize it, we can mark that variable as non renamable. */
- if (is_output
- && TREE_CODE (TREE_TYPE (TREE_OPERAND (inner, 0))) == VECTOR_TYPE)
- {
- struct sra_elt *elt
- = maybe_lookup_element_for_expr (TREE_OPERAND (inner, 0));
- if (elt)
- elt->is_vector_lhs = true;
- }
- /* A bit field reference (access to *multiple* fields simultaneously)
- is not currently scalarized. Consider this an access to the full
- outer element, to which walk_tree will bring us next. */
- goto use_all;
-
- CASE_CONVERT:
- /* Similarly, a nop explicitly wants to look at an object in a
- type other than the one we've scalarized. */
- goto use_all;
-
- case VIEW_CONVERT_EXPR:
- /* Likewise for a view conversion, but with an additional twist:
- it can be on the LHS and, in this case, an access to the full
- outer element would mean a killing def. So we need to punt
- if we haven't already a full access to the current element,
- because we cannot pretend to have a killing def if we only
- have a partial access at some level. */
- if (is_output && !use_all_p && inner != expr)
- disable_scalarization = true;
- goto use_all;
-
- case WITH_SIZE_EXPR:
- /* This is a transparent wrapper. The entire inner expression really
- is being used. */
- goto use_all;
-
- use_all:
- expr_p = &TREE_OPERAND (inner, 0);
- inner = expr = *expr_p;
- use_all_p = true;
- break;
-
- default:
-#ifdef ENABLE_CHECKING
- /* Validate that we're not missing any references. */
- gcc_assert (!walk_tree (&inner, sra_find_candidate_decl, NULL, NULL));
-#endif
- return;
- }
-}
-
-/* Walk the arguments of a GIMPLE_CALL looking for scalarizable aggregates.
- If we find one, invoke FNS->USE. */
+/* Search the given tree for a declaration by skipping handled components and
+ exclude it from the candidates. */
static void
-sra_walk_gimple_call (gimple stmt, gimple_stmt_iterator *gsi,
- const struct sra_walk_fns *fns)
+disqualify_base_of_expr (tree t, const char *reason)
{
- int i;
- int nargs = gimple_call_num_args (stmt);
-
- for (i = 0; i < nargs; i++)
- sra_walk_expr (gimple_call_arg_ptr (stmt, i), gsi, false, fns);
+ while (handled_component_p (t))
+ t = TREE_OPERAND (t, 0);
- if (gimple_call_lhs (stmt))
- sra_walk_expr (gimple_call_lhs_ptr (stmt), gsi, true, fns);
+ if (DECL_P (t))
+ disqualify_candidate (t, reason);
}
-/* Walk the inputs and outputs of a GIMPLE_ASM looking for scalarizable
- aggregates. If we find one, invoke FNS->USE. */
+/* Scan expression EXPR and create access structures for all accesses to
+ candidates for scalarization. Return the created access or NULL if none is
+ created. */
-static void
-sra_walk_gimple_asm (gimple stmt, gimple_stmt_iterator *gsi,
- const struct sra_walk_fns *fns)
-{
- size_t i;
- for (i = 0; i < gimple_asm_ninputs (stmt); i++)
- sra_walk_expr (&TREE_VALUE (gimple_asm_input_op (stmt, i)), gsi, false, fns);
- for (i = 0; i < gimple_asm_noutputs (stmt); i++)
- sra_walk_expr (&TREE_VALUE (gimple_asm_output_op (stmt, i)), gsi, true, fns);
-}
-
-/* Walk a GIMPLE_ASSIGN and categorize the assignment appropriately. */
-
-static void
-sra_walk_gimple_assign (gimple stmt, gimple_stmt_iterator *gsi,
- const struct sra_walk_fns *fns)
+static struct access *
+build_access_from_expr_1 (tree *expr_ptr, bool write)
{
- struct sra_elt *lhs_elt = NULL, *rhs_elt = NULL;
- tree lhs, rhs;
+ struct access *ret = NULL;
+ tree expr = *expr_ptr;
+ bool partial_ref;
- /* If there is more than 1 element on the RHS, only walk the lhs. */
- if (!gimple_assign_single_p (stmt))
+ if (TREE_CODE (expr) == BIT_FIELD_REF
+ || TREE_CODE (expr) == IMAGPART_EXPR
+ || TREE_CODE (expr) == REALPART_EXPR)
{
- sra_walk_expr (gimple_assign_lhs_ptr (stmt), gsi, true, fns);
- return;
+ expr = TREE_OPERAND (expr, 0);
+ partial_ref = true;
}
+ else
+ partial_ref = false;
- lhs = gimple_assign_lhs (stmt);
- rhs = gimple_assign_rhs1 (stmt);
- lhs_elt = maybe_lookup_element_for_expr (lhs);
- rhs_elt = maybe_lookup_element_for_expr (rhs);
+ /* We need to dive through V_C_Es in order to get the size of its parameter
+ and not the result type. Ada produces such statements. We are also
+ capable of handling the topmost V_C_E but not any of those buried in other
+ handled components. */
+ if (TREE_CODE (expr) == VIEW_CONVERT_EXPR)
+ expr = TREE_OPERAND (expr, 0);
- /* If both sides are scalarizable, this is a COPY operation. */
- if (lhs_elt && rhs_elt)
+ if (contains_view_convert_expr_p (expr))
{
- fns->copy (lhs_elt, rhs_elt, gsi);
- return;
+ disqualify_base_of_expr (expr, "V_C_E under a different handled "
+ "component.");
+ return NULL;
}
- /* If the RHS is scalarizable, handle it. There are only two cases. */
- if (rhs_elt)
+ switch (TREE_CODE (expr))
{
- if (!rhs_elt->is_scalar && !TREE_SIDE_EFFECTS (lhs))
- fns->ldst (rhs_elt, lhs, gsi, false);
- else
- fns->use (rhs_elt, gimple_assign_rhs1_ptr (stmt), gsi, false, false);
- }
-
- /* If it isn't scalarizable, there may be scalarizable variables within, so
- check for a call or else walk the RHS to see if we need to do any
- copy-in operations. We need to do it before the LHS is scalarized so
- that the statements get inserted in the proper place, before any
- copy-out operations. */
- else
- sra_walk_expr (gimple_assign_rhs1_ptr (stmt), gsi, false, fns);
+ case VAR_DECL:
+ case PARM_DECL:
+ case RESULT_DECL:
+ case COMPONENT_REF:
+ case ARRAY_REF:
+ case ARRAY_RANGE_REF:
+ ret = create_access (expr, write);
+ break;
- /* Likewise, handle the LHS being scalarizable. We have cases similar
- to those above, but also want to handle RHS being constant. */
- if (lhs_elt)
- {
- /* If this is an assignment from a constant, or constructor, then
- we have access to all of the elements individually. Invoke INIT. */
- if (TREE_CODE (rhs) == COMPLEX_EXPR
- || TREE_CODE (rhs) == COMPLEX_CST
- || TREE_CODE (rhs) == CONSTRUCTOR)
- fns->init (lhs_elt, rhs, gsi);
-
- /* If this is an assignment from read-only memory, treat this as if
- we'd been passed the constructor directly. Invoke INIT. */
- else if (TREE_CODE (rhs) == VAR_DECL
- && TREE_STATIC (rhs)
- && !DECL_EXTERNAL (rhs)
- && TREE_READONLY (rhs)
- && targetm.binds_local_p (rhs))
- fns->init (lhs_elt, DECL_INITIAL (rhs), gsi);
-
- /* If this is a copy from a non-scalarizable lvalue, invoke LDST.
- The lvalue requirement prevents us from trying to directly scalarize
- the result of a function call. Which would result in trying to call
- the function multiple times, and other evil things. */
- else if (!lhs_elt->is_scalar
- && !TREE_SIDE_EFFECTS (rhs) && is_gimple_addressable (rhs))
- fns->ldst (lhs_elt, rhs, gsi, true);
-
- /* Otherwise we're being used in some context that requires the
- aggregate to be seen as a whole. Invoke USE. */
- else
- fns->use (lhs_elt, gimple_assign_lhs_ptr (stmt), gsi, true, false);
+ default:
+ break;
}
- /* Similarly to above, LHS_ELT being null only means that the LHS as a
- whole is not a scalarizable reference. There may be occurrences of
- scalarizable variables within, which implies a USE. */
- else
- sra_walk_expr (gimple_assign_lhs_ptr (stmt), gsi, true, fns);
+ if (write && partial_ref && ret)
+ ret->grp_partial_lhs = 1;
+
+ return ret;
}
-/* Entry point to the walk functions. Search the entire function,
- invoking the callbacks in FNS on each of the references to
- scalarizable variables. */
+/* Callback of scan_function. Scan expression EXPR and create access
+ structures for all accesses to candidates for scalarization. Return true if
+ any access has been inserted. */
-static void
-sra_walk_function (const struct sra_walk_fns *fns)
+static bool
+build_access_from_expr (tree *expr_ptr,
+ gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED, bool write,
+ void *data ATTRIBUTE_UNUSED)
{
- basic_block bb;
- gimple_stmt_iterator si, ni;
-
- /* ??? Phase 4 could derive some benefit to walking the function in
- dominator tree order. */
-
- FOR_EACH_BB (bb)
- for (si = gsi_start_bb (bb); !gsi_end_p (si); si = ni)
- {
- gimple stmt;
-
- stmt = gsi_stmt (si);
-
- ni = si;
- gsi_next (&ni);
-
- /* If the statement does not reference memory, then it doesn't
- make any structure references that we care about. */
- if (!gimple_references_memory_p (stmt))
- continue;
-
- switch (gimple_code (stmt))
- {
- case GIMPLE_RETURN:
- /* If we have "return <retval>" then the return value is
- already exposed for our pleasure. Walk it as a USE to
- force all the components back in place for the return.
- */
- if (gimple_return_retval (stmt) == NULL_TREE)
- ;
- else
- sra_walk_expr (gimple_return_retval_ptr (stmt), &si, false,
- fns);
- break;
-
- case GIMPLE_ASSIGN:
- sra_walk_gimple_assign (stmt, &si, fns);
- break;
- case GIMPLE_CALL:
- sra_walk_gimple_call (stmt, &si, fns);
- break;
- case GIMPLE_ASM:
- sra_walk_gimple_asm (stmt, &si, fns);
- break;
-
- default:
- break;
- }
- }
+ return build_access_from_expr_1 (expr_ptr, write) != NULL;
}
-
-/* Phase One: Scan all referenced variables in the program looking for
- structures that could be decomposed. */
+/* Disqualify LHS and RHS for scalarization if STMT must end its basic block in
+ modes in which it matters, return true iff they have been disqualified. RHS
+ may be NULL, in that case ignore it. If we scalarize an aggregate in
+ intra-SRA we may need to add statements after each statement. This is not
+ possible if a statement unconditionally has to end the basic block. */
static bool
-find_candidates_for_sra (void)
+disqualify_ops_if_throwing_stmt (gimple stmt, tree lhs, tree rhs)
{
- bool any_set = false;
- tree var;
- referenced_var_iterator rvi;
-
- FOR_EACH_REFERENCED_VAR (var, rvi)
+ if (stmt_can_throw_internal (stmt) || stmt_ends_bb_p (stmt))
{
- if (decl_can_be_decomposed_p (var))
- {
- bitmap_set_bit (sra_candidates, DECL_UID (var));
- any_set = true;
- }
+ disqualify_base_of_expr (lhs, "LHS of a throwing stmt.");
+ if (rhs)
+ disqualify_base_of_expr (rhs, "RHS of a throwing stmt.");
+ return true;
}
-
- return any_set;
+ return false;
}
-
-/* Phase Two: Scan all references to scalarizable variables. Count the
- number of times they are used or copied respectively. */
-/* Callbacks to fill in SRA_WALK_FNS. Everything but USE is
- considered a copy, because we can decompose the reference such that
- the sub-elements needn't be contiguous. */
+/* Result code for scan_assign callback for scan_function. */
+enum scan_assign_result { SRA_SA_NONE, /* nothing done for the stmt */
+ SRA_SA_PROCESSED, /* stmt analyzed/changed */
+ SRA_SA_REMOVED }; /* stmt redundant and eliminated */
-static void
-scan_use (struct sra_elt *elt, tree *expr_p ATTRIBUTE_UNUSED,
- gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED,
- bool is_output ATTRIBUTE_UNUSED, bool use_all ATTRIBUTE_UNUSED)
-{
- elt->n_uses += 1;
-}
-static void
-scan_copy (struct sra_elt *lhs_elt, struct sra_elt *rhs_elt,
- gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED)
-{
- lhs_elt->n_copies += 1;
- rhs_elt->n_copies += 1;
-}
+/* Callback of scan_function. Scan expressions occuring in the statement
+ pointed to by STMT_EXPR, create access structures for all accesses to
+ candidates for scalarization and remove those candidates which occur in
+ statements or expressions that prevent them from being split apart. Return
+ true if any access has been inserted. */
-static void
-scan_init (struct sra_elt *lhs_elt, tree rhs ATTRIBUTE_UNUSED,
- gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED)
-{
- lhs_elt->n_copies += 1;
-}
-
-static void
-scan_ldst (struct sra_elt *elt, tree other ATTRIBUTE_UNUSED,
- gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED,
- bool is_output ATTRIBUTE_UNUSED)
+static enum scan_assign_result
+build_accesses_from_assign (gimple *stmt_ptr,
+ gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED,
+ void *data ATTRIBUTE_UNUSED)
{
- elt->n_copies += 1;
-}
+ gimple stmt = *stmt_ptr;
+ tree *lhs_ptr, *rhs_ptr;
+ struct access *lacc, *racc;
-/* Dump the values we collected during the scanning phase. */
-
-static void
-scan_dump (struct sra_elt *elt)
-{
- struct sra_elt *c;
-
- dump_sra_elt_name (dump_file, elt);
- fprintf (dump_file, ": n_uses=%u n_copies=%u\n", elt->n_uses, elt->n_copies);
+ if (!gimple_assign_single_p (stmt))
+ return SRA_SA_NONE;
- for (c = elt->children; c ; c = c->sibling)
- scan_dump (c);
+ lhs_ptr = gimple_assign_lhs_ptr (stmt);
+ rhs_ptr = gimple_assign_rhs1_ptr (stmt);
- for (c = elt->groups; c ; c = c->sibling)
- scan_dump (c);
-}
+ if (disqualify_ops_if_throwing_stmt (stmt, *lhs_ptr, *rhs_ptr))
+ return SRA_SA_NONE;
-/* Entry point to phase 2. Scan the entire function, building up
- scalarization data structures, recording copies and uses. */
+ racc = build_access_from_expr_1 (rhs_ptr, false);
+ lacc = build_access_from_expr_1 (lhs_ptr, true);
-static void
-scan_function (void)
-{
- static const struct sra_walk_fns fns = {
- scan_use, scan_copy, scan_init, scan_ldst, true
- };
- bitmap_iterator bi;
+ if (lacc && racc
+ && !lacc->grp_unscalarizable_region
+ && !racc->grp_unscalarizable_region
+ && AGGREGATE_TYPE_P (TREE_TYPE (*lhs_ptr))
+ /* FIXME: Turn the following line into an assert after PR 40058 is
+ fixed. */
+ && lacc->size == racc->size
+ && useless_type_conversion_p (lacc->type, racc->type))
+ {
+ struct assign_link *link;
- sra_walk_function (&fns);
+ link = (struct assign_link *) pool_alloc (link_pool);
+ memset (link, 0, sizeof (struct assign_link));
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- unsigned i;
+ link->lacc = lacc;
+ link->racc = racc;
- fputs ("\nScan results:\n", dump_file);
- EXECUTE_IF_SET_IN_BITMAP (sra_candidates, 0, i, bi)
- {
- tree var = referenced_var (i);
- struct sra_elt *elt = lookup_element (NULL, var, NULL, NO_INSERT);
- if (elt)
- scan_dump (elt);
- }
- fputc ('\n', dump_file);
+ add_link_to_rhs (racc, link);
}
+
+ return (lacc || racc) ? SRA_SA_PROCESSED : SRA_SA_NONE;
}
-
-/* Phase Three: Make decisions about which variables to scalarize, if any.
- All elements to be scalarized have replacement variables made for them. */
-/* A subroutine of build_element_name. Recursively build the element
- name on the obstack. */
+/* Callback of walk_stmt_load_store_addr_ops visit_addr used to determine
+ GIMPLE_ASM operands with memory constrains which cannot be scalarized. */
-static void
-build_element_name_1 (struct sra_elt *elt)
+static bool
+asm_visit_addr (gimple stmt ATTRIBUTE_UNUSED, tree op,
+ void *data ATTRIBUTE_UNUSED)
{
- tree t;
- char buffer[32];
+ if (DECL_P (op))
+ disqualify_candidate (op, "Non-scalarizable GIMPLE_ASM operand.");
- if (elt->parent)
- {
- build_element_name_1 (elt->parent);
- obstack_1grow (&sra_obstack, '$');
-
- if (TREE_CODE (elt->parent->type) == COMPLEX_TYPE)
- {
- if (elt->element == integer_zero_node)
- obstack_grow (&sra_obstack, "real", 4);
- else
- obstack_grow (&sra_obstack, "imag", 4);
- return;
- }
- }
-
- t = elt->element;
- if (TREE_CODE (t) == INTEGER_CST)
- {
- /* ??? Eh. Don't bother doing double-wide printing. */
- sprintf (buffer, HOST_WIDE_INT_PRINT_DEC, TREE_INT_CST_LOW (t));
- obstack_grow (&sra_obstack, buffer, strlen (buffer));
- }
- else if (TREE_CODE (t) == BIT_FIELD_REF)
- {
- sprintf (buffer, "B" HOST_WIDE_INT_PRINT_DEC,
- tree_low_cst (TREE_OPERAND (t, 2), 1));
- obstack_grow (&sra_obstack, buffer, strlen (buffer));
- sprintf (buffer, "F" HOST_WIDE_INT_PRINT_DEC,
- tree_low_cst (TREE_OPERAND (t, 1), 1));
- obstack_grow (&sra_obstack, buffer, strlen (buffer));
- }
- else
- {
- tree name = DECL_NAME (t);
- if (name)
- obstack_grow (&sra_obstack, IDENTIFIER_POINTER (name),
- IDENTIFIER_LENGTH (name));
- else
- {
- sprintf (buffer, "D%u", DECL_UID (t));
- obstack_grow (&sra_obstack, buffer, strlen (buffer));
- }
- }
+ return false;
}
-/* Construct a pretty variable name for an element's replacement variable.
- The name is built on the obstack. */
-static char *
-build_element_name (struct sra_elt *elt)
+/* Scan function and look for interesting statements. Return true if any has
+ been found or processed, as indicated by callbacks. SCAN_EXPR is a callback
+ called on all expressions within statements except assign statements and
+ those deemed entirely unsuitable for some reason (all operands in such
+ statements and expression are removed from candidate_bitmap). SCAN_ASSIGN
+ is a callback called on all assign statements, HANDLE_SSA_DEFS is a callback
+ called on assign statements and those call statements which have a lhs and
+ it is the only callback which can be NULL. ANALYSIS_STAGE is true when
+ running in the analysis stage of a pass and thus no statement is being
+ modified. DATA is a pointer passed to all callbacks. If any single
+ callback returns true, this function also returns true, otherwise it returns
+ false. */
+
+static bool
+scan_function (bool (*scan_expr) (tree *, gimple_stmt_iterator *, bool, void *),
+ enum scan_assign_result (*scan_assign) (gimple *,
+ gimple_stmt_iterator *,
+ void *),
+ bool (*handle_ssa_defs)(gimple, void *),
+ bool analysis_stage, void *data)
{
- build_element_name_1 (elt);
- obstack_1grow (&sra_obstack, '\0');
- return XOBFINISH (&sra_obstack, char *);
-}
+ gimple_stmt_iterator gsi;
+ basic_block bb;
+ unsigned i;
+ tree *t;
+ bool ret = false;
-/* Instantiate an element as an independent variable. */
+ FOR_EACH_BB (bb)
+ {
+ bool bb_changed = false;
-static void
-instantiate_element (struct sra_elt *elt)
-{
- struct sra_elt *base_elt;
- tree var, base;
- bool nowarn = TREE_NO_WARNING (elt->element);
+ gsi = gsi_start_bb (bb);
+ while (!gsi_end_p (gsi))
+ {
+ gimple stmt = gsi_stmt (gsi);
+ enum scan_assign_result assign_result;
+ bool any = false, deleted = false;
- for (base_elt = elt; base_elt->parent; base_elt = base_elt->parent)
- if (!nowarn)
- nowarn = TREE_NO_WARNING (base_elt->parent->element);
- base = base_elt->element;
+ switch (gimple_code (stmt))
+ {
+ case GIMPLE_RETURN:
+ t = gimple_return_retval_ptr (stmt);
+ if (*t != NULL_TREE)
+ any |= scan_expr (t, &gsi, false, data);
+ break;
- elt->replacement = var = make_rename_temp (elt->type, "SR");
+ case GIMPLE_ASSIGN:
+ assign_result = scan_assign (&stmt, &gsi, data);
+ any |= assign_result == SRA_SA_PROCESSED;
+ deleted = assign_result == SRA_SA_REMOVED;
+ if (handle_ssa_defs && assign_result != SRA_SA_REMOVED)
+ any |= handle_ssa_defs (stmt, data);
+ break;
- if (DECL_P (elt->element)
- && !tree_int_cst_equal (DECL_SIZE (var), DECL_SIZE (elt->element)))
- {
- DECL_SIZE (var) = DECL_SIZE (elt->element);
- DECL_SIZE_UNIT (var) = DECL_SIZE_UNIT (elt->element);
-
- elt->in_bitfld_block = 1;
- elt->replacement = fold_build3 (BIT_FIELD_REF, elt->type, var,
- DECL_SIZE (var),
- BYTES_BIG_ENDIAN
- ? size_binop (MINUS_EXPR,
- TYPE_SIZE (elt->type),
- DECL_SIZE (var))
- : bitsize_int (0));
- }
+ case GIMPLE_CALL:
+ /* Operands must be processed before the lhs. */
+ for (i = 0; i < gimple_call_num_args (stmt); i++)
+ {
+ tree *argp = gimple_call_arg_ptr (stmt, i);
+ any |= scan_expr (argp, &gsi, false, data);
+ }
- /* For vectors, if used on the left hand side with BIT_FIELD_REF,
- they are not a gimple register. */
- if (TREE_CODE (TREE_TYPE (var)) == VECTOR_TYPE && elt->is_vector_lhs)
- DECL_GIMPLE_REG_P (var) = 0;
+ if (gimple_call_lhs (stmt))
+ {
+ tree *lhs_ptr = gimple_call_lhs_ptr (stmt);
+ if (!analysis_stage
+ || !disqualify_ops_if_throwing_stmt (stmt,
+ *lhs_ptr, NULL))
+ {
+ any |= scan_expr (lhs_ptr, &gsi, true, data);
+ if (handle_ssa_defs)
+ any |= handle_ssa_defs (stmt, data);
+ }
+ }
+ break;
- DECL_SOURCE_LOCATION (var) = DECL_SOURCE_LOCATION (base);
- DECL_ARTIFICIAL (var) = 1;
+ case GIMPLE_ASM:
- if (TREE_THIS_VOLATILE (elt->type))
- {
- TREE_THIS_VOLATILE (var) = 1;
- TREE_SIDE_EFFECTS (var) = 1;
- }
+ if (analysis_stage)
+ walk_stmt_load_store_addr_ops (stmt, NULL, NULL, NULL,
+ asm_visit_addr);
+ for (i = 0; i < gimple_asm_ninputs (stmt); i++)
+ {
+ tree *op = &TREE_VALUE (gimple_asm_input_op (stmt, i));
+ any |= scan_expr (op, &gsi, false, data);
+ }
+ for (i = 0; i < gimple_asm_noutputs (stmt); i++)
+ {
+ tree *op = &TREE_VALUE (gimple_asm_output_op (stmt, i));
+ any |= scan_expr (op, &gsi, true, data);
+ }
- if (DECL_NAME (base) && !DECL_IGNORED_P (base))
- {
- char *pretty_name = build_element_name (elt);
- DECL_NAME (var) = get_identifier (pretty_name);
- obstack_free (&sra_obstack, pretty_name);
-
- SET_DECL_DEBUG_EXPR (var, generate_element_ref (elt));
- DECL_DEBUG_EXPR_IS_FROM (var) = 1;
-
- DECL_IGNORED_P (var) = 0;
- TREE_NO_WARNING (var) = nowarn;
- }
- else
- {
- DECL_IGNORED_P (var) = 1;
- /* ??? We can't generate any warning that would be meaningful. */
- TREE_NO_WARNING (var) = 1;
- }
+ default:
+ break;
+ }
- /* Zero-initialize bit-field scalarization variables, to avoid
- triggering undefined behavior. */
- if (TREE_CODE (elt->element) == BIT_FIELD_REF
- || (var != elt->replacement
- && TREE_CODE (elt->replacement) == BIT_FIELD_REF))
- {
- gimple_seq init = sra_build_assignment (var,
- fold_convert (TREE_TYPE (var),
- integer_zero_node)
- );
- insert_edge_copies_seq (init, ENTRY_BLOCK_PTR);
- mark_all_v_defs_seq (init);
- }
+ if (any)
+ {
+ ret = true;
+ bb_changed = true;
- if (dump_file)
- {
- fputs (" ", dump_file);
- dump_sra_elt_name (dump_file, elt);
- fputs (" -> ", dump_file);
- print_generic_expr (dump_file, var, dump_flags);
- fputc ('\n', dump_file);
+ if (!analysis_stage)
+ {
+ update_stmt (stmt);
+ if (!stmt_could_throw_p (stmt))
+ remove_stmt_from_eh_region (stmt);
+ }
+ }
+ if (deleted)
+ bb_changed = true;
+ else
+ {
+ gsi_next (&gsi);
+ ret = true;
+ }
+ }
+ if (!analysis_stage && bb_changed)
+ gimple_purge_dead_eh_edges (bb);
}
+
+ return ret;
}
-/* Make one pass across an element tree deciding whether or not it's
- profitable to instantiate individual leaf scalars.
+/* Helper of QSORT function. There are pointers to accesses in the array. An
+ access is considered smaller than another if it has smaller offset or if the
+ offsets are the same but is size is bigger. */
- PARENT_USES and PARENT_COPIES are the sum of the N_USES and N_COPIES
- fields all the way up the tree. */
+static int
+compare_access_positions (const void *a, const void *b)
+{
+ const access_p *fp1 = (const access_p *) a;
+ const access_p *fp2 = (const access_p *) b;
+ const access_p f1 = *fp1;
+ const access_p f2 = *fp2;
+
+ if (f1->offset != f2->offset)
+ return f1->offset < f2->offset ? -1 : 1;
+
+ if (f1->size == f2->size)
+ {
+ /* Put any non-aggregate type before any aggregate type. */
+ if (!is_gimple_reg_type (f1->type)
+ && is_gimple_reg_type (f2->type))
+ return 1;
+ else if (is_gimple_reg_type (f1->type)
+ && !is_gimple_reg_type (f2->type))
+ return -1;
+ /* Put the integral type with the bigger precision first. */
+ else if (INTEGRAL_TYPE_P (f1->type)
+ && INTEGRAL_TYPE_P (f2->type))
+ return TYPE_PRECISION (f1->type) > TYPE_PRECISION (f2->type) ? -1 : 1;
+ /* Put any integral type with non-full precision last. */
+ else if (INTEGRAL_TYPE_P (f1->type)
+ && (TREE_INT_CST_LOW (TYPE_SIZE (f1->type))
+ != TYPE_PRECISION (f1->type)))
+ return 1;
+ else if (INTEGRAL_TYPE_P (f2->type)
+ && (TREE_INT_CST_LOW (TYPE_SIZE (f2->type))
+ != TYPE_PRECISION (f2->type)))
+ return -1;
+ /* Stabilize the sort. */
+ return TYPE_UID (f1->type) - TYPE_UID (f2->type);
+ }
+
+ /* We want the bigger accesses first, thus the opposite operator in the next
+ line: */
+ return f1->size > f2->size ? -1 : 1;
+}
+
+
+/* Append a name of the declaration to the name obstack. A helper function for
+ make_fancy_name. */
static void
-decide_instantiation_1 (struct sra_elt *elt, unsigned int parent_uses,
- unsigned int parent_copies)
+make_fancy_decl_name (tree decl)
{
- if (dump_file && !elt->parent)
- {
- fputs ("Initial instantiation for ", dump_file);
- dump_sra_elt_name (dump_file, elt);
- fputc ('\n', dump_file);
- }
-
- if (elt->cannot_scalarize)
- return;
+ char buffer[32];
- if (elt->is_scalar)
- {
- /* The decision is simple: instantiate if we're used more frequently
- than the parent needs to be seen as a complete unit. */
- if (elt->n_uses + elt->n_copies + parent_copies > parent_uses)
- instantiate_element (elt);
- }
+ tree name = DECL_NAME (decl);
+ if (name)
+ obstack_grow (&name_obstack, IDENTIFIER_POINTER (name),
+ IDENTIFIER_LENGTH (name));
else
{
- struct sra_elt *c, *group;
- unsigned int this_uses = elt->n_uses + parent_uses;
- unsigned int this_copies = elt->n_copies + parent_copies;
-
- /* Consider groups of sub-elements as weighing in favour of
- instantiation whatever their size. */
- for (group = elt->groups; group ; group = group->sibling)
- FOR_EACH_ACTUAL_CHILD (c, group)
- {
- c->n_uses += group->n_uses;
- c->n_copies += group->n_copies;
- }
-
- for (c = elt->children; c ; c = c->sibling)
- decide_instantiation_1 (c, this_uses, this_copies);
+ sprintf (buffer, "D%u", DECL_UID (decl));
+ obstack_grow (&name_obstack, buffer, strlen (buffer));
}
}
-/* Compute the size and number of all instantiated elements below ELT.
- We will only care about this if the size of the complete structure
- fits in a HOST_WIDE_INT, so we don't have to worry about overflow. */
+/* Helper for make_fancy_name. */
-static unsigned int
-sum_instantiated_sizes (struct sra_elt *elt, unsigned HOST_WIDE_INT *sizep)
+static void
+make_fancy_name_1 (tree expr)
{
- if (elt->replacement)
+ char buffer[32];
+ tree index;
+
+ if (DECL_P (expr))
{
- *sizep += TREE_INT_CST_LOW (TYPE_SIZE_UNIT (elt->type));
- return 1;
+ make_fancy_decl_name (expr);
+ return;
}
- else
- {
- struct sra_elt *c;
- unsigned int count = 0;
- for (c = elt->children; c ; c = c->sibling)
- count += sum_instantiated_sizes (c, sizep);
-
- return count;
- }
-}
+ switch (TREE_CODE (expr))
+ {
+ case COMPONENT_REF:
+ make_fancy_name_1 (TREE_OPERAND (expr, 0));
+ obstack_1grow (&name_obstack, '$');
+ make_fancy_decl_name (TREE_OPERAND (expr, 1));
+ break;
-/* Instantiate fields in ELT->TYPE that are not currently present as
- children of ELT. */
+ case ARRAY_REF:
+ make_fancy_name_1 (TREE_OPERAND (expr, 0));
+ obstack_1grow (&name_obstack, '$');
+ /* Arrays with only one element may not have a constant as their
+ index. */
+ index = TREE_OPERAND (expr, 1);
+ if (TREE_CODE (index) != INTEGER_CST)
+ break;
+ sprintf (buffer, HOST_WIDE_INT_PRINT_DEC, TREE_INT_CST_LOW (index));
+ obstack_grow (&name_obstack, buffer, strlen (buffer));
-static void instantiate_missing_elements (struct sra_elt *elt);
+ break;
-static struct sra_elt *
-instantiate_missing_elements_1 (struct sra_elt *elt, tree child, tree type)
-{
- struct sra_elt *sub = lookup_element (elt, child, type, INSERT);
- if (sub->is_scalar)
- {
- if (sub->replacement == NULL)
- instantiate_element (sub);
+ case BIT_FIELD_REF:
+ case REALPART_EXPR:
+ case IMAGPART_EXPR:
+ gcc_unreachable (); /* we treat these as scalars. */
+ break;
+ default:
+ break;
}
- else
- instantiate_missing_elements (sub);
- return sub;
}
-/* Obtain the canonical type for field F of ELEMENT. */
+/* Create a human readable name for replacement variable of ACCESS. */
-static tree
-canon_type_for_field (tree f, tree element)
+static char *
+make_fancy_name (tree expr)
{
- tree field_type = TREE_TYPE (f);
-
- /* canonicalize_component_ref() unwidens some bit-field types (not
- marked as DECL_BIT_FIELD in C++), so we must do the same, lest we
- may introduce type mismatches. */
- if (INTEGRAL_TYPE_P (field_type)
- && DECL_MODE (f) != TYPE_MODE (field_type))
- field_type = TREE_TYPE (get_unwidened (build3 (COMPONENT_REF,
- field_type,
- element,
- f, NULL_TREE),
- NULL_TREE));
-
- return field_type;
+ make_fancy_name_1 (expr);
+ obstack_1grow (&name_obstack, '\0');
+ return XOBFINISH (&name_obstack, char *);
}
-/* Look for adjacent fields of ELT starting at F that we'd like to
- scalarize as a single variable. Return the last field of the
- group. */
+/* Helper function for build_ref_for_offset. */
-static tree
-try_instantiate_multiple_fields (struct sra_elt *elt, tree f)
+static bool
+build_ref_for_offset_1 (tree *res, tree type, HOST_WIDE_INT offset,
+ tree exp_type)
{
- int count;
- unsigned HOST_WIDE_INT align, bit, size, alchk;
- enum machine_mode mode;
- tree first = f, prev;
- tree type, var;
- struct sra_elt *block;
-
- /* Point fields are typically best handled as standalone entities. */
- if (POINTER_TYPE_P (TREE_TYPE (f)))
- return f;
-
- if (!is_sra_scalar_type (TREE_TYPE (f))
- || !host_integerp (DECL_FIELD_OFFSET (f), 1)
- || !host_integerp (DECL_FIELD_BIT_OFFSET (f), 1)
- || !host_integerp (DECL_SIZE (f), 1)
- || lookup_element (elt, f, NULL, NO_INSERT))
- return f;
-
- block = elt;
-
- /* For complex and array objects, there are going to be integer
- literals as child elements. In this case, we can't just take the
- alignment and mode of the decl, so we instead rely on the element
- type.
-
- ??? We could try to infer additional alignment from the full
- object declaration and the location of the sub-elements we're
- accessing. */
- for (count = 0; !DECL_P (block->element); count++)
- block = block->parent;
-
- align = DECL_ALIGN (block->element);
- alchk = GET_MODE_BITSIZE (DECL_MODE (block->element));
-
- if (count)
- {
- type = TREE_TYPE (block->element);
- while (count--)
- type = TREE_TYPE (type);
-
- align = TYPE_ALIGN (type);
- alchk = GET_MODE_BITSIZE (TYPE_MODE (type));
- }
-
- if (align < alchk)
- align = alchk;
-
- /* Coalescing wider fields is probably pointless and
- inefficient. */
- if (align > BITS_PER_WORD)
- align = BITS_PER_WORD;
-
- bit = tree_low_cst (DECL_FIELD_OFFSET (f), 1) * BITS_PER_UNIT
- + tree_low_cst (DECL_FIELD_BIT_OFFSET (f), 1);
- size = tree_low_cst (DECL_SIZE (f), 1);
-
- alchk = align - 1;
- alchk = ~alchk;
-
- if ((bit & alchk) != ((bit + size - 1) & alchk))
- return f;
-
- /* Find adjacent fields in the same alignment word. */
-
- for (prev = f, f = TREE_CHAIN (f);
- f && TREE_CODE (f) == FIELD_DECL
- && is_sra_scalar_type (TREE_TYPE (f))
- && host_integerp (DECL_FIELD_OFFSET (f), 1)
- && host_integerp (DECL_FIELD_BIT_OFFSET (f), 1)
- && host_integerp (DECL_SIZE (f), 1)
- && !lookup_element (elt, f, NULL, NO_INSERT);
- prev = f, f = TREE_CHAIN (f))
+ while (1)
{
- unsigned HOST_WIDE_INT nbit, nsize;
-
- nbit = tree_low_cst (DECL_FIELD_OFFSET (f), 1) * BITS_PER_UNIT
- + tree_low_cst (DECL_FIELD_BIT_OFFSET (f), 1);
- nsize = tree_low_cst (DECL_SIZE (f), 1);
-
- if (bit + size == nbit)
- {
- if ((bit & alchk) != ((nbit + nsize - 1) & alchk))
- {
- /* If we're at an alignment boundary, don't bother
- growing alignment such that we can include this next
- field. */
- if ((nbit & alchk)
- || GET_MODE_BITSIZE (DECL_MODE (f)) <= align)
- break;
-
- align = GET_MODE_BITSIZE (DECL_MODE (f));
- alchk = align - 1;
- alchk = ~alchk;
-
- if ((bit & alchk) != ((nbit + nsize - 1) & alchk))
- break;
- }
- size += nsize;
- }
- else if (nbit + nsize == bit)
- {
- if ((nbit & alchk) != ((bit + size - 1) & alchk))
- {
- if ((bit & alchk)
- || GET_MODE_BITSIZE (DECL_MODE (f)) <= align)
- break;
-
- align = GET_MODE_BITSIZE (DECL_MODE (f));
- alchk = align - 1;
- alchk = ~alchk;
+ tree fld;
+ tree tr_size, index;
+ HOST_WIDE_INT el_size;
- if ((nbit & alchk) != ((bit + size - 1) & alchk))
- break;
- }
- bit = nbit;
- size += nsize;
- }
- else
- break;
- }
-
- f = prev;
-
- if (f == first)
- return f;
-
- gcc_assert ((bit & alchk) == ((bit + size - 1) & alchk));
-
- /* Try to widen the bit range so as to cover padding bits as well. */
-
- if ((bit & ~alchk) || size != align)
- {
- unsigned HOST_WIDE_INT mbit = bit & alchk;
- unsigned HOST_WIDE_INT msize = align;
+ if (offset == 0 && exp_type
+ && useless_type_conversion_p (exp_type, type))
+ return true;
- for (f = TYPE_FIELDS (elt->type);
- f; f = TREE_CHAIN (f))
+ switch (TREE_CODE (type))
{
- unsigned HOST_WIDE_INT fbit, fsize;
-
- /* Skip the fields from first to prev. */
- if (f == first)
- {
- f = prev;
- continue;
- }
-
- if (!(TREE_CODE (f) == FIELD_DECL
- && host_integerp (DECL_FIELD_OFFSET (f), 1)
- && host_integerp (DECL_FIELD_BIT_OFFSET (f), 1)))
- continue;
-
- fbit = tree_low_cst (DECL_FIELD_OFFSET (f), 1) * BITS_PER_UNIT
- + tree_low_cst (DECL_FIELD_BIT_OFFSET (f), 1);
-
- /* If we're past the selected word, we're fine. */
- if ((bit & alchk) < (fbit & alchk))
- continue;
-
- if (host_integerp (DECL_SIZE (f), 1))
- fsize = tree_low_cst (DECL_SIZE (f), 1);
- else
- /* Assume a variable-sized field takes up all space till
- the end of the word. ??? Endianness issues? */
- fsize = align - (fbit & alchk);
-
- if ((fbit & alchk) < (bit & alchk))
+ case UNION_TYPE:
+ case QUAL_UNION_TYPE:
+ case RECORD_TYPE:
+ /* Some ADA records are half-unions, treat all of them the same. */
+ for (fld = TYPE_FIELDS (type); fld; fld = TREE_CHAIN (fld))
{
- /* A large field might start at a previous word and
- extend into the selected word. Exclude those
- bits. ??? Endianness issues? */
- HOST_WIDE_INT diff = fbit + fsize - mbit;
+ HOST_WIDE_INT pos, size;
+ tree expr, *expr_ptr;
- if (diff <= 0)
+ if (TREE_CODE (fld) != FIELD_DECL)
continue;
- mbit += diff;
- msize -= diff;
- }
- else
- {
- /* Non-overlapping, great. */
- if (fbit + fsize <= mbit
- || mbit + msize <= fbit)
+ pos = int_bit_position (fld);
+ gcc_assert (TREE_CODE (type) == RECORD_TYPE || pos == 0);
+ size = tree_low_cst (DECL_SIZE (fld), 1);
+ if (pos > offset || (pos + size) <= offset)
continue;
- if (fbit <= mbit)
+ if (res)
{
- unsigned HOST_WIDE_INT diff = fbit + fsize - mbit;
- mbit += diff;
- msize -= diff;
+ expr = build3 (COMPONENT_REF, TREE_TYPE (fld), *res, fld,
+ NULL_TREE);
+ expr_ptr = &expr;
}
- else if (fbit > mbit)
- msize -= (mbit + msize - fbit);
else
- gcc_unreachable ();
+ expr_ptr = NULL;
+ if (build_ref_for_offset_1 (expr_ptr, TREE_TYPE (fld),
+ offset - pos, exp_type))
+ {
+ if (res)
+ *res = expr;
+ return true;
+ }
}
- }
-
- bit = mbit;
- size = msize;
- }
+ return false;
- /* Now we know the bit range we're interested in. Find the smallest
- machine mode we can use to access it. */
+ case ARRAY_TYPE:
+ tr_size = TYPE_SIZE (TREE_TYPE (type));
+ if (!tr_size || !host_integerp (tr_size, 1))
+ return false;
+ el_size = tree_low_cst (tr_size, 1);
- for (mode = smallest_mode_for_size (size, MODE_INT);
- ;
- mode = GET_MODE_WIDER_MODE (mode))
- {
- gcc_assert (mode != VOIDmode);
+ if (res)
+ {
+ index = build_int_cst (TYPE_DOMAIN (type), offset / el_size);
+ if (!integer_zerop (TYPE_MIN_VALUE (TYPE_DOMAIN (type))))
+ index = int_const_binop (PLUS_EXPR, index,
+ TYPE_MIN_VALUE (TYPE_DOMAIN (type)),
+ 0);
+ *res = build4 (ARRAY_REF, TREE_TYPE (type), *res, index,
+ NULL_TREE, NULL_TREE);
+ }
+ offset = offset % el_size;
+ type = TREE_TYPE (type);
+ break;
- alchk = GET_MODE_PRECISION (mode) - 1;
- alchk = ~alchk;
+ default:
+ if (offset != 0)
+ return false;
- if ((bit & alchk) == ((bit + size - 1) & alchk))
- break;
+ if (exp_type)
+ return false;
+ else
+ return true;
+ }
}
+}
- gcc_assert (~alchk < align);
-
- /* Create the field group as a single variable. */
-
- /* We used to create a type for the mode above, but size turns
- to be out not of mode-size. As we need a matching type
- to build a BIT_FIELD_REF, use a nonstandard integer type as
- fallback. */
- type = lang_hooks.types.type_for_size (size, 1);
- if (!type || TYPE_PRECISION (type) != size)
- type = build_nonstandard_integer_type (size, 1);
- gcc_assert (type);
- var = build3 (BIT_FIELD_REF, type, NULL_TREE,
- bitsize_int (size), bitsize_int (bit));
-
- block = instantiate_missing_elements_1 (elt, var, type);
- gcc_assert (block && block->is_scalar);
-
- var = block->replacement;
- block->in_bitfld_block = 2;
+/* Construct an expression that would reference a part of aggregate *EXPR of
+ type TYPE at the given OFFSET of the type EXP_TYPE. If EXPR is NULL, the
+ function only determines whether it can build such a reference without
+ actually doing it.
- /* Add the member fields to the group, such that they access
- portions of the group variable. */
+ FIXME: Eventually this should be replaced with
+ maybe_fold_offset_to_reference() from tree-ssa-ccp.c but that requires a
+ minor rewrite of fold_stmt.
+ */
- for (f = first; f != TREE_CHAIN (prev); f = TREE_CHAIN (f))
- {
- tree field_type = canon_type_for_field (f, elt->element);
- struct sra_elt *fld = lookup_element (block, f, field_type, INSERT);
-
- gcc_assert (fld && fld->is_scalar && !fld->replacement);
-
- fld->replacement = fold_build3 (BIT_FIELD_REF, field_type, var,
- bitsize_int (TYPE_PRECISION (field_type)),
- bitsize_int
- ((TREE_INT_CST_LOW (DECL_FIELD_OFFSET (f))
- * BITS_PER_UNIT
- + (TREE_INT_CST_LOW
- (DECL_FIELD_BIT_OFFSET (f)))
- - (TREE_INT_CST_LOW
- (TREE_OPERAND (block->element, 2))))
- & ~alchk));
- fld->in_bitfld_block = 1;
- }
-
- return prev;
-}
-
-static void
-instantiate_missing_elements (struct sra_elt *elt)
+static bool
+build_ref_for_offset (tree *expr, tree type, HOST_WIDE_INT offset,
+ tree exp_type, bool allow_ptr)
{
- tree type = elt->type;
-
- switch (TREE_CODE (type))
+ if (allow_ptr && POINTER_TYPE_P (type))
{
- case RECORD_TYPE:
- {
- tree f;
- for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
- if (TREE_CODE (f) == FIELD_DECL)
- {
- tree last = try_instantiate_multiple_fields (elt, f);
-
- if (last != f)
- {
- f = last;
- continue;
- }
-
- instantiate_missing_elements_1 (elt, f,
- canon_type_for_field
- (f, elt->element));
- }
- break;
- }
-
- case ARRAY_TYPE:
- {
- tree i, max, subtype;
-
- i = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
- max = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
- subtype = TREE_TYPE (type);
-
- while (1)
- {
- instantiate_missing_elements_1 (elt, i, subtype);
- if (tree_int_cst_equal (i, max))
- break;
- i = int_const_binop (PLUS_EXPR, i, integer_one_node, true);
- }
-
- break;
- }
-
- case COMPLEX_TYPE:
type = TREE_TYPE (type);
- instantiate_missing_elements_1 (elt, integer_zero_node, type);
- instantiate_missing_elements_1 (elt, integer_one_node, type);
- break;
-
- default:
- gcc_unreachable ();
+ if (expr)
+ *expr = fold_build1 (INDIRECT_REF, type, *expr);
}
-}
-/* Return true if there is only one non aggregate field in the record, TYPE.
- Return false otherwise. */
-
-static bool
-single_scalar_field_in_record_p (tree type)
-{
- int num_fields = 0;
- tree field;
- if (TREE_CODE (type) != RECORD_TYPE)
- return false;
-
- for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
- if (TREE_CODE (field) == FIELD_DECL)
- {
- num_fields++;
-
- if (num_fields == 2)
- return false;
-
- if (AGGREGATE_TYPE_P (TREE_TYPE (field)))
- return false;
- }
-
- return true;
+ return build_ref_for_offset_1 (expr, type, offset, exp_type);
}
-/* Make one pass across an element tree deciding whether to perform block
- or element copies. If we decide on element copies, instantiate all
- elements. Return true if there are any instantiated sub-elements. */
+/* The very first phase of intraprocedural SRA. It marks in candidate_bitmap
+ those with type which is suitable for scalarization. */
static bool
-decide_block_copy (struct sra_elt *elt)
+find_var_candidates (void)
{
- struct sra_elt *c;
- bool any_inst;
-
- /* We shouldn't be invoked on groups of sub-elements as they must
- behave like their parent as far as block copy is concerned. */
- gcc_assert (!elt->is_group);
+ tree var, type;
+ referenced_var_iterator rvi;
+ bool ret = false;
- /* If scalarization is disabled, respect it. */
- if (elt->cannot_scalarize)
+ FOR_EACH_REFERENCED_VAR (var, rvi)
{
- elt->use_block_copy = 1;
+ if (TREE_CODE (var) != VAR_DECL && TREE_CODE (var) != PARM_DECL)
+ continue;
+ type = TREE_TYPE (var);
+
+ if (!AGGREGATE_TYPE_P (type)
+ || needs_to_live_in_memory (var)
+ || TREE_THIS_VOLATILE (var)
+ || !COMPLETE_TYPE_P (type)
+ || !host_integerp (TYPE_SIZE (type), 1)
+ || tree_low_cst (TYPE_SIZE (type), 1) == 0
+ || type_internals_preclude_sra_p (type))
+ continue;
- if (dump_file)
- {
- fputs ("Scalarization disabled for ", dump_file);
- dump_sra_elt_name (dump_file, elt);
- fputc ('\n', dump_file);
- }
+ bitmap_set_bit (candidate_bitmap, DECL_UID (var));
- /* Disable scalarization of sub-elements */
- for (c = elt->children; c; c = c->sibling)
+ if (dump_file && (dump_flags & TDF_DETAILS))
{
- c->cannot_scalarize = 1;
- decide_block_copy (c);
+ fprintf (dump_file, "Candidate (%d): ", DECL_UID (var));
+ print_generic_expr (dump_file, var, 0);
+ fprintf (dump_file, "\n");
}
+ ret = true;
+ }
- /* Groups behave like their parent. */
- for (c = elt->groups; c; c = c->sibling)
- {
- c->cannot_scalarize = 1;
- c->use_block_copy = 1;
- }
+ return ret;
+}
- return false;
- }
+/* Sort all accesses for the given variable, check for partial overlaps and
+ return NULL if there are any. If there are none, pick a representative for
+ each combination of offset and size and create a linked list out of them.
+ Return the pointer to the first representative and make sure it is the first
+ one in the vector of accesses. */
- /* Don't decide if we've no uses and no groups. */
- if (elt->n_uses == 0 && elt->n_copies == 0 && elt->groups == NULL)
- ;
+static struct access *
+sort_and_splice_var_accesses (tree var)
+{
+ int i, j, access_count;
+ struct access *res, **prev_acc_ptr = &res;
+ VEC (access_p, heap) *access_vec;
+ bool first = true;
+ HOST_WIDE_INT low = -1, high = 0;
- else if (!elt->is_scalar)
- {
- tree size_tree = TYPE_SIZE_UNIT (elt->type);
- bool use_block_copy = true;
-
- /* Tradeoffs for COMPLEX types pretty much always make it better
- to go ahead and split the components. */
- if (TREE_CODE (elt->type) == COMPLEX_TYPE)
- use_block_copy = false;
-
- /* Don't bother trying to figure out the rest if the structure is
- so large we can't do easy arithmetic. This also forces block
- copies for variable sized structures. */
- else if (host_integerp (size_tree, 1))
- {
- unsigned HOST_WIDE_INT full_size, inst_size = 0;
- unsigned int max_size, max_count, inst_count, full_count;
-
- /* If the sra-max-structure-size parameter is 0, then the
- user has not overridden the parameter and we can choose a
- sensible default. */
- max_size = SRA_MAX_STRUCTURE_SIZE
- ? SRA_MAX_STRUCTURE_SIZE
- : MOVE_RATIO (optimize_function_for_speed_p (cfun)) * UNITS_PER_WORD;
- max_count = SRA_MAX_STRUCTURE_COUNT
- ? SRA_MAX_STRUCTURE_COUNT
- : MOVE_RATIO (optimize_function_for_speed_p (cfun));
-
- full_size = tree_low_cst (size_tree, 1);
- full_count = count_type_elements (elt->type, false);
- inst_count = sum_instantiated_sizes (elt, &inst_size);
-
- /* If there is only one scalar field in the record, don't block copy. */
- if (single_scalar_field_in_record_p (elt->type))
- use_block_copy = false;
-
- /* ??? What to do here. If there are two fields, and we've only
- instantiated one, then instantiating the other is clearly a win.
- If there are a large number of fields then the size of the copy
- is much more of a factor. */
-
- /* If the structure is small, and we've made copies, go ahead
- and instantiate, hoping that the copies will go away. */
- if (full_size <= max_size
- && (full_count - inst_count) <= max_count
- && elt->n_copies > elt->n_uses)
- use_block_copy = false;
- else if (inst_count * 100 >= full_count * SRA_FIELD_STRUCTURE_RATIO
- && inst_size * 100 >= full_size * SRA_FIELD_STRUCTURE_RATIO)
- use_block_copy = false;
-
- /* In order to avoid block copy, we have to be able to instantiate
- all elements of the type. See if this is possible. */
- if (!use_block_copy
- && (!can_completely_scalarize_p (elt)
- || !type_can_instantiate_all_elements (elt->type)))
- use_block_copy = true;
- }
+ access_vec = get_base_access_vector (var);
+ if (!access_vec)
+ return NULL;
+ access_count = VEC_length (access_p, access_vec);
- elt->use_block_copy = use_block_copy;
+ /* Sort by <OFFSET, SIZE>. */
+ qsort (VEC_address (access_p, access_vec), access_count, sizeof (access_p),
+ compare_access_positions);
- /* Groups behave like their parent. */
- for (c = elt->groups; c; c = c->sibling)
- c->use_block_copy = use_block_copy;
+ i = 0;
+ while (i < access_count)
+ {
+ struct access *access = VEC_index (access_p, access_vec, i);
+ bool modification = access->write;
+ bool grp_read = !access->write;
+ bool grp_partial_lhs = access->grp_partial_lhs;
+ bool first_scalar = is_gimple_reg_type (access->type);
+ bool unscalarizable_region = access->grp_unscalarizable_region;
- if (dump_file)
+ if (first || access->offset >= high)
{
- fprintf (dump_file, "Using %s for ",
- use_block_copy ? "block-copy" : "element-copy");
- dump_sra_elt_name (dump_file, elt);
- fputc ('\n', dump_file);
+ first = false;
+ low = access->offset;
+ high = access->offset + access->size;
}
+ else if (access->offset > low && access->offset + access->size > high)
+ return NULL;
+ else
+ gcc_assert (access->offset >= low
+ && access->offset + access->size <= high);
- if (!use_block_copy)
+ j = i + 1;
+ while (j < access_count)
{
- instantiate_missing_elements (elt);
- return true;
+ struct access *ac2 = VEC_index (access_p, access_vec, j);
+ if (ac2->offset != access->offset || ac2->size != access->size)
+ break;
+ modification |= ac2->write;
+ grp_read |= !ac2->write;
+ grp_partial_lhs |= ac2->grp_partial_lhs;
+ unscalarizable_region |= ac2->grp_unscalarizable_region;
+ relink_to_new_repr (access, ac2);
+
+ /* If there are both aggregate-type and scalar-type accesses with
+ this combination of size and offset, the comparison function
+ should have put the scalars first. */
+ gcc_assert (first_scalar || !is_gimple_reg_type (ac2->type));
+ ac2->group_representative = access;
+ j++;
}
- }
- any_inst = elt->replacement != NULL;
+ i = j;
- for (c = elt->children; c ; c = c->sibling)
- any_inst |= decide_block_copy (c);
+ access->group_representative = access;
+ access->grp_write = modification;
+ access->grp_read = grp_read;
+ access->grp_partial_lhs = grp_partial_lhs;
+ access->grp_unscalarizable_region = unscalarizable_region;
+ if (access->first_link)
+ add_access_to_work_queue (access);
- return any_inst;
+ *prev_acc_ptr = access;
+ prev_acc_ptr = &access->next_grp;
+ }
+
+ gcc_assert (res == VEC_index (access_p, access_vec, 0));
+ return res;
}
-/* Entry point to phase 3. Instantiate scalar replacement variables. */
+/* Create a variable for the given ACCESS which determines the type, name and a
+ few other properties. Return the variable declaration and store it also to
+ ACCESS->replacement. */
-static void
-decide_instantiations (void)
+static tree
+create_access_replacement (struct access *access)
{
- unsigned int i;
- bool cleared_any;
- bitmap_head done_head;
- bitmap_iterator bi;
+ tree repl;
+
+ repl = create_tmp_var (access->type, "SR");
+ get_var_ann (repl);
+ add_referenced_var (repl);
+ mark_sym_for_renaming (repl);
- /* We cannot clear bits from a bitmap we're iterating over,
- so save up all the bits to clear until the end. */
- bitmap_initialize (&done_head, &bitmap_default_obstack);
- cleared_any = false;
+ if (!access->grp_partial_lhs
+ && (TREE_CODE (access->type) == COMPLEX_TYPE
+ || TREE_CODE (access->type) == VECTOR_TYPE))
+ DECL_GIMPLE_REG_P (repl) = 1;
- EXECUTE_IF_SET_IN_BITMAP (sra_candidates, 0, i, bi)
+ DECL_SOURCE_LOCATION (repl) = DECL_SOURCE_LOCATION (access->base);
+ DECL_ARTIFICIAL (repl) = 1;
+
+ if (DECL_NAME (access->base)
+ && !DECL_IGNORED_P (access->base)
+ && !DECL_ARTIFICIAL (access->base))
{
- tree var = referenced_var (i);
- struct sra_elt *elt = lookup_element (NULL, var, NULL, NO_INSERT);
- if (elt)
- {
- decide_instantiation_1 (elt, 0, 0);
- if (!decide_block_copy (elt))
- elt = NULL;
- }
- if (!elt)
- {
- bitmap_set_bit (&done_head, i);
- cleared_any = true;
- }
+ char *pretty_name = make_fancy_name (access->expr);
+
+ DECL_NAME (repl) = get_identifier (pretty_name);
+ obstack_free (&name_obstack, pretty_name);
+
+ SET_DECL_DEBUG_EXPR (repl, access->expr);
+ DECL_DEBUG_EXPR_IS_FROM (repl) = 1;
+ DECL_IGNORED_P (repl) = 0;
}
- if (cleared_any)
+ DECL_IGNORED_P (repl) = DECL_IGNORED_P (access->base);
+ TREE_NO_WARNING (repl) = TREE_NO_WARNING (access->base);
+
+ if (dump_file)
{
- bitmap_and_compl_into (sra_candidates, &done_head);
- bitmap_and_compl_into (needs_copy_in, &done_head);
+ fprintf (dump_file, "Created a replacement for ");
+ print_generic_expr (dump_file, access->base, 0);
+ fprintf (dump_file, " offset: %u, size: %u: ",
+ (unsigned) access->offset, (unsigned) access->size);
+ print_generic_expr (dump_file, repl, 0);
+ fprintf (dump_file, "\n");
}
- bitmap_clear (&done_head);
-
- mark_set_for_renaming (sra_candidates);
- if (dump_file)
- fputc ('\n', dump_file);
+ return repl;
}
-
-/* Phase Four: Update the function to match the replacements created. */
+/* Return ACCESS scalar replacement, create it if it does not exist yet. */
-/* Mark all the variables in virtual operands in all the statements in
- LIST for renaming. */
-
-static void
-mark_all_v_defs_seq (gimple_seq seq)
+static inline tree
+get_access_replacement (struct access *access)
{
- gimple_stmt_iterator gsi;
+ gcc_assert (access->grp_to_be_replaced);
+
+ if (access->replacement_decl)
+ return access->replacement_decl;
- for (gsi = gsi_start (seq); !gsi_end_p (gsi); gsi_next (&gsi))
- update_stmt_if_modified (gsi_stmt (gsi));
+ access->replacement_decl = create_access_replacement (access);
+ return access->replacement_decl;
}
-/* Mark every replacement under ELT with TREE_NO_WARNING. */
+/* Build a subtree of accesses rooted in *ACCESS, and move the pointer in the
+ linked list along the way. Stop when *ACCESS is NULL or the access pointed
+ to it is not "within" the root. */
static void
-mark_no_warning (struct sra_elt *elt)
+build_access_subtree (struct access **access)
{
- if (!elt->all_no_warning)
+ struct access *root = *access, *last_child = NULL;
+ HOST_WIDE_INT limit = root->offset + root->size;
+
+ *access = (*access)->next_grp;
+ while (*access && (*access)->offset + (*access)->size <= limit)
{
- if (elt->replacement)
- TREE_NO_WARNING (elt->replacement) = 1;
+ if (!last_child)
+ root->first_child = *access;
else
- {
- struct sra_elt *c;
- FOR_EACH_ACTUAL_CHILD (c, elt)
- mark_no_warning (c);
- }
- elt->all_no_warning = true;
+ last_child->next_sibling = *access;
+ last_child = *access;
+
+ build_access_subtree (access);
}
}
-/* Build a single level component reference to ELT rooted at BASE. */
+/* Build a tree of access representatives, ACCESS is the pointer to the first
+ one, others are linked in a list by the next_grp field. Decide about scalar
+ replacements on the way, return true iff any are to be created. */
-static tree
-generate_one_element_ref (struct sra_elt *elt, tree base)
+static void
+build_access_trees (struct access *access)
{
- switch (TREE_CODE (TREE_TYPE (base)))
+ while (access)
{
- case RECORD_TYPE:
- {
- tree field = elt->element;
+ struct access *root = access;
- /* We can't test elt->in_bitfld_block here because, when this is
- called from instantiate_element, we haven't set this field
- yet. */
- if (TREE_CODE (field) == BIT_FIELD_REF)
- {
- tree ret = unshare_expr (field);
- TREE_OPERAND (ret, 0) = base;
- return ret;
- }
-
- /* Watch out for compatible records with differing field lists. */
- if (DECL_FIELD_CONTEXT (field) != TYPE_MAIN_VARIANT (TREE_TYPE (base)))
- field = find_compatible_field (TREE_TYPE (base), field);
-
- return build3 (COMPONENT_REF, elt->type, base, field, NULL);
- }
-
- case ARRAY_TYPE:
- if (TREE_CODE (elt->element) == RANGE_EXPR)
- return build4 (ARRAY_RANGE_REF, elt->type, base,
- TREE_OPERAND (elt->element, 0), NULL, NULL);
- else
- return build4 (ARRAY_REF, elt->type, base, elt->element, NULL, NULL);
-
- case COMPLEX_TYPE:
- if (elt->element == integer_zero_node)
- return build1 (REALPART_EXPR, elt->type, base);
- else
- return build1 (IMAGPART_EXPR, elt->type, base);
-
- default:
- gcc_unreachable ();
+ build_access_subtree (&access);
+ root->next_grp = access;
}
}
-/* Build a full component reference to ELT rooted at its native variable. */
+/* Analyze the subtree of accesses rooted in ROOT, scheduling replacements when
+ both seeming beneficial and when ALLOW_REPLACEMENTS allows it. Also set
+ all sorts of access flags appropriately along the way, notably always ser
+ grp_read when MARK_READ is true and grp_write when MARK_WRITE is true. */
-static tree
-generate_element_ref (struct sra_elt *elt)
+static bool
+analyze_access_subtree (struct access *root, bool allow_replacements,
+ bool mark_read, bool mark_write)
{
- if (elt->parent)
- return generate_one_element_ref (elt, generate_element_ref (elt->parent));
- else
- return elt->element;
-}
+ struct access *child;
+ HOST_WIDE_INT limit = root->offset + root->size;
+ HOST_WIDE_INT covered_to = root->offset;
+ bool scalar = is_gimple_reg_type (root->type);
+ bool hole = false, sth_created = false;
-/* Return true if BF is a bit-field that we can handle like a scalar. */
+ if (mark_read)
+ root->grp_read = true;
+ else if (root->grp_read)
+ mark_read = true;
-static bool
-scalar_bitfield_p (tree bf)
-{
- return (TREE_CODE (bf) == BIT_FIELD_REF
- && (is_gimple_reg (TREE_OPERAND (bf, 0))
- || (TYPE_MODE (TREE_TYPE (TREE_OPERAND (bf, 0))) != BLKmode
- && (!TREE_SIDE_EFFECTS (TREE_OPERAND (bf, 0))
- || (GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE
- (TREE_OPERAND (bf, 0))))
- <= BITS_PER_WORD)))));
-}
+ if (mark_write)
+ root->grp_write = true;
+ else if (root->grp_write)
+ mark_write = true;
-/* Create an assignment statement from SRC to DST. */
+ if (root->grp_unscalarizable_region)
+ allow_replacements = false;
-static gimple_seq
-sra_build_assignment (tree dst, tree src)
-{
- gimple stmt;
- gimple_seq seq = NULL, seq2 = NULL;
- /* Turning BIT_FIELD_REFs into bit operations enables other passes
- to do a much better job at optimizing the code.
- From dst = BIT_FIELD_REF <var, sz, off> we produce
-
- SR.1 = (scalar type) var;
- SR.2 = SR.1 >> off;
- SR.3 = SR.2 & ((1 << sz) - 1);
- ... possible sign extension of SR.3 ...
- dst = (destination type) SR.3;
- */
- if (scalar_bitfield_p (src))
+ for (child = root->first_child; child; child = child->next_sibling)
{
- tree var, shift, width;
- tree utype, stype;
- bool unsignedp = (INTEGRAL_TYPE_P (TREE_TYPE (src))
- ? TYPE_UNSIGNED (TREE_TYPE (src)) : true);
- struct gimplify_ctx gctx;
-
- var = TREE_OPERAND (src, 0);
- width = TREE_OPERAND (src, 1);
- /* The offset needs to be adjusted to a right shift quantity
- depending on the endianness. */
- if (BYTES_BIG_ENDIAN)
- {
- tree tmp = size_binop (PLUS_EXPR, width, TREE_OPERAND (src, 2));
- shift = size_binop (MINUS_EXPR, TYPE_SIZE (TREE_TYPE (var)), tmp);
- }
+ if (!hole && child->offset < covered_to)
+ hole = true;
else
- shift = TREE_OPERAND (src, 2);
-
- /* In weird cases we have non-integral types for the source or
- destination object.
- ??? For unknown reasons we also want an unsigned scalar type. */
- stype = TREE_TYPE (var);
- if (!INTEGRAL_TYPE_P (stype))
- stype = lang_hooks.types.type_for_size (TREE_INT_CST_LOW
- (TYPE_SIZE (stype)), 1);
- else if (!TYPE_UNSIGNED (stype))
- stype = unsigned_type_for (stype);
-
- utype = TREE_TYPE (dst);
- if (!INTEGRAL_TYPE_P (utype))
- utype = lang_hooks.types.type_for_size (TREE_INT_CST_LOW
- (TYPE_SIZE (utype)), 1);
- else if (!TYPE_UNSIGNED (utype))
- utype = unsigned_type_for (utype);
-
- /* Convert the base var of the BIT_FIELD_REF to the scalar type
- we use for computation if we cannot use it directly. */
- if (INTEGRAL_TYPE_P (TREE_TYPE (var)))
- var = fold_convert (stype, var);
- else
- var = fold_build1 (VIEW_CONVERT_EXPR, stype, var);
-
- if (!integer_zerop (shift))
- var = fold_build2 (RSHIFT_EXPR, stype, var, shift);
+ covered_to += child->size;
- /* If we need a masking operation, produce one. */
- if (TREE_INT_CST_LOW (width) == TYPE_PRECISION (stype))
- unsignedp = true;
- else
- {
- tree one = build_int_cst_wide (stype, 1, 0);
- tree mask = int_const_binop (LSHIFT_EXPR, one, width, 0);
- mask = int_const_binop (MINUS_EXPR, mask, one, 0);
- var = fold_build2 (BIT_AND_EXPR, stype, var, mask);
- }
+ sth_created |= analyze_access_subtree (child, allow_replacements,
+ mark_read, mark_write);
- /* After shifting and masking, convert to the target type. */
- var = fold_convert (utype, var);
+ root->grp_unscalarized_data |= child->grp_unscalarized_data;
+ hole |= !child->grp_covered;
+ }
- /* Perform sign extension, if required.
- ??? This should never be necessary. */
- if (!unsignedp)
+ if (allow_replacements && scalar && !root->first_child)
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
{
- tree signbit = int_const_binop (LSHIFT_EXPR,
- build_int_cst_wide (utype, 1, 0),
- size_binop (MINUS_EXPR, width,
- bitsize_int (1)), 0);
-
- var = fold_build2 (BIT_XOR_EXPR, utype, var, signbit);
- var = fold_build2 (MINUS_EXPR, utype, var, signbit);
+ fprintf (dump_file, "Marking ");
+ print_generic_expr (dump_file, root->base, 0);
+ fprintf (dump_file, " offset: %u, size: %u: ",
+ (unsigned) root->offset, (unsigned) root->size);
+ fprintf (dump_file, " to be replaced.\n");
}
- /* fold_build3 (BIT_FIELD_REF, ...) sometimes returns a cast. */
- STRIP_NOPS (dst);
-
- /* Finally, move and convert to the destination. */
- if (INTEGRAL_TYPE_P (TREE_TYPE (dst)))
- var = fold_convert (TREE_TYPE (dst), var);
- else
- var = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (dst), var);
-
- push_gimplify_context (&gctx);
- gctx.allow_rhs_cond_expr = true;
-
- gimplify_assign (dst, var, &seq);
-
- if (gimple_referenced_vars (cfun))
- for (var = gctx.temps; var; var = TREE_CHAIN (var))
- {
- add_referenced_var (var);
- mark_sym_for_renaming (var);
- }
- pop_gimplify_context (NULL);
-
- return seq;
+ root->grp_to_be_replaced = 1;
+ sth_created = true;
+ hole = false;
}
+ else if (covered_to < limit)
+ hole = true;
- /* fold_build3 (BIT_FIELD_REF, ...) sometimes returns a cast. */
- if (CONVERT_EXPR_P (dst))
+ if (sth_created && !hole)
{
- STRIP_NOPS (dst);
- src = fold_convert (TREE_TYPE (dst), src);
+ root->grp_covered = 1;
+ return true;
}
- /* It was hoped that we could perform some type sanity checking
- here, but since front-ends can emit accesses of fields in types
- different from their nominal types and copy structures containing
- them as a whole, we'd have to handle such differences here.
- Since such accesses under different types require compatibility
- anyway, there's little point in making tests and/or adding
- conversions to ensure the types of src and dst are the same.
- So we just assume type differences at this point are ok.
- The only exception we make here are pointer types, which can be different
- in e.g. structurally equal, but non-identical RECORD_TYPEs. */
- else if (POINTER_TYPE_P (TREE_TYPE (dst))
- && !useless_type_conversion_p (TREE_TYPE (dst), TREE_TYPE (src)))
- src = fold_convert (TREE_TYPE (dst), src);
-
- /* ??? Only call the gimplifier if we need to. Otherwise we may
- end up substituting with DECL_VALUE_EXPR - see PR37380. */
- if (!handled_component_p (src)
- && !SSA_VAR_P (src))
+ if (root->grp_write || TREE_CODE (root->base) == PARM_DECL)
+ root->grp_unscalarized_data = 1; /* not covered and written to */
+ if (sth_created)
+ return true;
+ return false;
+}
+
+/* Analyze all access trees linked by next_grp by the means of
+ analyze_access_subtree. */
+static bool
+analyze_access_trees (struct access *access)
+{
+ bool ret = false;
+
+ while (access)
{
- src = force_gimple_operand (src, &seq2, false, NULL_TREE);
- gimple_seq_add_seq (&seq, seq2);
+ if (analyze_access_subtree (access, true, false, false))
+ ret = true;
+ access = access->next_grp;
}
- stmt = gimple_build_assign (dst, src);
- gimple_seq_add_stmt (&seq, stmt);
- return seq;
-}
-/* BIT_FIELD_REFs must not be shared. sra_build_elt_assignment()
- takes care of assignments, but we must create copies for uses. */
-#define REPLDUP(t) (TREE_CODE (t) != BIT_FIELD_REF ? (t) : unshare_expr (t))
+ return ret;
+}
-/* Emit an assignment from SRC to DST, but if DST is a scalarizable
- BIT_FIELD_REF, turn it into bit operations. */
+/* Return true iff a potential new child of LACC at offset OFFSET and with size
+ SIZE would conflict with an already existing one. If exactly such a child
+ already exists in LACC, store a pointer to it in EXACT_MATCH. */
-static gimple_seq
-sra_build_bf_assignment (tree dst, tree src)
+static bool
+child_would_conflict_in_lacc (struct access *lacc, HOST_WIDE_INT norm_offset,
+ HOST_WIDE_INT size, struct access **exact_match)
{
- tree var, type, utype, tmp, tmp2, tmp3;
- gimple_seq seq;
- gimple stmt;
- tree cst, cst2, mask;
- tree minshift, maxshift;
+ struct access *child;
- if (TREE_CODE (dst) != BIT_FIELD_REF)
- return sra_build_assignment (dst, src);
+ for (child = lacc->first_child; child; child = child->next_sibling)
+ {
+ if (child->offset == norm_offset && child->size == size)
+ {
+ *exact_match = child;
+ return true;
+ }
- var = TREE_OPERAND (dst, 0);
+ if (child->offset < norm_offset + size
+ && child->offset + child->size > norm_offset)
+ return true;
+ }
- if (!scalar_bitfield_p (dst))
- return sra_build_assignment (REPLDUP (dst), src);
+ return false;
+}
- seq = NULL;
+/* Set the expr of TARGET to one just like MODEL but with is own base at the
+ bottom of the handled components. */
- cst = fold_convert (bitsizetype, TREE_OPERAND (dst, 2));
- cst2 = size_binop (PLUS_EXPR,
- fold_convert (bitsizetype, TREE_OPERAND (dst, 1)),
- cst);
+static void
+duplicate_expr_for_different_base (struct access *target,
+ struct access *model)
+{
+ tree t, expr = unshare_expr (model->expr);
- if (BYTES_BIG_ENDIAN)
- {
- maxshift = size_binop (MINUS_EXPR, TYPE_SIZE (TREE_TYPE (var)), cst);
- minshift = size_binop (MINUS_EXPR, TYPE_SIZE (TREE_TYPE (var)), cst2);
- }
- else
- {
- maxshift = cst2;
- minshift = cst;
- }
+ gcc_assert (handled_component_p (expr));
+ t = expr;
+ while (handled_component_p (TREE_OPERAND (t, 0)))
+ t = TREE_OPERAND (t, 0);
+ gcc_assert (TREE_OPERAND (t, 0) == model->base);
+ TREE_OPERAND (t, 0) = target->base;
- type = TREE_TYPE (var);
- if (!INTEGRAL_TYPE_P (type))
- type = lang_hooks.types.type_for_size
- (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (var))), 1);
- if (TYPE_UNSIGNED (type))
- utype = type;
- else
- utype = unsigned_type_for (type);
+ target->expr = expr;
+}
- mask = build_int_cst_wide (utype, 1, 0);
- if (TREE_INT_CST_LOW (maxshift) == TYPE_PRECISION (utype))
- cst = build_int_cst_wide (utype, 0, 0);
- else
- cst = int_const_binop (LSHIFT_EXPR, mask, maxshift, true);
- if (integer_zerop (minshift))
- cst2 = mask;
- else
- cst2 = int_const_binop (LSHIFT_EXPR, mask, minshift, true);
- mask = int_const_binop (MINUS_EXPR, cst, cst2, true);
- mask = fold_build1 (BIT_NOT_EXPR, utype, mask);
- if (TYPE_MAIN_VARIANT (utype) != TYPE_MAIN_VARIANT (TREE_TYPE (var))
- && !integer_zerop (mask))
- {
- tmp = var;
- if (!is_gimple_variable (tmp))
- tmp = unshare_expr (var);
- else
- TREE_NO_WARNING (var) = true;
+/* Create a new child access of PARENT, with all properties just like MODEL
+ except for its offset and with its grp_write false and grp_read true.
+ Return the new access. Note that this access is created long after all
+ splicing and sorting, it's not located in any access vector and is
+ automatically a representative of its group. */
- tmp2 = make_rename_temp (utype, "SR");
+static struct access *
+create_artificial_child_access (struct access *parent, struct access *model,
+ HOST_WIDE_INT new_offset)
+{
+ struct access *access;
+ struct access **child;
- if (INTEGRAL_TYPE_P (TREE_TYPE (var)))
- tmp = fold_convert (utype, tmp);
- else
- tmp = fold_build1 (VIEW_CONVERT_EXPR, utype, tmp);
+ gcc_assert (!model->grp_unscalarizable_region);
- stmt = gimple_build_assign (tmp2, tmp);
- gimple_seq_add_stmt (&seq, stmt);
- }
- else
- tmp2 = var;
+ access = (struct access *) pool_alloc (access_pool);
+ memset (access, 0, sizeof (struct access));
+ access->base = parent->base;
+ access->offset = new_offset;
+ access->size = model->size;
+ duplicate_expr_for_different_base (access, model);
+ access->type = model->type;
+ access->grp_write = true;
+ access->grp_read = false;
- if (!integer_zerop (mask))
- {
- tmp = make_rename_temp (utype, "SR");
- stmt = gimple_build_assign (tmp, fold_build2 (BIT_AND_EXPR, utype,
- tmp2, mask));
- gimple_seq_add_stmt (&seq, stmt);
- }
- else
- tmp = mask;
+ child = &parent->first_child;
+ while (*child && (*child)->offset < new_offset)
+ child = &(*child)->next_sibling;
- if (is_gimple_reg (src) && INTEGRAL_TYPE_P (TREE_TYPE (src)))
- tmp2 = src;
- else if (INTEGRAL_TYPE_P (TREE_TYPE (src)))
- {
- gimple_seq tmp_seq;
- tmp2 = make_rename_temp (TREE_TYPE (src), "SR");
- tmp_seq = sra_build_assignment (tmp2, src);
- gimple_seq_add_seq (&seq, tmp_seq);
- }
- else
- {
- gimple_seq tmp_seq;
- tmp2 = make_rename_temp
- (lang_hooks.types.type_for_size
- (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (src))),
- 1), "SR");
- tmp_seq = sra_build_assignment (tmp2, fold_build1 (VIEW_CONVERT_EXPR,
- TREE_TYPE (tmp2), src));
- gimple_seq_add_seq (&seq, tmp_seq);
- }
+ access->next_sibling = *child;
+ *child = access;
- if (!TYPE_UNSIGNED (TREE_TYPE (tmp2)))
- {
- gimple_seq tmp_seq;
- tree ut = unsigned_type_for (TREE_TYPE (tmp2));
- tmp3 = make_rename_temp (ut, "SR");
- tmp2 = fold_convert (ut, tmp2);
- tmp_seq = sra_build_assignment (tmp3, tmp2);
- gimple_seq_add_seq (&seq, tmp_seq);
-
- tmp2 = fold_build1 (BIT_NOT_EXPR, utype, mask);
- tmp2 = int_const_binop (RSHIFT_EXPR, tmp2, minshift, true);
- tmp2 = fold_convert (ut, tmp2);
- tmp2 = fold_build2 (BIT_AND_EXPR, ut, tmp3, tmp2);
-
- if (tmp3 != tmp2)
- {
- tmp3 = make_rename_temp (ut, "SR");
- tmp_seq = sra_build_assignment (tmp3, tmp2);
- gimple_seq_add_seq (&seq, tmp_seq);
- }
+ return access;
+}
- tmp2 = tmp3;
- }
- if (TYPE_MAIN_VARIANT (TREE_TYPE (tmp2)) != TYPE_MAIN_VARIANT (utype))
- {
- gimple_seq tmp_seq;
- tmp3 = make_rename_temp (utype, "SR");
- tmp2 = fold_convert (utype, tmp2);
- tmp_seq = sra_build_assignment (tmp3, tmp2);
- gimple_seq_add_seq (&seq, tmp_seq);
- tmp2 = tmp3;
- }
+/* Propagate all subaccesses of RACC across an assignment link to LACC. Return
+ true if any new subaccess was created. Additionally, if RACC is a scalar
+ access but LACC is not, change the type of the latter. */
- if (!integer_zerop (minshift))
- {
- tmp3 = make_rename_temp (utype, "SR");
- stmt = gimple_build_assign (tmp3, fold_build2 (LSHIFT_EXPR, utype,
- tmp2, minshift));
- gimple_seq_add_stmt (&seq, stmt);
- tmp2 = tmp3;
- }
+static bool
+propagate_subacesses_accross_link (struct access *lacc, struct access *racc)
+{
+ struct access *rchild;
+ HOST_WIDE_INT norm_delta = lacc->offset - racc->offset;
- if (utype != TREE_TYPE (var))
- tmp3 = make_rename_temp (utype, "SR");
- else
- tmp3 = var;
- stmt = gimple_build_assign (tmp3, fold_build2 (BIT_IOR_EXPR, utype,
- tmp, tmp2));
- gimple_seq_add_stmt (&seq, stmt);
+ bool ret = false;
+
+ if (is_gimple_reg_type (lacc->type)
+ || lacc->grp_unscalarizable_region
+ || racc->grp_unscalarizable_region)
+ return false;
- if (tmp3 != var)
+ if (!lacc->first_child && !racc->first_child
+ && is_gimple_reg_type (racc->type))
{
- if (TREE_TYPE (var) == type)
- stmt = gimple_build_assign (var, fold_convert (type, tmp3));
- else
- stmt = gimple_build_assign (var, fold_build1 (VIEW_CONVERT_EXPR,
- TREE_TYPE (var), tmp3));
- gimple_seq_add_stmt (&seq, stmt);
+ duplicate_expr_for_different_base (lacc, racc);
+ lacc->type = racc->type;
+ return false;
}
- return seq;
-}
-
-/* Expand an assignment of SRC to the scalarized representation of
- ELT. If it is a field group, try to widen the assignment to cover
- the full variable. */
-
-static gimple_seq
-sra_build_elt_assignment (struct sra_elt *elt, tree src)
-{
- tree dst = elt->replacement;
- tree var, tmp, cst, cst2;
- gimple stmt;
- gimple_seq seq;
-
- if (TREE_CODE (dst) != BIT_FIELD_REF
- || !elt->in_bitfld_block)
- return sra_build_assignment (REPLDUP (dst), src);
-
- var = TREE_OPERAND (dst, 0);
-
- /* Try to widen the assignment to the entire variable.
- We need the source to be a BIT_FIELD_REF as well, such that, for
- BIT_FIELD_REF<d,sz,dp> = BIT_FIELD_REF<s,sz,sp>,
- by design, conditions are met such that we can turn it into
- d = BIT_FIELD_REF<s,dw,sp-dp>. */
- if (elt->in_bitfld_block == 2
- && TREE_CODE (src) == BIT_FIELD_REF)
+ for (rchild = racc->first_child; rchild; rchild = rchild->next_sibling)
{
- tmp = src;
- cst = TYPE_SIZE (TREE_TYPE (var));
- cst2 = size_binop (MINUS_EXPR, TREE_OPERAND (src, 2),
- TREE_OPERAND (dst, 2));
+ struct access *new_acc = NULL;
+ HOST_WIDE_INT norm_offset = rchild->offset + norm_delta;
- src = TREE_OPERAND (src, 0);
-
- /* Avoid full-width bit-fields. */
- if (integer_zerop (cst2)
- && tree_int_cst_equal (cst, TYPE_SIZE (TREE_TYPE (src))))
- {
- if (INTEGRAL_TYPE_P (TREE_TYPE (src))
- && !TYPE_UNSIGNED (TREE_TYPE (src)))
- src = fold_convert (unsigned_type_for (TREE_TYPE (src)), src);
-
- /* If a single conversion won't do, we'll need a statement
- list. */
- if (TYPE_MAIN_VARIANT (TREE_TYPE (var))
- != TYPE_MAIN_VARIANT (TREE_TYPE (src)))
- {
- gimple_seq tmp_seq;
- seq = NULL;
-
- if (!INTEGRAL_TYPE_P (TREE_TYPE (src)))
- src = fold_build1 (VIEW_CONVERT_EXPR,
- lang_hooks.types.type_for_size
- (TREE_INT_CST_LOW
- (TYPE_SIZE (TREE_TYPE (src))),
- 1), src);
- gcc_assert (TYPE_UNSIGNED (TREE_TYPE (src)));
-
- tmp = make_rename_temp (TREE_TYPE (src), "SR");
- stmt = gimple_build_assign (tmp, src);
- gimple_seq_add_stmt (&seq, stmt);
-
- tmp_seq = sra_build_assignment (var,
- fold_convert (TREE_TYPE (var),
- tmp));
- gimple_seq_add_seq (&seq, tmp_seq);
-
- return seq;
- }
+ if (rchild->grp_unscalarizable_region)
+ continue;
- src = fold_convert (TREE_TYPE (var), src);
- }
- else
+ if (child_would_conflict_in_lacc (lacc, norm_offset, rchild->size,
+ &new_acc))
{
- src = fold_convert (TREE_TYPE (var), tmp);
+ if (new_acc && rchild->first_child)
+ ret |= propagate_subacesses_accross_link (new_acc, rchild);
+ continue;
}
- return sra_build_assignment (var, src);
+ /* If a (part of) a union field is on the RHS of an assignment, it can
+ have sub-accesses which do not make sense on the LHS (PR 40351).
+ Check that this is not the case. */
+ if (!build_ref_for_offset (NULL, TREE_TYPE (lacc->base), norm_offset,
+ rchild->type, false))
+ continue;
+
+ new_acc = create_artificial_child_access (lacc, rchild, norm_offset);
+ if (racc->first_child)
+ propagate_subacesses_accross_link (new_acc, rchild);
+
+ ret = true;
}
- return sra_build_bf_assignment (dst, src);
+ return ret;
}
-/* Generate a set of assignment statements in *LIST_P to copy all
- instantiated elements under ELT to or from the equivalent structure
- rooted at EXPR. COPY_OUT controls the direction of the copy, with
- true meaning to copy out of EXPR into ELT. */
+/* Propagate all subaccesses across assignment links. */
static void
-generate_copy_inout (struct sra_elt *elt, bool copy_out, tree expr,
- gimple_seq *seq_p)
+propagate_all_subaccesses (void)
{
- struct sra_elt *c;
- gimple_seq tmp_seq;
- tree t;
-
- if (!copy_out && TREE_CODE (expr) == SSA_NAME
- && TREE_CODE (TREE_TYPE (expr)) == COMPLEX_TYPE)
+ while (work_queue_head)
{
- tree r, i;
+ struct access *racc = pop_access_from_work_queue ();
+ struct assign_link *link;
- c = lookup_element (elt, integer_zero_node, NULL, NO_INSERT);
- r = c->replacement;
- c = lookup_element (elt, integer_one_node, NULL, NO_INSERT);
- i = c->replacement;
+ gcc_assert (racc->first_link);
- t = build2 (COMPLEX_EXPR, elt->type, r, i);
- tmp_seq = sra_build_bf_assignment (expr, t);
- SSA_NAME_DEF_STMT (expr) = gimple_seq_last_stmt (tmp_seq);
- gimple_seq_add_seq (seq_p, tmp_seq);
- }
- else if (elt->replacement)
- {
- if (copy_out)
- tmp_seq = sra_build_elt_assignment (elt, expr);
- else
- tmp_seq = sra_build_bf_assignment (expr, REPLDUP (elt->replacement));
- gimple_seq_add_seq (seq_p, tmp_seq);
- }
- else
- {
- FOR_EACH_ACTUAL_CHILD (c, elt)
+ for (link = racc->first_link; link; link = link->next)
{
- t = generate_one_element_ref (c, unshare_expr (expr));
- generate_copy_inout (c, copy_out, t, seq_p);
+ struct access *lacc = link->lacc;
+
+ if (!bitmap_bit_p (candidate_bitmap, DECL_UID (lacc->base)))
+ continue;
+ lacc = lacc->group_representative;
+ if (propagate_subacesses_accross_link (lacc, racc)
+ && lacc->first_link)
+ add_access_to_work_queue (lacc);
}
}
}
-/* Generate a set of assignment statements in *LIST_P to copy all instantiated
- elements under SRC to their counterparts under DST. There must be a 1-1
- correspondence of instantiated elements. */
+/* Go through all accesses collected throughout the (intraprocedural) analysis
+ stage, exclude overlapping ones, identify representatives and build trees
+ out of them, making decisions about scalarization on the way. Return true
+ iff there are any to-be-scalarized variables after this stage. */
-static void
-generate_element_copy (struct sra_elt *dst, struct sra_elt *src, gimple_seq *seq_p)
+static bool
+analyze_all_variable_accesses (void)
{
- struct sra_elt *dc, *sc;
-
- FOR_EACH_ACTUAL_CHILD (dc, dst)
- {
- sc = lookup_element (src, dc->element, NULL, NO_INSERT);
- if (!sc && dc->in_bitfld_block == 2)
- {
- struct sra_elt *dcs;
-
- FOR_EACH_ACTUAL_CHILD (dcs, dc)
- {
- sc = lookup_element (src, dcs->element, NULL, NO_INSERT);
- gcc_assert (sc);
- generate_element_copy (dcs, sc, seq_p);
- }
+ tree var;
+ referenced_var_iterator rvi;
+ bool res = false;
- continue;
- }
+ FOR_EACH_REFERENCED_VAR (var, rvi)
+ if (bitmap_bit_p (candidate_bitmap, DECL_UID (var)))
+ {
+ struct access *access;
- /* If DST and SRC are structs with the same elements, but do not have
- the same TYPE_MAIN_VARIANT, then lookup of DST FIELD_DECL in SRC
- will fail. Try harder by finding the corresponding FIELD_DECL
- in SRC. */
- if (!sc)
- {
- tree f;
-
- gcc_assert (useless_type_conversion_p (dst->type, src->type));
- gcc_assert (TREE_CODE (dc->element) == FIELD_DECL);
- for (f = TYPE_FIELDS (src->type); f ; f = TREE_CHAIN (f))
- if (simple_cst_equal (DECL_FIELD_OFFSET (f),
- DECL_FIELD_OFFSET (dc->element)) > 0
- && simple_cst_equal (DECL_FIELD_BIT_OFFSET (f),
- DECL_FIELD_BIT_OFFSET (dc->element)) > 0
- && simple_cst_equal (DECL_SIZE (f),
- DECL_SIZE (dc->element)) > 0
- && (useless_type_conversion_p (TREE_TYPE (dc->element),
- TREE_TYPE (f))
- || (POINTER_TYPE_P (TREE_TYPE (dc->element))
- && POINTER_TYPE_P (TREE_TYPE (f)))))
- break;
- gcc_assert (f != NULL_TREE);
- sc = lookup_element (src, f, NULL, NO_INSERT);
- }
+ access = sort_and_splice_var_accesses (var);
+ if (access)
+ build_access_trees (access);
+ else
+ disqualify_candidate (var,
+ "No or inhibitingly overlapping accesses.");
+ }
- generate_element_copy (dc, sc, seq_p);
- }
+ propagate_all_subaccesses ();
- if (dst->replacement)
- {
- gimple_seq tmp_seq;
+ FOR_EACH_REFERENCED_VAR (var, rvi)
+ if (bitmap_bit_p (candidate_bitmap, DECL_UID (var)))
+ {
+ struct access *access = get_first_repr_for_decl (var);
- gcc_assert (src->replacement);
+ if (analyze_access_trees (access))
+ {
+ res = true;
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "\nAccess trees for ");
+ print_generic_expr (dump_file, var, 0);
+ fprintf (dump_file, " (UID: %u): \n", DECL_UID (var));
+ dump_access_tree (dump_file, access);
+ fprintf (dump_file, "\n");
+ }
+ }
+ else
+ disqualify_candidate (var, "No scalar replacements to be created.");
+ }
- tmp_seq = sra_build_elt_assignment (dst, REPLDUP (src->replacement));
- gimple_seq_add_seq (seq_p, tmp_seq);
- }
+ return res;
}
-/* Generate a set of assignment statements in *LIST_P to zero all instantiated
- elements under ELT. In addition, do not assign to elements that have been
- marked VISITED but do reset the visited flag; this allows easy coordination
- with generate_element_init. */
+/* Return true iff a reference statement into aggregate AGG can be built for
+ every single to-be-replaced accesses that is a child of ACCESS, its sibling
+ or a child of its sibling. TOP_OFFSET is the offset from the processed
+ access subtree that has to be subtracted from offset of each access. */
-static void
-generate_element_zero (struct sra_elt *elt, gimple_seq *seq_p)
+static bool
+ref_expr_for_all_replacements_p (struct access *access, tree agg,
+ HOST_WIDE_INT top_offset)
{
- struct sra_elt *c;
-
- if (elt->visited)
+ do
{
- elt->visited = false;
- return;
- }
-
- if (!elt->in_bitfld_block)
- FOR_EACH_ACTUAL_CHILD (c, elt)
- generate_element_zero (c, seq_p);
-
- if (elt->replacement)
- {
- tree t;
- gimple_seq tmp_seq;
+ if (access->grp_to_be_replaced
+ && !build_ref_for_offset (NULL, TREE_TYPE (agg),
+ access->offset - top_offset,
+ access->type, false))
+ return false;
- gcc_assert (elt->is_scalar);
- t = fold_convert (elt->type, integer_zero_node);
+ if (access->first_child
+ && !ref_expr_for_all_replacements_p (access->first_child, agg,
+ top_offset))
+ return false;
- tmp_seq = sra_build_elt_assignment (elt, t);
- gimple_seq_add_seq (seq_p, tmp_seq);
+ access = access->next_sibling;
}
+ while (access);
+
+ return true;
}
-/* Generate an assignment VAR = INIT, where INIT may need gimplification.
- Add the result to *LIST_P. */
+/* Generate statements copying scalar replacements of accesses within a subtree
+ into or out of AGG. ACCESS is the first child of the root of the subtree to
+ be processed. AGG is an aggregate type expression (can be a declaration but
+ does not have to be, it can for example also be an indirect_ref).
+ TOP_OFFSET is the offset of the processed subtree which has to be subtracted
+ from offsets of individual accesses to get corresponding offsets for AGG.
+ If CHUNK_SIZE is non-null, copy only replacements in the interval
+ <start_offset, start_offset + chunk_size>, otherwise copy all. GSI is a
+ statement iterator used to place the new statements. WRITE should be true
+ when the statements should write from AGG to the replacement and false if
+ vice versa. if INSERT_AFTER is true, new statements will be added after the
+ current statement in GSI, they will be added before the statement
+ otherwise. */
static void
-generate_one_element_init (struct sra_elt *elt, tree init, gimple_seq *seq_p)
+generate_subtree_copies (struct access *access, tree agg,
+ HOST_WIDE_INT top_offset,
+ HOST_WIDE_INT start_offset, HOST_WIDE_INT chunk_size,
+ gimple_stmt_iterator *gsi, bool write,
+ bool insert_after)
{
- gimple_seq tmp_seq = sra_build_elt_assignment (elt, init);
- gimple_seq_add_seq (seq_p, tmp_seq);
-}
+ do
+ {
+ tree expr = unshare_expr (agg);
-/* Generate a set of assignment statements in *LIST_P to set all instantiated
- elements under ELT with the contents of the initializer INIT. In addition,
- mark all assigned elements VISITED; this allows easy coordination with
- generate_element_zero. Return false if we found a case we couldn't
- handle. */
+ if (chunk_size && access->offset >= start_offset + chunk_size)
+ return;
-static bool
-generate_element_init_1 (struct sra_elt *elt, tree init, gimple_seq *seq_p)
-{
- bool result = true;
- enum tree_code init_code;
- struct sra_elt *sub;
- tree t;
- unsigned HOST_WIDE_INT idx;
- tree value, purpose;
-
- /* We can be passed DECL_INITIAL of a static variable. It might have a
- conversion, which we strip off here. */
- STRIP_USELESS_TYPE_CONVERSION (init);
- init_code = TREE_CODE (init);
-
- if (elt->is_scalar)
- {
- if (elt->replacement)
+ if (access->grp_to_be_replaced
+ && (chunk_size == 0
+ || access->offset + access->size > start_offset))
{
- generate_one_element_init (elt, init, seq_p);
- elt->visited = true;
- }
- return result;
- }
+ tree repl = get_access_replacement (access);
+ bool ref_found;
+ gimple stmt;
- switch (init_code)
- {
- case COMPLEX_CST:
- case COMPLEX_EXPR:
- FOR_EACH_ACTUAL_CHILD (sub, elt)
- {
- if (sub->element == integer_zero_node)
- t = (init_code == COMPLEX_EXPR
- ? TREE_OPERAND (init, 0) : TREE_REALPART (init));
- else
- t = (init_code == COMPLEX_EXPR
- ? TREE_OPERAND (init, 1) : TREE_IMAGPART (init));
- result &= generate_element_init_1 (sub, t, seq_p);
- }
- break;
+ ref_found = build_ref_for_offset (&expr, TREE_TYPE (agg),
+ access->offset - top_offset,
+ access->type, false);
+ gcc_assert (ref_found);
- case CONSTRUCTOR:
- FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (init), idx, purpose, value)
- {
- /* Array constructors are routinely created with NULL indices. */
- if (purpose == NULL_TREE)
+ if (write)
{
- result = false;
- break;
- }
- if (TREE_CODE (purpose) == RANGE_EXPR)
- {
- tree lower = TREE_OPERAND (purpose, 0);
- tree upper = TREE_OPERAND (purpose, 1);
-
- while (1)
- {
- sub = lookup_element (elt, lower, NULL, NO_INSERT);
- if (sub != NULL)
- result &= generate_element_init_1 (sub, value, seq_p);
- if (tree_int_cst_equal (lower, upper))
- break;
- lower = int_const_binop (PLUS_EXPR, lower,
- integer_one_node, true);
- }
+ if (access->grp_partial_lhs)
+ expr = force_gimple_operand_gsi (gsi, expr, true, NULL_TREE,
+ !insert_after,
+ insert_after ? GSI_NEW_STMT
+ : GSI_SAME_STMT);
+ stmt = gimple_build_assign (repl, expr);
}
else
{
- sub = lookup_element (elt, purpose, NULL, NO_INSERT);
- if (sub != NULL)
- result &= generate_element_init_1 (sub, value, seq_p);
+ TREE_NO_WARNING (repl) = 1;
+ if (access->grp_partial_lhs)
+ repl = force_gimple_operand_gsi (gsi, repl, true, NULL_TREE,
+ !insert_after,
+ insert_after ? GSI_NEW_STMT
+ : GSI_SAME_STMT);
+ stmt = gimple_build_assign (expr, repl);
}
+
+ if (insert_after)
+ gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
+ else
+ gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
+ update_stmt (stmt);
}
- break;
- default:
- elt->visited = true;
- result = false;
- }
+ if (access->first_child)
+ generate_subtree_copies (access->first_child, agg, top_offset,
+ start_offset, chunk_size, gsi,
+ write, insert_after);
- return result;
+ access = access->next_sibling;
+ }
+ while (access);
}
-/* A wrapper function for generate_element_init_1 that handles cleanup after
- gimplification. */
+/* Assign zero to all scalar replacements in an access subtree. ACCESS is the
+ the root of the subtree to be processed. GSI is the statement iterator used
+ for inserting statements which are added after the current statement if
+ INSERT_AFTER is true or before it otherwise. */
-static bool
-generate_element_init (struct sra_elt *elt, tree init, gimple_seq *seq_p)
-{
- bool ret;
- struct gimplify_ctx gctx;
+static void
+init_subtree_with_zero (struct access *access, gimple_stmt_iterator *gsi,
+ bool insert_after)
- push_gimplify_context (&gctx);
- ret = generate_element_init_1 (elt, init, seq_p);
- pop_gimplify_context (NULL);
+{
+ struct access *child;
- /* The replacement can expose previously unreferenced variables. */
- if (ret && *seq_p)
+ if (access->grp_to_be_replaced)
{
- gimple_stmt_iterator i;
+ gimple stmt;
- for (i = gsi_start (*seq_p); !gsi_end_p (i); gsi_next (&i))
- find_new_referenced_vars (gsi_stmt (i));
+ stmt = gimple_build_assign (get_access_replacement (access),
+ fold_convert (access->type,
+ integer_zero_node));
+ if (insert_after)
+ gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
+ else
+ gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
+ update_stmt (stmt);
}
- return ret;
+ for (child = access->first_child; child; child = child->next_sibling)
+ init_subtree_with_zero (child, gsi, insert_after);
}
-/* Insert a gimple_seq SEQ on all the outgoing edges out of BB. Note that
- if BB has more than one edge, STMT will be replicated for each edge.
- Also, abnormal edges will be ignored. */
+/* Search for an access representative for the given expression EXPR and
+ return it or NULL if it cannot be found. */
-void
-insert_edge_copies_seq (gimple_seq seq, basic_block bb)
+static struct access *
+get_access_for_expr (tree expr)
{
- edge e;
- edge_iterator ei;
- unsigned n_copies = -1;
-
- FOR_EACH_EDGE (e, ei, bb->succs)
- if (!(e->flags & EDGE_ABNORMAL))
- n_copies++;
-
- FOR_EACH_EDGE (e, ei, bb->succs)
- if (!(e->flags & EDGE_ABNORMAL))
- gsi_insert_seq_on_edge (e, n_copies-- > 0 ? gimple_seq_copy (seq) : seq);
-}
-
-/* Helper function to insert LIST before GSI, and set up line number info. */
-
-void
-sra_insert_before (gimple_stmt_iterator *gsi, gimple_seq seq)
-{
- gimple stmt = gsi_stmt (*gsi);
-
- if (gimple_has_location (stmt))
- annotate_all_with_location (seq, gimple_location (stmt));
- gsi_insert_seq_before (gsi, seq, GSI_SAME_STMT);
-}
+ HOST_WIDE_INT offset, size, max_size;
+ tree base;
-/* Similarly, but insert after GSI. Handles insertion onto edges as well. */
+ /* FIXME: This should not be necessary but Ada produces V_C_Es with a type of
+ a different size than the size of its argument and we need the latter
+ one. */
+ if (TREE_CODE (expr) == VIEW_CONVERT_EXPR)
+ expr = TREE_OPERAND (expr, 0);
-void
-sra_insert_after (gimple_stmt_iterator *gsi, gimple_seq seq)
-{
- gimple stmt = gsi_stmt (*gsi);
+ base = get_ref_base_and_extent (expr, &offset, &size, &max_size);
+ if (max_size == -1 || !DECL_P (base))
+ return NULL;
- if (gimple_has_location (stmt))
- annotate_all_with_location (seq, gimple_location (stmt));
+ if (!bitmap_bit_p (candidate_bitmap, DECL_UID (base)))
+ return NULL;
- if (stmt_ends_bb_p (stmt))
- insert_edge_copies_seq (seq, gsi_bb (*gsi));
- else
- gsi_insert_seq_after (gsi, seq, GSI_SAME_STMT);
+ return get_var_base_offset_size_access (base, offset, max_size);
}
-/* Similarly, but replace the statement at GSI. */
-
-static void
-sra_replace (gimple_stmt_iterator *gsi, gimple_seq seq)
-{
- sra_insert_before (gsi, seq);
- unlink_stmt_vdef (gsi_stmt (*gsi));
- gsi_remove (gsi, false);
- if (gsi_end_p (*gsi))
- *gsi = gsi_last (gsi_seq (*gsi));
- else
- gsi_prev (gsi);
-}
-
-/* Data structure that bitfield_overlaps_p fills in with information
- about the element passed in and how much of it overlaps with the
- bit-range passed it to. */
-
-struct bitfield_overlap_info
-{
- /* The bit-length of an element. */
- tree field_len;
-
- /* The bit-position of the element in its parent. */
- tree field_pos;
-
- /* The number of bits of the element that overlap with the incoming
- bit range. */
- tree overlap_len;
-
- /* The first bit of the element that overlaps with the incoming bit
- range. */
- tree overlap_pos;
-};
-
-/* Return true if a BIT_FIELD_REF<(FLD->parent), BLEN, BPOS>
- expression (referenced as BF below) accesses any of the bits in FLD,
- false if it doesn't. If DATA is non-null, its field_len and
- field_pos are filled in such that BIT_FIELD_REF<(FLD->parent),
- field_len, field_pos> (referenced as BFLD below) represents the
- entire field FLD->element, and BIT_FIELD_REF<BFLD, overlap_len,
- overlap_pos> represents the portion of the entire field that
- overlaps with BF. */
+/* Callback for scan_function. Replace the expression EXPR with a scalar
+ replacement if there is one and generate other statements to do type
+ conversion or subtree copying if necessary. GSI is used to place newly
+ created statements, WRITE is true if the expression is being written to (it
+ is on a LHS of a statement or output in an assembly statement). */
static bool
-bitfield_overlaps_p (tree blen, tree bpos, struct sra_elt *fld,
- struct bitfield_overlap_info *data)
+sra_modify_expr (tree *expr, gimple_stmt_iterator *gsi, bool write,
+ void *data ATTRIBUTE_UNUSED)
{
- tree flen, fpos;
- bool ret;
+ struct access *access;
+ tree type, bfr;
- if (TREE_CODE (fld->element) == FIELD_DECL)
- {
- flen = fold_convert (bitsizetype, DECL_SIZE (fld->element));
- fpos = fold_convert (bitsizetype, DECL_FIELD_OFFSET (fld->element));
- fpos = size_binop (MULT_EXPR, fpos, bitsize_int (BITS_PER_UNIT));
- fpos = size_binop (PLUS_EXPR, fpos, DECL_FIELD_BIT_OFFSET (fld->element));
- }
- else if (TREE_CODE (fld->element) == BIT_FIELD_REF)
- {
- flen = fold_convert (bitsizetype, TREE_OPERAND (fld->element, 1));
- fpos = fold_convert (bitsizetype, TREE_OPERAND (fld->element, 2));
- }
- else if (TREE_CODE (fld->element) == INTEGER_CST)
+ if (TREE_CODE (*expr) == BIT_FIELD_REF)
{
- tree domain_type = TYPE_DOMAIN (TREE_TYPE (fld->parent->element));
- flen = fold_convert (bitsizetype, TYPE_SIZE (fld->type));
- fpos = fold_convert (bitsizetype, fld->element);
- if (domain_type && TYPE_MIN_VALUE (domain_type))
- fpos = size_binop (MINUS_EXPR, fpos,
- fold_convert (bitsizetype,
- TYPE_MIN_VALUE (domain_type)));
- fpos = size_binop (MULT_EXPR, flen, fpos);
+ bfr = *expr;
+ expr = &TREE_OPERAND (*expr, 0);
}
else
- gcc_unreachable ();
-
- gcc_assert (host_integerp (blen, 1)
- && host_integerp (bpos, 1)
- && host_integerp (flen, 1)
- && host_integerp (fpos, 1));
-
- ret = ((!tree_int_cst_lt (fpos, bpos)
- && tree_int_cst_lt (size_binop (MINUS_EXPR, fpos, bpos),
- blen))
- || (!tree_int_cst_lt (bpos, fpos)
- && tree_int_cst_lt (size_binop (MINUS_EXPR, bpos, fpos),
- flen)));
-
- if (!ret)
- return ret;
+ bfr = NULL_TREE;
- if (data)
- {
- tree bend, fend;
-
- data->field_len = flen;
- data->field_pos = fpos;
-
- fend = size_binop (PLUS_EXPR, fpos, flen);
- bend = size_binop (PLUS_EXPR, bpos, blen);
-
- if (tree_int_cst_lt (bend, fend))
- data->overlap_len = size_binop (MINUS_EXPR, bend, fpos);
- else
- data->overlap_len = NULL;
-
- if (tree_int_cst_lt (fpos, bpos))
- {
- data->overlap_pos = size_binop (MINUS_EXPR, bpos, fpos);
- data->overlap_len = size_binop (MINUS_EXPR,
- data->overlap_len
- ? data->overlap_len
- : data->field_len,
- data->overlap_pos);
- }
- else
- data->overlap_pos = NULL;
- }
-
- return ret;
-}
-
-/* Add to LISTP a sequence of statements that copies BLEN bits between
- VAR and the scalarized elements of ELT, starting a bit VPOS of VAR
- and at bit BPOS of ELT. The direction of the copy is given by
- TO_VAR. */
-
-static void
-sra_explode_bitfield_assignment (tree var, tree vpos, bool to_var,
- gimple_seq *seq_p, tree blen, tree bpos,
- struct sra_elt *elt)
-{
- struct sra_elt *fld;
- struct bitfield_overlap_info flp;
+ if (TREE_CODE (*expr) == REALPART_EXPR || TREE_CODE (*expr) == IMAGPART_EXPR)
+ expr = &TREE_OPERAND (*expr, 0);
+ access = get_access_for_expr (*expr);
+ if (!access)
+ return false;
+ type = TREE_TYPE (*expr);
- FOR_EACH_ACTUAL_CHILD (fld, elt)
+ if (access->grp_to_be_replaced)
{
- tree flen, fpos;
-
- if (!bitfield_overlaps_p (blen, bpos, fld, &flp))
- continue;
-
- flen = flp.overlap_len ? flp.overlap_len : flp.field_len;
- fpos = flp.overlap_pos ? flp.overlap_pos : bitsize_int (0);
-
- if (fld->replacement)
+ tree repl = get_access_replacement (access);
+ /* If we replace a non-register typed access simply use the original
+ access expression to extract the scalar component afterwards.
+ This happens if scalarizing a function return value or parameter
+ like in gcc.c-torture/execute/20041124-1.c, 20050316-1.c and
+ gcc.c-torture/compile/20011217-1.c. */
+ if (!is_gimple_reg_type (type))
{
- tree infld, invar, type;
- gimple_seq st;
-
- infld = fld->replacement;
-
- type = unsigned_type_for (TREE_TYPE (infld));
- if (TYPE_PRECISION (type) != TREE_INT_CST_LOW (flen))
- type = build_nonstandard_integer_type (TREE_INT_CST_LOW (flen), 1);
-
- if (TREE_CODE (infld) == BIT_FIELD_REF)
+ gimple stmt;
+ if (write)
{
- fpos = size_binop (PLUS_EXPR, fpos, TREE_OPERAND (infld, 2));
- infld = TREE_OPERAND (infld, 0);
+ tree ref = unshare_expr (access->expr);
+ if (access->grp_partial_lhs)
+ ref = force_gimple_operand_gsi (gsi, ref, true, NULL_TREE,
+ false, GSI_NEW_STMT);
+ stmt = gimple_build_assign (repl, ref);
+ gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
}
- else if (BYTES_BIG_ENDIAN && DECL_P (fld->element)
- && !tree_int_cst_equal (TYPE_SIZE (TREE_TYPE (infld)),
- DECL_SIZE (fld->element)))
+ else
{
- fpos = size_binop (PLUS_EXPR, fpos,
- TYPE_SIZE (TREE_TYPE (infld)));
- fpos = size_binop (MINUS_EXPR, fpos,
- DECL_SIZE (fld->element));
+ if (access->grp_partial_lhs)
+ repl = force_gimple_operand_gsi (gsi, repl, true, NULL_TREE,
+ true, GSI_SAME_STMT);
+ stmt = gimple_build_assign (unshare_expr (access->expr), repl);
+ gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
}
-
- infld = fold_build3 (BIT_FIELD_REF, type, infld, flen, fpos);
-
- invar = size_binop (MINUS_EXPR, flp.field_pos, bpos);
- if (flp.overlap_pos)
- invar = size_binop (PLUS_EXPR, invar, flp.overlap_pos);
- invar = size_binop (PLUS_EXPR, invar, vpos);
-
- invar = fold_build3 (BIT_FIELD_REF, type, var, flen, invar);
-
- if (to_var)
- st = sra_build_bf_assignment (invar, infld);
- else
- st = sra_build_bf_assignment (infld, invar);
-
- gimple_seq_add_seq (seq_p, st);
}
else
{
- tree sub = size_binop (MINUS_EXPR, flp.field_pos, bpos);
- sub = size_binop (PLUS_EXPR, vpos, sub);
- if (flp.overlap_pos)
- sub = size_binop (PLUS_EXPR, sub, flp.overlap_pos);
+ gcc_assert (useless_type_conversion_p (type, access->type));
+ *expr = repl;
+ }
+ }
- sra_explode_bitfield_assignment (var, sub, to_var, seq_p,
- flen, fpos, fld);
+ if (access->first_child)
+ {
+ HOST_WIDE_INT start_offset, chunk_size;
+ if (bfr
+ && host_integerp (TREE_OPERAND (bfr, 1), 1)
+ && host_integerp (TREE_OPERAND (bfr, 2), 1))
+ {
+ start_offset = tree_low_cst (TREE_OPERAND (bfr, 1), 1);
+ chunk_size = tree_low_cst (TREE_OPERAND (bfr, 2), 1);
}
+ else
+ start_offset = chunk_size = 0;
+
+ generate_subtree_copies (access->first_child, access->base, 0,
+ start_offset, chunk_size, gsi, write, write);
}
+ return true;
}
-/* Add to LISTBEFOREP statements that copy scalarized members of ELT
- that overlap with BIT_FIELD_REF<(ELT->element), BLEN, BPOS> back
- into the full variable, and to LISTAFTERP, if non-NULL, statements
- that copy the (presumably modified) overlapping portions of the
- full variable back to the scalarized variables. */
+/* Store all replacements in the access tree rooted in TOP_RACC either to their
+ base aggregate if there are unscalarized data or directly to LHS
+ otherwise. */
static void
-sra_sync_for_bitfield_assignment (gimple_seq *seq_before_p,
- gimple_seq *seq_after_p,
- tree blen, tree bpos,
- struct sra_elt *elt)
+handle_unscalarized_data_in_subtree (struct access *top_racc, tree lhs,
+ gimple_stmt_iterator *gsi)
{
- struct sra_elt *fld;
- struct bitfield_overlap_info flp;
-
- FOR_EACH_ACTUAL_CHILD (fld, elt)
- if (bitfield_overlaps_p (blen, bpos, fld, &flp))
- {
- if (fld->replacement || (!flp.overlap_len && !flp.overlap_pos))
- {
- generate_copy_inout (fld, false, generate_element_ref (fld),
- seq_before_p);
- mark_no_warning (fld);
- if (seq_after_p)
- generate_copy_inout (fld, true, generate_element_ref (fld),
- seq_after_p);
- }
- else
- {
- tree flen = flp.overlap_len ? flp.overlap_len : flp.field_len;
- tree fpos = flp.overlap_pos ? flp.overlap_pos : bitsize_int (0);
-
- sra_sync_for_bitfield_assignment (seq_before_p, seq_after_p,
- flen, fpos, fld);
- }
- }
+ if (top_racc->grp_unscalarized_data)
+ generate_subtree_copies (top_racc->first_child, top_racc->base, 0, 0, 0,
+ gsi, false, false);
+ else
+ generate_subtree_copies (top_racc->first_child, lhs, top_racc->offset,
+ 0, 0, gsi, false, false);
}
-/* Scalarize a USE. To recap, this is either a simple reference to ELT,
- if elt is scalar, or some occurrence of ELT that requires a complete
- aggregate. IS_OUTPUT is true if ELT is being modified. */
+
+/* Try to generate statements to load all sub-replacements in an access
+ (sub)tree (LACC is the first child) from scalar replacements in the TOP_RACC
+ (sub)tree. If that is not possible, refresh the TOP_RACC base aggregate and
+ load the accesses from it. LEFT_OFFSET is the offset of the left whole
+ subtree being copied, RIGHT_OFFSET is the same thing for the right subtree.
+ GSI is stmt iterator used for statement insertions. *REFRESHED is true iff
+ the rhs top aggregate has already been refreshed by contents of its scalar
+ reductions and is set to true if this function has to do it. */
static void
-scalarize_use (struct sra_elt *elt, tree *expr_p, gimple_stmt_iterator *gsi,
- bool is_output, bool use_all)
+load_assign_lhs_subreplacements (struct access *lacc, struct access *top_racc,
+ HOST_WIDE_INT left_offset,
+ HOST_WIDE_INT right_offset,
+ gimple_stmt_iterator *old_gsi,
+ gimple_stmt_iterator *new_gsi,
+ bool *refreshed, tree lhs)
{
- gimple stmt = gsi_stmt (*gsi);
- tree bfexpr;
-
- if (elt->replacement)
- {
- tree replacement = elt->replacement;
-
- /* If we have a replacement, then updating the reference is as
- simple as modifying the existing statement in place. */
- if (is_output
- && TREE_CODE (elt->replacement) == BIT_FIELD_REF
- && is_gimple_reg (TREE_OPERAND (elt->replacement, 0))
- && is_gimple_assign (stmt)
- && gimple_assign_lhs_ptr (stmt) == expr_p)
- {
- gimple_seq newseq;
- /* RHS must be a single operand. */
- gcc_assert (gimple_assign_single_p (stmt));
- newseq = sra_build_elt_assignment (elt, gimple_assign_rhs1 (stmt));
- sra_replace (gsi, newseq);
- return;
- }
- else if (!is_output
- && TREE_CODE (elt->replacement) == BIT_FIELD_REF
- && is_gimple_assign (stmt)
- && gimple_assign_rhs1_ptr (stmt) == expr_p)
- {
- tree tmp = make_rename_temp
- (TREE_TYPE (gimple_assign_lhs (stmt)), "SR");
- gimple_seq newseq = sra_build_assignment (tmp, REPLDUP (elt->replacement));
-
- sra_insert_before (gsi, newseq);
- replacement = tmp;
- }
- if (is_output)
- update_stmt_if_modified (stmt);
- *expr_p = REPLDUP (replacement);
- update_stmt (stmt);
- }
- else if (use_all && is_output
- && is_gimple_assign (stmt)
- && TREE_CODE (bfexpr
- = gimple_assign_lhs (stmt)) == BIT_FIELD_REF
- && &TREE_OPERAND (bfexpr, 0) == expr_p
- && INTEGRAL_TYPE_P (TREE_TYPE (bfexpr))
- && TREE_CODE (TREE_TYPE (*expr_p)) == RECORD_TYPE)
+ do
{
- gimple_seq seq_before = NULL;
- gimple_seq seq_after = NULL;
- tree blen = fold_convert (bitsizetype, TREE_OPERAND (bfexpr, 1));
- tree bpos = fold_convert (bitsizetype, TREE_OPERAND (bfexpr, 2));
- bool update = false;
-
- if (!elt->use_block_copy)
+ if (lacc->grp_to_be_replaced)
{
- tree type = TREE_TYPE (bfexpr);
- tree var = make_rename_temp (type, "SR"), tmp, vpos;
- gimple st;
-
- gimple_assign_set_lhs (stmt, var);
- update = true;
+ struct access *racc;
+ HOST_WIDE_INT offset = lacc->offset - left_offset + right_offset;
+ gimple stmt;
+ tree rhs;
- if (!TYPE_UNSIGNED (type))
+ racc = find_access_in_subtree (top_racc, offset, lacc->size);
+ if (racc && racc->grp_to_be_replaced)
{
- type = unsigned_type_for (type);
- tmp = make_rename_temp (type, "SR");
- st = gimple_build_assign (tmp, fold_convert (type, var));
- gimple_seq_add_stmt (&seq_after, st);
- var = tmp;
+ rhs = get_access_replacement (racc);
+ if (!useless_type_conversion_p (lacc->type, racc->type))
+ rhs = fold_build1 (VIEW_CONVERT_EXPR, lacc->type, rhs);
}
-
- /* If VAR is wider than BLEN bits, it is padded at the
- most-significant end. We want to set VPOS such that
- <BIT_FIELD_REF VAR BLEN VPOS> would refer to the
- least-significant BLEN bits of VAR. */
- if (BYTES_BIG_ENDIAN)
- vpos = size_binop (MINUS_EXPR, TYPE_SIZE (type), blen);
else
- vpos = bitsize_int (0);
- sra_explode_bitfield_assignment
- (var, vpos, false, &seq_after, blen, bpos, elt);
- }
- else
- sra_sync_for_bitfield_assignment
- (&seq_before, &seq_after, blen, bpos, elt);
-
- if (seq_before)
- {
- mark_all_v_defs_seq (seq_before);
- sra_insert_before (gsi, seq_before);
- }
- if (seq_after)
- {
- mark_all_v_defs_seq (seq_after);
- sra_insert_after (gsi, seq_after);
- }
-
- if (update)
- update_stmt (stmt);
- }
- else if (use_all && !is_output
- && is_gimple_assign (stmt)
- && TREE_CODE (bfexpr
- = gimple_assign_rhs1 (stmt)) == BIT_FIELD_REF
- && &TREE_OPERAND (gimple_assign_rhs1 (stmt), 0) == expr_p
- && INTEGRAL_TYPE_P (TREE_TYPE (bfexpr))
- && TREE_CODE (TREE_TYPE (*expr_p)) == RECORD_TYPE)
- {
- gimple_seq seq = NULL;
- tree blen = fold_convert (bitsizetype, TREE_OPERAND (bfexpr, 1));
- tree bpos = fold_convert (bitsizetype, TREE_OPERAND (bfexpr, 2));
- bool update = false;
-
- if (!elt->use_block_copy)
- {
- tree type = TREE_TYPE (bfexpr);
- tree var = make_rename_temp (type, "SR"), tmp, vpos;
- gimple st = NULL;
-
- gimple_assign_set_rhs1 (stmt, var);
- update = true;
-
- if (!TYPE_UNSIGNED (type))
{
- type = unsigned_type_for (type);
- tmp = make_rename_temp (type, "SR");
- st = gimple_build_assign (var,
- fold_convert (TREE_TYPE (var), tmp));
- var = tmp;
- }
+ bool repl_found;
- gimple_seq_add_stmt (&seq,
- gimple_build_assign
- (var, build_int_cst_wide (type, 0, 0)));
+ /* No suitable access on the right hand side, need to load from
+ the aggregate. See if we have to update it first... */
+ if (!*refreshed)
+ {
+ gcc_assert (top_racc->first_child);
+ handle_unscalarized_data_in_subtree (top_racc, lhs, old_gsi);
+ *refreshed = true;
+ }
- /* If VAR is wider than BLEN bits, it is padded at the
- most-significant end. We want to set VPOS such that
- <BIT_FIELD_REF VAR BLEN VPOS> would refer to the
- least-significant BLEN bits of VAR. */
- if (BYTES_BIG_ENDIAN)
- vpos = size_binop (MINUS_EXPR, TYPE_SIZE (type), blen);
- else
- vpos = bitsize_int (0);
- sra_explode_bitfield_assignment
- (var, vpos, true, &seq, blen, bpos, elt);
+ rhs = unshare_expr (top_racc->base);
+ repl_found = build_ref_for_offset (&rhs,
+ TREE_TYPE (top_racc->base),
+ offset, lacc->type, false);
+ gcc_assert (repl_found);
+ }
- if (st)
- gimple_seq_add_stmt (&seq, st);
+ stmt = gimple_build_assign (get_access_replacement (lacc), rhs);
+ gsi_insert_after (new_gsi, stmt, GSI_NEW_STMT);
+ update_stmt (stmt);
}
- else
- sra_sync_for_bitfield_assignment
- (&seq, NULL, blen, bpos, elt);
-
- if (seq)
+ else if (lacc->grp_read && !lacc->grp_covered && !*refreshed)
{
- mark_all_v_defs_seq (seq);
- sra_insert_before (gsi, seq);
+ handle_unscalarized_data_in_subtree (top_racc, lhs, old_gsi);
+ *refreshed = true;
}
- if (update)
- update_stmt (stmt);
- }
- else
- {
- gimple_seq seq = NULL;
-
- /* Otherwise we need some copies. If ELT is being read, then we
- want to store all (modified) sub-elements back into the
- structure before the reference takes place. If ELT is being
- written, then we want to load the changed values back into
- our shadow variables. */
- /* ??? We don't check modified for reads, we just always write all of
- the values. We should be able to record the SSA number of the VOP
- for which the values were last read. If that number matches the
- SSA number of the VOP in the current statement, then we needn't
- emit an assignment. This would also eliminate double writes when
- a structure is passed as more than one argument to a function call.
- This optimization would be most effective if sra_walk_function
- processed the blocks in dominator order. */
-
- generate_copy_inout (elt, is_output, generate_element_ref (elt), &seq);
- if (seq == NULL)
- return;
- mark_all_v_defs_seq (seq);
- if (is_output)
- sra_insert_after (gsi, seq);
- else
- {
- sra_insert_before (gsi, seq);
- if (use_all)
- mark_no_warning (elt);
- }
+ if (lacc->first_child)
+ load_assign_lhs_subreplacements (lacc->first_child, top_racc,
+ left_offset, right_offset,
+ old_gsi, new_gsi, refreshed, lhs);
+ lacc = lacc->next_sibling;
}
+ while (lacc);
}
-/* Scalarize a COPY. To recap, this is an assignment statement between
- two scalarizable references, LHS_ELT and RHS_ELT. */
+/* Modify assignments with a CONSTRUCTOR on their RHS. STMT contains a pointer
+ to the assignment and GSI is the statement iterator pointing at it. Returns
+ the same values as sra_modify_assign. */
-static void
-scalarize_copy (struct sra_elt *lhs_elt, struct sra_elt *rhs_elt,
- gimple_stmt_iterator *gsi)
+static enum scan_assign_result
+sra_modify_constructor_assign (gimple *stmt, gimple_stmt_iterator *gsi)
{
- gimple_seq seq;
- gimple stmt;
-
- if (lhs_elt->replacement && rhs_elt->replacement)
- {
- /* If we have two scalar operands, modify the existing statement. */
- stmt = gsi_stmt (*gsi);
-
- /* See the commentary in sra_walk_function concerning
- RETURN_EXPR, and why we should never see one here. */
- gcc_assert (is_gimple_assign (stmt));
- gcc_assert (gimple_assign_copy_p (stmt));
+ tree lhs = gimple_assign_lhs (*stmt);
+ struct access *acc;
+ acc = get_access_for_expr (lhs);
+ if (!acc)
+ return SRA_SA_NONE;
- gimple_assign_set_lhs (stmt, lhs_elt->replacement);
- gimple_assign_set_rhs1 (stmt, REPLDUP (rhs_elt->replacement));
- update_stmt (stmt);
- }
- else if (lhs_elt->use_block_copy || rhs_elt->use_block_copy)
+ if (VEC_length (constructor_elt,
+ CONSTRUCTOR_ELTS (gimple_assign_rhs1 (*stmt))) > 0)
{
- /* If either side requires a block copy, then sync the RHS back
- to the original structure, leave the original assignment
- statement (which will perform the block copy), then load the
- LHS values out of its now-updated original structure. */
- /* ??? Could perform a modified pair-wise element copy. That
- would at least allow those elements that are instantiated in
- both structures to be optimized well. */
-
- seq = NULL;
- generate_copy_inout (rhs_elt, false,
- generate_element_ref (rhs_elt), &seq);
- if (seq)
- {
- mark_all_v_defs_seq (seq);
- sra_insert_before (gsi, seq);
- }
+ /* I have never seen this code path trigger but if it can happen the
+ following should handle it gracefully. */
+ if (access_has_children_p (acc))
+ generate_subtree_copies (acc->first_child, acc->base, 0, 0, 0, gsi,
+ true, true);
+ return SRA_SA_PROCESSED;
+ }
- seq = NULL;
- generate_copy_inout (lhs_elt, true,
- generate_element_ref (lhs_elt), &seq);
- if (seq)
- {
- mark_all_v_defs_seq (seq);
- sra_insert_after (gsi, seq);
- }
+ if (acc->grp_covered)
+ {
+ init_subtree_with_zero (acc, gsi, false);
+ unlink_stmt_vdef (*stmt);
+ gsi_remove (gsi, true);
+ return SRA_SA_REMOVED;
}
else
{
- /* Otherwise both sides must be fully instantiated. In which
- case perform pair-wise element assignments and replace the
- original block copy statement. */
-
- stmt = gsi_stmt (*gsi);
- update_stmt_if_modified (stmt);
-
- seq = NULL;
- generate_element_copy (lhs_elt, rhs_elt, &seq);
- gcc_assert (seq);
- mark_all_v_defs_seq (seq);
- sra_replace (gsi, seq);
+ init_subtree_with_zero (acc, gsi, true);
+ return SRA_SA_PROCESSED;
}
}
-/* Scalarize an INIT. To recap, this is an assignment to a scalarizable
- reference from some form of constructor: CONSTRUCTOR, COMPLEX_CST or
- COMPLEX_EXPR. If RHS is NULL, it should be treated as an empty
- CONSTRUCTOR. */
-static void
-scalarize_init (struct sra_elt *lhs_elt, tree rhs, gimple_stmt_iterator *gsi)
+/* Callback of scan_function to process assign statements. It examines both
+ sides of the statement, replaces them with a scalare replacement if there is
+ one and generating copying of replacements if scalarized aggregates have been
+ used in the assignment. STMT is a pointer to the assign statement, GSI is
+ used to hold generated statements for type conversions and subtree
+ copying. */
+
+static enum scan_assign_result
+sra_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi,
+ void *data ATTRIBUTE_UNUSED)
{
- bool result = true;
- gimple_seq seq = NULL, init_seq = NULL;
+ struct access *lacc, *racc;
+ tree lhs, rhs;
+ bool modify_this_stmt = false;
+ bool force_gimple_rhs = false;
+
+ if (!gimple_assign_single_p (*stmt))
+ return SRA_SA_NONE;
+ lhs = gimple_assign_lhs (*stmt);
+ rhs = gimple_assign_rhs1 (*stmt);
- /* Generate initialization statements for all members extant in the RHS. */
- if (rhs)
+ if (TREE_CODE (rhs) == CONSTRUCTOR)
+ return sra_modify_constructor_assign (stmt, gsi);
+
+ if (TREE_CODE (rhs) == REALPART_EXPR || TREE_CODE (lhs) == REALPART_EXPR
+ || TREE_CODE (rhs) == IMAGPART_EXPR || TREE_CODE (lhs) == IMAGPART_EXPR
+ || TREE_CODE (rhs) == BIT_FIELD_REF || TREE_CODE (lhs) == BIT_FIELD_REF)
{
- /* Unshare the expression just in case this is from a decl's initial. */
- rhs = unshare_expr (rhs);
- result = generate_element_init (lhs_elt, rhs, &init_seq);
+ modify_this_stmt = sra_modify_expr (gimple_assign_rhs1_ptr (*stmt),
+ gsi, false, data);
+ modify_this_stmt |= sra_modify_expr (gimple_assign_lhs_ptr (*stmt),
+ gsi, true, data);
+ return modify_this_stmt ? SRA_SA_PROCESSED : SRA_SA_NONE;
}
- if (!result)
+ lacc = get_access_for_expr (lhs);
+ racc = get_access_for_expr (rhs);
+ if (!lacc && !racc)
+ return SRA_SA_NONE;
+
+ if (lacc && lacc->grp_to_be_replaced)
{
- /* If we failed to convert the entire initializer, then we must
- leave the structure assignment in place and must load values
- from the structure into the slots for which we did not find
- constants. The easiest way to do this is to generate a complete
- copy-out, and then follow that with the constant assignments
- that we were able to build. DCE will clean things up. */
- gimple_seq seq0 = NULL;
- generate_copy_inout (lhs_elt, true, generate_element_ref (lhs_elt),
- &seq0);
- gimple_seq_add_seq (&seq0, seq);
- seq = seq0;
+ lhs = get_access_replacement (lacc);
+ gimple_assign_set_lhs (*stmt, lhs);
+ modify_this_stmt = true;
+ if (lacc->grp_partial_lhs)
+ force_gimple_rhs = true;
}
- else
+
+ if (racc && racc->grp_to_be_replaced)
{
- /* CONSTRUCTOR is defined such that any member not mentioned is assigned
- a zero value. Initialize the rest of the instantiated elements. */
- generate_element_zero (lhs_elt, &seq);
- gimple_seq_add_seq (&seq, init_seq);
+ rhs = get_access_replacement (racc);
+ modify_this_stmt = true;
+ if (racc->grp_partial_lhs)
+ force_gimple_rhs = true;
}
- if (lhs_elt->use_block_copy || !result)
+ if (modify_this_stmt)
{
- /* Since LHS is not fully instantiated, we must leave the structure
- assignment in place. Treating this case differently from a USE
- exposes constants to later optimizations. */
- if (seq)
+ if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
{
- mark_all_v_defs_seq (seq);
- sra_insert_after (gsi, seq);
+ /* If we can avoid creating a VIEW_CONVERT_EXPR do so.
+ ??? This should move to fold_stmt which we simply should
+ call after building a VIEW_CONVERT_EXPR here. */
+ if (AGGREGATE_TYPE_P (TREE_TYPE (lhs))
+ && !access_has_children_p (lacc))
+ {
+ tree expr = unshare_expr (lhs);
+ if (build_ref_for_offset (&expr, TREE_TYPE (lhs), racc->offset,
+ TREE_TYPE (rhs), false))
+ {
+ lhs = expr;
+ gimple_assign_set_lhs (*stmt, expr);
+ }
+ }
+ else if (AGGREGATE_TYPE_P (TREE_TYPE (rhs))
+ && !access_has_children_p (racc))
+ {
+ tree expr = unshare_expr (rhs);
+ if (build_ref_for_offset (&expr, TREE_TYPE (rhs), lacc->offset,
+ TREE_TYPE (lhs), false))
+ rhs = expr;
+ }
+ if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
+ {
+ rhs = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (lhs), rhs);
+ if (!is_gimple_reg (lhs))
+ force_gimple_rhs = true;
+ }
}
- }
- else
- {
- /* The LHS is fully instantiated. The list of initializations
- replaces the original structure assignment. */
- gcc_assert (seq);
- update_stmt_if_modified (gsi_stmt (*gsi));
- mark_all_v_defs_seq (seq);
- sra_replace (gsi, seq);
- }
-}
-
-/* A subroutine of scalarize_ldst called via walk_tree. Set TREE_NO_TRAP
- on all INDIRECT_REFs. */
-
-static tree
-mark_notrap (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
-{
- tree t = *tp;
- if (TREE_CODE (t) == INDIRECT_REF)
- {
- TREE_THIS_NOTRAP (t) = 1;
- *walk_subtrees = 0;
+ if (force_gimple_rhs)
+ rhs = force_gimple_operand_gsi (gsi, rhs, true, NULL_TREE,
+ true, GSI_SAME_STMT);
+ if (gimple_assign_rhs1 (*stmt) != rhs)
+ {
+ gimple_assign_set_rhs_from_tree (gsi, rhs);
+ gcc_assert (*stmt == gsi_stmt (*gsi));
+ }
}
- else if (IS_TYPE_OR_DECL_P (t))
- *walk_subtrees = 0;
- return NULL;
-}
-
-/* Scalarize a LDST. To recap, this is an assignment between one scalarizable
- reference ELT and one non-scalarizable reference OTHER. IS_OUTPUT is true
- if ELT is on the left-hand side. */
-
-static void
-scalarize_ldst (struct sra_elt *elt, tree other,
- gimple_stmt_iterator *gsi, bool is_output)
-{
- /* Shouldn't have gotten called for a scalar. */
- gcc_assert (!elt->replacement);
-
- if (elt->use_block_copy)
- {
- /* Since ELT is not fully instantiated, we have to leave the
- block copy in place. Treat this as a USE. */
- scalarize_use (elt, NULL, gsi, is_output, false);
+ /* From this point on, the function deals with assignments in between
+ aggregates when at least one has scalar reductions of some of its
+ components. There are three possible scenarios: Both the LHS and RHS have
+ to-be-scalarized components, 2) only the RHS has or 3) only the LHS has.
+
+ In the first case, we would like to load the LHS components from RHS
+ components whenever possible. If that is not possible, we would like to
+ read it directly from the RHS (after updating it by storing in it its own
+ components). If there are some necessary unscalarized data in the LHS,
+ those will be loaded by the original assignment too. If neither of these
+ cases happen, the original statement can be removed. Most of this is done
+ by load_assign_lhs_subreplacements.
+
+ In the second case, we would like to store all RHS scalarized components
+ directly into LHS and if they cover the aggregate completely, remove the
+ statement too. In the third case, we want the LHS components to be loaded
+ directly from the RHS (DSE will remove the original statement if it
+ becomes redundant).
+
+ This is a bit complex but manageable when types match and when unions do
+ not cause confusion in a way that we cannot really load a component of LHS
+ from the RHS or vice versa (the access representing this level can have
+ subaccesses that are accessible only through a different union field at a
+ higher level - different from the one used in the examined expression).
+ Unions are fun.
+
+ Therefore, I specially handle a fourth case, happening when there is a
+ specific type cast or it is impossible to locate a scalarized subaccess on
+ the other side of the expression. If that happens, I simply "refresh" the
+ RHS by storing in it is scalarized components leave the original statement
+ there to do the copying and then load the scalar replacements of the LHS.
+ This is what the first branch does. */
+
+ if (contains_view_convert_expr_p (rhs) || contains_view_convert_expr_p (lhs)
+ || (access_has_children_p (racc)
+ && !ref_expr_for_all_replacements_p (racc, lhs, racc->offset))
+ || (access_has_children_p (lacc)
+ && !ref_expr_for_all_replacements_p (lacc, rhs, lacc->offset)))
+ {
+ if (access_has_children_p (racc))
+ generate_subtree_copies (racc->first_child, racc->base, 0, 0, 0,
+ gsi, false, false);
+ if (access_has_children_p (lacc))
+ generate_subtree_copies (lacc->first_child, lacc->base, 0, 0, 0,
+ gsi, true, true);
}
else
{
- /* The interesting case is when ELT is fully instantiated. In this
- case we can have each element stored/loaded directly to/from the
- corresponding slot in OTHER. This avoids a block copy. */
-
- gimple_seq seq = NULL;
- gimple stmt = gsi_stmt (*gsi);
-
- update_stmt_if_modified (stmt);
- generate_copy_inout (elt, is_output, other, &seq);
- gcc_assert (seq);
- mark_all_v_defs_seq (seq);
-
- /* Preserve EH semantics. */
- if (stmt_ends_bb_p (stmt))
+ if (access_has_children_p (lacc) && access_has_children_p (racc))
{
- gimple_stmt_iterator si;
- gimple first;
- gimple_seq blist = NULL;
- bool thr = stmt_could_throw_p (stmt);
-
- /* If the last statement of this BB created an EH edge
- before scalarization, we have to locate the first
- statement that can throw in the new statement list and
- use that as the last statement of this BB, such that EH
- semantics is preserved. All statements up to this one
- are added to the same BB. All other statements in the
- list will be added to normal outgoing edges of the same
- BB. If they access any memory, it's the same memory, so
- we can assume they won't throw. */
- si = gsi_start (seq);
- for (first = gsi_stmt (si);
- thr && !gsi_end_p (si) && !stmt_could_throw_p (first);
- first = gsi_stmt (si))
+ gimple_stmt_iterator orig_gsi = *gsi;
+ bool refreshed;
+
+ if (lacc->grp_read && !lacc->grp_covered)
{
- gsi_remove (&si, false);
- gimple_seq_add_stmt (&blist, first);
+ handle_unscalarized_data_in_subtree (racc, lhs, gsi);
+ refreshed = true;
}
+ else
+ refreshed = false;
- /* Extract the first remaining statement from LIST, this is
- the EH statement if there is one. */
- gsi_remove (&si, false);
-
- if (blist)
- sra_insert_before (gsi, blist);
-
- /* Replace the old statement with this new representative. */
- gsi_replace (gsi, first, true);
+ load_assign_lhs_subreplacements (lacc->first_child, racc,
+ lacc->offset, racc->offset,
+ &orig_gsi, gsi, &refreshed, lhs);
+ if (!refreshed || !racc->grp_unscalarized_data)
+ {
+ if (*stmt == gsi_stmt (*gsi))
+ gsi_next (gsi);
- if (!gsi_end_p (si))
+ unlink_stmt_vdef (*stmt);
+ gsi_remove (&orig_gsi, true);
+ return SRA_SA_REMOVED;
+ }
+ }
+ else
+ {
+ if (access_has_children_p (racc))
{
- /* If any reference would trap, then they all would. And more
- to the point, the first would. Therefore none of the rest
- will trap since the first didn't. Indicate this by
- iterating over the remaining statements and set
- TREE_THIS_NOTRAP in all INDIRECT_REFs. */
- do
+ if (!racc->grp_unscalarized_data)
{
- walk_gimple_stmt (&si, NULL, mark_notrap, NULL);
- gsi_next (&si);
+ generate_subtree_copies (racc->first_child, lhs,
+ racc->offset, 0, 0, gsi,
+ false, false);
+ gcc_assert (*stmt == gsi_stmt (*gsi));
+ unlink_stmt_vdef (*stmt);
+ gsi_remove (gsi, true);
+ return SRA_SA_REMOVED;
}
- while (!gsi_end_p (si));
-
- insert_edge_copies_seq (seq, gsi_bb (*gsi));
+ else
+ generate_subtree_copies (racc->first_child, lhs,
+ racc->offset, 0, 0, gsi, false, true);
}
+ else if (access_has_children_p (lacc))
+ generate_subtree_copies (lacc->first_child, rhs, lacc->offset,
+ 0, 0, gsi, true, true);
}
- else
- sra_replace (gsi, seq);
}
+ return modify_this_stmt ? SRA_SA_PROCESSED : SRA_SA_NONE;
}
-/* Generate initializations for all scalarizable parameters. */
+/* Generate statements initializing scalar replacements of parts of function
+ parameters. */
static void
-scalarize_parms (void)
+initialize_parameter_reductions (void)
{
+ gimple_stmt_iterator gsi;
gimple_seq seq = NULL;
- unsigned i;
- bitmap_iterator bi;
-
- EXECUTE_IF_SET_IN_BITMAP (needs_copy_in, 0, i, bi)
- {
- tree var = referenced_var (i);
- struct sra_elt *elt = lookup_element (NULL, var, NULL, NO_INSERT);
- generate_copy_inout (elt, true, var, &seq);
- }
+ tree parm;
- if (seq)
+ for (parm = DECL_ARGUMENTS (current_function_decl);
+ parm;
+ parm = TREE_CHAIN (parm))
{
- insert_edge_copies_seq (seq, ENTRY_BLOCK_PTR);
- mark_all_v_defs_seq (seq);
- }
-}
-
-/* Entry point to phase 4. Update the function to match replacements. */
+ VEC (access_p, heap) *access_vec;
+ struct access *access;
-static void
-scalarize_function (void)
-{
- static const struct sra_walk_fns fns = {
- scalarize_use, scalarize_copy, scalarize_init, scalarize_ldst, false
- };
-
- sra_walk_function (&fns);
- scalarize_parms ();
- gsi_commit_edge_inserts ();
-}
-
-
-/* Debug helper function. Print ELT in a nice human-readable format. */
+ if (!bitmap_bit_p (candidate_bitmap, DECL_UID (parm)))
+ continue;
+ access_vec = get_base_access_vector (parm);
+ if (!access_vec)
+ continue;
-static void
-dump_sra_elt_name (FILE *f, struct sra_elt *elt)
-{
- if (elt->parent && TREE_CODE (elt->parent->type) == COMPLEX_TYPE)
- {
- fputs (elt->element == integer_zero_node ? "__real__ " : "__imag__ ", f);
- dump_sra_elt_name (f, elt->parent);
- }
- else
- {
- if (elt->parent)
- dump_sra_elt_name (f, elt->parent);
- if (DECL_P (elt->element))
+ if (!seq)
{
- if (TREE_CODE (elt->element) == FIELD_DECL)
- fputc ('.', f);
- print_generic_expr (f, elt->element, dump_flags);
+ seq = gimple_seq_alloc ();
+ gsi = gsi_start (seq);
}
- else if (TREE_CODE (elt->element) == BIT_FIELD_REF)
- fprintf (f, "$B" HOST_WIDE_INT_PRINT_DEC "F" HOST_WIDE_INT_PRINT_DEC,
- tree_low_cst (TREE_OPERAND (elt->element, 2), 1),
- tree_low_cst (TREE_OPERAND (elt->element, 1), 1));
- else if (TREE_CODE (elt->element) == RANGE_EXPR)
- fprintf (f, "["HOST_WIDE_INT_PRINT_DEC".."HOST_WIDE_INT_PRINT_DEC"]",
- TREE_INT_CST_LOW (TREE_OPERAND (elt->element, 0)),
- TREE_INT_CST_LOW (TREE_OPERAND (elt->element, 1)));
- else
- fprintf (f, "[" HOST_WIDE_INT_PRINT_DEC "]",
- TREE_INT_CST_LOW (elt->element));
- }
-}
-/* Likewise, but callable from the debugger. */
+ for (access = VEC_index (access_p, access_vec, 0);
+ access;
+ access = access->next_grp)
+ generate_subtree_copies (access, parm, 0, 0, 0, &gsi, true, true);
+ }
-void
-debug_sra_elt_name (struct sra_elt *elt)
-{
- dump_sra_elt_name (stderr, elt);
- fputc ('\n', stderr);
+ if (seq)
+ gsi_insert_seq_on_edge_immediate (single_succ_edge (ENTRY_BLOCK_PTR), seq);
}
-void
-sra_init_cache (void)
+/* The "main" function of intraprocedural SRA passes. Runs the analysis and if
+ it reveals there are components of some aggregates to be scalarized, it runs
+ the required transformations. */
+static unsigned int
+perform_intra_sra (void)
{
- if (sra_type_decomp_cache)
- return;
+ int ret = 0;
+ sra_initialize ();
- sra_type_decomp_cache = BITMAP_ALLOC (NULL);
- sra_type_inst_cache = BITMAP_ALLOC (NULL);
-}
+ if (!find_var_candidates ())
+ goto out;
+ if (!scan_function (build_access_from_expr, build_accesses_from_assign, NULL,
+ true, NULL))
+ goto out;
-/* Main entry point. */
+ if (!analyze_all_variable_accesses ())
+ goto out;
-static unsigned int
-tree_sra (void)
-{
- /* Initialize local variables. */
- gcc_obstack_init (&sra_obstack);
- sra_candidates = BITMAP_ALLOC (NULL);
- needs_copy_in = BITMAP_ALLOC (NULL);
- sra_init_cache ();
- sra_map = htab_create (101, sra_elt_hash, sra_elt_eq, NULL);
-
- /* Scan. If we find anything, instantiate and scalarize. */
- if (find_candidates_for_sra ())
- {
- scan_function ();
- decide_instantiations ();
- scalarize_function ();
- }
+ scan_function (sra_modify_expr, sra_modify_assign, NULL,
+ false, NULL);
+ initialize_parameter_reductions ();
+ ret = TODO_update_ssa;
- /* Free allocated memory. */
- htab_delete (sra_map);
- sra_map = NULL;
- BITMAP_FREE (sra_candidates);
- BITMAP_FREE (needs_copy_in);
- BITMAP_FREE (sra_type_decomp_cache);
- BITMAP_FREE (sra_type_inst_cache);
- obstack_free (&sra_obstack, NULL);
- return 0;
+ out:
+ sra_deinitialize ();
+ return ret;
}
+/* Perform early intraprocedural SRA. */
static unsigned int
-tree_sra_early (void)
+early_intra_sra (void)
{
- unsigned int ret;
-
- early_sra = true;
- ret = tree_sra ();
- early_sra = false;
+ sra_mode = SRA_MODE_EARLY_INTRA;
+ return perform_intra_sra ();
+}
- return ret;
+/* Perform "late" intraprocedural SRA. */
+static unsigned int
+late_intra_sra (void)
+{
+ sra_mode = SRA_MODE_INTRA;
+ return perform_intra_sra ();
}
+
static bool
-gate_sra (void)
+gate_intra_sra (void)
{
return flag_tree_sra != 0;
}
+
struct gimple_opt_pass pass_sra_early =
{
{
GIMPLE_PASS,
- "esra", /* name */
- gate_sra, /* gate */
- tree_sra_early, /* execute */
+ "esra", /* name */
+ gate_intra_sra, /* gate */
+ early_intra_sra, /* execute */
NULL, /* sub */
NULL, /* next */
0, /* static_pass_number */
TV_TREE_SRA, /* tv_id */
- PROP_cfg | PROP_ssa, /* properties_required */
+ PROP_cfg | PROP_ssa, /* properties_required */
0, /* properties_provided */
- 0, /* properties_destroyed */
+ 0, /* properties_destroyed */
0, /* todo_flags_start */
TODO_dump_func
| TODO_update_ssa
@@ -3683,20 +2327,21 @@ struct gimple_opt_pass pass_sra_early =
}
};
+
struct gimple_opt_pass pass_sra =
{
{
GIMPLE_PASS,
- "sra", /* name */
- gate_sra, /* gate */
- tree_sra, /* execute */
+ "sra", /* name */
+ gate_intra_sra, /* gate */
+ late_intra_sra, /* execute */
NULL, /* sub */
NULL, /* next */
0, /* static_pass_number */
TV_TREE_SRA, /* tv_id */
- PROP_cfg | PROP_ssa, /* properties_required */
+ PROP_cfg | PROP_ssa, /* properties_required */
0, /* properties_provided */
- 0, /* properties_destroyed */
+ 0, /* properties_destroyed */
TODO_update_address_taken, /* todo_flags_start */
TODO_dump_func
| TODO_update_ssa
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index 8982280fb2c..6cbec5de2bf 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -155,10 +155,13 @@ ptr_deref_may_alias_global_p (tree ptr)
if (!pi)
return true;
+ /* ??? This does not use TBAA to prune globals ptr may not access. */
return pt_solution_includes_global (&pi->pt);
}
-/* Return true if dereferencing PTR may alias DECL. */
+/* Return true if dereferencing PTR may alias DECL.
+ The caller is responsible for applying TBAA to see if PTR
+ may access DECL at all. */
static bool
ptr_deref_may_alias_decl_p (tree ptr, tree decl)
@@ -190,7 +193,9 @@ ptr_deref_may_alias_decl_p (tree ptr, tree decl)
return pt_solution_includes (&pi->pt, decl);
}
-/* Return true if dereferenced PTR1 and PTR2 may alias. */
+/* Return true if dereferenced PTR1 and PTR2 may alias.
+ The caller is responsible for applying TBAA to see if accesses
+ through PTR1 and PTR2 may conflict at all. */
static bool
ptr_derefs_may_alias_p (tree ptr1, tree ptr2)
@@ -222,85 +227,11 @@ ptr_derefs_may_alias_p (tree ptr1, tree ptr2)
if (!pi1 || !pi2)
return true;
+ /* ??? This does not use TBAA to prune decls from the intersection
+ that not both pointers may access. */
return pt_solutions_intersect (&pi1->pt, &pi2->pt);
}
-/* Return true if STMT is an "escape" site from the current function. Escape
- sites those statements which might expose the address of a variable
- outside the current function. STMT is an escape site iff:
-
- 1- STMT is a function call, or
- 2- STMT is an __asm__ expression, or
- 3- STMT is an assignment to a non-local variable, or
- 4- STMT is a return statement.
-
- Return the type of escape site found, if we found one, or NO_ESCAPE
- if none. */
-
-enum escape_type
-is_escape_site (gimple stmt)
-{
- if (is_gimple_call (stmt))
- {
- if (gimple_call_flags (stmt) & (ECF_PURE | ECF_CONST))
- return ESCAPE_TO_PURE_CONST;
-
- return ESCAPE_TO_CALL;
- }
- else if (gimple_code (stmt) == GIMPLE_ASM)
- return ESCAPE_TO_ASM;
- else if (is_gimple_assign (stmt))
- {
- tree lhs = gimple_assign_lhs (stmt);
-
- /* Get to the base of _REF nodes. */
- if (TREE_CODE (lhs) != SSA_NAME)
- lhs = get_base_address (lhs);
-
- /* If we couldn't recognize the LHS of the assignment, assume that it
- is a non-local store. */
- if (lhs == NULL_TREE)
- return ESCAPE_UNKNOWN;
-
- if (gimple_assign_cast_p (stmt))
- {
- tree from = TREE_TYPE (gimple_assign_rhs1 (stmt));
- tree to = TREE_TYPE (lhs);
-
- /* If the RHS is a conversion between a pointer and an integer, the
- pointer escapes since we can't track the integer. */
- if (POINTER_TYPE_P (from) && !POINTER_TYPE_P (to))
- return ESCAPE_BAD_CAST;
- }
-
- /* If the LHS is an SSA name, it can't possibly represent a non-local
- memory store. */
- if (TREE_CODE (lhs) == SSA_NAME)
- return NO_ESCAPE;
-
- /* If the LHS is a non-global decl, it isn't a non-local memory store.
- If the LHS escapes, the RHS escape is dealt with in the PTA solver. */
- if (DECL_P (lhs)
- && !is_global_var (lhs))
- return NO_ESCAPE;
-
- /* FIXME: LHS is not an SSA_NAME. Even if it's an assignment to a
- local variables we cannot be sure if it will escape, because we
- don't have information about objects not in SSA form. Need to
- implement something along the lines of
-
- J.-D. Choi, M. Gupta, M. J. Serrano, V. C. Sreedhar, and S. P.
- Midkiff, ``Escape analysis for java,'' in Proceedings of the
- Conference on Object-Oriented Programming Systems, Languages, and
- Applications (OOPSLA), pp. 1-19, 1999. */
- return ESCAPE_STORED_IN_GLOBAL;
- }
- else if (gimple_code (stmt) == GIMPLE_RETURN)
- return ESCAPE_TO_RETURN;
-
- return NO_ESCAPE;
-}
-
/* Dump alias information on FILE. */
@@ -323,7 +254,14 @@ dump_alias_info (FILE *file)
dump_variable (file, var);
}
- fprintf (file, "\n\nFlow-insensitive points-to information for %s\n\n", funcname);
+ fprintf (file, "\nCall clobber information\n");
+
+ fprintf (file, "\nESCAPED");
+ dump_points_to_solution (file, &cfun->gimple_df->escaped);
+ fprintf (file, "\nCALLUSED");
+ dump_points_to_solution (file, &cfun->gimple_df->callused);
+
+ fprintf (file, "\n\nFlow-insensitive points-to information\n\n");
for (i = 1; i < num_ssa_names; i++)
{
@@ -373,37 +311,45 @@ get_ptr_info (tree t)
return pi;
}
-/* Dump points-to information for SSA_NAME PTR into FILE. */
+/* Dump the points-to set *PT into FILE. */
void
-dump_points_to_info_for (FILE *file, tree ptr)
+dump_points_to_solution (FILE *file, struct pt_solution *pt)
{
- struct ptr_info_def *pi = SSA_NAME_PTR_INFO (ptr);
+ if (pt->anything)
+ fprintf (file, ", points-to anything");
- print_generic_expr (file, ptr, dump_flags);
+ if (pt->nonlocal)
+ fprintf (file, ", points-to non-local");
- if (pi)
+ if (pt->escaped)
+ fprintf (file, ", points-to escaped");
+
+ if (pt->null)
+ fprintf (file, ", points-to NULL");
+
+ if (pt->vars)
{
- if (pi->pt.anything)
- fprintf (file, ", points-to anything");
+ fprintf (file, ", points-to vars: ");
+ dump_decl_set (file, pt->vars);
+ if (pt->vars_contains_global)
+ fprintf (file, " (includes global vars)");
+ }
+}
- if (pi->pt.nonlocal)
- fprintf (file, ", points-to non-local");
+/* Dump points-to information for SSA_NAME PTR into FILE. */
- if (pi->pt.escaped)
- fprintf (file, ", points-to escaped");
+void
+dump_points_to_info_for (FILE *file, tree ptr)
+{
+ struct ptr_info_def *pi = SSA_NAME_PTR_INFO (ptr);
- if (pi->pt.null)
- fprintf (file, ", points-to NULL");
+ print_generic_expr (file, ptr, dump_flags);
- if (pi->pt.vars)
- {
- fprintf (file, ", points-to vars: ");
- dump_decl_set (file, pi->pt.vars);
- if (pi->pt.vars_contains_global)
- fprintf (file, " (includes global vars)");
- }
- }
+ if (pi)
+ dump_points_to_solution (file, &pi->pt);
+ else
+ fprintf (file, ", points-to anything");
fprintf (file, "\n");
}
@@ -417,6 +363,55 @@ debug_points_to_info_for (tree var)
dump_points_to_info_for (stderr, var);
}
+
+/* Initializes the alias-oracle reference representation *R from REF. */
+
+void
+ao_ref_init (ao_ref *r, tree ref)
+{
+ r->ref = ref;
+ r->base = NULL_TREE;
+ r->offset = 0;
+ r->size = -1;
+ r->max_size = -1;
+ r->ref_alias_set = -1;
+ r->base_alias_set = -1;
+}
+
+/* Returns the base object of the memory reference *REF. */
+
+tree
+ao_ref_base (ao_ref *ref)
+{
+ if (ref->base)
+ return ref->base;
+ ref->base = get_ref_base_and_extent (ref->ref, &ref->offset, &ref->size,
+ &ref->max_size);
+ return ref->base;
+}
+
+/* Returns the base object alias set of the memory reference *REF. */
+
+static alias_set_type ATTRIBUTE_UNUSED
+ao_ref_base_alias_set (ao_ref *ref)
+{
+ if (ref->base_alias_set != -1)
+ return ref->base_alias_set;
+ ref->base_alias_set = get_alias_set (ao_ref_base (ref));
+ return ref->base_alias_set;
+}
+
+/* Returns the reference alias set of the memory reference *REF. */
+
+alias_set_type
+ao_ref_alias_set (ao_ref *ref)
+{
+ if (ref->ref_alias_set != -1)
+ return ref->ref_alias_set;
+ ref->ref_alias_set = get_alias_set (ref->ref);
+ return ref->ref_alias_set;
+}
+
/* Return 1 if TYPE1 and TYPE2 are to be considered equivalent for the
purpose of TBAA. Return 0 if they are distinct and -1 if we cannot
decide. */
@@ -468,8 +463,7 @@ nonaliasing_component_refs_p (tree ref1, tree type1,
/* Now search for the type1 in the access path of ref2. This
would be a common base for doing offset based disambiguation on. */
- /* Skip the outermost ref - we would have caught that earlier. */
- refp = &TREE_OPERAND (ref2, 0);
+ refp = &ref2;
while (handled_component_p (*refp)
&& same_type_for_tbaa (TREE_TYPE (*refp), type1) == 0)
refp = &TREE_OPERAND (*refp, 0);
@@ -485,7 +479,7 @@ nonaliasing_component_refs_p (tree ref1, tree type1,
return ranges_overlap_p (offset1, max_size1, offset2, max_size2);
}
/* If we didn't find a common base, try the other way around. */
- refp = &TREE_OPERAND (ref1, 0);
+ refp = &ref1;
while (handled_component_p (*refp)
&& same_type_for_tbaa (TREE_TYPE (*refp), type2) == 0)
refp = &TREE_OPERAND (*refp, 0);
@@ -653,26 +647,35 @@ indirect_refs_may_alias_p (tree ref1, tree ptr1,
/* Return true, if the two memory references REF1 and REF2 may alias. */
static bool
-refs_may_alias_p_1 (tree ref1, tree ref2)
+refs_may_alias_p_1 (ao_ref *ref1, ao_ref *ref2, bool tbaa_p)
{
tree base1, base2;
HOST_WIDE_INT offset1 = 0, offset2 = 0;
HOST_WIDE_INT size1 = -1, size2 = -1;
HOST_WIDE_INT max_size1 = -1, max_size2 = -1;
bool var1_p, var2_p, ind1_p, ind2_p;
-
- gcc_assert ((SSA_VAR_P (ref1)
- || handled_component_p (ref1)
- || INDIRECT_REF_P (ref1)
- || TREE_CODE (ref1) == TARGET_MEM_REF)
- && (SSA_VAR_P (ref2)
- || handled_component_p (ref2)
- || INDIRECT_REF_P (ref2)
- || TREE_CODE (ref2) == TARGET_MEM_REF));
+ alias_set_type set;
+
+ gcc_assert ((!ref1->ref
+ || SSA_VAR_P (ref1->ref)
+ || handled_component_p (ref1->ref)
+ || INDIRECT_REF_P (ref1->ref)
+ || TREE_CODE (ref1->ref) == TARGET_MEM_REF)
+ && (!ref2->ref
+ || SSA_VAR_P (ref2->ref)
+ || handled_component_p (ref2->ref)
+ || INDIRECT_REF_P (ref2->ref)
+ || TREE_CODE (ref2->ref) == TARGET_MEM_REF));
/* Decompose the references into their base objects and the access. */
- base1 = get_ref_base_and_extent (ref1, &offset1, &size1, &max_size1);
- base2 = get_ref_base_and_extent (ref2, &offset2, &size2, &max_size2);
+ base1 = ao_ref_base (ref1);
+ offset1 = ref1->offset;
+ size1 = ref1->size;
+ max_size1 = ref1->max_size;
+ base2 = ao_ref_base (ref2);
+ offset2 = ref2->offset;
+ size2 = ref2->size;
+ max_size2 = ref2->max_size;
/* We can end up with registers or constants as bases for example from
*D.1663_44 = VIEW_CONVERT_EXPR<struct DB_LSN>(__tmp$B0F64_59);
@@ -694,35 +697,38 @@ refs_may_alias_p_1 (tree ref1, tree ref2)
base2, offset2, max_size2);
/* First defer to TBAA if possible. */
- if (flag_strict_aliasing
- && !alias_sets_conflict_p (get_alias_set (ref1), get_alias_set (ref2)))
+ if (tbaa_p
+ && flag_strict_aliasing
+ && !alias_sets_conflict_p (ao_ref_alias_set (ref1),
+ ao_ref_alias_set (ref2)))
return false;
/* If one reference is a TARGET_MEM_REF weird things are allowed. Still
TBAA disambiguation based on the access type is possible, so bail
out only after that check. */
- if (TREE_CODE (ref1) == TARGET_MEM_REF
- || TREE_CODE (ref2) == TARGET_MEM_REF)
+ if ((ref1->ref && TREE_CODE (ref1->ref) == TARGET_MEM_REF)
+ || (ref2->ref && TREE_CODE (ref2->ref) == TARGET_MEM_REF))
return true;
/* Dispatch to the pointer-vs-decl or pointer-vs-pointer disambiguators. */
ind1_p = INDIRECT_REF_P (base1);
ind2_p = INDIRECT_REF_P (base2);
+ set = tbaa_p ? -1 : 0;
if (var1_p && ind2_p)
- return indirect_ref_may_alias_decl_p (ref2, TREE_OPERAND (base2, 0),
- offset2, max_size2, -1,
- ref1, base1,
- offset1, max_size1, -1);
+ return indirect_ref_may_alias_decl_p (ref2->ref, TREE_OPERAND (base2, 0),
+ offset2, max_size2, set,
+ ref1->ref, base1,
+ offset1, max_size1, set);
else if (ind1_p && var2_p)
- return indirect_ref_may_alias_decl_p (ref1, TREE_OPERAND (base1, 0),
- offset1, max_size1, -1,
- ref2, base2,
- offset2, max_size2, -1);
+ return indirect_ref_may_alias_decl_p (ref1->ref, TREE_OPERAND (base1, 0),
+ offset1, max_size1, set,
+ ref2->ref, base2,
+ offset2, max_size2, set);
else if (ind1_p && ind2_p)
- return indirect_refs_may_alias_p (ref1, TREE_OPERAND (base1, 0),
- offset1, max_size1, -1,
- ref2, TREE_OPERAND (base2, 0),
- offset2, max_size2, -1);
+ return indirect_refs_may_alias_p (ref1->ref, TREE_OPERAND (base1, 0),
+ offset1, max_size1, set,
+ ref2->ref, TREE_OPERAND (base2, 0),
+ offset2, max_size2, set);
gcc_unreachable ();
}
@@ -730,7 +736,11 @@ refs_may_alias_p_1 (tree ref1, tree ref2)
bool
refs_may_alias_p (tree ref1, tree ref2)
{
- bool res = refs_may_alias_p_1 (ref1, ref2);
+ ao_ref r1, r2;
+ bool res;
+ ao_ref_init (&r1, ref1);
+ ao_ref_init (&r2, ref2);
+ res = refs_may_alias_p_1 (&r1, &r2, true);
if (res)
++alias_stats.refs_may_alias_p_may_alias;
else
@@ -738,6 +748,29 @@ refs_may_alias_p (tree ref1, tree ref2)
return res;
}
+/* Returns true if there is a anti-dependence for the STORE that
+ executes after the LOAD. */
+
+bool
+refs_anti_dependent_p (tree load, tree store)
+{
+ ao_ref r1, r2;
+ ao_ref_init (&r1, load);
+ ao_ref_init (&r2, store);
+ return refs_may_alias_p_1 (&r1, &r2, false);
+}
+
+/* Returns true if there is a output dependence for the stores
+ STORE1 and STORE2. */
+
+bool
+refs_output_dependent_p (tree store1, tree store2)
+{
+ ao_ref r1, r2;
+ ao_ref_init (&r1, store1);
+ ao_ref_init (&r2, store2);
+ return refs_may_alias_p_1 (&r1, &r2, false);
+}
/* If the call CALL may use the memory reference REF return true,
otherwise return false. */
@@ -865,7 +898,7 @@ ref_maybe_used_by_stmt_p (gimple stmt, tree ref)
return true, otherwise return false. */
static bool
-call_may_clobber_ref_p_1 (gimple call, tree ref)
+call_may_clobber_ref_p_1 (gimple call, ao_ref *ref)
{
tree base;
@@ -874,7 +907,7 @@ call_may_clobber_ref_p_1 (gimple call, tree ref)
& (ECF_PURE|ECF_CONST|ECF_LOOPING_CONST_OR_PURE|ECF_NOVOPS))
return false;
- base = get_base_address (ref);
+ base = ao_ref_base (ref);
if (!base)
return true;
@@ -915,10 +948,13 @@ call_may_clobber_ref_p_1 (gimple call, tree ref)
return true;
}
-static bool
+static bool ATTRIBUTE_UNUSED
call_may_clobber_ref_p (gimple call, tree ref)
{
- bool res = call_may_clobber_ref_p_1 (call, ref);
+ bool res;
+ ao_ref r;
+ ao_ref_init (&r, ref);
+ res = call_may_clobber_ref_p_1 (call, &r);
if (res)
++alias_stats.call_may_clobber_ref_p_may_alias;
else
@@ -931,34 +967,52 @@ call_may_clobber_ref_p (gimple call, tree ref)
otherwise return false. */
bool
-stmt_may_clobber_ref_p (gimple stmt, tree ref)
+stmt_may_clobber_ref_p_1 (gimple stmt, ao_ref *ref)
{
if (is_gimple_call (stmt))
{
tree lhs = gimple_call_lhs (stmt);
if (lhs
- && !is_gimple_reg (lhs)
- && refs_may_alias_p (ref, lhs))
- return true;
+ && !is_gimple_reg (lhs))
+ {
+ ao_ref r;
+ ao_ref_init (&r, lhs);
+ if (refs_may_alias_p_1 (ref, &r, true))
+ return true;
+ }
- return call_may_clobber_ref_p (stmt, ref);
+ return call_may_clobber_ref_p_1 (stmt, ref);
}
else if (is_gimple_assign (stmt))
- return refs_may_alias_p (ref, gimple_assign_lhs (stmt));
+ {
+ ao_ref r;
+ ao_ref_init (&r, gimple_assign_lhs (stmt));
+ return refs_may_alias_p_1 (ref, &r, true);
+ }
else if (gimple_code (stmt) == GIMPLE_ASM)
return true;
return false;
}
-static tree get_continuation_for_phi (gimple, tree, bitmap *);
+bool
+stmt_may_clobber_ref_p (gimple stmt, tree ref)
+{
+ ao_ref r;
+ ao_ref_init (&r, ref);
+ return stmt_may_clobber_ref_p_1 (stmt, &r);
+}
+
+
+static tree get_continuation_for_phi (gimple, ao_ref *, bitmap *);
/* Walk the virtual use-def chain of VUSE until hitting the virtual operand
TARGET or a statement clobbering the memory reference REF in which
case false is returned. The walk starts with VUSE, one argument of PHI. */
static bool
-maybe_skip_until (gimple phi, tree target, tree ref, tree vuse, bitmap *visited)
+maybe_skip_until (gimple phi, tree target, ao_ref *ref,
+ tree vuse, bitmap *visited)
{
if (!*visited)
*visited = BITMAP_ALLOC (NULL);
@@ -982,7 +1036,7 @@ maybe_skip_until (gimple phi, tree target, tree ref, tree vuse, bitmap *visited)
}
/* A clobbering statement or the end of the IL ends it failing. */
else if (gimple_nop_p (def_stmt)
- || stmt_may_clobber_ref_p (def_stmt, ref))
+ || stmt_may_clobber_ref_p_1 (def_stmt, ref))
return false;
vuse = gimple_vuse (def_stmt);
}
@@ -996,7 +1050,7 @@ maybe_skip_until (gimple phi, tree target, tree ref, tree vuse, bitmap *visited)
be found. */
static tree
-get_continuation_for_phi (gimple phi, tree ref, bitmap *visited)
+get_continuation_for_phi (gimple phi, ao_ref *ref, bitmap *visited)
{
unsigned nargs = gimple_phi_num_args (phi);
@@ -1044,11 +1098,19 @@ get_continuation_for_phi (gimple phi, tree ref, bitmap *visited)
WALKER returns non-NULL the walk stops and its result is returned.
At the end of a non-successful walk NULL is returned.
+ TRANSLATE if non-NULL is called with a pointer to REF, the virtual
+ use which definition is a statement that may clobber REF and DATA.
+ If TRANSLATE returns (void *)-1 the walk stops and NULL is returned.
+ If TRANSLATE returns non-NULL the walk stops and its result is returned.
+ If TRANSLATE returns NULL the walk continues and TRANSLATE is supposed
+ to adjust REF and *DATA to make that valid.
+
TODO: Cache the vector of equivalent vuses per ref, vuse pair. */
void *
-walk_non_aliased_vuses (tree ref, tree vuse,
- void *(*walker)(tree, tree, void *), void *data)
+walk_non_aliased_vuses (ao_ref *ref, tree vuse,
+ void *(*walker)(ao_ref *, tree, void *),
+ void *(*translate)(ao_ref *, tree, void *), void *data)
{
bitmap visited = NULL;
void *res;
@@ -1071,8 +1133,22 @@ walk_non_aliased_vuses (tree ref, tree vuse,
vuse = get_continuation_for_phi (def_stmt, ref, &visited);
else
{
- if (stmt_may_clobber_ref_p (def_stmt, ref))
- break;
+ if (stmt_may_clobber_ref_p_1 (def_stmt, ref))
+ {
+ if (!translate)
+ break;
+ res = (*translate) (ref, vuse, data);
+ /* Failed lookup and translation. */
+ if (res == (void *)-1)
+ {
+ res = NULL;
+ break;
+ }
+ /* Lookup succeeded. */
+ else if (res != NULL)
+ break;
+ /* Translation succeeded, continue walking. */
+ }
vuse = gimple_vuse (def_stmt);
}
}
diff --git a/gcc/tree-ssa-alias.h b/gcc/tree-ssa-alias.h
index 5f951ae1625..9115e61c22c 100644
--- a/gcc/tree-ssa-alias.h
+++ b/gcc/tree-ssa-alias.h
@@ -24,26 +24,6 @@
#include "coretypes.h"
-/* The reasons a variable may escape a function. */
-enum escape_type
-{
- NO_ESCAPE = 0, /* Doesn't escape. */
- ESCAPE_STORED_IN_GLOBAL = 1 << 0,
- ESCAPE_TO_ASM = 1 << 1, /* Passed by address to an assembly
- statement. */
- ESCAPE_TO_CALL = 1 << 2, /* Escapes to a function call. */
- ESCAPE_BAD_CAST = 1 << 3, /* Cast from pointer to integer */
- ESCAPE_TO_RETURN = 1 << 4, /* Returned from function. */
- ESCAPE_TO_PURE_CONST = 1 << 5, /* Escapes to a pure or constant
- function call. */
- ESCAPE_IS_GLOBAL = 1 << 6, /* Is a global variable. */
- ESCAPE_IS_PARM = 1 << 7, /* Is an incoming function argument. */
- ESCAPE_UNKNOWN = 1 << 8 /* We believe it escapes for
- some reason not enumerated
- above. */
-};
-
-
/* The points-to solution.
The points-to solution is a union of pt_vars and the abstract
@@ -74,20 +54,56 @@ struct GTY(()) pt_solution
};
+/* Simplified and cached information about a memory reference tree.
+ Used by the alias-oracle internally and externally in alternate
+ interfaces. */
+typedef struct ao_ref_s
+{
+ /* The original full memory reference tree or NULL_TREE if that is
+ not available. */
+ tree ref;
+
+ /* The following fields are the decomposed reference as returned
+ by get_ref_base_and_extent. */
+ /* The base object of the memory reference or NULL_TREE if all of
+ the following fields are not yet computed. */
+ tree base;
+ /* The offset relative to the base. */
+ HOST_WIDE_INT offset;
+ /* The size of the access. */
+ HOST_WIDE_INT size;
+ /* The maximum possible extent of the access or -1 if unconstrained. */
+ HOST_WIDE_INT max_size;
+
+ /* The alias set of the access or -1 if not yet computed. */
+ alias_set_type ref_alias_set;
+
+ /* The alias set of the base object or -1 if not yet computed. */
+ alias_set_type base_alias_set;
+} ao_ref;
+
+
/* In tree-ssa-alias.c */
-extern enum escape_type is_escape_site (gimple);
+extern void ao_ref_init (ao_ref *, tree);
+extern tree ao_ref_base (ao_ref *);
+extern alias_set_type ao_ref_alias_set (ao_ref *);
extern bool ptr_deref_may_alias_global_p (tree);
extern bool refs_may_alias_p (tree, tree);
+extern bool refs_anti_dependent_p (tree, tree);
+extern bool refs_output_dependent_p (tree, tree);
extern bool ref_maybe_used_by_stmt_p (gimple, tree);
extern bool stmt_may_clobber_ref_p (gimple, tree);
-extern void *walk_non_aliased_vuses (tree, tree,
- void *(*)(tree, tree, void *), void *);
+extern bool stmt_may_clobber_ref_p_1 (gimple, ao_ref *);
+extern void *walk_non_aliased_vuses (ao_ref *, tree,
+ void *(*)(ao_ref *, tree, void *),
+ void *(*)(ao_ref *, tree, void *), void *);
extern unsigned int walk_aliased_vdefs (tree, tree,
bool (*)(tree, tree, void *), void *,
bitmap *);
extern struct ptr_info_def *get_ptr_info (tree);
extern void dump_alias_info (FILE *);
extern void debug_alias_info (void);
+extern void dump_points_to_solution (FILE *, struct pt_solution *);
extern void dump_points_to_info_for (FILE *, tree);
extern void debug_points_to_info_for (tree);
extern void dump_alias_stats (FILE *);
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
index 437d4267dd3..3c88766a998 100644
--- a/gcc/tree-ssa-ccp.c
+++ b/gcc/tree-ssa-ccp.c
@@ -958,6 +958,30 @@ ccp_fold (gimple stmt)
}
}
}
+ else if (TREE_CODE (rhs) == CONSTRUCTOR
+ && TREE_CODE (TREE_TYPE (rhs)) == VECTOR_TYPE
+ && (CONSTRUCTOR_NELTS (rhs)
+ == TYPE_VECTOR_SUBPARTS (TREE_TYPE (rhs))))
+ {
+ unsigned i;
+ tree val, list;
+
+ list = NULL_TREE;
+ FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (rhs), i, val)
+ {
+ if (TREE_CODE (val) == SSA_NAME
+ && get_value (val)->lattice_val == CONSTANT)
+ val = get_value (val)->value;
+ if (TREE_CODE (val) == INTEGER_CST
+ || TREE_CODE (val) == REAL_CST
+ || TREE_CODE (val) == FIXED_CST)
+ list = tree_cons (NULL_TREE, val, list);
+ else
+ return NULL_TREE;
+ }
+
+ return build_vector (TREE_TYPE (rhs), nreverse (list));
+ }
if (kind == tcc_reference)
{
@@ -1024,7 +1048,8 @@ ccp_fold (gimple stmt)
if (!useless_type_conversion_p (TREE_TYPE (lhs),
TREE_TYPE (op0))
&& ((tem = maybe_fold_offset_to_address
- (op0, integer_zero_node, TREE_TYPE (lhs)))
+ (gimple_location (stmt),
+ op0, integer_zero_node, TREE_TYPE (lhs)))
!= NULL_TREE))
return tem;
return op0;
@@ -1061,8 +1086,8 @@ ccp_fold (gimple stmt)
&& TREE_CODE (op1) == INTEGER_CST)
{
tree lhs = gimple_assign_lhs (stmt);
- tree tem = maybe_fold_offset_to_address (op0, op1,
- TREE_TYPE (lhs));
+ tree tem = maybe_fold_offset_to_address
+ (gimple_location (stmt), op0, op1, TREE_TYPE (lhs));
if (tem != NULL_TREE)
return tem;
}
@@ -1620,10 +1645,13 @@ struct gimple_opt_pass pass_ccp =
/* A subroutine of fold_stmt. Attempts to fold *(A+O) to A[X].
BASE is an array type. OFFSET is a byte displacement. ORIG_TYPE
- is the desired result type. */
+ is the desired result type.
+
+ LOC is the location of the original expression. */
static tree
-maybe_fold_offset_to_array_ref (tree base, tree offset, tree orig_type,
+maybe_fold_offset_to_array_ref (location_t loc, tree base, tree offset,
+ tree orig_type,
bool allow_negative_idx)
{
tree min_idx, idx, idx_type, elt_offset = integer_zero_node;
@@ -1756,16 +1784,23 @@ maybe_fold_offset_to_array_ref (tree base, tree offset, tree orig_type,
&& compare_tree_int (idx, 0) < 0)
return NULL_TREE;
- return build4 (ARRAY_REF, elt_type, base, idx, NULL_TREE, NULL_TREE);
+ {
+ tree t = build4 (ARRAY_REF, elt_type, base, idx, NULL_TREE, NULL_TREE);
+ SET_EXPR_LOCATION (t, loc);
+ return t;
+ }
}
/* Attempt to fold *(S+O) to S.X.
BASE is a record type. OFFSET is a byte displacement. ORIG_TYPE
- is the desired result type. */
+ is the desired result type.
+
+ LOC is the location of the original expression. */
static tree
-maybe_fold_offset_to_component_ref (tree record_type, tree base, tree offset,
+maybe_fold_offset_to_component_ref (location_t loc, tree record_type,
+ tree base, tree offset,
tree orig_type, bool base_is_ptr)
{
tree f, t, field_type, tail_array_field, field_offset;
@@ -1848,14 +1883,16 @@ maybe_fold_offset_to_component_ref (tree record_type, tree base, tree offset,
new_base = build1 (INDIRECT_REF, record_type, base);
else
new_base = base;
+ protected_set_expr_location (new_base, loc);
new_base = build3 (COMPONENT_REF, field_type, new_base, f, NULL_TREE);
+ protected_set_expr_location (new_base, loc);
/* Recurse to possibly find the match. */
- ret = maybe_fold_offset_to_array_ref (new_base, t, orig_type,
+ ret = maybe_fold_offset_to_array_ref (loc, new_base, t, orig_type,
f == TYPE_FIELDS (record_type));
if (ret)
return ret;
- ret = maybe_fold_offset_to_component_ref (field_type, new_base, t,
+ ret = maybe_fold_offset_to_component_ref (loc, field_type, new_base, t,
orig_type, false);
if (ret)
return ret;
@@ -1871,25 +1908,32 @@ maybe_fold_offset_to_component_ref (tree record_type, tree base, tree offset,
/* If we get here, we've got an aggregate field, and a possibly
nonzero offset into them. Recurse and hope for a valid match. */
if (base_is_ptr)
- base = build1 (INDIRECT_REF, record_type, base);
+ {
+ base = build1 (INDIRECT_REF, record_type, base);
+ SET_EXPR_LOCATION (base, loc);
+ }
base = build3 (COMPONENT_REF, field_type, base, f, NULL_TREE);
+ SET_EXPR_LOCATION (base, loc);
- t = maybe_fold_offset_to_array_ref (base, offset, orig_type,
+ t = maybe_fold_offset_to_array_ref (loc, base, offset, orig_type,
f == TYPE_FIELDS (record_type));
if (t)
return t;
- return maybe_fold_offset_to_component_ref (field_type, base, offset,
+ return maybe_fold_offset_to_component_ref (loc, field_type, base, offset,
orig_type, false);
}
/* Attempt to express (ORIG_TYPE)BASE+OFFSET as BASE->field_of_orig_type
- or BASE[index] or by combination of those.
+ or BASE[index] or by combination of those.
+
+ LOC is the location of original expression.
Before attempting the conversion strip off existing ADDR_EXPRs and
handled component refs. */
tree
-maybe_fold_offset_to_reference (tree base, tree offset, tree orig_type)
+maybe_fold_offset_to_reference (location_t loc, tree base, tree offset,
+ tree orig_type)
{
tree ret;
tree type;
@@ -1936,13 +1980,17 @@ maybe_fold_offset_to_reference (tree base, tree offset, tree orig_type)
return NULL_TREE;
type = TREE_TYPE (TREE_TYPE (base));
}
- ret = maybe_fold_offset_to_component_ref (type, base, offset,
+ ret = maybe_fold_offset_to_component_ref (loc, type, base, offset,
orig_type, base_is_ptr);
if (!ret)
{
if (base_is_ptr)
- base = build1 (INDIRECT_REF, type, base);
- ret = maybe_fold_offset_to_array_ref (base, offset, orig_type, true);
+ {
+ base = build1 (INDIRECT_REF, type, base);
+ SET_EXPR_LOCATION (base, loc);
+ }
+ ret = maybe_fold_offset_to_array_ref (loc,
+ base, offset, orig_type, true);
}
return ret;
}
@@ -1950,17 +1998,21 @@ maybe_fold_offset_to_reference (tree base, tree offset, tree orig_type)
/* Attempt to express (ORIG_TYPE)&BASE+OFFSET as &BASE->field_of_orig_type
or &BASE[index] or by combination of those.
+ LOC is the location of the original expression.
+
Before attempting the conversion strip off existing component refs. */
tree
-maybe_fold_offset_to_address (tree addr, tree offset, tree orig_type)
+maybe_fold_offset_to_address (location_t loc, tree addr, tree offset,
+ tree orig_type)
{
tree t;
gcc_assert (POINTER_TYPE_P (TREE_TYPE (addr))
&& POINTER_TYPE_P (orig_type));
- t = maybe_fold_offset_to_reference (addr, offset, TREE_TYPE (orig_type));
+ t = maybe_fold_offset_to_reference (loc, addr, offset,
+ TREE_TYPE (orig_type));
if (t != NULL_TREE)
{
tree orig = addr;
@@ -1997,7 +2049,9 @@ maybe_fold_offset_to_address (tree addr, tree offset, tree orig_type)
ptr_type = build_pointer_type (TREE_TYPE (t));
if (!useless_type_conversion_p (orig_type, ptr_type))
return NULL_TREE;
- return build_fold_addr_expr_with_type (t, ptr_type);
+ t = build_fold_addr_expr_with_type (t, ptr_type);
+ protected_set_expr_location (t, loc);
+ return t;
}
return NULL_TREE;
@@ -2011,6 +2065,7 @@ maybe_fold_stmt_indirect (tree expr, tree base, tree offset)
{
tree t;
bool volatile_p = TREE_THIS_VOLATILE (expr);
+ location_t loc = EXPR_LOCATION (expr);
/* We may well have constructed a double-nested PLUS_EXPR via multiple
substitutions. Fold that down to one. Remove NON_LVALUE_EXPRs that
@@ -2051,7 +2106,7 @@ maybe_fold_stmt_indirect (tree expr, tree base, tree offset)
return DECL_INITIAL (base);
/* Try folding *(&B+O) to B.X. */
- t = maybe_fold_offset_to_reference (base_addr, offset,
+ t = maybe_fold_offset_to_reference (loc, base_addr, offset,
TREE_TYPE (expr));
if (t)
{
@@ -2090,7 +2145,7 @@ maybe_fold_stmt_indirect (tree expr, tree base, tree offset)
/* Try folding *(B+O) to B->X. Still an improvement. */
if (POINTER_TYPE_P (TREE_TYPE (base)))
{
- t = maybe_fold_offset_to_reference (base, offset,
+ t = maybe_fold_offset_to_reference (loc, base, offset,
TREE_TYPE (expr));
if (t)
return t;
@@ -2115,7 +2170,7 @@ maybe_fold_stmt_indirect (tree expr, tree base, tree offset)
which may be able to propagate further. */
tree
-maybe_fold_stmt_addition (tree res_type, tree op0, tree op1)
+maybe_fold_stmt_addition (location_t loc, tree res_type, tree op0, tree op1)
{
tree ptd_type;
tree t;
@@ -2212,12 +2267,15 @@ maybe_fold_stmt_addition (tree res_type, tree op0, tree op1)
ptd_type = TREE_TYPE (TREE_TYPE (op0));
/* At which point we can try some of the same things as for indirects. */
- t = maybe_fold_offset_to_array_ref (op0, op1, ptd_type, true);
+ t = maybe_fold_offset_to_array_ref (loc, op0, op1, ptd_type, true);
if (!t)
- t = maybe_fold_offset_to_component_ref (TREE_TYPE (op0), op0, op1,
+ t = maybe_fold_offset_to_component_ref (loc, TREE_TYPE (op0), op0, op1,
ptd_type, false);
if (t)
- t = build1 (ADDR_EXPR, res_type, t);
+ {
+ t = build1 (ADDR_EXPR, res_type, t);
+ SET_EXPR_LOCATION (t, loc);
+ }
return t;
}
@@ -2654,6 +2712,25 @@ fold_gimple_assign (gimple_stmt_iterator *si)
build_fold_addr_expr (tem));
}
+ else if (TREE_CODE (rhs) == CONSTRUCTOR
+ && TREE_CODE (TREE_TYPE (rhs)) == VECTOR_TYPE
+ && (CONSTRUCTOR_NELTS (rhs)
+ == TYPE_VECTOR_SUBPARTS (TREE_TYPE (rhs))))
+ {
+ /* Fold a constant vector CONSTRUCTOR to VECTOR_CST. */
+ unsigned i;
+ tree val;
+
+ FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (rhs), i, val)
+ if (TREE_CODE (val) != INTEGER_CST
+ && TREE_CODE (val) != REAL_CST
+ && TREE_CODE (val) != FIXED_CST)
+ return NULL_TREE;
+
+ return build_vector_from_ctor (TREE_TYPE (rhs),
+ CONSTRUCTOR_ELTS (rhs));
+ }
+
/* If we couldn't fold the RHS, hand over to the generic
fold routines. */
if (result == NULL_TREE)
@@ -2697,7 +2774,8 @@ fold_gimple_assign (gimple_stmt_iterator *si)
&& POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (stmt))))
{
tree type = gimple_expr_type (stmt);
- tree t = maybe_fold_offset_to_address (gimple_assign_rhs1 (stmt),
+ tree t = maybe_fold_offset_to_address (gimple_location (stmt),
+ gimple_assign_rhs1 (stmt),
integer_zero_node, type);
if (t)
return t;
@@ -2717,7 +2795,8 @@ fold_gimple_assign (gimple_stmt_iterator *si)
(TREE_TYPE (gimple_assign_lhs (stmt)), type))
type = TREE_TYPE (gimple_assign_rhs1 (stmt));
}
- result = maybe_fold_stmt_addition (type,
+ result = maybe_fold_stmt_addition (gimple_location (stmt),
+ type,
gimple_assign_rhs1 (stmt),
gimple_assign_rhs2 (stmt));
}
@@ -3023,14 +3102,9 @@ optimize_stack_restore (gimple_stmt_iterator i)
return NULL_TREE;
stack_save_gsi = gsi_for_stmt (stack_save);
- push_stmt_changes (gsi_stmt_ptr (&stack_save_gsi));
rhs = build_int_cst (TREE_TYPE (gimple_call_arg (call, 0)), 0);
if (!update_call_from_tree (&stack_save_gsi, rhs))
- {
- discard_stmt_changes (gsi_stmt_ptr (&stack_save_gsi));
- return NULL_TREE;
- }
- pop_stmt_changes (gsi_stmt_ptr (&stack_save_gsi));
+ return NULL_TREE;
/* No effect, so the statement will be deleted. */
return integer_zero_node;
@@ -3252,8 +3326,6 @@ execute_fold_all_builtins (void)
}
old_stmt = stmt;
- push_stmt_changes (gsi_stmt_ptr (&i));
-
if (!update_call_from_tree (&i, result))
{
gimplify_and_update_call_from_tree (&i, result);
@@ -3261,7 +3333,7 @@ execute_fold_all_builtins (void)
}
stmt = gsi_stmt (i);
- pop_stmt_changes (gsi_stmt_ptr (&i));
+ update_stmt (stmt);
if (maybe_clean_or_replace_eh_stmt (old_stmt, stmt)
&& gimple_purge_dead_eh_edges (bb))
diff --git a/gcc/tree-ssa-copy.c b/gcc/tree-ssa-copy.c
index 9dad1cdc940..d919681fb1a 100644
--- a/gcc/tree-ssa-copy.c
+++ b/gcc/tree-ssa-copy.c
@@ -151,44 +151,6 @@ may_propagate_copy_into_asm (tree dest)
}
-/* Given two SSA_NAMEs pointers ORIG and NEW such that we are copy
- propagating NEW into ORIG, consolidate aliasing information so that
- they both share the same memory tags. */
-
-void
-merge_alias_info (tree orig_name, tree new_name)
-{
- gcc_assert (POINTER_TYPE_P (TREE_TYPE (orig_name))
- && POINTER_TYPE_P (TREE_TYPE (new_name)));
-
-#if defined ENABLE_CHECKING
- gcc_assert (useless_type_conversion_p (TREE_TYPE (orig_name),
- TREE_TYPE (new_name)));
-#endif
-
- /* Check that flow-sensitive information is compatible. Notice that
- we may not merge flow-sensitive information here. This function
- is called when propagating equivalences dictated by the IL, like
- a copy operation P_i = Q_j, and from equivalences dictated by
- control-flow, like if (P_i == Q_j).
-
- In the former case, P_i and Q_j are equivalent in every block
- dominated by the assignment, so their flow-sensitive information
- is always the same. However, in the latter case, the pointers
- P_i and Q_j are only equivalent in one of the sub-graphs out of
- the predicate, so their flow-sensitive information is not the
- same in every block dominated by the predicate.
-
- Since we cannot distinguish one case from another in this
- function, we cannot merge flow-sensitive information by
- intersecting. Instead the only thing we can do is to _not_
- merge flow-sensitive information.
-
- ??? At some point we should enhance this machinery to distinguish
- both cases in the caller. */
-}
-
-
/* Common code for propagate_value and replace_exp.
Replace use operand OP_P with VAL. FOR_PROPAGATION indicates if the
@@ -198,9 +160,8 @@ static void
replace_exp_1 (use_operand_p op_p, tree val,
bool for_propagation ATTRIBUTE_UNUSED)
{
- tree op = USE_FROM_PTR (op_p);
-
#if defined ENABLE_CHECKING
+ tree op = USE_FROM_PTR (op_p);
gcc_assert (!(for_propagation
&& TREE_CODE (op) == SSA_NAME
&& TREE_CODE (val) == SSA_NAME
@@ -208,11 +169,7 @@ replace_exp_1 (use_operand_p op_p, tree val,
#endif
if (TREE_CODE (val) == SSA_NAME)
- {
- if (TREE_CODE (op) == SSA_NAME && POINTER_TYPE_P (TREE_TYPE (op)))
- merge_alias_info (op, val);
- SET_USE (op_p, val);
- }
+ SET_USE (op_p, val);
else
SET_USE (op_p, unsave_expr_now (val));
}
@@ -262,11 +219,7 @@ propagate_tree_value (tree *op_p, tree val)
#endif
if (TREE_CODE (val) == SSA_NAME)
- {
- if (*op_p && TREE_CODE (*op_p) == SSA_NAME && POINTER_TYPE_P (TREE_TYPE (*op_p)))
- merge_alias_info (*op_p, val);
- *op_p = val;
- }
+ *op_p = val;
else
*op_p = unsave_expr_now (val);
}
@@ -872,8 +825,24 @@ fini_copy_prop (void)
for (i = 1; i < num_ssa_names; i++)
{
tree var = ssa_name (i);
- if (var && copy_of[i].value && copy_of[i].value != var)
- tmp[i].value = get_last_copy_of (var);
+ if (!var
+ || !copy_of[i].value
+ || copy_of[i].value == var)
+ continue;
+
+ tmp[i].value = get_last_copy_of (var);
+
+ /* In theory the points-to solution of all members of the
+ copy chain is their intersection. For now we do not bother
+ to compute this but only make sure we do not lose points-to
+ information completely by setting the points-to solution
+ of the representative to the first solution we find if
+ it doesn't have one already. */
+ if (tmp[i].value != var
+ && POINTER_TYPE_P (TREE_TYPE (var))
+ && SSA_NAME_PTR_INFO (var)
+ && !SSA_NAME_PTR_INFO (tmp[i].value))
+ duplicate_ssa_name_ptr_info (tmp[i].value, SSA_NAME_PTR_INFO (var));
}
substitute_and_fold (tmp, false);
diff --git a/gcc/tree-ssa-copyrename.c b/gcc/tree-ssa-copyrename.c
index ac8bba32456..8b15d12d728 100644
--- a/gcc/tree-ssa-copyrename.c
+++ b/gcc/tree-ssa-copyrename.c
@@ -233,20 +233,6 @@ copy_rename_partition_coalesce (var_map map, tree var1, tree var2, FILE *debug)
return false;
}
- /* Don't coalesce if the aliasing sets of the types are different. */
- if (POINTER_TYPE_P (TREE_TYPE (root1))
- && POINTER_TYPE_P (TREE_TYPE (root2))
- && ((get_alias_set (TREE_TYPE (TREE_TYPE (root1)))
- != get_alias_set (TREE_TYPE (TREE_TYPE (root2))))
- || (DECL_P (root1) && DECL_P (root2)
- && DECL_NO_TBAA_P (root1) != DECL_NO_TBAA_P (root2))))
- {
- if (debug)
- fprintf (debug, " : 2 different aliasing sets. No coalesce.\n");
- return false;
- }
-
-
/* Merge the two partitions. */
p3 = partition_union (map->var_partition, p1, p2);
diff --git a/gcc/tree-ssa-dce.c b/gcc/tree-ssa-dce.c
index 293d67a15ce..714a130bf58 100644
--- a/gcc/tree-ssa-dce.c
+++ b/gcc/tree-ssa-dce.c
@@ -295,7 +295,6 @@ mark_stmt_if_obviously_necessary (gimple stmt, bool aggressive)
case GIMPLE_ASM:
case GIMPLE_RESX:
case GIMPLE_RETURN:
- case GIMPLE_CHANGE_DYNAMIC_TYPE:
mark_stmt_necessary (stmt, true);
return;
@@ -997,10 +996,9 @@ eliminate_unnecessary_stmts (void)
fprintf (dump_file, "\n");
}
- push_stmt_changes (gsi_stmt_ptr (&gsi));
gimple_call_set_lhs (stmt, NULL_TREE);
maybe_clean_or_replace_eh_stmt (stmt, stmt);
- pop_stmt_changes (gsi_stmt_ptr (&gsi));
+ update_stmt (stmt);
release_ssa_name (name);
}
notice_special_calls (stmt);
diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c
index 2d1e457757a..d998d94e2b9 100644
--- a/gcc/tree-ssa-dom.c
+++ b/gcc/tree-ssa-dom.c
@@ -134,7 +134,7 @@ static VEC(expr_hash_elt_t,heap) *avail_exprs_stack;
expressions are removed from AVAIL_EXPRS. Else we may change the
hash code for an expression and be unable to find/remove it from
AVAIL_EXPRS. */
-static VEC(gimple_p,heap) *stmts_to_rescan;
+static VEC(gimple,heap) *stmts_to_rescan;
/* Structure for entries in the expression hash table. */
@@ -626,7 +626,7 @@ tree_ssa_dominator_optimize (void)
avail_exprs = htab_create (1024, real_avail_expr_hash, avail_expr_eq, free_expr_hash_elt);
avail_exprs_stack = VEC_alloc (expr_hash_elt_t, heap, 20);
const_and_copies_stack = VEC_alloc (tree, heap, 20);
- stmts_to_rescan = VEC_alloc (gimple_p, heap, 20);
+ stmts_to_rescan = VEC_alloc (gimple, heap, 20);
need_eh_cleanup = BITMAP_ALLOC (NULL);
/* Setup callbacks for the generic dominator tree walker. */
@@ -742,7 +742,7 @@ tree_ssa_dominator_optimize (void)
VEC_free (expr_hash_elt_t, heap, avail_exprs_stack);
VEC_free (tree, heap, const_and_copies_stack);
- VEC_free (gimple_p, heap, stmts_to_rescan);
+ VEC_free (gimple, heap, stmts_to_rescan);
/* Free the value-handle array. */
threadedge_finalize_values ();
@@ -1047,17 +1047,16 @@ dom_opt_finalize_block (struct dom_walk_data *walk_data, basic_block bb)
/* If we queued any statements to rescan in this block, then
go ahead and rescan them now. */
- while (VEC_length (gimple_p, stmts_to_rescan) > 0)
+ while (VEC_length (gimple, stmts_to_rescan) > 0)
{
- gimple *stmt_p = VEC_last (gimple_p, stmts_to_rescan);
- gimple stmt = *stmt_p;
+ gimple stmt = VEC_last (gimple, stmts_to_rescan);
basic_block stmt_bb = gimple_bb (stmt);
if (stmt_bb != bb)
break;
- VEC_pop (gimple_p, stmts_to_rescan);
- pop_stmt_changes (stmt_p);
+ VEC_pop (gimple, stmts_to_rescan);
+ update_stmt (stmt);
}
}
@@ -2130,7 +2129,6 @@ optimize_stmt (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
update_stmt_if_modified (stmt);
opt_stats.num_stmts++;
- push_stmt_changes (gsi_stmt_ptr (&si));
if (dump_file && (dump_flags & TDF_DETAILS))
{
@@ -2253,21 +2251,12 @@ optimize_stmt (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
}
}
+ /* Queue the statement to be re-scanned after all the
+ AVAIL_EXPRS have been processed. The change buffer stack for
+ all the pushed statements will be processed when this queue
+ is emptied. */
if (may_have_exposed_new_symbols)
- {
- /* Queue the statement to be re-scanned after all the
- AVAIL_EXPRS have been processed. The change buffer stack for
- all the pushed statements will be processed when this queue
- is emptied. */
- VEC_safe_push (gimple_p, heap, stmts_to_rescan, gsi_stmt_ptr (&si));
- }
- else
- {
- /* Otherwise, just discard the recently pushed change buffer. If
- not, the STMTS_TO_RESCAN queue will get out of synch with the
- change buffer stack. */
- discard_stmt_changes (gsi_stmt_ptr (&si));
- }
+ VEC_safe_push (gimple, heap, stmts_to_rescan, gsi_stmt (si));
}
/* Search for an existing instance of STMT in the AVAIL_EXPRS table.
@@ -2565,8 +2554,6 @@ propagate_rhs_into_lhs (gimple stmt, tree lhs, tree rhs, bitmap interesting_name
print_gimple_stmt (dump_file, use_stmt, 0, dump_flags);
}
- push_stmt_changes (&use_stmt);
-
/* Propagate the RHS into this use of the LHS. */
FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
propagate_value (use_p, rhs);
@@ -2601,7 +2588,6 @@ propagate_rhs_into_lhs (gimple stmt, tree lhs, tree rhs, bitmap interesting_name
bitmap_set_bit (interesting_names, SSA_NAME_VERSION (result));
}
- discard_stmt_changes (&use_stmt);
continue;
}
else if (gimple_debug_bind_p (use_stmt))
@@ -2620,9 +2606,8 @@ propagate_rhs_into_lhs (gimple stmt, tree lhs, tree rhs, bitmap interesting_name
fold_stmt_inplace (use_stmt);
/* Sometimes propagation can expose new operands to the
- renamer. Note this will call update_stmt at the
- appropriate time. */
- pop_stmt_changes (&use_stmt);
+ renamer. */
+ update_stmt (use_stmt);
/* Dump details. */
if (dump_file && (dump_flags & TDF_DETAILS))
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
index 38a81254e3d..7e380b196ea 100644
--- a/gcc/tree-ssa-forwprop.c
+++ b/gcc/tree-ssa-forwprop.c
@@ -717,6 +717,7 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs,
tree *rhsp, *lhsp;
gimple use_stmt = gsi_stmt (*use_stmt_gsi);
enum tree_code rhs_code;
+ bool res = true;
gcc_assert (TREE_CODE (def_rhs) == ADDR_EXPR);
@@ -739,7 +740,11 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs,
address which we cannot do in a single statement. */
if (!single_use_p
|| (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (def_rhs))
- && !is_gimple_min_invariant (def_rhs)))
+ && (!is_gimple_min_invariant (def_rhs)
+ || (INTEGRAL_TYPE_P (TREE_TYPE (lhs))
+ && POINTER_TYPE_P (TREE_TYPE (def_rhs))
+ && (TYPE_PRECISION (TREE_TYPE (lhs))
+ > TYPE_PRECISION (TREE_TYPE (def_rhs)))))))
return forward_propagate_addr_expr (lhs, def_rhs);
gimple_assign_set_rhs1 (use_stmt, unshare_expr (def_rhs));
@@ -760,19 +765,26 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs,
/* Now see if the LHS node is an INDIRECT_REF using NAME. If so,
propagate the ADDR_EXPR into the use of NAME and fold the result. */
if (TREE_CODE (lhs) == INDIRECT_REF
- && TREE_OPERAND (lhs, 0) == name
- && may_propagate_address_into_dereference (def_rhs, lhs)
- && (lhsp != gimple_assign_lhs_ptr (use_stmt)
- || useless_type_conversion_p (TREE_TYPE (TREE_OPERAND (def_rhs, 0)),
- TREE_TYPE (rhs))))
+ && TREE_OPERAND (lhs, 0) == name)
{
- *lhsp = unshare_expr (TREE_OPERAND (def_rhs, 0));
- fold_stmt_inplace (use_stmt);
- tidy_after_forward_propagate_addr (use_stmt);
+ if (may_propagate_address_into_dereference (def_rhs, lhs)
+ && (lhsp != gimple_assign_lhs_ptr (use_stmt)
+ || useless_type_conversion_p
+ (TREE_TYPE (TREE_OPERAND (def_rhs, 0)), TREE_TYPE (rhs))))
+ {
+ *lhsp = unshare_expr (TREE_OPERAND (def_rhs, 0));
+ fold_stmt_inplace (use_stmt);
+ tidy_after_forward_propagate_addr (use_stmt);
- /* Continue propagating into the RHS if this was not the only use. */
- if (single_use_p)
- return true;
+ /* Continue propagating into the RHS if this was not the only use. */
+ if (single_use_p)
+ return true;
+ }
+ else
+ /* We can have a struct assignment dereferencing our name twice.
+ Note that we didn't propagate into the lhs to not falsely
+ claim we did when propagating into the rhs. */
+ res = false;
}
/* Strip away any outer COMPONENT_REF, ARRAY_REF or ADDR_EXPR
@@ -792,7 +804,7 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs,
*rhsp = unshare_expr (TREE_OPERAND (def_rhs, 0));
fold_stmt_inplace (use_stmt);
tidy_after_forward_propagate_addr (use_stmt);
- return true;
+ return res;
}
/* Now see if the RHS node is an INDIRECT_REF using NAME. If so,
@@ -823,7 +835,7 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs,
true, GSI_NEW_STMT);
gimple_assign_set_rhs1 (use_stmt, new_rhs);
tidy_after_forward_propagate_addr (use_stmt);
- return true;
+ return res;
}
/* If the defining rhs comes from an indirect reference, then do not
convert into a VIEW_CONVERT_EXPR. */
@@ -837,7 +849,7 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs,
*rhsp = new_rhs;
fold_stmt_inplace (use_stmt);
tidy_after_forward_propagate_addr (use_stmt);
- return true;
+ return res;
}
}
@@ -862,7 +874,8 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs,
of the elements in X into &x[C1 + C2/element size]. */
if (TREE_CODE (rhs2) == INTEGER_CST)
{
- tree new_rhs = maybe_fold_stmt_addition (TREE_TYPE (def_rhs),
+ tree new_rhs = maybe_fold_stmt_addition (gimple_location (use_stmt),
+ TREE_TYPE (def_rhs),
def_rhs, rhs2);
if (new_rhs)
{
@@ -943,19 +956,17 @@ forward_propagate_addr_expr (tree name, tree rhs)
{
gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt);
- push_stmt_changes (&use_stmt);
result = forward_propagate_addr_expr_1 (name, rhs, &gsi,
single_use_p);
/* If the use has moved to a different statement adjust
- the update machinery. */
+ the update machinery for the old statement too. */
if (use_stmt != gsi_stmt (gsi))
{
- pop_stmt_changes (&use_stmt);
- use_stmt = gsi_stmt (gsi);
update_stmt (use_stmt);
+ use_stmt = gsi_stmt (gsi);
}
- else
- pop_stmt_changes (&use_stmt);
+
+ update_stmt (use_stmt);
}
all &= result;
@@ -1349,7 +1360,7 @@ tree_ssa_forward_propagate_single_use_vars (void)
static bool
gate_forwprop (void)
{
- return 1;
+ return flag_tree_forwprop;
}
struct gimple_opt_pass pass_forwprop =
diff --git a/gcc/tree-ssa-live.c b/gcc/tree-ssa-live.c
index dc82df0ad3b..e70812dcc8c 100644
--- a/gcc/tree-ssa-live.c
+++ b/gcc/tree-ssa-live.c
@@ -435,6 +435,7 @@ remove_unused_scope_block_p (tree scope)
will be output to file. */
if (TREE_CODE (*t) == FUNCTION_DECL)
unused = false;
+
/* If a decl has a value expr, we need to instantiate it
regardless of debug info generation, to avoid codegen
differences in memory overlap tests. update_equiv_regs() may
@@ -535,7 +536,25 @@ remove_unused_scope_block_p (tree scope)
/* For terse debug info we can eliminate info on unused variables. */
else if (debug_info_level == DINFO_LEVEL_NONE
|| debug_info_level == DINFO_LEVEL_TERSE)
- ;
+ {
+ /* Even for -g0/-g1 don't prune outer scopes from artificial
+ functions, otherwise diagnostics using tree_nonartificial_location
+ will not be emitted properly. */
+ if (inlined_function_outer_scope_p (scope))
+ {
+ tree ao = scope;
+
+ while (ao
+ && TREE_CODE (ao) == BLOCK
+ && BLOCK_ABSTRACT_ORIGIN (ao) != ao)
+ ao = BLOCK_ABSTRACT_ORIGIN (ao);
+ if (ao
+ && TREE_CODE (ao) == FUNCTION_DECL
+ && DECL_DECLARED_INLINE_P (ao)
+ && lookup_attribute ("artificial", DECL_ATTRIBUTES (ao)))
+ unused = false;
+ }
+ }
else if (BLOCK_VARS (scope) || BLOCK_NUM_NONLOCALIZED_VARS (scope))
unused = false;
/* See if this block is important for representation of inlined function.
@@ -562,7 +581,9 @@ mark_all_vars_used (tree *expr_p, void *data)
walk_tree (expr_p, mark_all_vars_used_1, data, NULL);
}
-/* Dump scope blocks. */
+
+/* Dump scope blocks starting at SCOPE to FILE. INDENT is the
+ indentation level and FLAGS is as in print_generic_expr. */
static void
dump_scope_block (FILE *file, int indent, tree scope, int flags)
@@ -616,12 +637,26 @@ dump_scope_block (FILE *file, int indent, tree scope, int flags)
fprintf (file, "\n%*s}\n",indent, "");
}
+
+/* Dump the tree of lexical scopes of current_function_decl to FILE.
+ FLAGS is as in print_generic_expr. */
+
void
dump_scope_blocks (FILE *file, int flags)
{
dump_scope_block (file, 0, DECL_INITIAL (current_function_decl), flags);
}
+
+/* Dump the tree of lexical scopes of current_function_decl to stderr.
+ FLAGS is as in print_generic_expr. */
+
+void
+debug_scope_blocks (int flags)
+{
+ dump_scope_blocks (stderr, flags);
+}
+
/* Remove local variables that are not referenced in the IL. */
void
@@ -633,6 +668,9 @@ remove_unused_locals (void)
var_ann_t ann;
bitmap global_unused_vars = NULL;
+ /* Removing declarations from lexical blocks when not optimizing is
+ not only a waste of time, it actually causes differences in stack
+ layout. */
if (!optimize)
return;
@@ -701,8 +739,7 @@ remove_unused_locals (void)
if (TREE_CODE (var) != FUNCTION_DECL
&& (!(ann = var_ann (var))
- || !ann->used)
- && (optimize || DECL_ARTIFICIAL (var)))
+ || !ann->used))
{
if (is_global_var (var))
{
@@ -761,8 +798,7 @@ remove_unused_locals (void)
&& TREE_CODE (t) != PARM_DECL
&& TREE_CODE (t) != RESULT_DECL
&& !(ann = var_ann (t))->used
- && !TREE_ADDRESSABLE (t)
- && (optimize || DECL_ARTIFICIAL (t)))
+ && !TREE_ADDRESSABLE (t))
remove_referenced_var (t);
remove_unused_scope_block_p (DECL_INITIAL (current_function_decl));
if (dump_file && (dump_flags & TDF_DETAILS))
diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c
index 4a1cde489e3..b0b7fe3f198 100644
--- a/gcc/tree-ssa-loop-im.c
+++ b/gcc/tree-ssa-loop-im.c
@@ -1796,6 +1796,10 @@ gen_lsm_tmp_name (tree ref)
lsm_tmp_name_add ("R");
break;
+ case INTEGER_CST:
+ /* Nothing. */
+ break;
+
default:
gcc_unreachable ();
}
diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c
index 67448bd68c4..2047b944bec 100644
--- a/gcc/tree-ssa-loop-ivopts.c
+++ b/gcc/tree-ssa-loop-ivopts.c
@@ -1923,6 +1923,24 @@ strip_offset_1 (tree expr, bool inside_addr, bool top_compref,
return fold_convert (orig_type, expr);
+ case MULT_EXPR:
+ op1 = TREE_OPERAND (expr, 1);
+ if (!cst_and_fits_in_hwi (op1))
+ return orig_expr;
+
+ op0 = TREE_OPERAND (expr, 0);
+ op0 = strip_offset_1 (op0, false, false, &off0);
+ if (op0 == TREE_OPERAND (expr, 0))
+ return orig_expr;
+
+ *offset = off0 * int_cst_value (op1);
+ if (integer_zerop (op0))
+ expr = op0;
+ else
+ expr = fold_build2 (MULT_EXPR, type, op0, op1);
+
+ return fold_convert (orig_type, expr);
+
case ARRAY_REF:
case ARRAY_RANGE_REF:
if (!inside_addr)
@@ -3303,6 +3321,19 @@ force_expr_to_var_cost (tree expr, bool speed)
break;
+ case NEGATE_EXPR:
+ op0 = TREE_OPERAND (expr, 0);
+ STRIP_NOPS (op0);
+ op1 = NULL_TREE;
+
+ if (is_gimple_val (op0))
+ cost0 = zero_cost;
+ else
+ cost0 = force_expr_to_var_cost (op0, speed);
+
+ cost1 = zero_cost;
+ break;
+
default:
/* Just an arbitrary value, FIXME. */
return new_cost (target_spill_cost[speed], 0);
@@ -3314,6 +3345,7 @@ force_expr_to_var_cost (tree expr, bool speed)
case POINTER_PLUS_EXPR:
case PLUS_EXPR:
case MINUS_EXPR:
+ case NEGATE_EXPR:
cost = new_cost (add_cost (mode, speed), 0);
break;
@@ -3416,8 +3448,8 @@ ptr_difference_cost (struct ivopts_data *data,
unsigned HOST_WIDE_INT *offset, bitmap *depends_on)
{
HOST_WIDE_INT diff = 0;
- comp_cost cost;
- bool speed = optimize_loop_for_speed_p (data->current_loop);
+ aff_tree aff_e1, aff_e2;
+ tree type;
gcc_assert (TREE_CODE (e1) == ADDR_EXPR);
@@ -3435,12 +3467,14 @@ ptr_difference_cost (struct ivopts_data *data,
*symbol_present = false;
*var_present = true;
-
- cost = force_var_cost (data, e1, depends_on);
- cost = add_costs (cost, force_var_cost (data, e2, depends_on));
- cost.cost += add_cost (Pmode, speed);
- return cost;
+ type = signed_type_for (TREE_TYPE (e1));
+ tree_to_aff_combination (e1, type, &aff_e1);
+ tree_to_aff_combination (e2, type, &aff_e2);
+ aff_combination_scale (&aff_e2, double_int_minus_one);
+ aff_combination_add (&aff_e1, &aff_e2);
+
+ return force_var_cost (data, aff_combination_to_tree (&aff_e1), depends_on);
}
/* Estimates cost of expressing difference E1 - E2 as
@@ -3454,9 +3488,10 @@ difference_cost (struct ivopts_data *data,
tree e1, tree e2, bool *symbol_present, bool *var_present,
unsigned HOST_WIDE_INT *offset, bitmap *depends_on)
{
- comp_cost cost;
enum machine_mode mode = TYPE_MODE (TREE_TYPE (e1));
unsigned HOST_WIDE_INT off1, off2;
+ aff_tree aff_e1, aff_e2;
+ tree type;
e1 = strip_offset (e1, &off1);
e2 = strip_offset (e2, &off2);
@@ -3466,8 +3501,8 @@ difference_cost (struct ivopts_data *data,
STRIP_NOPS (e2);
if (TREE_CODE (e1) == ADDR_EXPR)
- return ptr_difference_cost (data, e1, e2, symbol_present, var_present, offset,
- depends_on);
+ return ptr_difference_cost (data, e1, e2, symbol_present, var_present,
+ offset, depends_on);
*symbol_present = false;
if (operand_equal_p (e1, e2, 0))
@@ -3475,23 +3510,26 @@ difference_cost (struct ivopts_data *data,
*var_present = false;
return zero_cost;
}
+
*var_present = true;
+
if (integer_zerop (e2))
return force_var_cost (data, e1, depends_on);
if (integer_zerop (e1))
{
- cost = force_var_cost (data, e2, depends_on);
+ comp_cost cost = force_var_cost (data, e2, depends_on);
cost.cost += multiply_by_cost (-1, mode, data->speed);
-
return cost;
}
- cost = force_var_cost (data, e1, depends_on);
- cost = add_costs (cost, force_var_cost (data, e2, depends_on));
- cost.cost += add_cost (mode, data->speed);
+ type = signed_type_for (TREE_TYPE (e1));
+ tree_to_aff_combination (e1, type, &aff_e1);
+ tree_to_aff_combination (e2, type, &aff_e2);
+ aff_combination_scale (&aff_e2, double_int_minus_one);
+ aff_combination_add (&aff_e1, &aff_e2);
- return cost;
+ return force_var_cost (data, aff_combination_to_tree (&aff_e1), depends_on);
}
/* Determines the cost of the computation by that USE is expressed
@@ -3512,7 +3550,6 @@ get_computation_cost_at (struct ivopts_data *data,
HOST_WIDE_INT ratio, aratio;
bool var_present, symbol_present;
comp_cost cost;
- unsigned n_sums;
double_int rat;
bool speed = optimize_bb_for_speed_p (gimple_bb (at));
@@ -3545,7 +3582,7 @@ get_computation_cost_at (struct ivopts_data *data,
return infinite_cost;
}
- if (TYPE_PRECISION (utype) != TYPE_PRECISION (ctype))
+ if (TYPE_PRECISION (utype) < TYPE_PRECISION (ctype))
{
/* TODO -- add direct handling of this case. */
goto fallback;
@@ -3570,6 +3607,9 @@ get_computation_cost_at (struct ivopts_data *data,
else
return infinite_cost;
+ STRIP_NOPS (cbase);
+ ctype = TREE_TYPE (cbase);
+
/* use = ubase + ratio * (var - cbase). If either cbase is a constant
or ratio == 1, it is better to handle this like
@@ -3592,6 +3632,18 @@ get_computation_cost_at (struct ivopts_data *data,
&symbol_present, &var_present, &offset,
depends_on);
}
+ else if (address_p
+ && !POINTER_TYPE_P (ctype)
+ && multiplier_allowed_in_address_p (ratio,
+ TYPE_MODE (TREE_TYPE (utype))))
+ {
+ cbase
+ = fold_build2 (MULT_EXPR, ctype, cbase, build_int_cst (ctype, ratio));
+ cost = difference_cost (data,
+ ubase, cbase,
+ &symbol_present, &var_present, &offset,
+ depends_on);
+ }
else
{
cost = force_var_cost (data, cbase, depends_on);
@@ -3609,39 +3661,38 @@ get_computation_cost_at (struct ivopts_data *data,
offset -= ratio * cstepi;
/* Now the computation is in shape symbol + var1 + const + ratio * var2.
- (symbol/var/const parts may be omitted). If we are looking for an address,
- find the cost of addressing this. */
+ (symbol/var1/const parts may be omitted). If we are looking for an
+ address, find the cost of addressing this. */
if (address_p)
- return add_costs (cost, get_address_cost (symbol_present, var_present,
- offset, ratio,
- TYPE_MODE (TREE_TYPE (*use->op_p)), speed));
+ return add_costs (cost,
+ get_address_cost (symbol_present, var_present,
+ offset, ratio,
+ TYPE_MODE (TREE_TYPE (utype)), speed));
/* Otherwise estimate the costs for computing the expression. */
- aratio = ratio > 0 ? ratio : -ratio;
if (!symbol_present && !var_present && !offset)
{
if (ratio != 1)
cost.cost += multiply_by_cost (ratio, TYPE_MODE (ctype), speed);
-
return cost;
}
- if (aratio != 1)
- cost.cost += multiply_by_cost (aratio, TYPE_MODE (ctype), speed);
-
- n_sums = 1;
- if (var_present
- /* Symbol + offset should be compile-time computable. */
- && (symbol_present || offset))
- n_sums++;
+ /* Symbol + offset should be compile-time computable so consider that they
+ are added once to the variable, if present. */
+ if (var_present && (symbol_present || offset))
+ cost.cost += add_cost (TYPE_MODE (ctype), speed)
+ / AVG_LOOP_NITER (data->current_loop);
/* Having offset does not affect runtime cost in case it is added to
symbol, but it increases complexity. */
if (offset)
cost.complexity++;
- cost.cost += n_sums * add_cost (TYPE_MODE (ctype), speed);
- return cost;
+ cost.cost += add_cost (TYPE_MODE (ctype), speed);
+
+ aratio = ratio > 0 ? ratio : -ratio;
+ if (aratio != 1)
+ cost.cost += multiply_by_cost (aratio, TYPE_MODE (ctype), speed);
fallback:
{
@@ -5305,8 +5356,6 @@ rewrite_use_compare (struct ivopts_data *data,
static void
rewrite_use (struct ivopts_data *data, struct iv_use *use, struct iv_cand *cand)
{
- push_stmt_changes (&use->stmt);
-
switch (use->type)
{
case USE_NONLINEAR_EXPR:
@@ -5324,8 +5373,8 @@ rewrite_use (struct ivopts_data *data, struct iv_use *use, struct iv_cand *cand)
default:
gcc_unreachable ();
}
-
- pop_stmt_changes (&use->stmt);
+
+ update_stmt (use->stmt);
}
/* Rewrite the uses using the selected induction variables. */
diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c
index 3892a43e213..18fd6b26e4a 100644
--- a/gcc/tree-ssa-loop-niter.c
+++ b/gcc/tree-ssa-loop-niter.c
@@ -534,7 +534,7 @@ inverse (tree x, tree mask)
}
/* Derives the upper bound BND on the number of executions of loop with exit
- condition S * i <> C, assuming that the loop is not infinite. If
+ condition S * i <> C, assuming that this exit is taken. If
NO_OVERFLOW is true, then the control variable of the loop does not
overflow. If NO_OVERFLOW is true or BNDS.below >= 0, then BNDS.up
contains the upper bound on the value of C. */
@@ -574,7 +574,7 @@ number_of_iterations_ne_max (mpz_t bnd, bool no_overflow, tree c, tree s,
/* Determines number of iterations of loop whose ending condition
is IV <> FINAL. TYPE is the type of the iv. The number of
- iterations is stored to NITER. NEVER_INFINITE is true if
+ iterations is stored to NITER. EXIT_MUST_BE_TAKEN is true if
we know that the exit must be taken eventually, i.e., that the IV
ever reaches the value FINAL (we derived this earlier, and possibly set
NITER->assumptions to make sure this is the case). BNDS contains the
@@ -582,7 +582,7 @@ number_of_iterations_ne_max (mpz_t bnd, bool no_overflow, tree c, tree s,
static bool
number_of_iterations_ne (tree type, affine_iv *iv, tree final,
- struct tree_niter_desc *niter, bool never_infinite,
+ struct tree_niter_desc *niter, bool exit_must_be_taken,
bounds *bnds)
{
tree niter_type = unsigned_type_for (type);
@@ -639,9 +639,9 @@ number_of_iterations_ne (tree type, affine_iv *iv, tree final,
build_int_cst (niter_type, 1), bits);
s = fold_binary_to_constant (RSHIFT_EXPR, niter_type, s, bits);
- if (!never_infinite)
+ if (!exit_must_be_taken)
{
- /* If we cannot assume that the loop is not infinite, record the
+ /* If we cannot assume that the exit is taken eventually, record the
assumptions for divisibility of c. */
assumption = fold_build2 (FLOOR_MOD_EXPR, niter_type, c, d);
assumption = fold_build2 (EQ_EXPR, boolean_type_node,
@@ -664,20 +664,21 @@ number_of_iterations_ne (tree type, affine_iv *iv, tree final,
of the final value does not overflow are recorded in NITER. If we
find the final value, we adjust DELTA and return TRUE. Otherwise
we return false. BNDS bounds the value of IV1->base - IV0->base,
- and will be updated by the same amount as DELTA. */
+ and will be updated by the same amount as DELTA. EXIT_MUST_BE_TAKEN is
+ true if we know that the exit must be taken eventually. */
static bool
number_of_iterations_lt_to_ne (tree type, affine_iv *iv0, affine_iv *iv1,
struct tree_niter_desc *niter,
tree *delta, tree step,
- bounds *bnds)
+ bool exit_must_be_taken, bounds *bnds)
{
tree niter_type = TREE_TYPE (step);
tree mod = fold_build2 (FLOOR_MOD_EXPR, niter_type, *delta, step);
tree tmod;
mpz_t mmod;
tree assumption = boolean_true_node, bound, noloop;
- bool ret = false;
+ bool ret = false, fv_comp_no_overflow;
tree type1 = type;
if (POINTER_TYPE_P (type))
type1 = sizetype;
@@ -692,17 +693,31 @@ number_of_iterations_lt_to_ne (tree type, affine_iv *iv0, affine_iv *iv1,
mpz_set_double_int (mmod, tree_to_double_int (mod), true);
mpz_neg (mmod, mmod);
+ /* If the induction variable does not overflow and the exit is taken,
+ then the computation of the final value does not overflow. This is
+ also obviously the case if the new final value is equal to the
+ current one. Finally, we postulate this for pointer type variables,
+ as the code cannot rely on the object to that the pointer points being
+ placed at the end of the address space (and more pragmatically,
+ TYPE_{MIN,MAX}_VALUE is not defined for pointers). */
+ if (integer_zerop (mod) || POINTER_TYPE_P (type))
+ fv_comp_no_overflow = true;
+ else if (!exit_must_be_taken)
+ fv_comp_no_overflow = false;
+ else
+ fv_comp_no_overflow =
+ (iv0->no_overflow && integer_nonzerop (iv0->step))
+ || (iv1->no_overflow && integer_nonzerop (iv1->step));
+
if (integer_nonzerop (iv0->step))
{
/* The final value of the iv is iv1->base + MOD, assuming that this
computation does not overflow, and that
iv0->base <= iv1->base + MOD. */
- if (!iv0->no_overflow && !integer_zerop (mod))
+ if (!fv_comp_no_overflow)
{
bound = fold_build2 (MINUS_EXPR, type1,
TYPE_MAX_VALUE (type1), tmod);
- if (POINTER_TYPE_P (type))
- bound = fold_convert (type, bound);
assumption = fold_build2 (LE_EXPR, boolean_type_node,
iv1->base, bound);
if (integer_zerop (assumption))
@@ -726,12 +741,10 @@ number_of_iterations_lt_to_ne (tree type, affine_iv *iv0, affine_iv *iv1,
/* The final value of the iv is iv0->base - MOD, assuming that this
computation does not overflow, and that
iv0->base - MOD <= iv1->base. */
- if (!iv1->no_overflow && !integer_zerop (mod))
+ if (!fv_comp_no_overflow)
{
bound = fold_build2 (PLUS_EXPR, type1,
TYPE_MIN_VALUE (type1), tmod);
- if (POINTER_TYPE_P (type))
- bound = fold_convert (type, bound);
assumption = fold_build2 (GE_EXPR, boolean_type_node,
iv0->base, bound);
if (integer_zerop (assumption))
@@ -969,13 +982,13 @@ assert_loop_rolls_lt (tree type, affine_iv *iv0, affine_iv *iv1,
/* Determines number of iterations of loop whose ending condition
is IV0 < IV1. TYPE is the type of the iv. The number of
iterations is stored to NITER. BNDS bounds the difference
- IV1->base - IV0->base. */
+ IV1->base - IV0->base. EXIT_MUST_BE_TAKEN is true if we know
+ that the exit must be taken eventually. */
static bool
number_of_iterations_lt (tree type, affine_iv *iv0, affine_iv *iv1,
struct tree_niter_desc *niter,
- bool never_infinite ATTRIBUTE_UNUSED,
- bounds *bnds)
+ bool exit_must_be_taken, bounds *bnds)
{
tree niter_type = unsigned_type_for (type);
tree delta, step, s;
@@ -1034,7 +1047,7 @@ number_of_iterations_lt (tree type, affine_iv *iv0, affine_iv *iv1,
transform the condition to != comparison. In particular, this will be
the case if DELTA is constant. */
if (number_of_iterations_lt_to_ne (type, iv0, iv1, niter, &delta, step,
- bnds))
+ exit_must_be_taken, bnds))
{
affine_iv zps;
@@ -1076,14 +1089,14 @@ number_of_iterations_lt (tree type, affine_iv *iv0, affine_iv *iv1,
/* Determines number of iterations of loop whose ending condition
is IV0 <= IV1. TYPE is the type of the iv. The number of
- iterations is stored to NITER. NEVER_INFINITE is true if
+ iterations is stored to NITER. EXIT_MUST_BE_TAKEN is true if
we know that this condition must eventually become false (we derived this
earlier, and possibly set NITER->assumptions to make sure this
is the case). BNDS bounds the difference IV1->base - IV0->base. */
static bool
number_of_iterations_le (tree type, affine_iv *iv0, affine_iv *iv1,
- struct tree_niter_desc *niter, bool never_infinite,
+ struct tree_niter_desc *niter, bool exit_must_be_taken,
bounds *bnds)
{
tree assumption;
@@ -1094,9 +1107,13 @@ number_of_iterations_le (tree type, affine_iv *iv0, affine_iv *iv1,
/* Say that IV0 is the control variable. Then IV0 <= IV1 iff
IV0 < IV1 + 1, assuming that IV1 is not equal to the greatest
value of the type. This we must know anyway, since if it is
- equal to this value, the loop rolls forever. */
+ equal to this value, the loop rolls forever. We do not check
+ this condition for pointer type ivs, as the code cannot rely on
+ the object to that the pointer points being placed at the end of
+ the address space (and more pragmatically, TYPE_{MIN,MAX}_VALUE is
+ not defined for pointers). */
- if (!never_infinite)
+ if (!exit_must_be_taken && !POINTER_TYPE_P (type))
{
if (integer_nonzerop (iv0->step))
assumption = fold_build2 (NE_EXPR, boolean_type_node,
@@ -1131,7 +1148,8 @@ number_of_iterations_le (tree type, affine_iv *iv0, affine_iv *iv1,
bounds_add (bnds, double_int_one, type1);
- return number_of_iterations_lt (type, iv0, iv1, niter, never_infinite, bnds);
+ return number_of_iterations_lt (type, iv0, iv1, niter, exit_must_be_taken,
+ bnds);
}
/* Dumps description of affine induction variable IV to FILE. */
@@ -1177,7 +1195,7 @@ number_of_iterations_cond (struct loop *loop,
affine_iv *iv1, struct tree_niter_desc *niter,
bool only_exit)
{
- bool never_infinite, ret;
+ bool exit_must_be_taken = false, ret;
bounds bnds;
/* The meaning of these assumptions is this:
@@ -1202,42 +1220,27 @@ number_of_iterations_cond (struct loop *loop,
code = swap_tree_comparison (code);
}
- if (!only_exit)
- {
- /* If this is not the only possible exit from the loop, the information
- that the induction variables cannot overflow as derived from
- signedness analysis cannot be relied upon. We use them e.g. in the
- following way: given loop for (i = 0; i <= n; i++), if i is
- signed, it cannot overflow, thus this loop is equivalent to
- for (i = 0; i < n + 1; i++); however, if n == MAX, but the loop
- is exited in some other way before i overflows, this transformation
- is incorrect (the new loop exits immediately). */
- iv0->no_overflow = false;
- iv1->no_overflow = false;
- }
-
if (POINTER_TYPE_P (type))
{
/* Comparison of pointers is undefined unless both iv0 and iv1 point
to the same object. If they do, the control variable cannot wrap
(as wrap around the bounds of memory will never return a pointer
that would be guaranteed to point to the same object, even if we
- avoid undefined behavior by casting to size_t and back). The
- restrictions on pointer arithmetics and comparisons of pointers
- ensure that using the no-overflow assumptions is correct in this
- case even if ONLY_EXIT is false. */
+ avoid undefined behavior by casting to size_t and back). */
iv0->no_overflow = true;
iv1->no_overflow = true;
}
- /* If the control induction variable does not overflow, the loop obviously
- cannot be infinite. */
- if (!integer_zerop (iv0->step) && iv0->no_overflow)
- never_infinite = true;
- else if (!integer_zerop (iv1->step) && iv1->no_overflow)
- never_infinite = true;
- else
- never_infinite = false;
+ /* If the control induction variable does not overflow and the only exit
+ from the loop is the one that we analyze, we know it must be taken
+ eventually. */
+ if (only_exit)
+ {
+ if (!integer_zerop (iv0->step) && iv0->no_overflow)
+ exit_must_be_taken = true;
+ else if (!integer_zerop (iv1->step) && iv1->no_overflow)
+ exit_must_be_taken = true;
+ }
/* We can handle the case when neither of the sides of the comparison is
invariant, provided that the test is NE_EXPR. This rarely occurs in
@@ -1308,16 +1311,16 @@ number_of_iterations_cond (struct loop *loop,
case NE_EXPR:
gcc_assert (integer_zerop (iv1->step));
ret = number_of_iterations_ne (type, iv0, iv1->base, niter,
- never_infinite, &bnds);
+ exit_must_be_taken, &bnds);
break;
case LT_EXPR:
- ret = number_of_iterations_lt (type, iv0, iv1, niter, never_infinite,
+ ret = number_of_iterations_lt (type, iv0, iv1, niter, exit_must_be_taken,
&bnds);
break;
case LE_EXPR:
- ret = number_of_iterations_le (type, iv0, iv1, niter, never_infinite,
+ ret = number_of_iterations_le (type, iv0, iv1, niter, exit_must_be_taken,
&bnds);
break;
diff --git a/gcc/tree-ssa-loop-prefetch.c b/gcc/tree-ssa-loop-prefetch.c
index bcff26ae7ae..b4797076768 100644
--- a/gcc/tree-ssa-loop-prefetch.c
+++ b/gcc/tree-ssa-loop-prefetch.c
@@ -109,6 +109,23 @@ along with GCC; see the file COPYING3. If not see
prefetch instructions with guards in cases where 5) was not sufficient
to satisfy the constraints?
+ The function is_loop_prefetching_profitable() implements a cost model
+ to determine if prefetching is profitable for a given loop. The cost
+ model has two heuristcs:
+ 1. A heuristic that determines whether the given loop has enough CPU
+ ops that can be overlapped with cache missing memory ops.
+ If not, the loop won't benefit from prefetching. This is implemented
+ by requirung the ratio between the instruction count and the mem ref
+ count to be above a certain minimum.
+ 2. A heuristic that disables prefetching in a loop with an unknown trip
+ count if the prefetching cost is above a certain limit. The relative
+ prefetching cost is estimated by taking the ratio between the
+ prefetch count and the total intruction count (this models the I-cache
+ cost).
+ The limits used in these heuristics are defined as parameters with
+ reasonable default values. Machine-specific default values will be
+ added later.
+
Some other TODO:
-- write and use more general reuse analysis (that could be also used
in other cache aimed loop optimizations)
@@ -476,7 +493,7 @@ gather_memory_references_ref (struct loop *loop, struct mem_ref_group **refs,
true if there are no other memory references inside the loop. */
static struct mem_ref_group *
-gather_memory_references (struct loop *loop, bool *no_other_refs)
+gather_memory_references (struct loop *loop, bool *no_other_refs, unsigned *ref_count)
{
basic_block *body = get_loop_body_in_dom_order (loop);
basic_block bb;
@@ -487,6 +504,7 @@ gather_memory_references (struct loop *loop, bool *no_other_refs)
struct mem_ref_group *refs = NULL;
*no_other_refs = true;
+ *ref_count = 0;
/* Scan the loop body in order, so that the former references precede the
later ones. */
@@ -513,11 +531,17 @@ gather_memory_references (struct loop *loop, bool *no_other_refs)
rhs = gimple_assign_rhs1 (stmt);
if (REFERENCE_CLASS_P (rhs))
+ {
*no_other_refs &= gather_memory_references_ref (loop, &refs,
rhs, false, stmt);
+ *ref_count += 1;
+ }
if (REFERENCE_CLASS_P (lhs))
+ {
*no_other_refs &= gather_memory_references_ref (loop, &refs,
lhs, true, stmt);
+ *ref_count += 1;
+ }
}
}
free (body);
@@ -846,20 +870,20 @@ schedule_prefetches (struct mem_ref_group *groups, unsigned unroll_factor,
return any;
}
-/* Determine whether there is any reference suitable for prefetching
- in GROUPS. */
+/* Estimate the number of prefetches in the given GROUPS. */
-static bool
-anything_to_prefetch_p (struct mem_ref_group *groups)
+static int
+estimate_prefetch_count (struct mem_ref_group *groups)
{
struct mem_ref *ref;
+ int prefetch_count = 0;
for (; groups; groups = groups->next)
for (ref = groups->refs; ref; ref = ref->next)
if (should_issue_prefetch_p (ref))
- return true;
+ prefetch_count++;
- return false;
+ return prefetch_count;
}
/* Issue prefetches for the reference REF into loop as decided before.
@@ -1449,6 +1473,71 @@ determine_loop_nest_reuse (struct loop *loop, struct mem_ref_group *refs,
}
}
+/* Do a cost-benefit analysis to determine if prefetching is profitable
+ for the current loop given the following parameters:
+ AHEAD: the iteration ahead distance,
+ EST_NITER: the estimated trip count,
+ NINSNS: estimated number of instructions in the loop,
+ PREFETCH_COUNT: an estimate of the number of prefetches
+ MEM_REF_COUNT: total number of memory references in the loop. */
+
+static bool
+is_loop_prefetching_profitable (unsigned ahead, HOST_WIDE_INT est_niter,
+ unsigned ninsns, unsigned prefetch_count,
+ unsigned mem_ref_count)
+{
+ int insn_to_mem_ratio, insn_to_prefetch_ratio;
+
+ if (mem_ref_count == 0)
+ return false;
+
+ /* Prefetching improves performance by overlapping cache missing
+ memory accesses with CPU operations. If the loop does not have
+ enough CPU operations to overlap with memory operations, prefetching
+ won't give a significant benefit. One approximate way of checking
+ this is to require the ratio of instructions to memory references to
+ be above a certain limit. This approximation works well in practice.
+ TODO: Implement a more precise computation by estimating the time
+ for each CPU or memory op in the loop. Time estimates for memory ops
+ should account for cache misses. */
+ insn_to_mem_ratio = ninsns / mem_ref_count;
+
+ if (insn_to_mem_ratio < PREFETCH_MIN_INSN_TO_MEM_RATIO)
+ return false;
+
+ /* Profitability of prefetching is highly dependent on the trip count.
+ For a given AHEAD distance, the first AHEAD iterations do not benefit
+ from prefetching, and the last AHEAD iterations execute useless
+ prefetches. So, if the trip count is not large enough relative to AHEAD,
+ prefetching may cause serious performance degradation. To avoid this
+ problem when the trip count is not known at compile time, we
+ conservatively skip loops with high prefetching costs. For now, only
+ the I-cache cost is considered. The relative I-cache cost is estimated
+ by taking the ratio between the number of prefetches and the total
+ number of instructions. Since we are using integer arithmetic, we
+ compute the reciprocal of this ratio.
+ TODO: Account for loop unrolling, which may reduce the costs of
+ shorter stride prefetches. Note that not accounting for loop
+ unrolling over-estimates the cost and hence gives more conservative
+ results. */
+ if (est_niter < 0)
+ {
+ insn_to_prefetch_ratio = ninsns / prefetch_count;
+ return insn_to_prefetch_ratio >= MIN_INSN_TO_PREFETCH_RATIO;
+ }
+
+ if (est_niter <= (HOST_WIDE_INT) ahead)
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file,
+ "Not prefetching -- loop estimated to roll only %d times\n",
+ (int) est_niter);
+ return false;
+ }
+ return true;
+}
+
+
/* Issue prefetch instructions for array references in LOOP. Returns
true if the LOOP was unrolled. */
@@ -1460,6 +1549,8 @@ loop_prefetch_arrays (struct loop *loop)
HOST_WIDE_INT est_niter;
struct tree_niter_desc desc;
bool unrolled = false, no_other_refs;
+ unsigned prefetch_count;
+ unsigned mem_ref_count;
if (optimize_loop_nest_for_size_p (loop))
{
@@ -1469,12 +1560,13 @@ loop_prefetch_arrays (struct loop *loop)
}
/* Step 1: gather the memory references. */
- refs = gather_memory_references (loop, &no_other_refs);
+ refs = gather_memory_references (loop, &no_other_refs, &mem_ref_count);
/* Step 2: estimate the reuse effects. */
prune_by_reuse (refs);
- if (!anything_to_prefetch_p (refs))
+ prefetch_count = estimate_prefetch_count (refs);
+ if (prefetch_count == 0)
goto fail;
determine_loop_nest_reuse (loop, refs, no_other_refs);
@@ -1485,27 +1577,23 @@ loop_prefetch_arrays (struct loop *loop)
the loop body. */
time = tree_num_loop_insns (loop, &eni_time_weights);
ahead = (PREFETCH_LATENCY + time - 1) / time;
- est_niter = estimated_loop_iterations_int (loop, false);
-
- /* The prefetches will run for AHEAD iterations of the original loop. Unless
- the loop rolls at least AHEAD times, prefetching the references does not
- make sense. */
- if (est_niter >= 0 && est_niter <= (HOST_WIDE_INT) ahead)
- {
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file,
- "Not prefetching -- loop estimated to roll only %d times\n",
- (int) est_niter);
- goto fail;
- }
-
- mark_nontemporal_stores (loop, refs);
+ est_niter = estimated_loop_iterations_int (loop, false);
ninsns = tree_num_loop_insns (loop, &eni_size_weights);
unroll_factor = determine_unroll_factor (loop, refs, ninsns, &desc,
est_niter);
if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "Ahead %d, unroll factor %d\n", ahead, unroll_factor);
+ fprintf (dump_file, "Ahead %d, unroll factor %d, trip count "
+ HOST_WIDE_INT_PRINT_DEC "\n"
+ "insn count %d, mem ref count %d, prefetch count %d\n",
+ ahead, unroll_factor, est_niter,
+ ninsns, mem_ref_count, prefetch_count);
+
+ if (!is_loop_prefetching_profitable (ahead, est_niter, ninsns,
+ prefetch_count, mem_ref_count))
+ goto fail;
+
+ mark_nontemporal_stores (loop, refs);
/* Step 4: what to prefetch? */
if (!schedule_prefetches (refs, unroll_factor, ahead))
@@ -1556,7 +1644,11 @@ tree_ssa_prefetch_arrays (void)
fprintf (dump_file, " L1 cache size: %d lines, %d kB\n",
L1_CACHE_SIZE_BYTES / L1_CACHE_LINE_SIZE, L1_CACHE_SIZE);
fprintf (dump_file, " L1 cache line size: %d\n", L1_CACHE_LINE_SIZE);
- fprintf (dump_file, " L2 cache size: %d kB\n", L2_CACHE_SIZE);
+ fprintf (dump_file, " L2 cache size: %d kB\n", L2_CACHE_SIZE);
+ fprintf (dump_file, " min insn-to-prefetch ratio: %d \n",
+ MIN_INSN_TO_PREFETCH_RATIO);
+ fprintf (dump_file, " min insn-to-mem ratio: %d \n",
+ PREFETCH_MIN_INSN_TO_MEM_RATIO);
fprintf (dump_file, "\n");
}
diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c
index 8d08aa7709f..7e4e1bd5eb6 100644
--- a/gcc/tree-ssa-math-opts.c
+++ b/gcc/tree-ssa-math-opts.c
@@ -97,7 +97,10 @@ along with GCC; see the file COPYING3. If not see
#include "alloc-pool.h"
#include "basic-block.h"
#include "target.h"
-
+#include "diagnostic.h"
+#include "rtl.h"
+#include "expr.h"
+#include "optabs.h"
/* This structure represents one basic block that either computes a
division, or is a common dominator for basic block that compute a
@@ -879,3 +882,381 @@ struct gimple_opt_pass pass_convert_to_rsqrt =
| TODO_verify_stmts /* todo_flags_finish */
}
};
+
+/* A symbolic number is used to detect byte permutation and selection
+ patterns. Therefore the field N contains an artificial number
+ consisting of byte size markers:
+
+ 0 - byte has the value 0
+ 1..size - byte contains the content of the byte
+ number indexed with that value minus one */
+
+struct symbolic_number {
+ unsigned HOST_WIDEST_INT n;
+ int size;
+};
+
+/* Perform a SHIFT or ROTATE operation by COUNT bits on symbolic
+ number N. Return false if the requested operation is not permitted
+ on a symbolic number. */
+
+static inline bool
+do_shift_rotate (enum tree_code code,
+ struct symbolic_number *n,
+ int count)
+{
+ if (count % 8 != 0)
+ return false;
+
+ /* Zero out the extra bits of N in order to avoid them being shifted
+ into the significant bits. */
+ if (n->size < (int)sizeof (HOST_WIDEST_INT))
+ n->n &= ((unsigned HOST_WIDEST_INT)1 << (n->size * BITS_PER_UNIT)) - 1;
+
+ switch (code)
+ {
+ case LSHIFT_EXPR:
+ n->n <<= count;
+ break;
+ case RSHIFT_EXPR:
+ n->n >>= count;
+ break;
+ case LROTATE_EXPR:
+ n->n = (n->n << count) | (n->n >> ((n->size * BITS_PER_UNIT) - count));
+ break;
+ case RROTATE_EXPR:
+ n->n = (n->n >> count) | (n->n << ((n->size * BITS_PER_UNIT) - count));
+ break;
+ default:
+ return false;
+ }
+ return true;
+}
+
+/* Perform sanity checking for the symbolic number N and the gimple
+ statement STMT. */
+
+static inline bool
+verify_symbolic_number_p (struct symbolic_number *n, gimple stmt)
+{
+ tree lhs_type;
+
+ lhs_type = gimple_expr_type (stmt);
+
+ if (TREE_CODE (lhs_type) != INTEGER_TYPE)
+ return false;
+
+ if (TYPE_PRECISION (lhs_type) != n->size * BITS_PER_UNIT)
+ return false;
+
+ return true;
+}
+
+/* find_bswap_1 invokes itself recursively with N and tries to perform
+ the operation given by the rhs of STMT on the result. If the
+ operation could successfully be executed the function returns the
+ tree expression of the source operand and NULL otherwise. */
+
+static tree
+find_bswap_1 (gimple stmt, struct symbolic_number *n, int limit)
+{
+ enum tree_code code;
+ tree rhs1, rhs2 = NULL;
+ gimple rhs1_stmt, rhs2_stmt;
+ tree source_expr1;
+ enum gimple_rhs_class rhs_class;
+
+ if (!limit || !is_gimple_assign (stmt))
+ return NULL_TREE;
+
+ rhs1 = gimple_assign_rhs1 (stmt);
+
+ if (TREE_CODE (rhs1) != SSA_NAME)
+ return NULL_TREE;
+
+ code = gimple_assign_rhs_code (stmt);
+ rhs_class = gimple_assign_rhs_class (stmt);
+ rhs1_stmt = SSA_NAME_DEF_STMT (rhs1);
+
+ if (rhs_class == GIMPLE_BINARY_RHS)
+ rhs2 = gimple_assign_rhs2 (stmt);
+
+ /* Handle unary rhs and binary rhs with integer constants as second
+ operand. */
+
+ if (rhs_class == GIMPLE_UNARY_RHS
+ || (rhs_class == GIMPLE_BINARY_RHS
+ && TREE_CODE (rhs2) == INTEGER_CST))
+ {
+ if (code != BIT_AND_EXPR
+ && code != LSHIFT_EXPR
+ && code != RSHIFT_EXPR
+ && code != LROTATE_EXPR
+ && code != RROTATE_EXPR
+ && code != NOP_EXPR
+ && code != CONVERT_EXPR)
+ return NULL_TREE;
+
+ source_expr1 = find_bswap_1 (rhs1_stmt, n, limit - 1);
+
+ /* If find_bswap_1 returned NULL STMT is a leaf node and we have
+ to initialize the symbolic number. */
+ if (!source_expr1)
+ {
+ /* Set up the symbolic number N by setting each byte to a
+ value between 1 and the byte size of rhs1. The highest
+ order byte is set to 1 and the lowest order byte to
+ n.size. */
+ n->size = TYPE_PRECISION (TREE_TYPE (rhs1));
+ if (n->size % BITS_PER_UNIT != 0)
+ return NULL_TREE;
+ n->size /= BITS_PER_UNIT;
+ n->n = (sizeof (HOST_WIDEST_INT) < 8 ? 0 :
+ (unsigned HOST_WIDEST_INT)0x01020304 << 32 | 0x05060708);
+ n->n >>= (sizeof (HOST_WIDEST_INT) - n->size) * BITS_PER_UNIT;
+
+ source_expr1 = rhs1;
+ }
+
+ switch (code)
+ {
+ case BIT_AND_EXPR:
+ {
+ int i;
+ unsigned HOST_WIDEST_INT val = widest_int_cst_value (rhs2);
+ unsigned HOST_WIDEST_INT tmp = val;
+
+ /* Only constants masking full bytes are allowed. */
+ for (i = 0; i < n->size; i++, tmp >>= BITS_PER_UNIT)
+ if ((tmp & 0xff) != 0 && (tmp & 0xff) != 0xff)
+ return NULL_TREE;
+
+ n->n &= val;
+ }
+ break;
+ case LSHIFT_EXPR:
+ case RSHIFT_EXPR:
+ case LROTATE_EXPR:
+ case RROTATE_EXPR:
+ if (!do_shift_rotate (code, n, (int)TREE_INT_CST_LOW (rhs2)))
+ return NULL_TREE;
+ break;
+ CASE_CONVERT:
+ {
+ int type_size;
+
+ type_size = TYPE_PRECISION (gimple_expr_type (stmt));
+ if (type_size % BITS_PER_UNIT != 0)
+ return NULL_TREE;
+
+ if (type_size / BITS_PER_UNIT < (int)(sizeof (HOST_WIDEST_INT)))
+ {
+ /* If STMT casts to a smaller type mask out the bits not
+ belonging to the target type. */
+ n->size = type_size / BITS_PER_UNIT;
+ n->n &= ((unsigned HOST_WIDEST_INT)1 << type_size) - 1;
+ }
+ }
+ break;
+ default:
+ return NULL_TREE;
+ };
+ return verify_symbolic_number_p (n, stmt) ? source_expr1 : NULL;
+ }
+
+ /* Handle binary rhs. */
+
+ if (rhs_class == GIMPLE_BINARY_RHS)
+ {
+ struct symbolic_number n1, n2;
+ tree source_expr2;
+
+ if (code != BIT_IOR_EXPR)
+ return NULL_TREE;
+
+ if (TREE_CODE (rhs2) != SSA_NAME)
+ return NULL_TREE;
+
+ rhs2_stmt = SSA_NAME_DEF_STMT (rhs2);
+
+ switch (code)
+ {
+ case BIT_IOR_EXPR:
+ source_expr1 = find_bswap_1 (rhs1_stmt, &n1, limit - 1);
+
+ if (!source_expr1)
+ return NULL_TREE;
+
+ source_expr2 = find_bswap_1 (rhs2_stmt, &n2, limit - 1);
+
+ if (source_expr1 != source_expr2
+ || n1.size != n2.size)
+ return NULL_TREE;
+
+ n->size = n1.size;
+ n->n = n1.n | n2.n;
+
+ if (!verify_symbolic_number_p (n, stmt))
+ return NULL_TREE;
+
+ break;
+ default:
+ return NULL_TREE;
+ }
+ return source_expr1;
+ }
+ return NULL_TREE;
+}
+
+/* Check if STMT completes a bswap implementation consisting of ORs,
+ SHIFTs and ANDs. Return the source tree expression on which the
+ byte swap is performed and NULL if no bswap was found. */
+
+static tree
+find_bswap (gimple stmt)
+{
+/* The number which the find_bswap result should match in order to
+ have a full byte swap. The insignificant bytes are masked out
+ before using it. */
+ unsigned HOST_WIDEST_INT cmp =
+ sizeof (HOST_WIDEST_INT) < 8 ? 0 :
+ (unsigned HOST_WIDEST_INT)0x08070605 << 32 | 0x04030201;
+
+ struct symbolic_number n;
+ tree source_expr;
+
+ source_expr = find_bswap_1 (stmt, &n,
+ TREE_INT_CST_LOW (
+ TYPE_SIZE_UNIT (gimple_expr_type (stmt))));
+
+ if (!source_expr)
+ return NULL_TREE;
+
+ /* Zero out the extra bits of N and CMP. */
+ if (n.size < (int)sizeof (HOST_WIDEST_INT))
+ {
+ unsigned HOST_WIDEST_INT mask =
+ ((unsigned HOST_WIDEST_INT)1 << (n.size * BITS_PER_UNIT)) - 1;
+
+ n.n &= mask;
+ cmp &= mask;
+ }
+
+ /* A complete byte swap should make the symbolic number to start
+ with the largest digit in the highest order byte. */
+ if (cmp != n.n)
+ return NULL_TREE;
+
+ return source_expr;
+}
+
+/* Find manual byte swap implementations and turn them into a bswap
+ builtin invokation. */
+
+static unsigned int
+execute_optimize_bswap (void)
+{
+ basic_block bb;
+ bool bswap32_p, bswap64_p;
+ bool changed = false;
+
+ if (BITS_PER_UNIT != 8)
+ return 0;
+
+ if (sizeof (HOST_WIDEST_INT) < 8)
+ return 0;
+
+ bswap32_p = (built_in_decls[BUILT_IN_BSWAP32]
+ && optab_handler (bswap_optab, SImode)->insn_code !=
+ CODE_FOR_nothing);
+ bswap64_p = (built_in_decls[BUILT_IN_BSWAP64]
+ && optab_handler (bswap_optab, DImode)->insn_code !=
+ CODE_FOR_nothing);
+
+ if (!bswap32_p && !bswap64_p)
+ return 0;
+
+ FOR_EACH_BB (bb)
+ {
+ gimple_stmt_iterator gsi;
+
+ for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ gimple stmt = gsi_stmt (gsi);
+ tree bswap_src;
+ tree fndecl = NULL_TREE;
+ int type_size;
+ gimple call;
+
+ if (!is_gimple_assign (stmt)
+ || gimple_assign_rhs_code (stmt) != BIT_IOR_EXPR)
+ continue;
+
+ type_size = TYPE_PRECISION (gimple_expr_type (stmt));
+
+ switch (type_size)
+ {
+ case 32:
+ if (bswap32_p)
+ fndecl = built_in_decls[BUILT_IN_BSWAP32];
+ break;
+ case 64:
+ if (bswap64_p)
+ fndecl = built_in_decls[BUILT_IN_BSWAP64];
+ break;
+ default:
+ continue;
+ }
+
+ if (!fndecl)
+ continue;
+
+ bswap_src = find_bswap (stmt);
+
+ if (!bswap_src)
+ continue;
+
+ changed = true;
+ call = gimple_build_call (fndecl, 1, bswap_src);
+ gimple_call_set_lhs (call, gimple_assign_lhs (stmt));
+
+ if (dump_file)
+ {
+ fprintf (dump_file, "%d bit bswap implementation found at: ",
+ (int)type_size);
+ print_gimple_stmt (dump_file, stmt, 0, 0);
+ }
+
+ gsi_insert_after (&gsi, call, GSI_SAME_STMT);
+ gsi_remove (&gsi, true);
+ }
+ }
+
+ return (changed ? TODO_dump_func | TODO_update_ssa | TODO_verify_ssa
+ | TODO_verify_stmts : 0);
+}
+
+static bool
+gate_optimize_bswap (void)
+{
+ return flag_expensive_optimizations && optimize;
+}
+
+struct gimple_opt_pass pass_optimize_bswap =
+{
+ {
+ GIMPLE_PASS,
+ "bswap", /* name */
+ gate_optimize_bswap, /* gate */
+ execute_optimize_bswap, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ TV_NONE, /* tv_id */
+ PROP_ssa, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0 /* todo_flags_finish */
+ }
+};
diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c
index 97bbf8f17f8..9f97e794190 100644
--- a/gcc/tree-ssa-operands.c
+++ b/gcc/tree-ssa-operands.c
@@ -150,12 +150,6 @@ static void get_expr_operands (gimple, tree *, int);
/* Number of functions with initialized ssa_operands. */
static int n_initialized = 0;
-/* Stack of statements to change. Every call to
- push_stmt_changes pushes the stmt onto the stack. Calls to
- pop_stmt_changes pop a stmt off of the stack and compute the set
- of changes for the popped statement. */
-static VEC(gimple_p,heap) *scb_stack;
-
/* Return the DECL_UID of the base variable of T. */
static inline unsigned
@@ -194,7 +188,8 @@ create_vop_var (void)
gcc_assert (cfun->gimple_df->vop == NULL_TREE);
- global_var = build_decl (VAR_DECL, get_identifier (".MEM"),
+ global_var = build_decl (BUILTINS_LOCATION, VAR_DECL,
+ get_identifier (".MEM"),
void_type_node);
DECL_ARTIFICIAL (global_var) = 1;
TREE_READONLY (global_var) = 0;
@@ -234,7 +229,6 @@ init_ssa_operands (void)
build_vuse = NULL_TREE;
build_vdef = NULL_TREE;
bitmap_obstack_initialize (&operands_bitmap_obstack);
- scb_stack = VEC_alloc (gimple_p, heap, 20);
}
gcc_assert (gimple_ssa_operands (cfun)->operand_memory == NULL);
@@ -260,11 +254,6 @@ fini_ssa_operands (void)
VEC_free (tree, heap, build_uses);
build_vdef = NULL_TREE;
build_vuse = NULL_TREE;
-
- /* The change buffer stack had better be empty. */
- gcc_assert (VEC_length (gimple_p, scb_stack) == 0);
- VEC_free (gimple_p, heap, scb_stack);
- scb_stack = NULL;
}
gimple_ssa_operands (cfun)->free_defs = NULL;
@@ -926,19 +915,9 @@ get_expr_operands (gimple stmt, tree *expr_p, int flags)
case REALPART_EXPR:
case IMAGPART_EXPR:
{
- tree ref;
- HOST_WIDE_INT offset, size, maxsize;
-
if (TREE_THIS_VOLATILE (expr))
gimple_set_has_volatile_ops (stmt, true);
- ref = get_ref_base_and_extent (expr, &offset, &size, &maxsize);
- if (TREE_CODE (ref) == INDIRECT_REF)
- {
- get_indirect_ref_operands (stmt, ref, flags, false);
- flags |= opf_no_vops;
- }
-
get_expr_operands (stmt, &TREE_OPERAND (expr, 0), flags);
if (code == COMPONENT_REF)
@@ -1025,9 +1004,6 @@ get_expr_operands (gimple stmt, tree *expr_p, int flags)
return;
}
- case CHANGE_DYNAMIC_TYPE_EXPR:
- gcc_unreachable ();
-
case FUNCTION_DECL:
case LABEL_DECL:
case CONST_DECL:
@@ -1355,62 +1331,6 @@ debug_immediate_uses_for (tree var)
}
-/* Push *STMT_P on the SCB_STACK. This function is deprecated, do not
- introduce new uses of it. */
-
-void
-push_stmt_changes (gimple *stmt_p)
-{
- gimple stmt = *stmt_p;
-
- /* It makes no sense to keep track of PHI nodes. */
- if (gimple_code (stmt) == GIMPLE_PHI)
- return;
-
- VEC_safe_push (gimple_p, heap, scb_stack, stmt_p);
-}
-
-/* Pop the top stmt from SCB_STACK and act on the differences between
- what was recorded by push_stmt_changes and the current state of
- the statement. This function is deprecated, do not introduce
- new uses of it. */
-
-void
-pop_stmt_changes (gimple *stmt_p)
-{
- gimple *stmt2_p, stmt = *stmt_p;
-
- /* It makes no sense to keep track of PHI nodes. */
- if (gimple_code (stmt) == GIMPLE_PHI)
- return;
-
- stmt2_p = VEC_pop (gimple_p, scb_stack);
- gcc_assert (stmt_p == stmt2_p);
-
- /* Force an operand re-scan on the statement and mark any newly
- exposed variables. This also will mark the virtual operand
- for renaming if necessary. */
- update_stmt (stmt);
-}
-
-/* Discard the topmost stmt from SCB_STACK. This is useful
- when the caller realized that it did not actually modified the
- statement. It avoids the expensive operand re-scan.
- This function is deprecated, do not introduce new uses of it. */
-
-void
-discard_stmt_changes (gimple *stmt_p)
-{
- gimple *stmt2_p, stmt = *stmt_p;
-
- /* It makes no sense to keep track of PHI nodes. */
- if (gimple_code (stmt) == GIMPLE_PHI)
- return;
-
- stmt2_p = VEC_pop (gimple_p, scb_stack);
- gcc_assert (stmt_p == stmt2_p);
-}
-
/* Unlink STMTs virtual definition from the IL by propagating its use. */
void
diff --git a/gcc/tree-ssa-operands.h b/gcc/tree-ssa-operands.h
index 691db93bc4c..5a8e02696d4 100644
--- a/gcc/tree-ssa-operands.h
+++ b/gcc/tree-ssa-operands.h
@@ -114,10 +114,6 @@ extern void debug_decl_set (bitmap);
extern bool ssa_operands_active (void);
-extern void push_stmt_changes (gimple *);
-extern void pop_stmt_changes (gimple *);
-extern void discard_stmt_changes (gimple *);
-
extern void unlink_stmt_vdef (gimple);
enum ssa_op_iter_type {
diff --git a/gcc/tree-ssa-phiprop.c b/gcc/tree-ssa-phiprop.c
index 6ccc30ec808..022e4af9a48 100644
--- a/gcc/tree-ssa-phiprop.c
+++ b/gcc/tree-ssa-phiprop.c
@@ -381,7 +381,7 @@ tree_ssa_phiprop (void)
static bool
gate_phiprop (void)
{
- return 1;
+ return flag_tree_phiprop;
}
struct gimple_opt_pass pass_phiprop =
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
index ace136d4d43..92269b5b772 100644
--- a/gcc/tree-ssa-pre.c
+++ b/gcc/tree-ssa-pre.c
@@ -134,7 +134,7 @@ along with GCC; see the file COPYING3. If not see
/* Representation of expressions on value numbers:
- Expressions consisting of value numbers are represented the same
+ Expressions consisting of value numbers are represented the same
way as our VN internally represents them, with an additional
"pre_expr" wrapping around them in order to facilitate storing all
of the expressions in the same sets. */
@@ -1252,12 +1252,12 @@ do_unary:
static tree
translate_vuse_through_block (VEC (vn_reference_op_s, heap) *operands,
- tree vuse,
+ alias_set_type set, tree type, tree vuse,
basic_block phiblock,
basic_block block)
{
gimple phi = SSA_NAME_DEF_STMT (vuse);
- tree ref;
+ ao_ref ref;
if (gimple_bb (phi) != phiblock)
return vuse;
@@ -1268,13 +1268,13 @@ translate_vuse_through_block (VEC (vn_reference_op_s, heap) *operands,
return PHI_ARG_DEF (phi, e->dest_idx);
}
- if (!(ref = get_ref_from_reference_ops (operands)))
+ if (!ao_ref_init_from_vn_reference (&ref, set, type, operands))
return NULL_TREE;
/* Use the alias-oracle to find either the PHI node in this block,
the first VUSE used in this block that is equivalent to vuse or
the first VUSE which definition in this block kills the value. */
- while (!stmt_may_clobber_ref_p (phi, ref))
+ while (!stmt_may_clobber_ref_p_1 (phi, &ref))
{
vuse = gimple_vuse (phi);
phi = SSA_NAME_DEF_STMT (vuse);
@@ -1290,7 +1290,7 @@ translate_vuse_through_block (VEC (vn_reference_op_s, heap) *operands,
return NULL_TREE;
}
-/* Like find_leader, but checks for the value existing in SET1 *or*
+/* Like bitmap_find_leader, but checks for the value existing in SET1 *or*
SET2. This is used to avoid making a set consisting of the union
of PA_IN and ANTIC_IN during insert. */
@@ -1317,23 +1317,7 @@ get_expr_type (const pre_expr e)
case CONSTANT:
return TREE_TYPE (PRE_EXPR_CONSTANT (e));
case REFERENCE:
- {
- vn_reference_op_t vro;
-
- gcc_assert (PRE_EXPR_REFERENCE (e)->operands);
- vro = VEC_index (vn_reference_op_s,
- PRE_EXPR_REFERENCE (e)->operands,
- 0);
- /* We don't store type along with COMPONENT_REF because it is
- always the same as FIELD_DECL's type. */
- if (!vro->type)
- {
- gcc_assert (vro->opcode == COMPONENT_REF);
- return TREE_TYPE (vro->op0);
- }
- return vro->type;
- }
-
+ return PRE_EXPR_REFERENCE (e)->type;
case NARY:
return PRE_EXPR_NARY (e)->type;
}
@@ -1661,6 +1645,7 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
if (vuse)
{
newvuse = translate_vuse_through_block (newoperands,
+ ref->set, ref->type,
vuse, phiblock, pred);
if (newvuse == NULL_TREE)
{
@@ -1675,7 +1660,8 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
unsigned int new_val_id;
pre_expr constant;
- tree result = vn_reference_lookup_pieces (newvuse,
+ tree result = vn_reference_lookup_pieces (newvuse, ref->set,
+ ref->type,
newoperands,
&newref, true);
if (newref)
@@ -1706,7 +1692,8 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
new_val_id = get_next_value_id ();
VEC_safe_grow_cleared (bitmap_set_t, heap, value_expressions,
get_max_value_id() + 1);
- newref = vn_reference_insert_pieces (newvuse,
+ newref = vn_reference_insert_pieces (newvuse, ref->set,
+ ref->type,
newoperands,
result, new_val_id);
newoperands = NULL;
@@ -1884,10 +1871,10 @@ value_dies_in_block_x (pre_expr expr, basic_block block)
tree vuse = PRE_EXPR_REFERENCE (expr)->vuse;
vn_reference_t refx = PRE_EXPR_REFERENCE (expr);
gimple def;
- tree ref = NULL_TREE;
gimple_stmt_iterator gsi;
unsigned id = get_expression_id (expr);
bool res = false;
+ ao_ref ref;
if (!vuse)
return false;
@@ -1902,6 +1889,7 @@ value_dies_in_block_x (pre_expr expr, basic_block block)
top of the basic block, a statement uses VUSE there can be no kill
inbetween that use and the original statement that loaded {e, VUSE},
so we can stop walking. */
+ ref.base = NULL_TREE;
for (gsi = gsi_start_bb (block); !gsi_end_p (gsi); gsi_next (&gsi))
{
tree def_vuse, def_vdef;
@@ -1924,16 +1912,15 @@ value_dies_in_block_x (pre_expr expr, basic_block block)
}
/* Init ref only if we really need it. */
- if (ref == NULL_TREE)
+ if (ref.base == NULL_TREE
+ && !ao_ref_init_from_vn_reference (&ref, refx->set, refx->type,
+ refx->operands))
{
- if (!(ref = get_ref_from_reference_ops (refx->operands)))
- {
- res = true;
- break;
- }
+ res = true;
+ break;
}
/* If the statement may clobber expr, it dies. */
- if (stmt_may_clobber_ref_p (def, ref))
+ if (stmt_may_clobber_ref_p_1 (def, &ref))
{
res = true;
break;
@@ -2575,8 +2562,8 @@ is_exception_related (gimple stmt)
|| gimple_assign_rhs_code (stmt) == EXC_PTR_EXPR));
}
-/* Return true if OP is a tree which we can perform PRE on
- on. This may not match the operations we can value number, but in
+/* Return true if OP is a tree which we can perform PRE on.
+ This may not match the operations we can value number, but in
a perfect world would. */
static bool
@@ -2647,6 +2634,36 @@ create_component_ref_by_pieces_1 (basic_block block, vn_reference_t ref,
return folded;
}
break;
+ case TARGET_MEM_REF:
+ {
+ vn_reference_op_t nextop = VEC_index (vn_reference_op_s, ref->operands,
+ *operand);
+ pre_expr op0expr;
+ tree genop0 = NULL_TREE;
+ tree baseop = create_component_ref_by_pieces_1 (block, ref, operand,
+ stmts, domstmt);
+ if (!baseop)
+ return NULL_TREE;
+ if (currop->op0)
+ {
+ op0expr = get_or_alloc_expr_for (currop->op0);
+ genop0 = find_or_generate_expression (block, op0expr,
+ stmts, domstmt);
+ if (!genop0)
+ return NULL_TREE;
+ }
+ if (DECL_P (baseop))
+ return build6 (TARGET_MEM_REF, currop->type,
+ baseop, NULL_TREE,
+ genop0, currop->op1, currop->op2,
+ unshare_expr (nextop->op1));
+ else
+ return build6 (TARGET_MEM_REF, currop->type,
+ NULL_TREE, baseop,
+ genop0, currop->op1, currop->op2,
+ unshare_expr (nextop->op1));
+ }
+ break;
case ADDR_EXPR:
if (currop->op0)
{
@@ -2902,8 +2919,8 @@ create_expression_by_pieces (basic_block block, pre_expr expr,
gimple_seq *stmts, gimple domstmt, tree type)
{
tree temp, name;
- tree folded, newexpr;
- gimple_seq forced_stmts;
+ tree folded;
+ gimple_seq forced_stmts = NULL;
unsigned int value_id;
gimple_stmt_iterator gsi;
tree exprtype = type ? type : get_expr_type (expr);
@@ -2975,13 +2992,16 @@ create_expression_by_pieces (basic_block block, pre_expr expr,
default:
return NULL_TREE;
}
- folded = fold_convert (exprtype, folded);
+
+ if (!useless_type_conversion_p (exprtype, TREE_TYPE (folded)))
+ folded = fold_convert (exprtype, folded);
+
/* Force the generated expression to be a sequence of GIMPLE
statements.
We have to call unshare_expr because force_gimple_operand may
modify the tree we pass to it. */
- newexpr = force_gimple_operand (unshare_expr (folded), &forced_stmts,
- false, NULL);
+ folded = force_gimple_operand (unshare_expr (folded), &forced_stmts,
+ false, NULL);
/* If we have any intermediate expressions to the value sets, add them
to the value sets and chain them in the instruction stream. */
@@ -3025,7 +3045,7 @@ create_expression_by_pieces (basic_block block, pre_expr expr,
|| TREE_CODE (exprtype) == VECTOR_TYPE)
DECL_GIMPLE_REG_P (temp) = 1;
- newstmt = gimple_build_assign (temp, newexpr);
+ newstmt = gimple_build_assign (temp, folded);
name = make_ssa_name (temp, newstmt);
gimple_assign_set_lhs (newstmt, name);
gimple_set_plf (newstmt, NECESSARY, false);
@@ -3760,7 +3780,8 @@ compute_avail (void)
continue;
copy_reference_ops_from_call (stmt, &ops);
- vn_reference_lookup_pieces (gimple_vuse (stmt),
+ vn_reference_lookup_pieces (gimple_vuse (stmt), 0,
+ gimple_expr_type (stmt),
ops, &ref, false);
VEC_free (vn_reference_op_s, heap, ops);
if (!ref)
@@ -4134,7 +4155,7 @@ eliminate (void)
/* Changing an indirect call to a direct call may
have exposed different semantics. This may
require an SSA update. */
- todo |= TODO_update_ssa;
+ todo |= TODO_update_ssa_only_virtuals;
}
}
}
diff --git a/gcc/tree-ssa-propagate.c b/gcc/tree-ssa-propagate.c
index 93210c8ab37..ab9cee34a21 100644
--- a/gcc/tree-ssa-propagate.c
+++ b/gcc/tree-ssa-propagate.c
@@ -1109,9 +1109,6 @@ substitute_and_fold (prop_value_t *prop_value, bool use_ranges_p)
continue;
}
- /* Record the state of the statement before replacements. */
- push_stmt_changes (gsi_stmt_ptr (&i));
-
/* Replace the statement with its folded version and mark it
folded. */
did_replace = false;
@@ -1172,15 +1169,10 @@ substitute_and_fold (prop_value_t *prop_value, bool use_ranges_p)
}
/* Determine what needs to be done to update the SSA form. */
- pop_stmt_changes (gsi_stmt_ptr (&i));
+ update_stmt (stmt);
if (!is_gimple_debug (stmt))
something_changed = true;
}
- else
- {
- /* The statement was not modified, discard the change buffer. */
- discard_stmt_changes (gsi_stmt_ptr (&i));
- }
if (dump_file && (dump_flags & TDF_DETAILS))
{
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index b101aebd9e4..8557b0b07c9 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -488,20 +488,26 @@ copy_reference_ops_from_ref (tree ref, VEC(vn_reference_op_s, heap) **result)
if (TREE_CODE (ref) == TARGET_MEM_REF)
{
vn_reference_op_s temp;
+ tree base;
+
+ base = TMR_SYMBOL (ref) ? TMR_SYMBOL (ref) : TMR_BASE (ref);
+ if (!base)
+ base = build_int_cst (ptr_type_node, 0);
memset (&temp, 0, sizeof (temp));
/* We do not care for spurious type qualifications. */
temp.type = TYPE_MAIN_VARIANT (TREE_TYPE (ref));
temp.opcode = TREE_CODE (ref);
- temp.op0 = TMR_SYMBOL (ref) ? TMR_SYMBOL (ref) : TMR_BASE (ref);
- temp.op1 = TMR_INDEX (ref);
+ temp.op0 = TMR_INDEX (ref);
+ temp.op1 = TMR_STEP (ref);
+ temp.op2 = TMR_OFFSET (ref);
VEC_safe_push (vn_reference_op_s, heap, *result, &temp);
memset (&temp, 0, sizeof (temp));
temp.type = NULL_TREE;
- temp.opcode = TREE_CODE (ref);
- temp.op0 = TMR_STEP (ref);
- temp.op1 = TMR_OFFSET (ref);
+ temp.opcode = TREE_CODE (base);
+ temp.op0 = base;
+ temp.op1 = TMR_ORIGINAL (ref);
VEC_safe_push (vn_reference_op_s, heap, *result, &temp);
return;
}
@@ -537,28 +543,35 @@ copy_reference_ops_from_ref (tree ref, VEC(vn_reference_op_s, heap) **result)
a matching type is not necessary and a mismatching type
is always a spurious difference. */
temp.type = NULL_TREE;
+ temp.op0 = TREE_OPERAND (ref, 1);
+ temp.op1 = TREE_OPERAND (ref, 2);
/* If this is a reference to a union member, record the union
member size as operand. Do so only if we are doing
expression insertion (during FRE), as PRE currently gets
confused with this. */
if (may_insert
- && TREE_OPERAND (ref, 2) == NULL_TREE
- && TREE_CODE (DECL_CONTEXT (TREE_OPERAND (ref, 1))) == UNION_TYPE
- && integer_zerop (DECL_FIELD_OFFSET (TREE_OPERAND (ref, 1)))
- && integer_zerop (DECL_FIELD_BIT_OFFSET (TREE_OPERAND (ref, 1))))
- temp.op0 = TYPE_SIZE (TREE_TYPE (TREE_OPERAND (ref, 1)));
- else
- {
- /* Record field as operand. */
- temp.op0 = TREE_OPERAND (ref, 1);
- temp.op1 = TREE_OPERAND (ref, 2);
- }
+ && temp.op1 == NULL_TREE
+ && TREE_CODE (DECL_CONTEXT (temp.op0)) == UNION_TYPE
+ && integer_zerop (DECL_FIELD_OFFSET (temp.op0))
+ && integer_zerop (DECL_FIELD_BIT_OFFSET (temp.op0))
+ && host_integerp (DECL_SIZE (temp.op0), 0))
+ temp.op0 = DECL_SIZE (temp.op0);
break;
case ARRAY_RANGE_REF:
case ARRAY_REF:
/* Record index as operand. */
temp.op0 = TREE_OPERAND (ref, 1);
- temp.op1 = TREE_OPERAND (ref, 2);
+ /* Record even constant lower bounds. */
+ if (TREE_OPERAND (ref, 2))
+ temp.op1 = TREE_OPERAND (ref, 2);
+ else
+ {
+ tree domain = TYPE_DOMAIN (TREE_TYPE (TREE_OPERAND (ref, 0)));
+ if (domain
+ && TYPE_MIN_VALUE (domain)
+ && !integer_zerop (TYPE_MIN_VALUE (domain)))
+ temp.op1 = TYPE_MIN_VALUE (domain);
+ }
temp.op2 = TREE_OPERAND (ref, 3);
break;
case STRING_CST:
@@ -606,24 +619,68 @@ copy_reference_ops_from_ref (tree ref, VEC(vn_reference_op_s, heap) **result)
}
}
-/* Re-create a reference tree from the reference ops OPS.
- Returns NULL_TREE if the ops were not handled.
- This routine needs to be kept in sync with copy_reference_ops_from_ref. */
+/* Build a alias-oracle reference abstraction in *REF from the vn_reference
+ operands in *OPS, the reference alias set SET and the reference type TYPE.
+ Return true if something useful was produced. */
-tree
-get_ref_from_reference_ops (VEC(vn_reference_op_s, heap) *ops)
+bool
+ao_ref_init_from_vn_reference (ao_ref *ref,
+ alias_set_type set, tree type,
+ VEC (vn_reference_op_s, heap) *ops)
{
vn_reference_op_t op;
unsigned i;
- tree ref, *op0_p = &ref;
+ tree base = NULL_TREE;
+ tree *op0_p = &base;
+ HOST_WIDE_INT offset = 0;
+ HOST_WIDE_INT max_size;
+ HOST_WIDE_INT size = -1;
+ tree size_tree = NULL_TREE;
+
+ /* First get the final access size from just the outermost expression. */
+ op = VEC_index (vn_reference_op_s, ops, 0);
+ if (op->opcode == COMPONENT_REF)
+ {
+ if (TREE_CODE (op->op0) == INTEGER_CST)
+ size_tree = op->op0;
+ else
+ size_tree = DECL_SIZE (op->op0);
+ }
+ else if (op->opcode == BIT_FIELD_REF)
+ size_tree = op->op0;
+ else
+ {
+ enum machine_mode mode = TYPE_MODE (type);
+ if (mode == BLKmode)
+ size_tree = TYPE_SIZE (type);
+ else
+ size = GET_MODE_BITSIZE (mode);
+ }
+ if (size_tree != NULL_TREE)
+ {
+ if (!host_integerp (size_tree, 1))
+ size = -1;
+ else
+ size = TREE_INT_CST_LOW (size_tree);
+ }
+
+ /* Initially, maxsize is the same as the accessed element size.
+ In the following it will only grow (or become -1). */
+ max_size = size;
+ /* Compute cumulative bit-offset for nested component-refs and array-refs,
+ and find the ultimate containing object. */
for (i = 0; VEC_iterate (vn_reference_op_s, ops, i, op); ++i)
{
switch (op->opcode)
{
+ /* These may be in the reference ops, but we cannot do anything
+ sensible with them here. */
case CALL_EXPR:
- return NULL_TREE;
+ case ADDR_EXPR:
+ return false;
+ /* Record the base objects. */
case ALIGN_INDIRECT_REF:
case INDIRECT_REF:
*op0_p = build1 (op->opcode, op->type, NULL_TREE);
@@ -636,23 +693,69 @@ get_ref_from_reference_ops (VEC(vn_reference_op_s, heap) *ops)
op0_p = &TREE_OPERAND (*op0_p, 0);
break;
+ case VAR_DECL:
+ case PARM_DECL:
+ case RESULT_DECL:
+ case SSA_NAME:
+ case FILTER_EXPR:
+ case EXC_PTR_EXPR:
+ *op0_p = op->op0;
+ break;
+
+ /* And now the usual component-reference style ops. */
case BIT_FIELD_REF:
- *op0_p = build3 (BIT_FIELD_REF, op->type, NULL_TREE,
- op->op0, op->op1);
- op0_p = &TREE_OPERAND (*op0_p, 0);
+ offset += tree_low_cst (op->op1, 0);
break;
case COMPONENT_REF:
- *op0_p = build3 (COMPONENT_REF, TREE_TYPE (op->op0), NULL_TREE,
- op->op0, op->op1);
- op0_p = &TREE_OPERAND (*op0_p, 0);
- break;
+ {
+ tree field = op->op0;
+ /* We do not have a complete COMPONENT_REF tree here so we
+ cannot use component_ref_field_offset. Do the interesting
+ parts manually. */
+
+ /* Our union trick, done for offset zero only. */
+ if (TREE_CODE (field) == INTEGER_CST)
+ ;
+ else if (op->op1
+ || !host_integerp (DECL_FIELD_OFFSET (field), 1))
+ max_size = -1;
+ else
+ {
+ offset += (TREE_INT_CST_LOW (DECL_FIELD_OFFSET (field))
+ * BITS_PER_UNIT);
+ offset += TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (field));
+ }
+ break;
+ }
case ARRAY_RANGE_REF:
case ARRAY_REF:
- *op0_p = build4 (op->opcode, op->type, NULL_TREE,
- op->op0, op->op1, op->op2);
- op0_p = &TREE_OPERAND (*op0_p, 0);
+ /* Same for ARRAY_REFs. We do not have access to the array
+ type here, but we recorded the lower bound in op1. */
+ if (op->op2
+ || !host_integerp (op->op0, 0)
+ || (op->op1 && !host_integerp (op->op1, 0))
+ || !host_integerp (TYPE_SIZE (op->type), 1))
+ max_size = -1;
+ else
+ {
+ HOST_WIDE_INT hindex = TREE_INT_CST_LOW (op->op0);
+ if (op->op1)
+ hindex -= TREE_INT_CST_LOW (op->op1);
+ hindex *= TREE_INT_CST_LOW (TYPE_SIZE (op->type));
+ offset += hindex;
+ }
+ break;
+
+ case REALPART_EXPR:
+ break;
+
+ case IMAGPART_EXPR:
+ offset += size;
+ break;
+
+ case VIEW_CONVERT_EXPR:
break;
case STRING_CST:
@@ -661,37 +764,26 @@ get_ref_from_reference_ops (VEC(vn_reference_op_s, heap) *ops)
case VECTOR_CST:
case REAL_CST:
case CONSTRUCTOR:
- case VAR_DECL:
- case PARM_DECL:
case CONST_DECL:
- case RESULT_DECL:
- case SSA_NAME:
- case FILTER_EXPR:
- case EXC_PTR_EXPR:
- *op0_p = op->op0;
- break;
-
- case ADDR_EXPR:
- if (op->op0 != NULL_TREE)
- {
- gcc_assert (is_gimple_min_invariant (op->op0));
- *op0_p = op->op0;
- break;
- }
- /* Fallthrough. */
- case IMAGPART_EXPR:
- case REALPART_EXPR:
- case VIEW_CONVERT_EXPR:
- *op0_p = build1 (op->opcode, op->type, NULL_TREE);
- op0_p = &TREE_OPERAND (*op0_p, 0);
- break;
+ return false;
default:
- return NULL_TREE;
+ return false;
}
}
- return ref;
+ if (base == NULL_TREE)
+ return false;
+
+ ref->ref = NULL_TREE;
+ ref->base = base;
+ ref->offset = offset;
+ ref->size = size;
+ ref->max_size = max_size;
+ ref->ref_alias_set = set;
+ ref->base_alias_set = -1;
+
+ return true;
}
/* Copy the operations present in load/store/call REF into RESULT, a vector of
@@ -911,7 +1003,7 @@ vn_reference_lookup_1 (vn_reference_t vr, vn_reference_t *vnresult)
with the current VUSE and performs the expression lookup. */
static void *
-vn_reference_lookup_2 (tree op ATTRIBUTE_UNUSED, tree vuse, void *vr_)
+vn_reference_lookup_2 (ao_ref *op ATTRIBUTE_UNUSED, tree vuse, void *vr_)
{
vn_reference_t vr = (vn_reference_t)vr_;
void **slot;
@@ -934,13 +1026,169 @@ vn_reference_lookup_2 (tree op ATTRIBUTE_UNUSED, tree vuse, void *vr_)
return NULL;
}
+/* Callback for walk_non_aliased_vuses. Tries to perform a lookup
+ from the statement defining VUSE and if not successful tries to
+ translate *REFP and VR_ through an aggregate copy at the defintion
+ of VUSE. */
+
+static void *
+vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_)
+{
+ vn_reference_t vr = (vn_reference_t)vr_;
+ gimple def_stmt = SSA_NAME_DEF_STMT (vuse);
+ tree fndecl;
+ tree base;
+ HOST_WIDE_INT offset, size, maxsize;
+
+ base = ao_ref_base (ref);
+ offset = ref->offset;
+ size = ref->size;
+ maxsize = ref->max_size;
+
+ /* If we cannot constrain the size of the reference we cannot
+ test if anything kills it. */
+ if (maxsize == -1)
+ return (void *)-1;
+
+ /* def_stmt may-defs *ref. See if we can derive a value for *ref
+ from that defintion.
+ 1) Memset. */
+ if (is_gimple_reg_type (vr->type)
+ && is_gimple_call (def_stmt)
+ && (fndecl = gimple_call_fndecl (def_stmt))
+ && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
+ && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_MEMSET
+ && integer_zerop (gimple_call_arg (def_stmt, 1))
+ && host_integerp (gimple_call_arg (def_stmt, 2), 1)
+ && TREE_CODE (gimple_call_arg (def_stmt, 0)) == ADDR_EXPR)
+ {
+ tree ref2 = TREE_OPERAND (gimple_call_arg (def_stmt, 0), 0);
+ tree base2;
+ HOST_WIDE_INT offset2, size2, maxsize2;
+ base2 = get_ref_base_and_extent (ref2, &offset2, &size2, &maxsize2);
+ size2 = TREE_INT_CST_LOW (gimple_call_arg (def_stmt, 2)) * 8;
+ if ((unsigned HOST_WIDE_INT)size2 / 8
+ == TREE_INT_CST_LOW (gimple_call_arg (def_stmt, 2))
+ && operand_equal_p (base, base2, 0)
+ && offset2 <= offset
+ && offset2 + size2 >= offset + maxsize)
+ {
+ tree val = fold_convert (vr->type, integer_zero_node);
+ unsigned int value_id = get_or_alloc_constant_value_id (val);
+ return vn_reference_insert_pieces (vuse, vr->set, vr->type,
+ VEC_copy (vn_reference_op_s,
+ heap, vr->operands),
+ val, value_id);
+ }
+ }
+
+ /* 2) Assignment from an empty CONSTRUCTOR. */
+ else if (is_gimple_reg_type (vr->type)
+ && gimple_assign_single_p (def_stmt)
+ && gimple_assign_rhs_code (def_stmt) == CONSTRUCTOR
+ && CONSTRUCTOR_NELTS (gimple_assign_rhs1 (def_stmt)) == 0)
+ {
+ tree base2;
+ HOST_WIDE_INT offset2, size2, maxsize2;
+ base2 = get_ref_base_and_extent (gimple_assign_lhs (def_stmt),
+ &offset2, &size2, &maxsize2);
+ if (operand_equal_p (base, base2, 0)
+ && offset2 <= offset
+ && offset2 + size2 >= offset + maxsize)
+ {
+ tree val = fold_convert (vr->type, integer_zero_node);
+ unsigned int value_id = get_or_alloc_constant_value_id (val);
+ return vn_reference_insert_pieces (vuse, vr->set, vr->type,
+ VEC_copy (vn_reference_op_s,
+ heap, vr->operands),
+ val, value_id);
+ }
+ }
+
+ /* For aggregate copies translate the reference through them if
+ the copy kills ref. */
+ else if (gimple_assign_single_p (def_stmt)
+ && (DECL_P (gimple_assign_rhs1 (def_stmt))
+ || INDIRECT_REF_P (gimple_assign_rhs1 (def_stmt))
+ || handled_component_p (gimple_assign_rhs1 (def_stmt))))
+ {
+ tree base2;
+ HOST_WIDE_INT offset2, size2, maxsize2;
+ int i, j;
+ VEC (vn_reference_op_s, heap) *lhs = NULL, *rhs = NULL;
+ vn_reference_op_t vro;
+ ao_ref r;
+
+ /* See if the assignment kills REF. */
+ base2 = get_ref_base_and_extent (gimple_assign_lhs (def_stmt),
+ &offset2, &size2, &maxsize2);
+ if (!operand_equal_p (base, base2, 0)
+ || offset2 > offset
+ || offset2 + size2 < offset + maxsize)
+ return (void *)-1;
+
+ /* Find the common base of ref and the lhs. */
+ copy_reference_ops_from_ref (gimple_assign_lhs (def_stmt), &lhs);
+ i = VEC_length (vn_reference_op_s, vr->operands) - 1;
+ j = VEC_length (vn_reference_op_s, lhs) - 1;
+ while (j >= 0
+ && vn_reference_op_eq (VEC_index (vn_reference_op_s,
+ vr->operands, i),
+ VEC_index (vn_reference_op_s, lhs, j)))
+ {
+ i--;
+ j--;
+ }
+ /* i now points to the first additional op.
+ ??? LHS may not be completely contained in VR, one or more
+ VIEW_CONVERT_EXPRs could be in its way. We could at least
+ try handling outermost VIEW_CONVERT_EXPRs. */
+ if (j != -1)
+ return (void *)-1;
+ VEC_free (vn_reference_op_s, heap, lhs);
+
+ /* Now re-write REF to be based on the rhs of the assignment. */
+ copy_reference_ops_from_ref (gimple_assign_rhs1 (def_stmt), &rhs);
+ /* We need to pre-pend vr->operands[0..i] to rhs. */
+ if (i + 1 + VEC_length (vn_reference_op_s, rhs)
+ > VEC_length (vn_reference_op_s, vr->operands))
+ {
+ VEC (vn_reference_op_s, heap) *old = vr->operands;
+ VEC_safe_grow (vn_reference_op_s, heap, vr->operands,
+ i + 1 + VEC_length (vn_reference_op_s, rhs));
+ if (old == shared_lookup_references
+ && vr->operands != old)
+ shared_lookup_references = NULL;
+ }
+ else
+ VEC_truncate (vn_reference_op_s, vr->operands,
+ i + 1 + VEC_length (vn_reference_op_s, rhs));
+ for (j = 0; VEC_iterate (vn_reference_op_s, rhs, j, vro); ++j)
+ VEC_replace (vn_reference_op_s, vr->operands, i + 1 + j, vro);
+ VEC_free (vn_reference_op_s, heap, rhs);
+ vr->hashcode = vn_reference_compute_hash (vr);
+
+ /* Adjust *ref from the new operands. */
+ if (!ao_ref_init_from_vn_reference (&r, vr->set, vr->type, vr->operands))
+ return (void *)-1;
+ gcc_assert (ref->size == r.size);
+ *ref = r;
+
+ /* Keep looking for the adjusted *REF / VR pair. */
+ return NULL;
+ }
+
+ /* Bail out and stop walking. */
+ return (void *)-1;
+}
+
/* Lookup a reference operation by it's parts, in the current hash table.
Returns the resulting value number if it exists in the hash table,
NULL_TREE otherwise. VNRESULT will be filled in with the actual
vn_reference_t stored in the hashtable if something is found. */
tree
-vn_reference_lookup_pieces (tree vuse,
+vn_reference_lookup_pieces (tree vuse, alias_set_type set, tree type,
VEC (vn_reference_op_s, heap) *operands,
vn_reference_t *vnresult, bool maywalk)
{
@@ -950,9 +1198,19 @@ vn_reference_lookup_pieces (tree vuse,
if (!vnresult)
vnresult = &tmp;
*vnresult = NULL;
-
+
vr1.vuse = vuse ? SSA_VAL (vuse) : NULL_TREE;
- vr1.operands = valueize_refs (operands);
+ VEC_truncate (vn_reference_op_s, shared_lookup_references, 0);
+ VEC_safe_grow (vn_reference_op_s, heap, shared_lookup_references,
+ VEC_length (vn_reference_op_s, operands));
+ memcpy (VEC_address (vn_reference_op_s, shared_lookup_references),
+ VEC_address (vn_reference_op_s, operands),
+ sizeof (vn_reference_op_s)
+ * VEC_length (vn_reference_op_s, operands));
+ vr1.operands = operands = shared_lookup_references
+ = valueize_refs (shared_lookup_references);
+ vr1.type = type;
+ vr1.set = set;
vr1.hashcode = vn_reference_compute_hash (&vr1);
vn_reference_lookup_1 (&vr1, vnresult);
@@ -960,12 +1218,14 @@ vn_reference_lookup_pieces (tree vuse,
&& maywalk
&& vr1.vuse)
{
- tree ref = get_ref_from_reference_ops (operands);
- if (!ref)
- return NULL_TREE;
- *vnresult =
- (vn_reference_t)walk_non_aliased_vuses (ref, vr1.vuse,
- vn_reference_lookup_2, &vr1);
+ ao_ref r;
+ if (ao_ref_init_from_vn_reference (&r, set, type, vr1.operands))
+ *vnresult =
+ (vn_reference_t)walk_non_aliased_vuses (&r, vr1.vuse,
+ vn_reference_lookup_2,
+ vn_reference_lookup_3, &vr1);
+ if (vr1.operands != operands)
+ VEC_free (vn_reference_op_s, heap, vr1.operands);
}
if (*vnresult)
@@ -984,22 +1244,30 @@ tree
vn_reference_lookup (tree op, tree vuse, bool maywalk,
vn_reference_t *vnresult)
{
+ VEC (vn_reference_op_s, heap) *operands;
struct vn_reference_s vr1;
if (vnresult)
*vnresult = NULL;
vr1.vuse = vuse ? SSA_VAL (vuse) : NULL_TREE;
- vr1.operands = valueize_shared_reference_ops_from_ref (op);
+ vr1.operands = operands = valueize_shared_reference_ops_from_ref (op);
+ vr1.type = TREE_TYPE (op);
+ vr1.set = get_alias_set (op);
vr1.hashcode = vn_reference_compute_hash (&vr1);
if (maywalk
&& vr1.vuse)
{
vn_reference_t wvnresult;
+ ao_ref r;
+ ao_ref_init (&r, op);
wvnresult =
- (vn_reference_t)walk_non_aliased_vuses (op, vr1.vuse,
- vn_reference_lookup_2, &vr1);
+ (vn_reference_t)walk_non_aliased_vuses (&r, vr1.vuse,
+ vn_reference_lookup_2,
+ vn_reference_lookup_3, &vr1);
+ if (vr1.operands != operands)
+ VEC_free (vn_reference_op_s, heap, vr1.operands);
if (wvnresult)
{
if (vnresult)
@@ -1030,6 +1298,8 @@ vn_reference_insert (tree op, tree result, tree vuse)
vr1->value_id = get_or_alloc_constant_value_id (result);
vr1->vuse = vuse ? SSA_VAL (vuse) : NULL_TREE;
vr1->operands = valueize_refs (create_reference_ops_from_ref (op));
+ vr1->type = TREE_TYPE (op);
+ vr1->set = get_alias_set (op);
vr1->hashcode = vn_reference_compute_hash (vr1);
vr1->result = TREE_CODE (result) == SSA_NAME ? SSA_VAL (result) : result;
@@ -1057,7 +1327,7 @@ vn_reference_insert (tree op, tree result, tree vuse)
structure we created. */
vn_reference_t
-vn_reference_insert_pieces (tree vuse,
+vn_reference_insert_pieces (tree vuse, alias_set_type set, tree type,
VEC (vn_reference_op_s, heap) *operands,
tree result, unsigned int value_id)
@@ -1069,6 +1339,8 @@ vn_reference_insert_pieces (tree vuse,
vr1->value_id = value_id;
vr1->vuse = vuse ? SSA_VAL (vuse) : NULL_TREE;
vr1->operands = valueize_refs (operands);
+ vr1->type = type;
+ vr1->set = set;
vr1->hashcode = vn_reference_compute_hash (vr1);
if (result && TREE_CODE (result) == SSA_NAME)
result = SSA_VAL (result);
@@ -1090,7 +1362,7 @@ vn_reference_insert_pieces (tree vuse,
/* Compute and return the hash value for nary operation VBO1. */
-inline hashval_t
+hashval_t
vn_nary_op_compute_hash (const vn_nary_op_t vno1)
{
hashval_t hash = 0;
@@ -1232,7 +1504,7 @@ vn_nary_op_lookup_stmt (gimple stmt, vn_nary_op_t *vnresult)
*vnresult = NULL;
vno1.opcode = gimple_assign_rhs_code (stmt);
vno1.length = gimple_num_ops (stmt) - 1;
- vno1.type = TREE_TYPE (gimple_assign_lhs (stmt));
+ vno1.type = gimple_expr_type (stmt);
for (i = 0; i < vno1.length; ++i)
vno1.op[i] = gimple_op (stmt, i + 1);
if (vno1.opcode == REALPART_EXPR
@@ -1340,7 +1612,7 @@ vn_nary_op_insert_stmt (gimple stmt, tree result)
vno1->value_id = VN_INFO (result)->value_id;
vno1->opcode = gimple_assign_rhs_code (stmt);
vno1->length = length;
- vno1->type = TREE_TYPE (gimple_assign_lhs (stmt));
+ vno1->type = gimple_expr_type (stmt);
for (i = 0; i < vno1->length; ++i)
vno1->op[i] = gimple_op (stmt, i + 1);
if (vno1->opcode == REALPART_EXPR
@@ -1662,6 +1934,8 @@ visit_reference_op_call (tree lhs, gimple stmt)
vr1.vuse = vuse ? SSA_VAL (vuse) : NULL_TREE;
vr1.operands = valueize_shared_reference_ops_from_call (stmt);
+ vr1.type = gimple_expr_type (stmt);
+ vr1.set = 0;
vr1.hashcode = vn_reference_compute_hash (&vr1);
result = vn_reference_lookup_1 (&vr1, NULL);
if (result)
@@ -1679,6 +1953,8 @@ visit_reference_op_call (tree lhs, gimple stmt)
vr2 = (vn_reference_t) pool_alloc (current_info->references_pool);
vr2->vuse = vr1.vuse;
vr2->operands = valueize_refs (create_reference_ops_from_call (stmt));
+ vr2->type = vr1.type;
+ vr2->set = vr1.set;
vr2->hashcode = vr1.hashcode;
vr2->result = lhs;
slot = htab_find_slot_with_hash (current_info->references,
@@ -1700,6 +1976,12 @@ visit_reference_op_load (tree lhs, tree op, gimple stmt)
bool changed = false;
tree result = vn_reference_lookup (op, gimple_vuse (stmt), true, NULL);
+ /* If we have a VCE, try looking up its operand as it might be stored in
+ a different type. */
+ if (!result && TREE_CODE (op) == VIEW_CONVERT_EXPR)
+ result = vn_reference_lookup (TREE_OPERAND (op, 0), gimple_vuse (stmt),
+ true, NULL);
+
/* We handle type-punning through unions by value-numbering based
on offset and size of the access. Be prepared to handle a
type-mismatch here via creating a VIEW_CONVERT_EXPR. */
@@ -2065,7 +2347,7 @@ simplify_binary_expression (gimple stmt)
fold_defer_overflow_warnings ();
result = fold_binary (gimple_assign_rhs_code (stmt),
- TREE_TYPE (gimple_get_lhs (stmt)), op0, op1);
+ gimple_expr_type (stmt), op0, op1);
if (result)
STRIP_USELESS_TYPE_CONVERSION (result);
@@ -2421,7 +2703,7 @@ compare_ops (const void *pa, const void *pb)
basic_block bbb;
if (gimple_nop_p (opstmta) && gimple_nop_p (opstmtb))
- return 0;
+ return SSA_NAME_VERSION (opa) - SSA_NAME_VERSION (opb);
else if (gimple_nop_p (opstmta))
return -1;
else if (gimple_nop_p (opstmtb))
@@ -2431,7 +2713,7 @@ compare_ops (const void *pa, const void *pb)
bbb = gimple_bb (opstmtb);
if (!bba && !bbb)
- return 0;
+ return SSA_NAME_VERSION (opa) - SSA_NAME_VERSION (opb);
else if (!bba)
return -1;
else if (!bbb)
@@ -2441,12 +2723,15 @@ compare_ops (const void *pa, const void *pb)
{
if (gimple_code (opstmta) == GIMPLE_PHI
&& gimple_code (opstmtb) == GIMPLE_PHI)
- return 0;
+ return SSA_NAME_VERSION (opa) - SSA_NAME_VERSION (opb);
else if (gimple_code (opstmta) == GIMPLE_PHI)
return -1;
else if (gimple_code (opstmtb) == GIMPLE_PHI)
return 1;
- return gimple_uid (opstmta) - gimple_uid (opstmtb);
+ else if (gimple_uid (opstmta) != gimple_uid (opstmtb))
+ return gimple_uid (opstmta) - gimple_uid (opstmtb);
+ else
+ return SSA_NAME_VERSION (opa) - SSA_NAME_VERSION (opb);
}
return rpo_numbers[bba->index] - rpo_numbers[bbb->index];
}
diff --git a/gcc/tree-ssa-sccvn.h b/gcc/tree-ssa-sccvn.h
index c8171c22710..c60c28ac11a 100644
--- a/gcc/tree-ssa-sccvn.h
+++ b/gcc/tree-ssa-sccvn.h
@@ -21,6 +21,10 @@
#ifndef TREE_SSA_SCCVN_H
#define TREE_SSA_SCCVN_H
+/* In tree-ssa-sccvn.c */
+bool expressions_equal_p (tree, tree);
+
+
/* TOP of the VN lattice. */
extern tree VN_TOP;
@@ -92,6 +96,8 @@ typedef struct vn_reference_s
unsigned int value_id;
hashval_t hashcode;
tree vuse;
+ alias_set_type set;
+ tree type;
VEC (vn_reference_op_s, heap) *operands;
tree result;
} *vn_reference_t;
@@ -177,13 +183,14 @@ void vn_reference_fold_indirect (VEC (vn_reference_op_s, heap) **,
unsigned int *);
void copy_reference_ops_from_ref (tree, VEC(vn_reference_op_s, heap) **);
void copy_reference_ops_from_call (gimple, VEC(vn_reference_op_s, heap) **);
-tree get_ref_from_reference_ops (VEC(vn_reference_op_s, heap) *ops);
-tree vn_reference_lookup_pieces (tree,
+bool ao_ref_init_from_vn_reference (ao_ref *, alias_set_type, tree,
+ VEC (vn_reference_op_s, heap) *);
+tree vn_reference_lookup_pieces (tree, alias_set_type, tree,
VEC (vn_reference_op_s, heap) *,
vn_reference_t *, bool);
tree vn_reference_lookup (tree, tree, bool, vn_reference_t *);
vn_reference_t vn_reference_insert (tree, tree, tree);
-vn_reference_t vn_reference_insert_pieces (tree,
+vn_reference_t vn_reference_insert_pieces (tree, alias_set_type, tree,
VEC (vn_reference_op_s, heap) *,
tree, unsigned int);
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index 8ba1f853800..f60b24c9c52 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -226,10 +226,6 @@ struct variable_info
/* True if this is a heap variable. */
unsigned int is_heap_var:1;
- /* True if we may not use TBAA to prune references to this
- variable. This is used for C++ placement new. */
- unsigned int no_tbaa_pruning : 1;
-
/* True if this field may contain pointers. */
unsigned int may_have_pointers : 1;
@@ -360,7 +356,6 @@ static varinfo_t
new_var_info (tree t, unsigned int id, const char *name)
{
varinfo_t ret = (varinfo_t) pool_alloc (variable_info_pool);
- tree var;
ret->id = id;
ret->name = name;
@@ -371,12 +366,6 @@ new_var_info (tree t, unsigned int id, const char *name)
ret->is_unknown_size_var = false;
ret->is_full_var = false;
ret->may_have_pointers = true;
- var = t;
- if (TREE_CODE (var) == SSA_NAME)
- var = SSA_NAME_VAR (var);
- ret->no_tbaa_pruning = (DECL_P (var)
- && POINTER_TYPE_P (TREE_TYPE (var))
- && DECL_NO_TBAA_P (var));
ret->solution = BITMAP_ALLOC (&pta_obstack);
ret->oldsolution = BITMAP_ALLOC (&oldpta_obstack);
ret->next = NULL;
@@ -1425,9 +1414,6 @@ unify_nodes (constraint_graph_t graph, unsigned int to, unsigned int from,
merge_graph_nodes (graph, to, from);
merge_node_constraints (graph, to, from);
- if (get_varinfo (from)->no_tbaa_pruning)
- get_varinfo (to)->no_tbaa_pruning = true;
-
/* Mark TO as changed if FROM was changed. If TO was already marked
as changed, decrease the changed count. */
@@ -1678,6 +1664,19 @@ do_ds_constraint (constraint_t c, bitmap delta)
unsigned int t;
HOST_WIDE_INT fieldoffset = v->offset + loff;
+ /* If v is a NONLOCAL then this is an escape point. */
+ if (j == nonlocal_id)
+ {
+ t = find (escaped_id);
+ if (add_graph_edge (graph, t, rhs)
+ && bitmap_ior_into (get_varinfo (t)->solution, sol)
+ && !TEST_BIT (changed, t))
+ {
+ SET_BIT (changed, t);
+ changed_count++;
+ }
+ }
+
if (v->is_special_var)
continue;
@@ -1694,18 +1693,24 @@ do_ds_constraint (constraint_t c, bitmap delta)
if (v->may_have_pointers)
{
t = find (v->id);
- if (add_graph_edge (graph, t, rhs))
+ if (add_graph_edge (graph, t, rhs)
+ && bitmap_ior_into (get_varinfo (t)->solution, sol)
+ && !TEST_BIT (changed, t))
{
- if (bitmap_ior_into (get_varinfo (t)->solution, sol))
- {
- if (t == rhs)
- sol = get_varinfo (rhs)->solution;
- if (!TEST_BIT (changed, t))
- {
- SET_BIT (changed, t);
- changed_count++;
- }
- }
+ SET_BIT (changed, t);
+ changed_count++;
+ }
+ }
+ /* If v is a global variable then this is an escape point. */
+ if (is_global_var (v->decl))
+ {
+ t = find (escaped_id);
+ if (add_graph_edge (graph, t, rhs)
+ && bitmap_ior_into (get_varinfo (t)->solution, sol)
+ && !TEST_BIT (changed, t))
+ {
+ SET_BIT (changed, t);
+ changed_count++;
}
}
@@ -1878,7 +1883,8 @@ equiv_class_label_eq (const void *p1, const void *p2)
{
const_equiv_class_label_t const eql1 = (const_equiv_class_label_t) p1;
const_equiv_class_label_t const eql2 = (const_equiv_class_label_t) p2;
- return bitmap_equal_p (eql1->labels, eql2->labels);
+ return (eql1->hashcode == eql2->hashcode
+ && bitmap_equal_p (eql1->labels, eql2->labels));
}
/* Lookup a equivalence class in TABLE by the bitmap of LABELS it
@@ -3093,6 +3099,28 @@ do_deref (VEC (ce_s, heap) **constraints)
}
}
+static void get_constraint_for_1 (tree, VEC (ce_s, heap) **, bool);
+
+/* Given a tree T, return the constraint expression for taking the
+ address of it. */
+
+static void
+get_constraint_for_address_of (tree t, VEC (ce_s, heap) **results)
+{
+ struct constraint_expr *c;
+ unsigned int i;
+
+ get_constraint_for_1 (t, results, true);
+
+ for (i = 0; VEC_iterate (ce_s, *results, i, c); i++)
+ {
+ if (c->type == DEREF)
+ c->type = SCALAR;
+ else
+ c->type = ADDRESSOF;
+ }
+}
+
/* Given a tree T, return the constraint expression for it. */
static void
@@ -3144,23 +3172,8 @@ get_constraint_for_1 (tree t, VEC (ce_s, heap) **results, bool address_p)
switch (TREE_CODE (t))
{
case ADDR_EXPR:
- {
- struct constraint_expr *c;
- unsigned int i;
- tree exp = TREE_OPERAND (t, 0);
-
- get_constraint_for_1 (exp, results, true);
-
- for (i = 0; VEC_iterate (ce_s, *results, i, c); i++)
- {
- if (c->type == DEREF)
- c->type = SCALAR;
- else
- c->type = ADDRESSOF;
- }
- return;
- }
- break;
+ get_constraint_for_address_of (TREE_OPERAND (t, 0), results);
+ return;
default:;
}
break;
@@ -3346,6 +3359,22 @@ handle_rhs_call (gimple stmt, VEC(ce_s, heap) **results)
if (gimple_call_chain (stmt))
make_escape_constraint (gimple_call_chain (stmt));
+ /* And if we applied NRV the address of the return slot escapes as well. */
+ if (gimple_call_return_slot_opt_p (stmt)
+ && gimple_call_lhs (stmt) != NULL_TREE
+ && TREE_ADDRESSABLE (gimple_call_lhs (stmt)))
+ {
+ VEC(ce_s, heap) *tmpc = NULL;
+ struct constraint_expr lhsc, *c;
+ get_constraint_for_address_of (gimple_call_lhs (stmt), &tmpc);
+ lhsc.var = escaped_id;
+ lhsc.offset = 0;
+ lhsc.type = SCALAR;
+ for (i = 0; VEC_iterate (ce_s, tmpc, i, c); ++i)
+ process_constraint (new_constraint (lhsc, *c));
+ VEC_free(ce_s, heap, tmpc);
+ }
+
/* Regular functions return nonlocal memory. */
rhsc.var = nonlocal_id;
rhsc.offset = 0;
@@ -3425,7 +3454,7 @@ handle_lhs_call (tree lhs, int flags, VEC(ce_s, heap) *rhsc)
static void
handle_const_call (gimple stmt, VEC(ce_s, heap) **results)
{
- struct constraint_expr rhsc, tmpc = { SCALAR, 0, 0 };
+ struct constraint_expr rhsc, tmpc = {SCALAR, 0, 0};
tree tmpvar = NULL_TREE;
unsigned int k;
@@ -3532,7 +3561,6 @@ find_func_aliases (gimple origt)
VEC(ce_s, heap) *lhsc = NULL;
VEC(ce_s, heap) *rhsc = NULL;
struct constraint_expr *c;
- enum escape_type stmt_escape_type;
/* Now build constraints expressions. */
if (gimple_code (t) == GIMPLE_PHI)
@@ -3724,46 +3752,21 @@ find_func_aliases (gimple origt)
process_constraint (new_constraint (*c, *c2));
}
}
+ /* If there is a store to a global variable the rhs escapes. */
+ if ((lhsop = get_base_address (lhsop)) != NULL_TREE
+ && DECL_P (lhsop)
+ && is_global_var (lhsop))
+ make_escape_constraint (rhsop);
}
- else if (gimple_code (t) == GIMPLE_CHANGE_DYNAMIC_TYPE)
- {
- unsigned int j;
-
- get_constraint_for (gimple_cdt_location (t), &lhsc);
- for (j = 0; VEC_iterate (ce_s, lhsc, j, c); ++j)
- get_varinfo (c->var)->no_tbaa_pruning = true;
- }
-
- stmt_escape_type = is_escape_site (t);
- if (stmt_escape_type == ESCAPE_STORED_IN_GLOBAL)
+ /* For conversions of pointers to non-pointers the pointer escapes. */
+ else if (gimple_assign_cast_p (t)
+ && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (t)))
+ && !POINTER_TYPE_P (TREE_TYPE (gimple_assign_lhs (t))))
{
- gcc_assert (is_gimple_assign (t));
- if (gimple_assign_rhs_code (t) == ADDR_EXPR)
- {
- tree rhs = gimple_assign_rhs1 (t);
- tree base = get_base_address (TREE_OPERAND (rhs, 0));
- if (base
- && (!DECL_P (base)
- || !is_global_var (base)))
- make_escape_constraint (rhs);
- }
- else if (get_gimple_rhs_class (gimple_assign_rhs_code (t))
- == GIMPLE_SINGLE_RHS)
- {
- if (could_have_pointers (gimple_assign_rhs1 (t)))
- make_escape_constraint (gimple_assign_rhs1 (t));
- }
- else
- gcc_unreachable ();
- }
- else if (stmt_escape_type == ESCAPE_BAD_CAST)
- {
- gcc_assert (is_gimple_assign (t));
- gcc_assert (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (t))
- || gimple_assign_rhs_code (t) == VIEW_CONVERT_EXPR);
make_escape_constraint (gimple_assign_rhs1 (t));
}
- else if (stmt_escape_type == ESCAPE_TO_ASM)
+ /* Handle asms conservatively by adding escape constraints to everything. */
+ else if (gimple_code (t) == GIMPLE_ASM)
{
unsigned i, noutputs;
const char **oconstraints;
@@ -4444,10 +4447,7 @@ dump_solution_for_var (FILE *file, unsigned int var)
{
fprintf (file, "%s ", get_varinfo (i)->name);
}
- fprintf (file, "}");
- if (vi->no_tbaa_pruning)
- fprintf (file, " no-tbaa-pruning");
- fprintf (file, "\n");
+ fprintf (file, "}\n");
}
}
@@ -4628,19 +4628,13 @@ shared_bitmap_add (bitmap pt_vars)
}
-/* Set bits in INTO corresponding to the variable uids in solution set FROM.
- If MEM_ALIAS_SET is not zero, we also use type based alias analysis to
- prune the points-to sets with this alias-set.
- Returns the number of pruned variables and updates the vars_contains_global
- member of *PT . */
+/* Set bits in INTO corresponding to the variable uids in solution set FROM. */
-static unsigned
-set_uids_in_ptset (bitmap into, bitmap from,
- alias_set_type mem_alias_set, struct pt_solution *pt)
+static void
+set_uids_in_ptset (bitmap into, bitmap from, struct pt_solution *pt)
{
unsigned int i;
bitmap_iterator bi;
- unsigned pruned = 0;
EXECUTE_IF_SET_IN_BITMAP (from, 0, i, bi)
{
@@ -4655,22 +4649,6 @@ set_uids_in_ptset (bitmap into, bitmap from,
|| TREE_CODE (vi->decl) == PARM_DECL
|| TREE_CODE (vi->decl) == RESULT_DECL)
{
- /* Don't type prune artificial vars or points-to sets
- for pointers that have not been dereferenced or with
- type-based pruning disabled. */
- if (!vi->is_artificial_var
- && !vi->no_tbaa_pruning
- && mem_alias_set != 0)
- {
- alias_set_type var_alias_set = get_alias_set (vi->decl);
- if (mem_alias_set != var_alias_set
- && !alias_set_subset_of (mem_alias_set, var_alias_set))
- {
- ++pruned;
- continue;
- }
- }
-
/* Add the decl to the points-to set. Note that the points-to
set contains global variables. */
bitmap_set_bit (into, DECL_UID (vi->decl));
@@ -4678,113 +4656,21 @@ set_uids_in_ptset (bitmap into, bitmap from,
pt->vars_contains_global = true;
}
}
-
- return pruned;
}
static bool have_alias_info = false;
-/* Emit a note for the pointer initialization point DEF. */
-
-static void
-emit_pointer_definition (tree ptr, bitmap visited)
-{
- gimple def = SSA_NAME_DEF_STMT (ptr);
- if (gimple_code (def) == GIMPLE_PHI)
- {
- use_operand_p argp;
- ssa_op_iter oi;
-
- FOR_EACH_PHI_ARG (argp, def, oi, SSA_OP_USE)
- {
- tree arg = USE_FROM_PTR (argp);
- if (TREE_CODE (arg) == SSA_NAME)
- {
- if (bitmap_set_bit (visited, SSA_NAME_VERSION (arg)))
- emit_pointer_definition (arg, visited);
- }
- else
- inform (0, "initialized from %qE", arg);
- }
- }
- else if (!gimple_nop_p (def))
- inform (gimple_location (def), "initialized from here");
-}
-
-/* Emit a strict aliasing warning for dereferencing the pointer PTR. */
+/* Compute the points-to solution *PT for the variable VI. */
static void
-emit_alias_warning (tree ptr)
+find_what_var_points_to (varinfo_t vi, struct pt_solution *pt)
{
- gimple use;
- imm_use_iterator ui;
- bool warned = false;
-
- FOR_EACH_IMM_USE_STMT (use, ui, ptr)
- {
- tree deref = NULL_TREE;
-
- if (gimple_has_lhs (use))
- {
- tree lhs = get_base_address (gimple_get_lhs (use));
- if (lhs
- && INDIRECT_REF_P (lhs)
- && TREE_OPERAND (lhs, 0) == ptr)
- deref = lhs;
- }
- if (gimple_assign_single_p (use))
- {
- tree rhs = get_base_address (gimple_assign_rhs1 (use));
- if (rhs
- && INDIRECT_REF_P (rhs)
- && TREE_OPERAND (rhs, 0) == ptr)
- deref = rhs;
- }
- else if (is_gimple_call (use))
- {
- unsigned i;
- for (i = 0; i < gimple_call_num_args (use); ++i)
- {
- tree op = get_base_address (gimple_call_arg (use, i));
- if (op
- && INDIRECT_REF_P (op)
- && TREE_OPERAND (op, 0) == ptr)
- deref = op;
- }
- }
- if (deref
- && !TREE_NO_WARNING (deref))
- {
- TREE_NO_WARNING (deref) = 1;
- warned |= warning_at (gimple_location (use), OPT_Wstrict_aliasing,
- "dereferencing pointer %qD does break "
- "strict-aliasing rules", SSA_NAME_VAR (ptr));
- }
- }
- if (warned)
- {
- bitmap visited = BITMAP_ALLOC (NULL);
- emit_pointer_definition (ptr, visited);
- BITMAP_FREE (visited);
- }
-}
-
-/* Compute the points-to solution *PT for the variable VI.
- Prunes the points-to set based on TBAA rules if DO_TBAA_PRUNING
- is true. Returns the number of TBAA pruned variables from the
- points-to set. */
-
-static unsigned int
-find_what_var_points_to (varinfo_t vi, struct pt_solution *pt,
- bool do_tbaa_pruning)
-{
- unsigned int i, pruned;
+ unsigned int i;
bitmap_iterator bi;
bitmap finished_solution;
bitmap result;
tree ptr = vi->decl;
- alias_set_type mem_alias_set;
memset (pt, 0, sizeof (struct pt_solution));
@@ -4821,7 +4707,7 @@ find_what_var_points_to (varinfo_t vi, struct pt_solution *pt,
/* Instead of doing extra work, simply do not create
elaborate points-to information for pt_anything pointers. */
if (pt->anything)
- return 0;
+ return;
/* Share the final set of variables when possible. */
finished_solution = BITMAP_GGC_ALLOC ();
@@ -4830,15 +4716,7 @@ find_what_var_points_to (varinfo_t vi, struct pt_solution *pt,
if (TREE_CODE (ptr) == SSA_NAME)
ptr = SSA_NAME_VAR (ptr);
- /* If the pointer decl is marked that no TBAA is to be applied,
- do not do tbaa pruning. */
- if (!do_tbaa_pruning
- || DECL_NO_TBAA_P (ptr))
- mem_alias_set = 0;
- else
- mem_alias_set = get_deref_alias_set (ptr);
- pruned = set_uids_in_ptset (finished_solution, vi->solution,
- mem_alias_set, pt);
+ set_uids_in_ptset (finished_solution, vi->solution, pt);
result = shared_bitmap_lookup (finished_solution);
if (!result)
{
@@ -4850,18 +4728,14 @@ find_what_var_points_to (varinfo_t vi, struct pt_solution *pt,
pt->vars = result;
bitmap_clear (finished_solution);
}
-
- return pruned;
}
-/* Given a pointer variable P, fill in its points-to set. Apply
- type-based pruning if IS_DEREFERENCED is true. */
+/* Given a pointer variable P, fill in its points-to set. */
static void
-find_what_p_points_to (tree p, bool is_dereferenced)
+find_what_p_points_to (tree p)
{
struct ptr_info_def *pi;
- unsigned int pruned;
tree lookup_p = p;
varinfo_t vi;
@@ -4877,23 +4751,7 @@ find_what_p_points_to (tree p, bool is_dereferenced)
return;
pi = get_ptr_info (p);
- pruned = find_what_var_points_to (vi, &pi->pt, is_dereferenced);
-
- if (!(pi->pt.anything || pi->pt.nonlocal || pi->pt.escaped)
- && bitmap_empty_p (pi->pt.vars)
- && pruned > 0
- && is_dereferenced
- && warn_strict_aliasing > 0
- && !SSA_NAME_IS_DEFAULT_DEF (p))
- {
- if (dump_file && dump_flags & TDF_DETAILS)
- {
- fprintf (dump_file, "alias warning for ");
- print_generic_expr (dump_file, p, 0);
- fprintf (dump_file, "\n");
- }
- emit_alias_warning (p);
- }
+ find_what_var_points_to (vi, &pi->pt);
}
@@ -5372,139 +5230,6 @@ remove_preds_and_fake_succs (constraint_graph_t graph)
bitmap_obstack_release (&predbitmap_obstack);
}
-/* Compute the set of variables we can't TBAA prune. */
-
-static void
-compute_tbaa_pruning (void)
-{
- unsigned int size = VEC_length (varinfo_t, varmap);
- unsigned int i;
- bool any;
-
- changed_count = 0;
- changed = sbitmap_alloc (size);
- sbitmap_zero (changed);
-
- /* Mark all initial no_tbaa_pruning nodes as changed. */
- any = false;
- for (i = 0; i < size; ++i)
- {
- varinfo_t ivi = get_varinfo (i);
-
- if (find (i) == i && ivi->no_tbaa_pruning)
- {
- any = true;
- if ((graph->succs[i] && !bitmap_empty_p (graph->succs[i]))
- || VEC_length (constraint_t, graph->complex[i]) > 0)
- {
- SET_BIT (changed, i);
- ++changed_count;
- }
- }
- }
-
- while (changed_count > 0)
- {
- struct topo_info *ti = init_topo_info ();
- ++stats.iterations;
-
- compute_topo_order (graph, ti);
-
- while (VEC_length (unsigned, ti->topo_order) != 0)
- {
- bitmap_iterator bi;
-
- i = VEC_pop (unsigned, ti->topo_order);
-
- /* If this variable is not a representative, skip it. */
- if (find (i) != i)
- continue;
-
- /* If the node has changed, we need to process the complex
- constraints and outgoing edges again. */
- if (TEST_BIT (changed, i))
- {
- unsigned int j;
- constraint_t c;
- VEC(constraint_t,heap) *complex = graph->complex[i];
-
- RESET_BIT (changed, i);
- --changed_count;
-
- /* Process the complex copy constraints. */
- for (j = 0; VEC_iterate (constraint_t, complex, j, c); ++j)
- {
- if (c->lhs.type == SCALAR && c->rhs.type == SCALAR)
- {
- varinfo_t lhsvi = get_varinfo (find (c->lhs.var));
-
- if (!lhsvi->no_tbaa_pruning)
- {
- lhsvi->no_tbaa_pruning = true;
- if (!TEST_BIT (changed, lhsvi->id))
- {
- SET_BIT (changed, lhsvi->id);
- ++changed_count;
- }
- }
- }
- }
-
- /* Propagate to all successors. */
- EXECUTE_IF_IN_NONNULL_BITMAP (graph->succs[i], 0, j, bi)
- {
- unsigned int to = find (j);
- varinfo_t tovi = get_varinfo (to);
-
- /* Don't propagate to ourselves. */
- if (to == i)
- continue;
-
- if (!tovi->no_tbaa_pruning)
- {
- tovi->no_tbaa_pruning = true;
- if (!TEST_BIT (changed, to))
- {
- SET_BIT (changed, to);
- ++changed_count;
- }
- }
- }
- }
- }
-
- free_topo_info (ti);
- }
-
- sbitmap_free (changed);
-
- if (any)
- {
- for (i = 0; i < size; ++i)
- {
- varinfo_t ivi = get_varinfo (i);
- varinfo_t ivip = get_varinfo (find (i));
-
- if (ivip->no_tbaa_pruning)
- {
- tree var = ivi->decl;
-
- if (TREE_CODE (var) == SSA_NAME)
- var = SSA_NAME_VAR (var);
-
- if (POINTER_TYPE_P (TREE_TYPE (var)))
- {
- DECL_NO_TBAA_P (var) = 1;
-
- /* Tell the RTL layer that this pointer can alias
- anything. */
- DECL_POINTER_ALIAS_SET (var) = 0;
- }
- }
- }
- }
-}
-
/* Initialize the heapvar for statement mapping. */
static void
@@ -5534,7 +5259,6 @@ compute_points_to_sets (void)
struct scc_info *si;
basic_block bb;
unsigned i;
- sbitmap dereferenced_ptrs;
timevar_push (TV_TREE_PTA);
@@ -5543,11 +5267,6 @@ compute_points_to_sets (void)
intra_create_variable_infos ();
- /* A bitmap of SSA_NAME pointers that are dereferenced. This is
- used to track which points-to sets may be TBAA pruned. */
- dereferenced_ptrs = sbitmap_alloc (num_ssa_names);
- sbitmap_zero (dereferenced_ptrs);
-
/* Now walk all statements and derive aliases. */
FOR_EACH_BB (bb)
{
@@ -5564,31 +5283,11 @@ compute_points_to_sets (void)
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
gimple stmt = gsi_stmt (gsi);
- use_operand_p use_p;
- ssa_op_iter iter;
-
- /* Mark dereferenced pointers. This is used by TBAA pruning
- of the points-to sets and the alias warning machinery. */
- FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
- {
- unsigned num_uses, num_loads, num_stores;
- tree op = USE_FROM_PTR (use_p);
-
- if (!POINTER_TYPE_P (TREE_TYPE (op)))
- continue;
-
- /* Determine whether OP is a dereferenced pointer. */
- count_uses_and_derefs (op, stmt,
- &num_uses, &num_loads, &num_stores);
- if (num_loads + num_stores > 0)
- SET_BIT (dereferenced_ptrs, SSA_NAME_VERSION (op));
- }
find_func_aliases (stmt);
}
}
-
if (dump_file)
{
fprintf (dump_file, "Points-to analysis\n\nConstraints:\n\n");
@@ -5642,15 +5341,13 @@ compute_points_to_sets (void)
solve_graph (graph);
- compute_tbaa_pruning ();
-
if (dump_file)
dump_sa_points_to_info (dump_file);
/* Compute the points-to sets for ESCAPED and CALLUSED used for
call-clobber analysis. */
- find_what_var_points_to (var_escaped, &cfun->gimple_df->escaped, false);
- find_what_var_points_to (var_callused, &cfun->gimple_df->callused, false);
+ find_what_var_points_to (var_escaped, &cfun->gimple_df->escaped);
+ find_what_var_points_to (var_callused, &cfun->gimple_df->callused);
/* Make sure the ESCAPED solution (which is used as placeholder in
other solutions) does not reference itself. This simplifies
@@ -5663,9 +5360,8 @@ compute_points_to_sets (void)
tree ptr = ssa_name (i);
if (ptr
&& POINTER_TYPE_P (TREE_TYPE (ptr)))
- find_what_p_points_to (ptr, TEST_BIT (dereferenced_ptrs, i));
+ find_what_p_points_to (ptr);
}
- sbitmap_free (dereferenced_ptrs);
timevar_pop (TV_TREE_PTA);
@@ -5737,6 +5433,11 @@ compute_may_aliases (void)
return 0;
}
+static bool
+gate_tree_pta (void)
+{
+ return flag_tree_pta;
+}
/* A dummy pass to cause points-to information to be computed via
TODO_rebuild_alias. */
@@ -5746,7 +5447,29 @@ struct gimple_opt_pass pass_build_alias =
{
GIMPLE_PASS,
"alias", /* name */
- NULL, /* gate */
+ gate_tree_pta, /* gate */
+ NULL, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ TV_NONE, /* tv_id */
+ PROP_cfg | PROP_ssa, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_rebuild_alias | TODO_dump_func /* todo_flags_finish */
+ }
+};
+
+/* A dummy pass to cause points-to information to be computed via
+ TODO_rebuild_alias. */
+
+struct gimple_opt_pass pass_build_ealias =
+{
+ {
+ GIMPLE_PASS,
+ "ealias", /* name */
+ gate_tree_pta, /* gate */
NULL, /* execute */
NULL, /* sub */
NULL, /* next */
diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c
index b29a954e233..40ddf055211 100644
--- a/gcc/tree-ssa.c
+++ b/gcc/tree-ssa.c
@@ -926,19 +926,9 @@ useless_type_conversion_p_1 (tree outer_type, tree inner_type)
|| TYPE_PRECISION (inner_type) != TYPE_PRECISION (outer_type))
return false;
- /* Conversions from a non-base to a base type are not useless.
- This way we preserve the invariant to do arithmetic in
- base types only. */
- if (TREE_TYPE (inner_type)
- && TREE_TYPE (inner_type) != inner_type
- && (TREE_TYPE (outer_type) == outer_type
- || TREE_TYPE (outer_type) == NULL_TREE))
- return false;
-
/* We don't need to preserve changes in the types minimum or
maximum value in general as these do not generate code
unless the types precisions are different. */
-
return true;
}
@@ -1271,7 +1261,7 @@ warn_uninit (tree t, const char *gmsgid, void *data)
if (xloc.file != floc.file
|| xloc.line < floc.line
|| xloc.line > LOCATION_LINE (cfun->function_end_locus))
- inform (input_location, "%J%qD was declared here", var, var);
+ inform (location, "%J%qD was declared here", var, var);
}
}
diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c
index 6f0343fe2a5..292c49cd126 100644
--- a/gcc/tree-switch-conversion.c
+++ b/gcc/tree-switch-conversion.c
@@ -499,6 +499,7 @@ build_one_array (gimple swtch, int num, tree arr_index_type, gimple phi,
tree name, cst;
gimple load;
gimple_stmt_iterator gsi = gsi_for_stmt (swtch);
+ location_t loc = gimple_location (swtch);
gcc_assert (info.default_values[num]);
@@ -517,7 +518,7 @@ build_one_array (gimple swtch, int num, tree arr_index_type, gimple phi,
ctor = build_constructor (array_type, info.constructors[num]);
TREE_CONSTANT (ctor) = true;
- decl = build_decl (VAR_DECL, NULL_TREE, array_type);
+ decl = build_decl (loc, VAR_DECL, NULL_TREE, array_type);
TREE_STATIC (decl) = 1;
DECL_INITIAL (decl) = ctor;
@@ -665,9 +666,9 @@ fix_phi_nodes (edge e1f, edge e2f, basic_block bbf)
static void
gen_inbound_check (gimple swtch)
{
- tree label_decl1 = create_artificial_label ();
- tree label_decl2 = create_artificial_label ();
- tree label_decl3 = create_artificial_label ();
+ tree label_decl1 = create_artificial_label (UNKNOWN_LOCATION);
+ tree label_decl2 = create_artificial_label (UNKNOWN_LOCATION);
+ tree label_decl3 = create_artificial_label (UNKNOWN_LOCATION);
gimple label1, label2, label3;
tree utype;
diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c
index 443ecd04088..7646cc1ad0f 100644
--- a/gcc/tree-vect-data-refs.c
+++ b/gcc/tree-vect-data-refs.c
@@ -363,7 +363,7 @@ vect_check_interleaving (struct data_reference *dra,
and DRB is accessed before DRA. */
diff_mod_size = (init_a - init_b) % type_size_a;
- if ((init_a - init_b) > step)
+ if (step && (init_a - init_b) > step)
return false;
if (diff_mod_size == 0)
@@ -385,7 +385,7 @@ vect_check_interleaving (struct data_reference *dra,
interleaving, and DRA is accessed before DRB. */
diff_mod_size = (init_b - init_a) % type_size_a;
- if ((init_b - init_a) > step)
+ if (step && (init_b - init_a) > step)
return false;
if (diff_mod_size == 0)
@@ -479,6 +479,7 @@ vect_mark_for_runtime_alias_test (ddr_p ddr, loop_vec_info loop_vinfo)
return true;
}
+
/* Function vect_analyze_data_ref_dependence.
Return TRUE if there (might) exist a dependence between a memory-reference
@@ -490,8 +491,8 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
loop_vec_info loop_vinfo)
{
unsigned int i;
- struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
- int vectorization_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
+ struct loop *loop = NULL;
+ int vectorization_factor = 0;
struct data_reference *dra = DDR_A (ddr);
struct data_reference *drb = DDR_B (ddr);
stmt_vec_info stmtinfo_a = vinfo_for_stmt (DR_STMT (dra));
@@ -508,23 +509,68 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
return false;
}
- if ((DR_IS_READ (dra) && DR_IS_READ (drb)) || dra == drb)
+ if (loop_vinfo)
+ {
+ loop = LOOP_VINFO_LOOP (loop_vinfo);
+ vectorization_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
+ }
+
+ if ((DR_IS_READ (dra) && DR_IS_READ (drb) && loop_vinfo) || dra == drb)
return false;
if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know)
{
+ if (loop_vinfo)
+ {
+ if (vect_print_dump_info (REPORT_DR_DETAILS))
+ {
+ fprintf (vect_dump, "versioning for alias required: "
+ "can't determine dependence between ");
+ print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
+ fprintf (vect_dump, " and ");
+ print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
+ }
+
+ /* Add to list of ddrs that need to be tested at run-time. */
+ return !vect_mark_for_runtime_alias_test (ddr, loop_vinfo);
+ }
+
+ /* When vectorizing a basic block unknown depnedence can still mean
+ strided access. */
+ if (vect_check_interleaving (dra, drb))
+ return false;
+
if (vect_print_dump_info (REPORT_DR_DETAILS))
{
- fprintf (vect_dump,
- "versioning for alias required: can't determine dependence between ");
+ fprintf (vect_dump, "can't determine dependence between ");
print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
fprintf (vect_dump, " and ");
print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
}
- /* Add to list of ddrs that need to be tested at run-time. */
- return !vect_mark_for_runtime_alias_test (ddr, loop_vinfo);
+
+ return true;
+ }
+
+ /* Versioning for alias is not yet supported for basic block SLP, and
+ dependence distance is unapplicable, hence, in case of known data
+ dependence, basic block vectorization is impossible for now. */
+ if (!loop_vinfo)
+ {
+ if (dra != drb && vect_check_interleaving (dra, drb))
+ return false;
+
+ if (vect_print_dump_info (REPORT_DR_DETAILS))
+ {
+ fprintf (vect_dump, "determined dependence between ");
+ print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
+ fprintf (vect_dump, " and ");
+ print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
+ }
+
+ return true;
}
+ /* Loop-based vectorization and known data dependence. */
if (DDR_NUM_DIST_VECTS (ddr) == 0)
{
if (vect_print_dump_info (REPORT_DR_DETAILS))
@@ -589,9 +635,8 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
{
- fprintf (vect_dump,
- "not vectorized, possible dependence "
- "between data-refs ");
+ fprintf (vect_dump, "not vectorized, possible dependence "
+ "between data-refs ");
print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
fprintf (vect_dump, " and ");
print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
@@ -609,15 +654,21 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
exist any data dependences between them. */
bool
-vect_analyze_data_ref_dependences (loop_vec_info loop_vinfo)
+vect_analyze_data_ref_dependences (loop_vec_info loop_vinfo,
+ bb_vec_info bb_vinfo)
{
unsigned int i;
- VEC (ddr_p, heap) * ddrs = LOOP_VINFO_DDRS (loop_vinfo);
+ VEC (ddr_p, heap) *ddrs = NULL;
struct data_dependence_relation *ddr;
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "=== vect_analyze_dependences ===");
+ if (loop_vinfo)
+ ddrs = LOOP_VINFO_DDRS (loop_vinfo);
+ else
+ ddrs = BB_VINFO_DDRS (bb_vinfo);
+
for (i = 0; VEC_iterate (ddr_p, ddrs, i, ddr); i++)
if (vect_analyze_data_ref_dependence (ddr, loop_vinfo))
return false;
@@ -644,7 +695,7 @@ vect_compute_data_ref_alignment (struct data_reference *dr)
gimple stmt = DR_STMT (dr);
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
- struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+ struct loop *loop = NULL;
tree ref = DR_REF (dr);
tree vectype;
tree base, base_addr;
@@ -655,6 +706,9 @@ vect_compute_data_ref_alignment (struct data_reference *dr)
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "vect_compute_data_ref_alignment:");
+ if (loop_vinfo)
+ loop = LOOP_VINFO_LOOP (loop_vinfo);
+
/* Initialize misalignment to unknown. */
SET_DR_MISALIGNMENT (dr, -1);
@@ -669,7 +723,7 @@ vect_compute_data_ref_alignment (struct data_reference *dr)
stays the same throughout the execution of the inner-loop, which is why
we have to check that the stride of the dataref in the inner-loop evenly
divides by the vector size. */
- if (nested_in_vect_loop_p (loop, stmt))
+ if (loop && nested_in_vect_loop_p (loop, stmt))
{
tree step = DR_STEP (dr);
HOST_WIDE_INT dr_step = TREE_INT_CST_LOW (step);
@@ -773,12 +827,18 @@ vect_compute_data_ref_alignment (struct data_reference *dr)
Return FALSE if a data reference is found that cannot be vectorized. */
static bool
-vect_compute_data_refs_alignment (loop_vec_info loop_vinfo)
+vect_compute_data_refs_alignment (loop_vec_info loop_vinfo,
+ bb_vec_info bb_vinfo)
{
- VEC (data_reference_p, heap) *datarefs = LOOP_VINFO_DATAREFS (loop_vinfo);
+ VEC (data_reference_p, heap) *datarefs;
struct data_reference *dr;
unsigned int i;
+ if (loop_vinfo)
+ datarefs = LOOP_VINFO_DATAREFS (loop_vinfo);
+ else
+ datarefs = BB_VINFO_DATAREFS (bb_vinfo);
+
for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++)
if (!vect_compute_data_ref_alignment (dr))
return false;
@@ -850,14 +910,19 @@ vect_update_misalignment_for_peel (struct data_reference *dr,
Return TRUE if all data references in the loop can be
handled with respect to alignment. */
-static bool
-vect_verify_datarefs_alignment (loop_vec_info loop_vinfo)
+bool
+vect_verify_datarefs_alignment (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo)
{
- VEC (data_reference_p, heap) *datarefs = LOOP_VINFO_DATAREFS (loop_vinfo);
+ VEC (data_reference_p, heap) *datarefs;
struct data_reference *dr;
enum dr_alignment_support supportable_dr_alignment;
unsigned int i;
+ if (loop_vinfo)
+ datarefs = LOOP_VINFO_DATAREFS (loop_vinfo);
+ else
+ datarefs = BB_VINFO_DATAREFS (bb_vinfo);
+
for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++)
{
gimple stmt = DR_STMT (dr);
@@ -1073,11 +1138,10 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
/* While cost model enhancements are expected in the future, the high level
view of the code at this time is as follows:
- A) If there is a misaligned write then see if peeling to align this write
- can make all data references satisfy vect_supportable_dr_alignment.
- If so, update data structures as needed and return true. Note that
- at this time vect_supportable_dr_alignment is known to return false
- for a misaligned write.
+ A) If there is an unsupported misaligned access then see if peeling
+ to align this access can make all data references satisfy
+ vect_supportable_dr_alignment. If so, update data structures
+ as needed and return true.
B) If peeling wasn't possible and there is a data reference with an
unknown misalignment that does not satisfy vect_supportable_dr_alignment
@@ -1104,8 +1168,7 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
in code size).
The scheme we use FORNOW: peel to force the alignment of the first
- misaligned store in the loop.
- Rationale: misaligned stores are not yet supported.
+ unsupported misaligned access in the loop.
TODO: Use a cost model. */
@@ -1113,6 +1176,7 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
{
stmt = DR_STMT (dr);
stmt_info = vinfo_for_stmt (stmt);
+ supportable_dr_alignment = vect_supportable_dr_alignment (dr);
/* For interleaving, only the alignment of the first access
matters. */
@@ -1120,7 +1184,7 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
&& DR_GROUP_FIRST_DR (stmt_info) != stmt)
continue;
- if (!DR_IS_READ (dr) && !aligned_access_p (dr))
+ if (!supportable_dr_alignment)
{
do_peeling = vector_alignment_reachable_p (dr);
if (do_peeling)
@@ -1131,15 +1195,15 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
}
}
- vect_versioning_for_alias_required =
- (VEC_length (ddr_p, LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo)) > 0);
+ vect_versioning_for_alias_required
+ = LOOP_REQUIRES_VERSIONING_FOR_ALIAS (loop_vinfo);
/* Temporarily, if versioning for alias is required, we disable peeling
until we support peeling and versioning. Often peeling for alignment
will require peeling for loop-bound, which in turn requires that we
know how to adjust the loop ivs after the loop. */
if (vect_versioning_for_alias_required
- || !vect_can_advance_ivs_p (loop_vinfo)
+ || !vect_can_advance_ivs_p (loop_vinfo)
|| !slpeel_can_duplicate_loop_p (loop, single_exit (loop)))
do_peeling = false;
@@ -1223,7 +1287,7 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "Peeling for alignment will be applied.");
- stat = vect_verify_datarefs_alignment (loop_vinfo);
+ stat = vect_verify_datarefs_alignment (loop_vinfo, NULL);
gcc_assert (stat);
return stat;
}
@@ -1301,7 +1365,7 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
}
/* Versioning requires at least one misaligned data reference. */
- if (VEC_length (gimple, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo)) == 0)
+ if (!LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT (loop_vinfo))
do_versioning = false;
else if (!do_versioning)
VEC_truncate (gimple, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo), 0);
@@ -1331,7 +1395,7 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
/* Peeling and versioning can't be done together at this time. */
gcc_assert (! (do_peeling && do_versioning));
- stat = vect_verify_datarefs_alignment (loop_vinfo);
+ stat = vect_verify_datarefs_alignment (loop_vinfo, NULL);
gcc_assert (stat);
return stat;
}
@@ -1339,7 +1403,7 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
/* This point is reached if neither peeling nor versioning is being done. */
gcc_assert (! (do_peeling || do_versioning));
- stat = vect_verify_datarefs_alignment (loop_vinfo);
+ stat = vect_verify_datarefs_alignment (loop_vinfo, NULL);
return stat;
}
@@ -1350,12 +1414,13 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
Return FALSE if a data reference is found that cannot be vectorized. */
bool
-vect_analyze_data_refs_alignment (loop_vec_info loop_vinfo)
+vect_analyze_data_refs_alignment (loop_vec_info loop_vinfo,
+ bb_vec_info bb_vinfo)
{
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "=== vect_analyze_data_refs_alignment ===");
- if (!vect_compute_data_refs_alignment (loop_vinfo))
+ if (!vect_compute_data_refs_alignment (loop_vinfo, bb_vinfo))
{
if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
fprintf (vect_dump,
@@ -1381,6 +1446,7 @@ vect_analyze_group_access (struct data_reference *dr)
gimple stmt = DR_STMT (dr);
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
+ bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info);
HOST_WIDE_INT dr_step = TREE_INT_CST_LOW (step);
HOST_WIDE_INT stride;
bool slp_impossible = false;
@@ -1406,8 +1472,7 @@ vect_analyze_group_access (struct data_reference *dr)
DR_GROUP_SIZE (vinfo_for_stmt (stmt)) = stride;
if (vect_print_dump_info (REPORT_DR_DETAILS))
{
- fprintf (vect_dump, "Detected single element interleaving %d ",
- DR_GROUP_SIZE (vinfo_for_stmt (stmt)));
+ fprintf (vect_dump, "Detected single element interleaving ");
print_generic_expr (vect_dump, DR_REF (dr), TDF_SLIM);
fprintf (vect_dump, " step ");
print_generic_expr (vect_dump, step, TDF_SLIM);
@@ -1508,8 +1573,8 @@ vect_analyze_group_access (struct data_reference *dr)
the type to get COUNT_IN_BYTES. */
count_in_bytes = type_size * count;
- /* Check that the size of the interleaving (including gaps) is not greater
- than STEP. */
+ /* Check that the size of the interleaving (including gaps) is not
+ greater than STEP. */
if (dr_step && dr_step < count_in_bytes + gaps * type_size)
{
if (vect_print_dump_info (REPORT_DETAILS))
@@ -1522,7 +1587,7 @@ vect_analyze_group_access (struct data_reference *dr)
/* Check that the size of the interleaving is equal to STEP for stores,
i.e., that there are no gaps. */
- if (dr_step != count_in_bytes)
+ if (dr_step && dr_step != count_in_bytes)
{
if (DR_IS_READ (dr))
{
@@ -1541,7 +1606,7 @@ vect_analyze_group_access (struct data_reference *dr)
}
/* Check that STEP is a multiple of type size. */
- if ((dr_step % type_size) != 0)
+ if (dr_step && (dr_step % type_size) != 0)
{
if (vect_print_dump_info (REPORT_DETAILS))
{
@@ -1566,6 +1631,10 @@ vect_analyze_group_access (struct data_reference *dr)
if (slp_impossible)
return false;
}
+
+ if (stride == 0)
+ stride = count;
+
DR_GROUP_SIZE (vinfo_for_stmt (stmt)) = stride;
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "Detected interleaving of size %d", (int)stride);
@@ -1573,7 +1642,14 @@ vect_analyze_group_access (struct data_reference *dr)
/* SLP: create an SLP data structure for every interleaving group of
stores for further analysis in vect_analyse_slp. */
if (!DR_IS_READ (dr) && !slp_impossible)
- VEC_safe_push (gimple, heap, LOOP_VINFO_STRIDED_STORES (loop_vinfo), stmt);
+ {
+ if (loop_vinfo)
+ VEC_safe_push (gimple, heap, LOOP_VINFO_STRIDED_STORES (loop_vinfo),
+ stmt);
+ if (bb_vinfo)
+ VEC_safe_push (gimple, heap, BB_VINFO_STRIDED_STORES (bb_vinfo),
+ stmt);
+ }
}
return true;
@@ -1592,21 +1668,24 @@ vect_analyze_data_ref_access (struct data_reference *dr)
gimple stmt = DR_STMT (dr);
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
- struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+ struct loop *loop = NULL;
HOST_WIDE_INT dr_step = TREE_INT_CST_LOW (step);
- if (!step)
+ if (loop_vinfo)
+ loop = LOOP_VINFO_LOOP (loop_vinfo);
+
+ if (loop_vinfo && !step)
{
if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "bad data-ref access");
+ fprintf (vect_dump, "bad data-ref access in loop");
return false;
}
- /* Don't allow invariant accesses. */
- if (dr_step == 0)
+ /* Don't allow invariant accesses in loops. */
+ if (loop_vinfo && dr_step == 0)
return false;
- if (nested_in_vect_loop_p (loop, stmt))
+ if (loop && nested_in_vect_loop_p (loop, stmt))
{
/* Interleaved accesses are not yet supported within outer-loop
vectorization for references in the inner-loop. */
@@ -1635,7 +1714,7 @@ vect_analyze_data_ref_access (struct data_reference *dr)
return true;
}
- if (nested_in_vect_loop_p (loop, stmt))
+ if (loop && nested_in_vect_loop_p (loop, stmt))
{
if (vect_print_dump_info (REPORT_ALIGNMENT))
fprintf (vect_dump, "strided access in outer loop.");
@@ -1657,15 +1736,20 @@ vect_analyze_data_ref_access (struct data_reference *dr)
FORNOW: handle only arrays and pointer accesses. */
bool
-vect_analyze_data_ref_accesses (loop_vec_info loop_vinfo)
+vect_analyze_data_ref_accesses (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo)
{
unsigned int i;
- VEC (data_reference_p, heap) *datarefs = LOOP_VINFO_DATAREFS (loop_vinfo);
+ VEC (data_reference_p, heap) *datarefs;
struct data_reference *dr;
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "=== vect_analyze_data_ref_accesses ===");
+ if (loop_vinfo)
+ datarefs = LOOP_VINFO_DATAREFS (loop_vinfo);
+ else
+ datarefs = BB_VINFO_DATAREFS (bb_vinfo);
+
for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++)
if (!vect_analyze_data_ref_access (dr))
{
@@ -1752,12 +1836,13 @@ vect_prune_runtime_alias_test_list (loop_vec_info loop_vinfo)
/* Function vect_analyze_data_refs.
- Find all the data references in the loop.
+ Find all the data references in the loop or basic block.
The general structure of the analysis of data refs in the vectorizer is as
follows:
- 1- vect_analyze_data_refs(loop): call compute_data_dependences_for_loop to
- find and analyze all data-refs in the loop and their dependences.
+ 1- vect_analyze_data_refs(loop/bb): call
+ compute_data_dependences_for_loop/bb to find and analyze all data-refs
+ in the loop/bb and their dependences.
2- vect_analyze_dependences(): apply dependence testing using ddrs.
3- vect_analyze_drs_alignment(): check that ref_stmt.alignment is ok.
4- vect_analyze_drs_access(): check that ref_stmt.step is ok.
@@ -1765,9 +1850,10 @@ vect_prune_runtime_alias_test_list (loop_vec_info loop_vinfo)
*/
bool
-vect_analyze_data_refs (loop_vec_info loop_vinfo)
+vect_analyze_data_refs (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo)
{
- struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+ struct loop *loop = NULL;
+ basic_block bb = NULL;
unsigned int i;
VEC (data_reference_p, heap) *datarefs;
struct data_reference *dr;
@@ -1775,14 +1861,26 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo)
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "=== vect_analyze_data_refs ===\n");
-
- compute_data_dependences_for_loop (loop, true,
- &LOOP_VINFO_DATAREFS (loop_vinfo),
- &LOOP_VINFO_DDRS (loop_vinfo));
+
+ if (loop_vinfo)
+ {
+ loop = LOOP_VINFO_LOOP (loop_vinfo);
+ compute_data_dependences_for_loop (loop, true,
+ &LOOP_VINFO_DATAREFS (loop_vinfo),
+ &LOOP_VINFO_DDRS (loop_vinfo));
+ datarefs = LOOP_VINFO_DATAREFS (loop_vinfo);
+ }
+ else
+ {
+ bb = BB_VINFO_BB (bb_vinfo);
+ compute_data_dependences_for_bb (bb, true,
+ &BB_VINFO_DATAREFS (bb_vinfo),
+ &BB_VINFO_DDRS (bb_vinfo));
+ datarefs = BB_VINFO_DATAREFS (bb_vinfo);
+ }
/* Go through the data-refs, check that the analysis succeeded. Update pointer
from stmt_vec_info struct to DR and vectype. */
- datarefs = LOOP_VINFO_DATAREFS (loop_vinfo);
for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++)
{
@@ -1834,7 +1932,7 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo)
inner-most enclosing loop). We do that by building a reference to the
first location accessed by the inner-loop, and analyze it relative to
the outer-loop. */
- if (nested_in_vect_loop_p (loop, stmt))
+ if (loop && nested_in_vect_loop_p (loop, stmt))
{
tree outer_step, outer_base, outer_init;
HOST_WIDE_INT pbitsize, pbitpos;
@@ -2053,7 +2151,6 @@ vect_create_addr_base_for_vector_ref (gimple stmt,
{
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info);
- struct loop *containing_loop = (gimple_bb (stmt))->loop_father;
tree data_ref_base = unshare_expr (DR_BASE_ADDRESS (dr));
tree base_name;
tree data_ref_base_var;
@@ -2065,22 +2162,28 @@ vect_create_addr_base_for_vector_ref (gimple stmt,
tree init = unshare_expr (DR_INIT (dr));
tree vect_ptr_type;
tree step = TYPE_SIZE_UNIT (TREE_TYPE (DR_REF (dr)));
+ loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
- gcc_assert (loop);
- if (loop != containing_loop)
+ if (loop_vinfo && loop && loop != (gimple_bb (stmt))->loop_father)
{
- loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
- struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+ struct loop *outer_loop = LOOP_VINFO_LOOP (loop_vinfo);
- gcc_assert (nested_in_vect_loop_p (loop, stmt));
+ gcc_assert (nested_in_vect_loop_p (outer_loop, stmt));
data_ref_base = unshare_expr (STMT_VINFO_DR_BASE_ADDRESS (stmt_info));
base_offset = unshare_expr (STMT_VINFO_DR_OFFSET (stmt_info));
init = unshare_expr (STMT_VINFO_DR_INIT (stmt_info));
}
- /* Create data_ref_base */
- base_name = build_fold_indirect_ref (data_ref_base);
+ if (loop_vinfo)
+ base_name = build_fold_indirect_ref (data_ref_base);
+ else
+ {
+ base_offset = ssize_int (0);
+ init = ssize_int (0);
+ base_name = build_fold_indirect_ref (unshare_expr (DR_REF (dr)));
+ }
+
data_ref_base_var = create_tmp_var (TREE_TYPE (data_ref_base), "batmp");
add_referenced_var (data_ref_base_var);
data_ref_base = force_gimple_operand (data_ref_base, &seq, true,
@@ -2110,15 +2213,24 @@ vect_create_addr_base_for_vector_ref (gimple stmt,
}
/* base + base_offset */
- addr_base = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (data_ref_base),
- data_ref_base, base_offset);
-
+ if (loop_vinfo)
+ addr_base = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (data_ref_base),
+ data_ref_base, base_offset);
+ else
+ {
+ if (TREE_CODE (DR_REF (dr)) == INDIRECT_REF)
+ addr_base = unshare_expr (TREE_OPERAND (DR_REF (dr), 0));
+ else
+ addr_base = build1 (ADDR_EXPR,
+ build_pointer_type (TREE_TYPE (DR_REF (dr))),
+ unshare_expr (DR_REF (dr)));
+ }
+
vect_ptr_type = build_pointer_type (STMT_VINFO_VECTYPE (stmt_info));
vec_stmt = fold_convert (vect_ptr_type, addr_base);
addr_expr = vect_get_new_vect_var (vect_ptr_type, vect_pointer_var,
get_name (base_name));
-
add_referenced_var (addr_expr);
vec_stmt = force_gimple_operand (vec_stmt, &seq, false, addr_expr);
gimple_seq_add_seq (new_stmt_list, seq);
@@ -2186,16 +2298,16 @@ vect_create_data_ref_ptr (gimple stmt, struct loop *at_loop,
tree base_name;
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
- struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
- bool nested_in_vect_loop = nested_in_vect_loop_p (loop, stmt);
- struct loop *containing_loop = (gimple_bb (stmt))->loop_father;
+ struct loop *loop = NULL;
+ bool nested_in_vect_loop = false;
+ struct loop *containing_loop = NULL;
tree vectype = STMT_VINFO_VECTYPE (stmt_info);
tree vect_ptr_type;
tree vect_ptr;
tree new_temp;
gimple vec_stmt;
gimple_seq new_stmt_list = NULL;
- edge pe;
+ edge pe = NULL;
basic_block new_bb;
tree vect_ptr_init;
struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info);
@@ -2205,7 +2317,23 @@ vect_create_data_ref_ptr (gimple stmt, struct loop *at_loop,
tree indx_before_incr, indx_after_incr;
gimple incr;
tree step;
-
+ bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info);
+ gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
+
+ if (loop_vinfo)
+ {
+ loop = LOOP_VINFO_LOOP (loop_vinfo);
+ nested_in_vect_loop = nested_in_vect_loop_p (loop, stmt);
+ containing_loop = (gimple_bb (stmt))->loop_father;
+ pe = loop_preheader_edge (loop);
+ }
+ else
+ {
+ gcc_assert (bb_vinfo);
+ only_init = true;
+ *ptr_incr = NULL;
+ }
+
/* Check the step (evolution) of the load in LOOP, and record
whether it's invariant. */
if (nested_in_vect_loop)
@@ -2227,10 +2355,9 @@ vect_create_data_ref_ptr (gimple stmt, struct loop *at_loop,
tree data_ref_base = base_name;
fprintf (vect_dump, "create vector-pointer variable to type: ");
print_generic_expr (vect_dump, vectype, TDF_SLIM);
- if (TREE_CODE (data_ref_base) == VAR_DECL)
- fprintf (vect_dump, " vectorizing a one dimensional array ref: ");
- else if (TREE_CODE (data_ref_base) == ARRAY_REF)
- fprintf (vect_dump, " vectorizing a multidimensional array ref: ");
+ if (TREE_CODE (data_ref_base) == VAR_DECL
+ || TREE_CODE (data_ref_base) == ARRAY_REF)
+ fprintf (vect_dump, " vectorizing an array ref: ");
else if (TREE_CODE (data_ref_base) == COMPONENT_REF)
fprintf (vect_dump, " vectorizing a record based array ref: ");
else if (TREE_CODE (data_ref_base) == SSA_NAME)
@@ -2305,11 +2432,15 @@ vect_create_data_ref_ptr (gimple stmt, struct loop *at_loop,
new_temp = vect_create_addr_base_for_vector_ref (stmt, &new_stmt_list,
offset, loop);
- pe = loop_preheader_edge (loop);
if (new_stmt_list)
{
- new_bb = gsi_insert_seq_on_edge_immediate (pe, new_stmt_list);
- gcc_assert (!new_bb);
+ if (pe)
+ {
+ new_bb = gsi_insert_seq_on_edge_immediate (pe, new_stmt_list);
+ gcc_assert (!new_bb);
+ }
+ else
+ gsi_insert_seq_before (&gsi, new_stmt_list, GSI_SAME_STMT);
}
*initial_address = new_temp;
@@ -2319,16 +2450,21 @@ vect_create_data_ref_ptr (gimple stmt, struct loop *at_loop,
fold_convert (vect_ptr_type, new_temp));
vect_ptr_init = make_ssa_name (vect_ptr, vec_stmt);
gimple_assign_set_lhs (vec_stmt, vect_ptr_init);
- new_bb = gsi_insert_on_edge_immediate (pe, vec_stmt);
- gcc_assert (!new_bb);
-
+ if (pe)
+ {
+ new_bb = gsi_insert_on_edge_immediate (pe, vec_stmt);
+ gcc_assert (!new_bb);
+ }
+ else
+ gsi_insert_before (&gsi, vec_stmt, GSI_SAME_STMT);
/** (4) Handle the updating of the vector-pointer inside the loop.
This is needed when ONLY_INIT is false, and also when AT_LOOP
is the inner-loop nested in LOOP (during outer-loop vectorization).
**/
- if (only_init && at_loop == loop) /* No update in loop is required. */
+ /* No update in loop is required. */
+ if (only_init && (!loop_vinfo || at_loop == loop))
{
/* Copy the points-to information if it exists. */
if (DR_PTR_INFO (dr))
@@ -2351,7 +2487,7 @@ vect_create_data_ref_ptr (gimple stmt, struct loop *at_loop,
vect_ptr, loop, &incr_gsi, insert_after,
&indx_before_incr, &indx_after_incr);
incr = gsi_stmt (incr_gsi);
- set_vinfo_for_stmt (incr, new_stmt_vec_info (incr, loop_vinfo));
+ set_vinfo_for_stmt (incr, new_stmt_vec_info (incr, loop_vinfo, NULL));
/* Copy the points-to information if it exists. */
if (DR_PTR_INFO (dr))
@@ -2359,8 +2495,6 @@ vect_create_data_ref_ptr (gimple stmt, struct loop *at_loop,
duplicate_ssa_name_ptr_info (indx_before_incr, DR_PTR_INFO (dr));
duplicate_ssa_name_ptr_info (indx_after_incr, DR_PTR_INFO (dr));
}
- merge_alias_info (vect_ptr_init, indx_before_incr);
- merge_alias_info (vect_ptr_init, indx_after_incr);
if (ptr_incr)
*ptr_incr = incr;
@@ -2383,7 +2517,7 @@ vect_create_data_ref_ptr (gimple stmt, struct loop *at_loop,
containing_loop, &incr_gsi, insert_after, &indx_before_incr,
&indx_after_incr);
incr = gsi_stmt (incr_gsi);
- set_vinfo_for_stmt (incr, new_stmt_vec_info (incr, loop_vinfo));
+ set_vinfo_for_stmt (incr, new_stmt_vec_info (incr, loop_vinfo, NULL));
/* Copy the points-to information if it exists. */
if (DR_PTR_INFO (dr))
@@ -2391,8 +2525,6 @@ vect_create_data_ref_ptr (gimple stmt, struct loop *at_loop,
duplicate_ssa_name_ptr_info (indx_before_incr, DR_PTR_INFO (dr));
duplicate_ssa_name_ptr_info (indx_after_incr, DR_PTR_INFO (dr));
}
- merge_alias_info (vect_ptr_init, indx_before_incr);
- merge_alias_info (vect_ptr_init, indx_after_incr);
if (ptr_incr)
*ptr_incr = incr;
@@ -2463,7 +2595,6 @@ bump_vector_ptr (tree dataref_ptr, gimple ptr_incr, gimple_stmt_iterator *gsi,
/* Copy the points-to information if it exists. */
if (DR_PTR_INFO (dr))
duplicate_ssa_name_ptr_info (new_dataref_ptr, DR_PTR_INFO (dr));
- merge_alias_info (new_dataref_ptr, dataref_ptr);
if (!ptr_incr)
return new_dataref_ptr;
@@ -3237,13 +3368,21 @@ vect_supportable_dr_alignment (struct data_reference *dr)
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
tree vectype = STMT_VINFO_VECTYPE (stmt_info);
enum machine_mode mode = TYPE_MODE (vectype);
- struct loop *vect_loop = LOOP_VINFO_LOOP (STMT_VINFO_LOOP_VINFO (stmt_info));
- bool nested_in_vect_loop = nested_in_vect_loop_p (vect_loop, stmt);
bool invariant_in_outerloop = false;
+ loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
+ struct loop *vect_loop = NULL;
+ bool nested_in_vect_loop = false;
if (aligned_access_p (dr))
return dr_aligned;
+ if (!loop_vinfo)
+ /* FORNOW: Misaligned accesses are supported only in loops. */
+ return dr_unaligned_unsupported;
+
+ vect_loop = LOOP_VINFO_LOOP (loop_vinfo);
+ nested_in_vect_loop = nested_in_vect_loop_p (vect_loop, stmt);
+
if (nested_in_vect_loop)
{
tree outerloop_step = STMT_VINFO_DR_STEP (stmt_info);
@@ -3335,6 +3474,11 @@ vect_supportable_dr_alignment (struct data_reference *dr)
/* Can't software pipeline the loads, but can at least do them. */
return dr_unaligned_supported;
}
+ else
+ {
+ if (movmisalign_optab->handlers[mode].insn_code != CODE_FOR_nothing)
+ return dr_unaligned_supported;
+ }
/* Unsupported. */
return dr_unaligned_unsupported;
diff --git a/gcc/tree-vect-loop-manip.c b/gcc/tree-vect-loop-manip.c
index 3d7f5938afa..eaf263c4270 100644
--- a/gcc/tree-vect-loop-manip.c
+++ b/gcc/tree-vect-loop-manip.c
@@ -371,7 +371,6 @@ slpeel_update_phi_nodes_for_guard1 (edge guard_edge, struct loop *loop,
basic_block orig_bb = loop->header;
edge new_exit_e;
tree current_new_name;
- tree name;
gimple_stmt_iterator gsi_orig, gsi_update;
/* Create new bb between loop and new_merge_bb. */
@@ -387,15 +386,6 @@ slpeel_update_phi_nodes_for_guard1 (edge guard_edge, struct loop *loop,
orig_phi = gsi_stmt (gsi_orig);
update_phi = gsi_stmt (gsi_update);
- /* Virtual phi; Mark it for renaming. We actually want to call
- mar_sym_for_renaming, but since all ssa renaming datastructures
- are going to be freed before we get to call ssa_update, we just
- record this name for now in a bitmap, and will mark it for
- renaming later. */
- name = PHI_RESULT (orig_phi);
- if (!is_gimple_reg (SSA_NAME_VAR (name)))
- bitmap_set_bit (vect_memsyms_to_rename, DECL_UID (SSA_NAME_VAR (name)));
-
/** 1. Handle new-merge-point phis **/
/* 1.1. Generate new phi node in NEW_MERGE_BB: */
@@ -1690,7 +1680,7 @@ conservative_cost_threshold (loop_vec_info loop_vinfo,
th = (unsigned) min_profitable_iters;
if (th && vect_print_dump_info (REPORT_COST))
- fprintf (vect_dump, "Vectorization may not be profitable.");
+ fprintf (vect_dump, "Profitability threshold is %u loop iterations.", th);
return th;
}
@@ -1740,8 +1730,8 @@ vect_do_peeling_for_loop_bound (loop_vec_info loop_vinfo, tree *ratio,
/* If cost model check not done during versioning and
peeling for alignment. */
- if (!VEC_length (gimple, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo))
- && !VEC_length (ddr_p, LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo))
+ if (!LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT (loop_vinfo)
+ && !LOOP_REQUIRES_VERSIONING_FOR_ALIAS (loop_vinfo)
&& !LOOP_PEELING_FOR_ALIGNMENT (loop_vinfo)
&& !cond_expr)
{
@@ -2290,10 +2280,10 @@ vect_create_cond_for_alias_checks (loop_vec_info loop_vinfo,
else
*cond_expr = part_cond_expr;
}
- if (vect_print_dump_info (REPORT_VECTORIZED_LOCATIONS))
- fprintf (vect_dump, "created %u versioning for alias checks.\n",
- VEC_length (ddr_p, may_alias_ddrs));
+ if (vect_print_dump_info (REPORT_VECTORIZED_LOCATIONS))
+ fprintf (vect_dump, "created %u versioning for alias checks.\n",
+ VEC_length (ddr_p, may_alias_ddrs));
}
@@ -2349,11 +2339,11 @@ vect_loop_versioning (loop_vec_info loop_vinfo, bool do_versioning,
*cond_expr = force_gimple_operand (*cond_expr, cond_expr_stmt_list,
false, NULL_TREE);
- if (VEC_length (gimple, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo)))
+ if (LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT (loop_vinfo))
vect_create_cond_for_align_checks (loop_vinfo, cond_expr,
cond_expr_stmt_list);
- if (VEC_length (ddr_p, LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo)))
+ if (LOOP_REQUIRES_VERSIONING_FOR_ALIAS (loop_vinfo))
vect_create_cond_for_alias_checks (loop_vinfo, cond_expr,
cond_expr_stmt_list);
diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
index c570a78e013..39ca007e27e 100644
--- a/gcc/tree-vect-loop.c
+++ b/gcc/tree-vect-loop.c
@@ -414,7 +414,9 @@ vect_analyze_scalar_cycles_1 (loop_vec_info loop_vinfo, struct loop *loop)
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "=== vect_analyze_scalar_cycles ===");
- /* First - identify all inductions. */
+ /* First - identify all inductions. Reduction detection assumes that all the
+ inductions have been identified, therefore, this order must not be
+ changed. */
for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
gimple phi = gsi_stmt (gsi);
@@ -456,13 +458,14 @@ vect_analyze_scalar_cycles_1 (loop_vec_info loop_vinfo, struct loop *loop)
}
- /* Second - identify all reductions. */
+ /* Second - identify all reductions and nested cycles. */
while (VEC_length (gimple, worklist) > 0)
{
gimple phi = VEC_pop (gimple, worklist);
tree def = PHI_RESULT (phi);
stmt_vec_info stmt_vinfo = vinfo_for_stmt (phi);
gimple reduc_stmt;
+ bool nested_cycle;
if (vect_print_dump_info (REPORT_DETAILS))
{
@@ -473,14 +476,28 @@ vect_analyze_scalar_cycles_1 (loop_vec_info loop_vinfo, struct loop *loop)
gcc_assert (is_gimple_reg (SSA_NAME_VAR (def)));
gcc_assert (STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_unknown_def_type);
- reduc_stmt = vect_is_simple_reduction (loop_vinfo, phi);
+ nested_cycle = (loop != LOOP_VINFO_LOOP (loop_vinfo));
+ reduc_stmt = vect_is_simple_reduction (loop_vinfo, phi, !nested_cycle);
if (reduc_stmt)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "Detected reduction.");
- STMT_VINFO_DEF_TYPE (stmt_vinfo) = vect_reduction_def;
- STMT_VINFO_DEF_TYPE (vinfo_for_stmt (reduc_stmt)) =
+ if (nested_cycle)
+ {
+ if (vect_print_dump_info (REPORT_DETAILS))
+ fprintf (vect_dump, "Detected vectorizable nested cycle.");
+
+ STMT_VINFO_DEF_TYPE (stmt_vinfo) = vect_nested_cycle;
+ STMT_VINFO_DEF_TYPE (vinfo_for_stmt (reduc_stmt)) =
+ vect_nested_cycle;
+ }
+ else
+ {
+ if (vect_print_dump_info (REPORT_DETAILS))
+ fprintf (vect_dump, "Detected reduction.");
+
+ STMT_VINFO_DEF_TYPE (stmt_vinfo) = vect_reduction_def;
+ STMT_VINFO_DEF_TYPE (vinfo_for_stmt (reduc_stmt)) =
vect_reduction_def;
+ }
}
else
if (vect_print_dump_info (REPORT_DETAILS))
@@ -488,7 +505,6 @@ vect_analyze_scalar_cycles_1 (loop_vec_info loop_vinfo, struct loop *loop)
}
VEC_free (gimple, heap, worklist);
- return;
}
@@ -640,14 +656,14 @@ new_loop_vec_info (struct loop *loop)
{
gimple phi = gsi_stmt (si);
gimple_set_uid (phi, 0);
- set_vinfo_for_stmt (phi, new_stmt_vec_info (phi, res));
+ set_vinfo_for_stmt (phi, new_stmt_vec_info (phi, res, NULL));
}
for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
{
gimple stmt = gsi_stmt (si);
gimple_set_uid (stmt, 0);
- set_vinfo_for_stmt (stmt, new_stmt_vec_info (stmt, res));
+ set_vinfo_for_stmt (stmt, new_stmt_vec_info (stmt, res, NULL));
}
}
}
@@ -846,7 +862,7 @@ vect_analyze_loop_form (struct loop *loop)
if (loop->num_nodes != 2)
{
if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
- fprintf (vect_dump, "not vectorized: too many BBs in loop.");
+ fprintf (vect_dump, "not vectorized: control flow in loop.");
return NULL;
}
@@ -908,7 +924,7 @@ vect_analyze_loop_form (struct loop *loop)
if (loop->num_nodes != 5)
{
if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
- fprintf (vect_dump, "not vectorized: too many BBs in loop.");
+ fprintf (vect_dump, "not vectorized: control flow in loop.");
destroy_loop_vec_info (inner_loop_vinfo, true);
return NULL;
}
@@ -1153,7 +1169,7 @@ vect_analyze_loop_operations (loop_vec_info loop_vinfo)
gcc_assert (stmt_info);
- if (!vect_analyze_stmt (stmt, &need_to_vectorize))
+ if (!vect_analyze_stmt (stmt, &need_to_vectorize, NULL))
return false;
if (STMT_VINFO_RELEVANT_P (stmt_info) && !PURE_SLP_STMT (stmt_info))
@@ -1316,7 +1332,7 @@ vect_analyze_loop (struct loop *loop)
FORNOW: Handle only simple, array references, which
alignment can be forced, and aligned pointer-references. */
- ok = vect_analyze_data_refs (loop_vinfo);
+ ok = vect_analyze_data_refs (loop_vinfo, NULL);
if (!ok)
{
if (vect_print_dump_info (REPORT_DETAILS))
@@ -1346,7 +1362,7 @@ vect_analyze_loop (struct loop *loop)
/* Analyze the alignment of the data-refs in the loop.
Fail if a data reference is found that cannot be vectorized. */
- ok = vect_analyze_data_refs_alignment (loop_vinfo);
+ ok = vect_analyze_data_refs_alignment (loop_vinfo, NULL);
if (!ok)
{
if (vect_print_dump_info (REPORT_DETAILS))
@@ -1367,7 +1383,7 @@ vect_analyze_loop (struct loop *loop)
/* Analyze data dependences between the data-refs in the loop.
FORNOW: fail at the first data dependence that we encounter. */
- ok = vect_analyze_data_ref_dependences (loop_vinfo);
+ ok = vect_analyze_data_ref_dependences (loop_vinfo, NULL);
if (!ok)
{
if (vect_print_dump_info (REPORT_DETAILS))
@@ -1379,7 +1395,7 @@ vect_analyze_loop (struct loop *loop)
/* Analyze the access patterns of the data-refs in the loop (consecutive,
complex, etc.). FORNOW: Only handle consecutive access pattern. */
- ok = vect_analyze_data_ref_accesses (loop_vinfo);
+ ok = vect_analyze_data_ref_accesses (loop_vinfo, NULL);
if (!ok)
{
if (vect_print_dump_info (REPORT_DETAILS))
@@ -1402,7 +1418,7 @@ vect_analyze_loop (struct loop *loop)
}
/* Check the SLP opportunities in the loop, analyze and build SLP trees. */
- ok = vect_analyze_slp (loop_vinfo);
+ ok = vect_analyze_slp (loop_vinfo, NULL);
if (ok)
{
/* Decide which possible SLP instances to SLP. */
@@ -1501,15 +1517,19 @@ report_vect_op (gimple stmt, const char *msg)
such that:
1. operation is commutative and associative and it is safe to
- change the order of the computation.
+ change the order of the computation (if CHECK_REDUCTION is true)
2. no uses for a2 in the loop (a2 is used out of the loop)
3. no uses of a1 in the loop besides the reduction operation.
Condition 1 is tested here.
- Conditions 2,3 are tested in vect_mark_stmts_to_be_vectorized. */
+ Conditions 2,3 are tested in vect_mark_stmts_to_be_vectorized.
+
+ Also detect a cross-iteration def-use cycle in nested loops, i.e., nested
+ cycles, if CHECK_REDUCTION is false. */
gimple
-vect_is_simple_reduction (loop_vec_info loop_info, gimple phi)
+vect_is_simple_reduction (loop_vec_info loop_info, gimple phi,
+ bool check_reduction)
{
struct loop *loop = (gimple_bb (phi))->loop_father;
struct loop *vect_loop = LOOP_VINFO_LOOP (loop_info);
@@ -1524,7 +1544,10 @@ vect_is_simple_reduction (loop_vec_info loop_info, gimple phi)
imm_use_iterator imm_iter;
use_operand_p use_p;
- gcc_assert (loop == vect_loop || flow_loop_nested_p (vect_loop, loop));
+ /* If CHECK_REDUCTION is true, we assume inner-most loop vectorization,
+ otherwise, we assume outer loop vectorization. */
+ gcc_assert ((check_reduction && loop == vect_loop)
+ || (!check_reduction && flow_loop_nested_p (vect_loop, loop)));
name = PHI_RESULT (phi);
nloop_uses = 0;
@@ -1591,7 +1614,8 @@ vect_is_simple_reduction (loop_vec_info loop_info, gimple phi)
code = gimple_assign_rhs_code (def_stmt);
- if (!commutative_tree_code (code) || !associative_tree_code (code))
+ if (check_reduction
+ && (!commutative_tree_code (code) || !associative_tree_code (code)))
{
if (vect_print_dump_info (REPORT_DETAILS))
report_vect_op (def_stmt, "reduction: not commutative/associative: ");
@@ -1614,7 +1638,6 @@ vect_is_simple_reduction (loop_vec_info loop_info, gimple phi)
return NULL;
}
- /* Check that it's ok to change the order of the computation. */
type = TREE_TYPE (gimple_assign_lhs (def_stmt));
if (TYPE_MAIN_VARIANT (type) != TYPE_MAIN_VARIANT (TREE_TYPE (op1))
|| TYPE_MAIN_VARIANT (type) != TYPE_MAIN_VARIANT (TREE_TYPE (op2)))
@@ -1631,7 +1654,8 @@ vect_is_simple_reduction (loop_vec_info loop_info, gimple phi)
return NULL;
}
- /* Generally, when vectorizing a reduction we change the order of the
+ /* Check that it's ok to change the order of the computation.
+ Generally, when vectorizing a reduction we change the order of the
computation. This may change the behavior of the program in some
cases, so we need to check that this is ok. One exception is when
vectorizing an outer-loop: the inner-loop is executed sequentially,
@@ -1640,7 +1664,7 @@ vect_is_simple_reduction (loop_vec_info loop_info, gimple phi)
/* CHECKME: check for !flag_finite_math_only too? */
if (SCALAR_FLOAT_TYPE_P (type) && !flag_associative_math
- && !nested_in_vect_loop_p (vect_loop, def_stmt))
+ && check_reduction)
{
/* Changing the order of operations changes the semantics. */
if (vect_print_dump_info (REPORT_DETAILS))
@@ -1648,14 +1672,14 @@ vect_is_simple_reduction (loop_vec_info loop_info, gimple phi)
return NULL;
}
else if (INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_TRAPS (type)
- && !nested_in_vect_loop_p (vect_loop, def_stmt))
+ && check_reduction)
{
/* Changing the order of operations changes the semantics. */
if (vect_print_dump_info (REPORT_DETAILS))
report_vect_op (def_stmt, "reduction: unsafe int math optimization: ");
return NULL;
}
- else if (SAT_FIXED_POINT_TYPE_P (type))
+ else if (SAT_FIXED_POINT_TYPE_P (type) && check_reduction)
{
/* Changing the order of operations changes the semantics. */
if (vect_print_dump_info (REPORT_DETAILS))
@@ -1664,10 +1688,10 @@ vect_is_simple_reduction (loop_vec_info loop_info, gimple phi)
return NULL;
}
- /* reduction is safe. we're dealing with one of the following:
+ /* Reduction is safe. We're dealing with one of the following:
1) integer arithmetic and no trapv
- 2) floating point arithmetic, and special flags permit this optimization.
- */
+ 2) floating point arithmetic, and special flags permit this optimization
+ 3) nested cycle (i.e., outer loop vectorization). */
def1 = SSA_NAME_DEF_STMT (op1);
def2 = SSA_NAME_DEF_STMT (op2);
if (!def1 || !def2 || gimple_nop_p (def1) || gimple_nop_p (def2))
@@ -1687,35 +1711,49 @@ vect_is_simple_reduction (loop_vec_info loop_info, gimple phi)
&& (is_gimple_assign (def1)
|| STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def1)) == vect_induction_def
|| (gimple_code (def1) == GIMPLE_PHI
- && STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def1)) == vect_internal_def
+ && STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def1))
+ == vect_internal_def
&& !is_loop_header_bb_p (gimple_bb (def1)))))
{
if (vect_print_dump_info (REPORT_DETAILS))
- report_vect_op (def_stmt, "detected reduction:");
+ report_vect_op (def_stmt, "detected reduction: ");
return def_stmt;
}
else if (def1 == phi
&& flow_bb_inside_loop_p (loop, gimple_bb (def2))
&& (is_gimple_assign (def2)
- || STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def2)) == vect_induction_def
+ || STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def2))
+ == vect_induction_def
|| (gimple_code (def2) == GIMPLE_PHI
- && STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def2)) == vect_internal_def
+ && STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def2))
+ == vect_internal_def
&& !is_loop_header_bb_p (gimple_bb (def2)))))
{
- /* Swap operands (just for simplicity - so that the rest of the code
- can assume that the reduction variable is always the last (second)
- argument). */
- if (vect_print_dump_info (REPORT_DETAILS))
- report_vect_op (def_stmt ,
- "detected reduction: need to swap operands:");
- swap_tree_operands (def_stmt, gimple_assign_rhs1_ptr (def_stmt),
- gimple_assign_rhs2_ptr (def_stmt));
+ if (check_reduction)
+ {
+ /* Swap operands (just for simplicity - so that the rest of the code
+ can assume that the reduction variable is always the last (second)
+ argument). */
+ if (vect_print_dump_info (REPORT_DETAILS))
+ report_vect_op (def_stmt,
+ "detected reduction: need to swap operands: ");
+
+ swap_tree_operands (def_stmt, gimple_assign_rhs1_ptr (def_stmt),
+ gimple_assign_rhs2_ptr (def_stmt));
+ }
+ else
+ {
+ if (vect_print_dump_info (REPORT_DETAILS))
+ report_vect_op (def_stmt, "detected reduction: ");
+ }
+
return def_stmt;
}
else
{
if (vect_print_dump_info (REPORT_DETAILS))
- report_vect_op (def_stmt, "reduction: unknown pattern.");
+ report_vect_op (def_stmt, "reduction: unknown pattern: ");
+
return NULL;
}
}
@@ -1760,7 +1798,7 @@ vect_estimate_min_profitable_iters (loop_vec_info loop_vinfo)
}
/* Requires loop versioning tests to handle misalignment. */
- if (VEC_length (gimple, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo)))
+ if (LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT (loop_vinfo))
{
/* FIXME: Make cost depend on complexity of individual check. */
vec_outside_cost +=
@@ -1770,7 +1808,8 @@ vect_estimate_min_profitable_iters (loop_vec_info loop_vinfo)
"versioning to treat misalignment.\n");
}
- if (VEC_length (ddr_p, LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo)))
+ /* Requires loop versioning with alias checks. */
+ if (LOOP_REQUIRES_VERSIONING_FOR_ALIAS (loop_vinfo))
{
/* FIXME: Make cost depend on complexity of individual check. */
vec_outside_cost +=
@@ -1780,11 +1819,9 @@ vect_estimate_min_profitable_iters (loop_vec_info loop_vinfo)
"versioning aliasing.\n");
}
- if (VEC_length (gimple, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo))
- || VEC_length (ddr_p, LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo)))
- {
- vec_outside_cost += TARG_COND_TAKEN_BRANCH_COST;
- }
+ if (LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT (loop_vinfo)
+ || LOOP_REQUIRES_VERSIONING_FOR_ALIAS (loop_vinfo))
+ vec_outside_cost += TARG_COND_TAKEN_BRANCH_COST;
/* Count statements in scalar loop. Using this as scalar cost for a single
iteration for now.
@@ -1950,12 +1987,12 @@ vect_estimate_min_profitable_iters (loop_vec_info loop_vinfo)
decide whether to vectorize at compile time. Hence the scalar version
do not carry cost model guard costs. */
if (!LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
- || VEC_length (gimple, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo))
- || VEC_length (ddr_p, LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo)))
+ || LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT (loop_vinfo)
+ || LOOP_REQUIRES_VERSIONING_FOR_ALIAS (loop_vinfo))
{
/* Cost model check occurs at versioning. */
- if (VEC_length (gimple, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo))
- || VEC_length (ddr_p, LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo)))
+ if (LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT (loop_vinfo)
+ || LOOP_REQUIRES_VERSIONING_FOR_ALIAS (loop_vinfo))
scalar_outside_cost += TARG_COND_NOT_TAKEN_BRANCH_COST;
else
{
@@ -2358,7 +2395,7 @@ get_initial_def_for_induction (gimple iv_phi)
add_referenced_var (vec_dest);
induction_phi = create_phi_node (vec_dest, iv_loop->header);
set_vinfo_for_stmt (induction_phi,
- new_stmt_vec_info (induction_phi, loop_vinfo));
+ new_stmt_vec_info (induction_phi, loop_vinfo, NULL));
induc_def = PHI_RESULT (induction_phi);
/* Create the iv update inside the loop */
@@ -2367,7 +2404,8 @@ get_initial_def_for_induction (gimple iv_phi)
vec_def = make_ssa_name (vec_dest, new_stmt);
gimple_assign_set_lhs (new_stmt, vec_def);
gsi_insert_before (&si, new_stmt, GSI_SAME_STMT);
- set_vinfo_for_stmt (new_stmt, new_stmt_vec_info (new_stmt, loop_vinfo));
+ set_vinfo_for_stmt (new_stmt, new_stmt_vec_info (new_stmt, loop_vinfo,
+ NULL));
/* Set the arguments of the phi node: */
add_phi_arg (induction_phi, vec_init, pe);
@@ -2409,7 +2447,7 @@ get_initial_def_for_induction (gimple iv_phi)
gsi_insert_before (&si, new_stmt, GSI_SAME_STMT);
set_vinfo_for_stmt (new_stmt,
- new_stmt_vec_info (new_stmt, loop_vinfo));
+ new_stmt_vec_info (new_stmt, loop_vinfo, NULL));
STMT_VINFO_RELATED_STMT (prev_stmt_vinfo) = new_stmt;
prev_stmt_vinfo = vinfo_for_stmt (new_stmt);
}
@@ -2533,6 +2571,7 @@ get_initial_def_for_reduction (gimple stmt, tree init_val, tree *adjustment_def)
case WIDEN_SUM_EXPR:
case DOT_PROD_EXPR:
case PLUS_EXPR:
+ case MINUS_EXPR:
if (nested_in_vect_loop)
*adjustment_def = vect_get_vec_def_for_operand (init_val, stmt, NULL);
else
@@ -2576,6 +2615,8 @@ get_initial_def_for_reduction (gimple stmt, tree init_val, tree *adjustment_def)
in vectorizable_operation.
STMT is the scalar reduction stmt that is being vectorized.
REDUCTION_PHI is the phi-node that carries the reduction computation.
+ REDUC_INDEX is the index of the operand in the right hand side of the
+ statement that is defined by REDUCTION_PHI.
This function:
1. Creates the reduction def-use cycle: sets the arguments for
@@ -2619,7 +2660,8 @@ static void
vect_create_epilog_for_reduction (tree vect_def, gimple stmt,
int ncopies,
enum tree_code reduc_code,
- gimple reduction_phi)
+ gimple reduction_phi,
+ int reduc_index)
{
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
stmt_vec_info prev_phi_info;
@@ -2663,14 +2705,16 @@ vect_create_epilog_for_reduction (tree vect_def, gimple stmt,
switch (get_gimple_rhs_class (gimple_assign_rhs_code (stmt)))
{
case GIMPLE_SINGLE_RHS:
- gcc_assert (TREE_OPERAND_LENGTH (gimple_assign_rhs1 (stmt)) == ternary_op);
- reduction_op = TREE_OPERAND (gimple_assign_rhs1 (stmt), 2);
+ gcc_assert (TREE_OPERAND_LENGTH (gimple_assign_rhs1 (stmt))
+ == ternary_op);
+ reduction_op = TREE_OPERAND (gimple_assign_rhs1 (stmt), reduc_index);
break;
case GIMPLE_UNARY_RHS:
reduction_op = gimple_assign_rhs1 (stmt);
break;
case GIMPLE_BINARY_RHS:
- reduction_op = gimple_assign_rhs2 (stmt);
+ reduction_op = reduc_index ?
+ gimple_assign_rhs2 (stmt) : gimple_assign_rhs1 (stmt);
break;
default:
gcc_unreachable ();
@@ -2747,7 +2791,7 @@ vect_create_epilog_for_reduction (tree vect_def, gimple stmt,
for (j = 0; j < ncopies; j++)
{
phi = create_phi_node (SSA_NAME_VAR (vect_def), exit_bb);
- set_vinfo_for_stmt (phi, new_stmt_vec_info (phi, loop_vinfo));
+ set_vinfo_for_stmt (phi, new_stmt_vec_info (phi, loop_vinfo, NULL));
if (j == 0)
new_phi = phi;
else
@@ -2758,6 +2802,7 @@ vect_create_epilog_for_reduction (tree vect_def, gimple stmt,
SET_PHI_ARG_DEF (phi, single_exit (loop)->dest_idx, def);
prev_phi_info = vinfo_for_stmt (phi);
}
+
exit_gsi = gsi_after_labels (exit_bb);
/* 2.2 Get the relevant tree-code to use in the epilog for schemes 2,3
@@ -2782,6 +2827,7 @@ vect_create_epilog_for_reduction (tree vect_def, gimple stmt,
gcc_assert (STMT_VINFO_IN_PATTERN_P (stmt_vinfo));
gcc_assert (STMT_VINFO_RELATED_STMT (stmt_vinfo) == stmt);
}
+
code = gimple_assign_rhs_code (orig_stmt);
scalar_dest = gimple_assign_lhs (orig_stmt);
scalar_type = TREE_TYPE (scalar_dest);
@@ -2974,6 +3020,11 @@ vect_finalize_reduction:
{
if (nested_in_vect_loop)
{
+ /* For MINUS_EXPR we create new_temp = loop_exit_def + adjustment_def
+ since the initial value is [0,0,...,0]. */
+ if (code == MINUS_EXPR)
+ code = PLUS_EXPR;
+
gcc_assert (TREE_CODE (TREE_TYPE (adjustment_def)) == VECTOR_TYPE);
expr = build2 (code, vectype, PHI_RESULT (new_phi), adjustment_def);
new_dest = vect_create_destination_var (scalar_dest, vectype);
@@ -2984,6 +3035,7 @@ vect_finalize_reduction:
expr = build2 (code, scalar_type, new_temp, adjustment_def);
new_dest = vect_create_destination_var (scalar_dest, scalar_type);
}
+
epilog_stmt = gimple_build_assign (new_dest, expr);
new_temp = make_ssa_name (new_dest, epilog_stmt);
gimple_assign_set_lhs (epilog_stmt, new_temp);
@@ -3025,7 +3077,8 @@ vect_finalize_reduction:
epilog_stmt = adjustment_def ? epilog_stmt : new_phi;
STMT_VINFO_VEC_STMT (stmt_vinfo) = epilog_stmt;
set_vinfo_for_stmt (epilog_stmt,
- new_stmt_vec_info (epilog_stmt, loop_vinfo));
+ new_stmt_vec_info (epilog_stmt, loop_vinfo,
+ NULL));
if (adjustment_def)
STMT_VINFO_RELATED_STMT (vinfo_for_stmt (epilog_stmt)) =
STMT_VINFO_RELATED_STMT (vinfo_for_stmt (new_phi));
@@ -3046,7 +3099,7 @@ vect_finalize_reduction:
Check if STMT performs a reduction operation that can be vectorized.
If VEC_STMT is also passed, vectorize the STMT: create a vectorized
- stmt to replace it, put it in VEC_STMT, and insert it at BSI.
+ stmt to replace it, put it in VEC_STMT, and insert it at GSI.
Return FALSE if not a vectorizable STMT, TRUE otherwise.
This function also handles reduction idioms (patterns) that have been
@@ -3118,9 +3171,16 @@ vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi,
gimple new_stmt = NULL;
int j;
tree ops[3];
+ bool nested_cycle = false, found_nested_cycle_def = false;
+ gimple reduc_def_stmt = NULL;
+ /* The default is that the reduction variable is the last in statement. */
+ int reduc_index = 2;
if (nested_in_vect_loop_p (loop, stmt))
- loop = loop->inner;
+ {
+ loop = loop->inner;
+ nested_cycle = true;
+ }
gcc_assert (ncopies >= 1);
@@ -3141,7 +3201,8 @@ vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi,
return false;
/* Make sure it was already recognized as a reduction computation. */
- if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_reduction_def)
+ if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_reduction_def
+ && STMT_VINFO_DEF_TYPE (stmt_info) != vect_nested_cycle)
return false;
/* 2. Has this been recognized as a reduction pattern?
@@ -3205,30 +3266,50 @@ vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi,
return false;
/* All uses but the last are expected to be defined in the loop.
- The last use is the reduction variable. */
+ The last use is the reduction variable. In case of nested cycle this
+ assumption is not true: we use reduc_index to record the index of the
+ reduction variable. */
for (i = 0; i < op_type-1; i++)
{
- is_simple_use = vect_is_simple_use (ops[i], loop_vinfo, &def_stmt,
+ is_simple_use = vect_is_simple_use (ops[i], loop_vinfo, NULL, &def_stmt,
&def, &dt);
gcc_assert (is_simple_use);
if (dt != vect_internal_def
&& dt != vect_external_def
&& dt != vect_constant_def
- && dt != vect_induction_def)
+ && dt != vect_induction_def
+ && dt != vect_nested_cycle)
return false;
+
+ if (dt == vect_nested_cycle)
+ {
+ found_nested_cycle_def = true;
+ reduc_def_stmt = def_stmt;
+ reduc_index = i;
+ }
}
- is_simple_use = vect_is_simple_use (ops[i], loop_vinfo, &def_stmt, &def,
- &dt);
+ is_simple_use = vect_is_simple_use (ops[i], loop_vinfo, NULL, &def_stmt,
+ &def, &dt);
gcc_assert (is_simple_use);
- gcc_assert (dt == vect_reduction_def);
- gcc_assert (gimple_code (def_stmt) == GIMPLE_PHI);
+ gcc_assert (dt == vect_reduction_def
+ || dt == vect_nested_cycle
+ || ((dt == vect_internal_def || dt == vect_external_def
+ || dt == vect_constant_def || dt == vect_induction_def)
+ && nested_cycle && found_nested_cycle_def));
+ if (!found_nested_cycle_def)
+ reduc_def_stmt = def_stmt;
+
+ gcc_assert (gimple_code (reduc_def_stmt) == GIMPLE_PHI);
if (orig_stmt)
- gcc_assert (orig_stmt == vect_is_simple_reduction (loop_vinfo, def_stmt));
+ gcc_assert (orig_stmt == vect_is_simple_reduction (loop_vinfo,
+ reduc_def_stmt,
+ !nested_cycle));
else
- gcc_assert (stmt == vect_is_simple_reduction (loop_vinfo, def_stmt));
+ gcc_assert (stmt == vect_is_simple_reduction (loop_vinfo, reduc_def_stmt,
+ !nested_cycle));
- if (STMT_VINFO_LIVE_P (vinfo_for_stmt (def_stmt)))
+ if (STMT_VINFO_LIVE_P (vinfo_for_stmt (reduc_def_stmt)))
return false;
/* 4. Supportable by target? */
@@ -3323,8 +3404,12 @@ vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi,
orig_code = code;
}
- if (!reduction_code_for_scalar_code (orig_code, &epilog_reduc_code))
- return false;
+ if (nested_cycle)
+ epilog_reduc_code = orig_code;
+ else
+ if (!reduction_code_for_scalar_code (orig_code, &epilog_reduc_code))
+ return false;
+
reduc_optab = optab_for_tree_code (epilog_reduc_code, vectype, optab_default);
if (!reduc_optab)
{
@@ -3398,19 +3483,27 @@ vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi,
{
/* Create the reduction-phi that defines the reduction-operand. */
new_phi = create_phi_node (vec_dest, loop->header);
- set_vinfo_for_stmt (new_phi, new_stmt_vec_info (new_phi, loop_vinfo));
+ set_vinfo_for_stmt (new_phi, new_stmt_vec_info (new_phi, loop_vinfo,
+ NULL));
}
/* Handle uses. */
if (j == 0)
{
- loop_vec_def0 = vect_get_vec_def_for_operand (ops[0], stmt, NULL);
+ loop_vec_def0 = vect_get_vec_def_for_operand (ops[!reduc_index],
+ stmt, NULL);
if (op_type == ternary_op)
{
- loop_vec_def1 = vect_get_vec_def_for_operand (ops[1], stmt, NULL);
+ if (reduc_index == 0)
+ loop_vec_def1 = vect_get_vec_def_for_operand (ops[2], stmt,
+ NULL);
+ else
+ loop_vec_def1 = vect_get_vec_def_for_operand (ops[1], stmt,
+ NULL);
}
- /* Get the vector def for the reduction variable from the phi node */
+ /* Get the vector def for the reduction variable from the phi
+ node. */
reduc_def = PHI_RESULT (new_phi);
first_phi = new_phi;
}
@@ -3429,12 +3522,31 @@ vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi,
STMT_VINFO_RELATED_STMT (prev_phi_info) = new_phi;
}
+
/* Arguments are ready. create the new vector stmt. */
if (op_type == binary_op)
- expr = build2 (code, vectype, loop_vec_def0, reduc_def);
+ {
+ if (reduc_index == 0)
+ expr = build2 (code, vectype, reduc_def, loop_vec_def0);
+ else
+ expr = build2 (code, vectype, loop_vec_def0, reduc_def);
+ }
else
- expr = build3 (code, vectype, loop_vec_def0, loop_vec_def1,
- reduc_def);
+ {
+ if (reduc_index == 0)
+ expr = build3 (code, vectype, reduc_def, loop_vec_def0,
+ loop_vec_def1);
+ else
+ {
+ if (reduc_index == 1)
+ expr = build3 (code, vectype, loop_vec_def0, reduc_def,
+ loop_vec_def1);
+ else
+ expr = build3 (code, vectype, loop_vec_def0, loop_vec_def1,
+ reduc_def);
+ }
+ }
+
new_stmt = gimple_build_assign (vec_dest, expr);
new_temp = make_ssa_name (vec_dest, new_stmt);
gimple_assign_set_lhs (new_stmt, new_temp);
@@ -3453,7 +3565,7 @@ vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi,
if (!single_defuse_cycle)
new_temp = gimple_assign_lhs (*vec_stmt);
vect_create_epilog_for_reduction (new_temp, stmt, epilog_copies,
- epilog_reduc_code, first_phi);
+ epilog_reduc_code, first_phi, reduc_index);
return true;
}
@@ -3596,7 +3708,8 @@ vectorizable_live_operation (gimple stmt,
op = TREE_OPERAND (gimple_op (stmt, 1), i);
else
op = gimple_op (stmt, i + 1);
- if (op && !vect_is_simple_use (op, loop_vinfo, &def_stmt, &def, &dt))
+ if (op
+ && !vect_is_simple_use (op, loop_vinfo, NULL, &def_stmt, &def, &dt))
{
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "use not simple.");
@@ -3648,16 +3761,12 @@ vect_transform_loop (loop_vec_info loop_vinfo)
|| (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
&& LOOP_VINFO_INT_NITERS (loop_vinfo) % vectorization_factor != 0));
- if (VEC_length (gimple, LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo))
- || VEC_length (ddr_p, LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo)))
+ if (LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT (loop_vinfo)
+ || LOOP_REQUIRES_VERSIONING_FOR_ALIAS (loop_vinfo))
vect_loop_versioning (loop_vinfo,
!do_peeling_for_loop_bound,
&cond_expr, &cond_expr_stmt_list);
- /* CHECKME: we wouldn't need this if we called update_ssa once
- for all loops. */
- bitmap_zero (vect_memsyms_to_rename);
-
/* If the loop has a symbolic number of iterations 'n' (i.e. it's not a
compile time constant), or it is a constant that doesn't divide by the
vectorization factor, then an epilog loop needs to be created.
@@ -3770,7 +3879,7 @@ vect_transform_loop (loop_vec_info loop_vinfo)
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "=== scheduling SLP instances ===");
- vect_schedule_slp (loop_vinfo);
+ vect_schedule_slp (loop_vinfo, NULL);
}
/* Hybrid SLP stmts must be vectorized in addition to SLP. */
@@ -3812,8 +3921,6 @@ vect_transform_loop (loop_vec_info loop_vinfo)
slpeel_make_loop_iterate_ntimes (loop, ratio);
- mark_set_for_renaming (vect_memsyms_to_rename);
-
/* The memory tags and pointers in vectorized statements need to
have their SSA forms updated. FIXME, why can't this be delayed
until all the loops have been transformed? */
diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c
index febbd643680..1971e6ad4d3 100644
--- a/gcc/tree-vect-patterns.c
+++ b/gcc/tree-vect-patterns.c
@@ -78,7 +78,7 @@ widened_name_p (tree name, gimple use_stmt, tree *half_type, gimple *def_stmt)
stmt_vinfo = vinfo_for_stmt (use_stmt);
loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
- if (!vect_is_simple_use (name, loop_vinfo, def_stmt, &def, &dt))
+ if (!vect_is_simple_use (name, loop_vinfo, NULL, def_stmt, &def, &dt))
return false;
if (dt != vect_internal_def
@@ -102,7 +102,8 @@ widened_name_p (tree name, gimple use_stmt, tree *half_type, gimple *def_stmt)
|| (TYPE_PRECISION (type) < (TYPE_PRECISION (*half_type) * 2)))
return false;
- if (!vect_is_simple_use (oprnd0, loop_vinfo, &dummy_gimple, &dummy, &dt))
+ if (!vect_is_simple_use (oprnd0, loop_vinfo, NULL, &dummy_gimple, &dummy,
+ &dt))
return false;
return true;
@@ -318,12 +319,7 @@ vect_recog_dot_prod_pattern (gimple last_stmt, tree *type_in, tree *type_out)
/* We don't allow changing the order of the computation in the inner-loop
when doing outer-loop vectorization. */
- if (nested_in_vect_loop_p (loop, last_stmt))
- {
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "vect_recog_dot_prod_pattern: not allowed.");
- return NULL;
- }
+ gcc_assert (!nested_in_vect_loop_p (loop, last_stmt));
return pattern_stmt;
}
@@ -637,12 +633,7 @@ vect_recog_widen_sum_pattern (gimple last_stmt, tree *type_in, tree *type_out)
/* We don't allow changing the order of the computation in the inner-loop
when doing outer-loop vectorization. */
- if (nested_in_vect_loop_p (loop, last_stmt))
- {
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "vect_recog_widen_sum_pattern: not allowed.");
- return NULL;
- }
+ gcc_assert (!nested_in_vect_loop_p (loop, last_stmt));
return pattern_stmt;
}
@@ -734,7 +725,7 @@ vect_pattern_recog_1 (
/* Mark the stmts that are involved in the pattern. */
gsi_insert_before (&si, pattern_stmt, GSI_SAME_STMT);
set_vinfo_for_stmt (pattern_stmt,
- new_stmt_vec_info (pattern_stmt, loop_vinfo));
+ new_stmt_vec_info (pattern_stmt, loop_vinfo, NULL));
pattern_stmt_info = vinfo_for_stmt (pattern_stmt);
STMT_VINFO_RELATED_STMT (pattern_stmt_info) = stmt;
diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
index eb1ca62a3a3..1017847a5f1 100644
--- a/gcc/tree-vect-slp.c
+++ b/gcc/tree-vect-slp.c
@@ -38,6 +38,29 @@ along with GCC; see the file COPYING3. If not see
#include "optabs.h"
#include "tree-vectorizer.h"
+/* Extract the location of the basic block in the source code.
+ Return the basic block location if succeed and NULL if not. */
+
+LOC
+find_bb_location (basic_block bb)
+{
+ gimple stmt = NULL;
+ gimple_stmt_iterator si;
+
+ if (!bb)
+ return UNKNOWN_LOC;
+
+ for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
+ {
+ stmt = gsi_stmt (si);
+ if (gimple_location (stmt) != UNKNOWN_LOC)
+ return gimple_location (stmt);
+ }
+
+ return UNKNOWN_LOC;
+}
+
+
/* Recursively free the memory allocated for the SLP tree rooted at NODE. */
static void
@@ -77,8 +100,9 @@ vect_free_slp_instance (slp_instance instance)
the SLP group (stored in FIRST_STMT_...). */
static bool
-vect_get_and_check_slp_defs (loop_vec_info loop_vinfo, slp_tree slp_node,
- gimple stmt, VEC (gimple, heap) **def_stmts0,
+vect_get_and_check_slp_defs (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
+ slp_tree slp_node, gimple stmt,
+ VEC (gimple, heap) **def_stmts0,
VEC (gimple, heap) **def_stmts1,
enum vect_def_type *first_stmt_dt0,
enum vect_def_type *first_stmt_dt1,
@@ -96,7 +120,10 @@ vect_get_and_check_slp_defs (loop_vec_info loop_vinfo, slp_tree slp_node,
stmt_vec_info stmt_info =
vinfo_for_stmt (VEC_index (gimple, SLP_TREE_SCALAR_STMTS (slp_node), 0));
enum gimple_rhs_class rhs_class;
- struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+ struct loop *loop = NULL;
+
+ if (loop_vinfo)
+ loop = LOOP_VINFO_LOOP (loop_vinfo);
rhs_class = get_gimple_rhs_class (gimple_assign_rhs_code (stmt));
number_of_oprnds = gimple_num_ops (stmt) - 1; /* RHS only */
@@ -105,7 +132,8 @@ vect_get_and_check_slp_defs (loop_vec_info loop_vinfo, slp_tree slp_node,
{
oprnd = gimple_op (stmt, i + 1);
- if (!vect_is_simple_use (oprnd, loop_vinfo, &def_stmt, &def, &dt[i])
+ if (!vect_is_simple_use (oprnd, loop_vinfo, bb_vinfo, &def_stmt, &def,
+ &dt[i])
|| (!def_stmt && dt[i] != vect_constant_def))
{
if (vect_print_dump_info (REPORT_SLP))
@@ -117,10 +145,10 @@ vect_get_and_check_slp_defs (loop_vec_info loop_vinfo, slp_tree slp_node,
return false;
}
- /* Check if DEF_STMT is a part of a pattern and get the def stmt from
- the pattern. Check that all the stmts of the node are in the
+ /* Check if DEF_STMT is a part of a pattern in LOOP and get the def stmt
+ from the pattern. Check that all the stmts of the node are in the
pattern. */
- if (def_stmt && gimple_bb (def_stmt)
+ if (loop && def_stmt && gimple_bb (def_stmt)
&& flow_bb_inside_loop_p (loop, gimple_bb (def_stmt))
&& vinfo_for_stmt (def_stmt)
&& STMT_VINFO_IN_PATTERN_P (vinfo_for_stmt (def_stmt)))
@@ -271,12 +299,13 @@ vect_get_and_check_slp_defs (loop_vec_info loop_vinfo, slp_tree slp_node,
TRUE. */
static bool
-vect_build_slp_tree (loop_vec_info loop_vinfo, slp_tree *node,
- unsigned int group_size,
- int *inside_cost, int *outside_cost,
- int ncopies_for_cost, unsigned int *max_nunits,
+vect_build_slp_tree (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
+ slp_tree *node, unsigned int group_size,
+ int *inside_cost, int *outside_cost,
+ int ncopies_for_cost, unsigned int *max_nunits,
VEC (int, heap) **load_permutation,
- VEC (slp_tree, heap) **loads)
+ VEC (slp_tree, heap) **loads,
+ unsigned int vectorization_factor)
{
VEC (gimple, heap) *def_stmts0 = VEC_alloc (gimple, heap, group_size);
VEC (gimple, heap) *def_stmts1 = VEC_alloc (gimple, heap, group_size);
@@ -290,7 +319,7 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, slp_tree *node,
tree lhs;
bool stop_recursion = false, need_same_oprnds = false;
tree vectype, scalar_type, first_op1 = NULL_TREE;
- unsigned int vectorization_factor = 0, ncopies;
+ unsigned int ncopies;
optab optab;
int icode;
enum machine_mode optab_op2_mode;
@@ -336,13 +365,18 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, slp_tree *node,
}
return false;
}
-
- gcc_assert (LOOP_VINFO_VECT_FACTOR (loop_vinfo));
- vectorization_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
+
ncopies = vectorization_factor / TYPE_VECTOR_SUBPARTS (vectype);
- if (ncopies > 1 && vect_print_dump_info (REPORT_SLP))
- fprintf (vect_dump, "SLP with multiple types ");
+ if (ncopies != 1)
+ {
+ if (vect_print_dump_info (REPORT_SLP))
+ fprintf (vect_dump, "SLP with multiple types ");
+ /* FORNOW: multiple types are unsupported in BB SLP. */
+ if (bb_vinfo)
+ return false;
+ }
+
/* In case of multiple types we need to detect the smallest type. */
if (*max_nunits < TYPE_VECTOR_SUBPARTS (vectype))
*max_nunits = TYPE_VECTOR_SUBPARTS (vectype);
@@ -438,8 +472,8 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, slp_tree *node,
if (REFERENCE_CLASS_P (lhs))
{
/* Store. */
- if (!vect_get_and_check_slp_defs (loop_vinfo, *node, stmt,
- &def_stmts0, &def_stmts1,
+ if (!vect_get_and_check_slp_defs (loop_vinfo, bb_vinfo, *node,
+ stmt, &def_stmts0, &def_stmts1,
&first_stmt_dt0,
&first_stmt_dt1,
&first_stmt_def0_type,
@@ -552,7 +586,7 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, slp_tree *node,
}
/* Find the def-stmts. */
- if (!vect_get_and_check_slp_defs (loop_vinfo, *node, stmt,
+ if (!vect_get_and_check_slp_defs (loop_vinfo, bb_vinfo, *node, stmt,
&def_stmts0, &def_stmts1,
&first_stmt_dt0, &first_stmt_dt1,
&first_stmt_def0_type,
@@ -590,9 +624,10 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, slp_tree *node,
SLP_TREE_RIGHT (left_node) = NULL;
SLP_TREE_OUTSIDE_OF_LOOP_COST (left_node) = 0;
SLP_TREE_INSIDE_OF_LOOP_COST (left_node) = 0;
- if (!vect_build_slp_tree (loop_vinfo, &left_node, group_size,
+ if (!vect_build_slp_tree (loop_vinfo, bb_vinfo, &left_node, group_size,
inside_cost, outside_cost, ncopies_for_cost,
- max_nunits, load_permutation, loads))
+ max_nunits, load_permutation, loads,
+ vectorization_factor))
return false;
SLP_TREE_LEFT (*node) = left_node;
@@ -607,9 +642,10 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, slp_tree *node,
SLP_TREE_RIGHT (right_node) = NULL;
SLP_TREE_OUTSIDE_OF_LOOP_COST (right_node) = 0;
SLP_TREE_INSIDE_OF_LOOP_COST (right_node) = 0;
- if (!vect_build_slp_tree (loop_vinfo, &right_node, group_size,
+ if (!vect_build_slp_tree (loop_vinfo, bb_vinfo, &right_node, group_size,
inside_cost, outside_cost, ncopies_for_cost,
- max_nunits, load_permutation, loads))
+ max_nunits, load_permutation, loads,
+ vectorization_factor))
return false;
SLP_TREE_RIGHT (*node) = right_node;
@@ -664,6 +700,31 @@ vect_mark_slp_stmts (slp_tree node, enum slp_vect_type mark, int j)
}
+/* Mark the statements of the tree rooted at NODE as relevant (vect_used). */
+
+static void
+vect_mark_slp_stmts_relevant (slp_tree node)
+{
+ int i;
+ gimple stmt;
+ stmt_vec_info stmt_info;
+
+ if (!node)
+ return;
+
+ for (i = 0; VEC_iterate (gimple, SLP_TREE_SCALAR_STMTS (node), i, stmt); i++)
+ {
+ stmt_info = vinfo_for_stmt (stmt);
+ gcc_assert (!STMT_VINFO_RELEVANT (stmt_info)
+ || STMT_VINFO_RELEVANT (stmt_info) == vect_used_in_scope);
+ STMT_VINFO_RELEVANT (stmt_info) = vect_used_in_scope;
+ }
+
+ vect_mark_slp_stmts_relevant (SLP_TREE_LEFT (node));
+ vect_mark_slp_stmts_relevant (SLP_TREE_RIGHT (node));
+}
+
+
/* Check if the permutation required by the SLP INSTANCE is supported.
Reorganize the SLP nodes stored in SLP_INSTANCE_LOADS if needed. */
@@ -736,7 +797,7 @@ vect_supported_load_permutation_p (slp_instance slp_instn, int group_size,
int i = 0, j, prev = -1, next, k;
bool supported;
- /* FORNOW: permutations are only supported for loop-aware SLP. */
+ /* FORNOW: permutations are only supported in SLP. */
if (!slp_instn)
return false;
@@ -809,7 +870,8 @@ vect_find_first_load_in_slp_instance (slp_instance instance)
Return FALSE if it's impossible to SLP any stmt in the loop. */
static bool
-vect_analyze_slp_instance (loop_vec_info loop_vinfo, gimple stmt)
+vect_analyze_slp_instance (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
+ gimple stmt)
{
slp_instance new_instance;
slp_tree node = XNEW (struct _slp_tree);
@@ -818,7 +880,6 @@ vect_analyze_slp_instance (loop_vec_info loop_vinfo, gimple stmt)
tree vectype, scalar_type;
gimple next;
unsigned int vectorization_factor = 0, ncopies;
- bool slp_impossible = false;
int inside_cost = 0, outside_cost = 0, ncopies_for_cost;
unsigned int max_nunits = 0;
VEC (int, heap) *load_permutation;
@@ -838,9 +899,25 @@ vect_analyze_slp_instance (loop_vec_info loop_vinfo, gimple stmt)
}
nunits = TYPE_VECTOR_SUBPARTS (vectype);
- vectorization_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
+ if (loop_vinfo)
+ vectorization_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
+ else
+ /* No multitypes in BB SLP. */
+ vectorization_factor = nunits;
+
ncopies = vectorization_factor / nunits;
+ /* Calculate the unrolling factor. */
+ unrolling_factor = least_common_multiple (nunits, group_size) / group_size;
+ if (unrolling_factor != 1 && !loop_vinfo)
+ {
+ if (vect_print_dump_info (REPORT_SLP))
+ fprintf (vect_dump, "Build SLP failed: unrolling required in basic"
+ " block SLP");
+
+ return false;
+ }
+
/* Create a node (a root of the SLP tree) for the packed strided stores. */
SLP_TREE_SCALAR_STMTS (node) = VEC_alloc (gimple, heap, group_size);
next = stmt;
@@ -858,9 +935,6 @@ vect_analyze_slp_instance (loop_vec_info loop_vinfo, gimple stmt)
SLP_TREE_OUTSIDE_OF_LOOP_COST (node) = 0;
SLP_TREE_INSIDE_OF_LOOP_COST (node) = 0;
- /* Calculate the unrolling factor. */
- unrolling_factor = least_common_multiple (nunits, group_size) / group_size;
-
/* Calculate the number of vector stmts to create based on the unrolling
factor (number of vectors is 1 if NUNITS >= GROUP_SIZE, and is
GROUP_SIZE / NUNITS otherwise. */
@@ -870,9 +944,10 @@ vect_analyze_slp_instance (loop_vec_info loop_vinfo, gimple stmt)
loads = VEC_alloc (slp_tree, heap, group_size);
/* Build the tree for the SLP instance. */
- if (vect_build_slp_tree (loop_vinfo, &node, group_size, &inside_cost,
- &outside_cost, ncopies_for_cost, &max_nunits,
- &load_permutation, &loads))
+ if (vect_build_slp_tree (loop_vinfo, bb_vinfo, &node, group_size,
+ &inside_cost, &outside_cost, ncopies_for_cost,
+ &max_nunits, &load_permutation, &loads,
+ vectorization_factor))
{
/* Create a new SLP instance. */
new_instance = XNEW (struct _slp_instance);
@@ -883,7 +958,7 @@ vect_analyze_slp_instance (loop_vec_info loop_vinfo, gimple stmt)
if (max_nunits > nunits)
unrolling_factor = least_common_multiple (max_nunits, group_size)
/ group_size;
-
+
SLP_INSTANCE_UNROLLING_FACTOR (new_instance) = unrolling_factor;
SLP_INSTANCE_OUTSIDE_OF_LOOP_COST (new_instance) = outside_cost;
SLP_INSTANCE_INSIDE_OF_LOOP_COST (new_instance) = inside_cost;
@@ -912,8 +987,14 @@ vect_analyze_slp_instance (loop_vec_info loop_vinfo, gimple stmt)
else
VEC_free (int, heap, SLP_INSTANCE_LOAD_PERMUTATION (new_instance));
- VEC_safe_push (slp_instance, heap, LOOP_VINFO_SLP_INSTANCES (loop_vinfo),
- new_instance);
+ if (loop_vinfo)
+ VEC_safe_push (slp_instance, heap,
+ LOOP_VINFO_SLP_INSTANCES (loop_vinfo),
+ new_instance);
+ else
+ VEC_safe_push (slp_instance, heap, BB_VINFO_SLP_INSTANCES (bb_vinfo),
+ new_instance);
+
if (vect_print_dump_info (REPORT_SLP))
vect_print_slp_tree (node);
@@ -926,12 +1007,7 @@ vect_analyze_slp_instance (loop_vec_info loop_vinfo, gimple stmt)
VEC_free (int, heap, load_permutation);
VEC_free (slp_tree, heap, loads);
- if (slp_impossible)
- return false;
-
- /* SLP failed for this instance, but it is still possible to SLP other stmts
- in the loop. */
- return true;
+ return false;
}
@@ -939,24 +1015,32 @@ vect_analyze_slp_instance (loop_vec_info loop_vinfo, gimple stmt)
trees of packed scalar stmts if SLP is possible. */
bool
-vect_analyze_slp (loop_vec_info loop_vinfo)
+vect_analyze_slp (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo)
{
unsigned int i;
- VEC (gimple, heap) *strided_stores = LOOP_VINFO_STRIDED_STORES (loop_vinfo);
+ VEC (gimple, heap) *strided_stores;
gimple store;
+ bool ok = false;
if (vect_print_dump_info (REPORT_SLP))
fprintf (vect_dump, "=== vect_analyze_slp ===");
+ if (loop_vinfo)
+ strided_stores = LOOP_VINFO_STRIDED_STORES (loop_vinfo);
+ else
+ strided_stores = BB_VINFO_STRIDED_STORES (bb_vinfo);
+
for (i = 0; VEC_iterate (gimple, strided_stores, i, store); i++)
- if (!vect_analyze_slp_instance (loop_vinfo, store))
- {
- /* SLP failed. No instance can be SLPed in the loop. */
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
- fprintf (vect_dump, "SLP failed.");
+ if (vect_analyze_slp_instance (loop_vinfo, bb_vinfo, store))
+ ok = true;
- return false;
- }
+ if (bb_vinfo && !ok)
+ {
+ if (vect_print_dump_info (REPORT_SLP))
+ fprintf (vect_dump, "Failed to SLP the basic block.");
+
+ return false;
+ }
return true;
}
@@ -1041,6 +1125,255 @@ vect_detect_hybrid_slp (loop_vec_info loop_vinfo)
vect_detect_hybrid_slp_stmts (SLP_INSTANCE_TREE (instance));
}
+
+/* Create and initialize a new bb_vec_info struct for BB, as well as
+ stmt_vec_info structs for all the stmts in it. */
+
+static bb_vec_info
+new_bb_vec_info (basic_block bb)
+{
+ bb_vec_info res = NULL;
+ gimple_stmt_iterator gsi;
+
+ res = (bb_vec_info) xcalloc (1, sizeof (struct _bb_vec_info));
+ BB_VINFO_BB (res) = bb;
+
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ gimple stmt = gsi_stmt (gsi);
+ gimple_set_uid (stmt, 0);
+ set_vinfo_for_stmt (stmt, new_stmt_vec_info (stmt, NULL, res));
+ }
+
+ BB_VINFO_STRIDED_STORES (res) = VEC_alloc (gimple, heap, 10);
+ BB_VINFO_SLP_INSTANCES (res) = VEC_alloc (slp_instance, heap, 2);
+
+ bb->aux = res;
+ return res;
+}
+
+
+/* Free BB_VINFO struct, as well as all the stmt_vec_info structs of all the
+ stmts in the basic block. */
+
+static void
+destroy_bb_vec_info (bb_vec_info bb_vinfo)
+{
+ basic_block bb;
+ gimple_stmt_iterator si;
+
+ if (!bb_vinfo)
+ return;
+
+ bb = BB_VINFO_BB (bb_vinfo);
+
+ for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
+ {
+ gimple stmt = gsi_stmt (si);
+ stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
+
+ if (stmt_info)
+ /* Free stmt_vec_info. */
+ free_stmt_vec_info (stmt);
+ }
+
+ VEC_free (gimple, heap, BB_VINFO_STRIDED_STORES (bb_vinfo));
+ VEC_free (slp_instance, heap, BB_VINFO_SLP_INSTANCES (bb_vinfo));
+ free (bb_vinfo);
+ bb->aux = NULL;
+}
+
+
+/* Analyze statements contained in SLP tree node after recursively analyzing
+ the subtree. Return TRUE if the operations are supported. */
+
+static bool
+vect_slp_analyze_node_operations (bb_vec_info bb_vinfo, slp_tree node)
+{
+ bool dummy;
+ int i;
+ gimple stmt;
+
+ if (!node)
+ return true;
+
+ if (!vect_slp_analyze_node_operations (bb_vinfo, SLP_TREE_LEFT (node))
+ || !vect_slp_analyze_node_operations (bb_vinfo, SLP_TREE_RIGHT (node)))
+ return false;
+
+ for (i = 0; VEC_iterate (gimple, SLP_TREE_SCALAR_STMTS (node), i, stmt); i++)
+ {
+ stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
+ gcc_assert (stmt_info);
+ gcc_assert (PURE_SLP_STMT (stmt_info));
+
+ if (!vect_analyze_stmt (stmt, &dummy, node))
+ return false;
+ }
+
+ return true;
+}
+
+
+/* Analyze statements in SLP instances of the basic block. Return TRUE if the
+ operations are supported. */
+
+static bool
+vect_slp_analyze_operations (bb_vec_info bb_vinfo)
+{
+ VEC (slp_instance, heap) *slp_instances = BB_VINFO_SLP_INSTANCES (bb_vinfo);
+ slp_instance instance;
+ int i;
+
+ for (i = 0; VEC_iterate (slp_instance, slp_instances, i, instance); )
+ {
+ if (!vect_slp_analyze_node_operations (bb_vinfo,
+ SLP_INSTANCE_TREE (instance)))
+ {
+ vect_free_slp_instance (instance);
+ VEC_ordered_remove (slp_instance, slp_instances, i);
+ }
+ else
+ i++;
+ }
+
+ if (!VEC_length (slp_instance, slp_instances))
+ return false;
+
+ return true;
+}
+
+
+/* Cheick if the basic block can be vectorized. */
+
+bb_vec_info
+vect_slp_analyze_bb (basic_block bb)
+{
+ bb_vec_info bb_vinfo;
+ VEC (ddr_p, heap) *ddrs;
+ VEC (slp_instance, heap) *slp_instances;
+ slp_instance instance;
+ int i, insns = 0;
+ gimple_stmt_iterator gsi;
+
+ if (vect_print_dump_info (REPORT_DETAILS))
+ fprintf (vect_dump, "===vect_slp_analyze_bb===\n");
+
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ insns++;
+
+ if (insns > PARAM_VALUE (PARAM_SLP_MAX_INSNS_IN_BB))
+ {
+ if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
+ fprintf (vect_dump, "not vectorized: too many instructions in basic "
+ "block.\n");
+
+ return NULL;
+ }
+
+ bb_vinfo = new_bb_vec_info (bb);
+ if (!bb_vinfo)
+ return NULL;
+
+ if (!vect_analyze_data_refs (NULL, bb_vinfo))
+ {
+ if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
+ fprintf (vect_dump, "not vectorized: unhandled data-ref in basic "
+ "block.\n");
+
+ destroy_bb_vec_info (bb_vinfo);
+ return NULL;
+ }
+
+ ddrs = BB_VINFO_DDRS (bb_vinfo);
+ if (!VEC_length (ddr_p, ddrs))
+ {
+ if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
+ fprintf (vect_dump, "not vectorized: not enough data-refs in basic "
+ "block.\n");
+
+ destroy_bb_vec_info (bb_vinfo);
+ return NULL;
+ }
+
+ if (!vect_analyze_data_refs_alignment (NULL, bb_vinfo))
+ {
+ if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
+ fprintf (vect_dump, "not vectorized: bad data alignment in basic "
+ "block.\n");
+
+ destroy_bb_vec_info (bb_vinfo);
+ return NULL;
+ }
+
+ if (!vect_analyze_data_ref_dependences (NULL, bb_vinfo))
+ {
+ if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
+ fprintf (vect_dump, "not vectorized: unhandled data dependence in basic"
+ " block.\n");
+
+ destroy_bb_vec_info (bb_vinfo);
+ return NULL;
+ }
+
+ if (!vect_analyze_data_ref_accesses (NULL, bb_vinfo))
+ {
+ if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
+ fprintf (vect_dump, "not vectorized: unhandled data access in basic "
+ "block.\n");
+
+ destroy_bb_vec_info (bb_vinfo);
+ return NULL;
+ }
+
+ if (!vect_verify_datarefs_alignment (NULL, bb_vinfo))
+ {
+ if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
+ fprintf (vect_dump, "not vectorized: unsupported alignment in basic "
+ "block.\n");
+
+ destroy_bb_vec_info (bb_vinfo);
+ return NULL;
+ }
+
+ /* Check the SLP opportunities in the basic block, analyze and build SLP
+ trees. */
+ if (!vect_analyze_slp (NULL, bb_vinfo))
+ {
+ if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
+ fprintf (vect_dump, "not vectorized: failed to find SLP opportunities "
+ "in basic block.\n");
+
+ destroy_bb_vec_info (bb_vinfo);
+ return NULL;
+ }
+
+ slp_instances = BB_VINFO_SLP_INSTANCES (bb_vinfo);
+
+ /* Mark all the statements that we want to vectorize as pure SLP and
+ relevant. */
+ for (i = 0; VEC_iterate (slp_instance, slp_instances, i, instance); i++)
+ {
+ vect_mark_slp_stmts (SLP_INSTANCE_TREE (instance), pure_slp, -1);
+ vect_mark_slp_stmts_relevant (SLP_INSTANCE_TREE (instance));
+ }
+
+ if (!vect_slp_analyze_operations (bb_vinfo))
+ {
+ if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
+ fprintf (vect_dump, "not vectorized: bad operation in basic block.\n");
+
+ destroy_bb_vec_info (bb_vinfo);
+ return NULL;
+ }
+
+ if (vect_print_dump_info (REPORT_DETAILS))
+ fprintf (vect_dump, "Basic block will be vectorized using SLP\n");
+
+ return bb_vinfo;
+}
+
+
/* SLP costs are calculated according to SLP instance unrolling factor (i.e.,
the number of created vector stmts depends on the unrolling factor). However,
the actual number of vector stmts for every SLP node depends on VF which is
@@ -1064,6 +1397,7 @@ vect_update_slp_costs_according_to_vf (loop_vec_info loop_vinfo)
/ SLP_INSTANCE_UNROLLING_FACTOR (instance);
}
+
/* For constant and loop invariant defs of SLP_NODE this function returns
(vector) defs (VEC_OPRNDS) that will be used in the vectorized stmts.
OP_NUM determines if we gather defs for operand 0 or operand 1 of the scalar
@@ -1284,6 +1618,7 @@ vect_get_slp_defs (slp_tree slp_node, VEC (tree,heap) **vec_oprnds0,
vect_get_constant_vectors (slp_node, vec_oprnds1, 1, number_of_vects);
}
+
/* Create NCOPIES permutation statements using the mask MASK_BYTES (by
building a vector of type MASK_TYPE from it) and two input vectors placed in
DR_CHAIN at FIRST_VEC_INDX and SECOND_VEC_INDX for the first copy and
@@ -1588,7 +1923,7 @@ vect_transform_slp_perm_load (gimple stmt, VEC (tree, heap) *dr_chain,
static bool
vect_schedule_slp_instance (slp_tree node, slp_instance instance,
- unsigned int vectorization_factor)
+ unsigned int vectorization_factor)
{
gimple stmt;
bool strided_store, is_store;
@@ -1658,7 +1993,7 @@ vect_schedule_slp_instance (slp_tree node, slp_instance instance,
si = gsi_for_stmt (SLP_INSTANCE_FIRST_LOAD_STMT (instance));
else
si = gsi_for_stmt (stmt);
-
+
is_store = vect_transform_stmt (stmt, &si, &strided_store, node, instance);
if (is_store)
{
@@ -1680,20 +2015,29 @@ vect_schedule_slp_instance (slp_tree node, slp_instance instance,
bool
-vect_schedule_slp (loop_vec_info loop_vinfo)
+vect_schedule_slp (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo)
{
- VEC (slp_instance, heap) *slp_instances =
- LOOP_VINFO_SLP_INSTANCES (loop_vinfo);
+ VEC (slp_instance, heap) *slp_instances;
slp_instance instance;
- unsigned int i;
+ unsigned int i, vf;
bool is_store = false;
+ if (loop_vinfo)
+ {
+ slp_instances = LOOP_VINFO_SLP_INSTANCES (loop_vinfo);
+ vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
+ }
+ else
+ {
+ slp_instances = BB_VINFO_SLP_INSTANCES (bb_vinfo);
+ vf = 1;
+ }
+
for (i = 0; VEC_iterate (slp_instance, slp_instances, i, instance); i++)
{
/* Schedule the tree of INSTANCE. */
is_store = vect_schedule_slp_instance (SLP_INSTANCE_TREE (instance),
- instance, LOOP_VINFO_VECT_FACTOR (loop_vinfo));
-
+ instance, vf);
if (vect_print_dump_info (REPORT_VECTORIZED_LOCATIONS)
|| vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
fprintf (vect_dump, "vectorizing stmts using SLP.");
@@ -1701,3 +2045,52 @@ vect_schedule_slp (loop_vec_info loop_vinfo)
return is_store;
}
+
+
+/* Vectorize the basic block. */
+
+void
+vect_slp_transform_bb (basic_block bb)
+{
+ bb_vec_info bb_vinfo = vec_info_for_bb (bb);
+ gimple_stmt_iterator si;
+
+ gcc_assert (bb_vinfo);
+
+ if (vect_print_dump_info (REPORT_DETAILS))
+ fprintf (vect_dump, "SLPing BB\n");
+
+ for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
+ {
+ gimple stmt = gsi_stmt (si);
+ stmt_vec_info stmt_info;
+
+ if (vect_print_dump_info (REPORT_DETAILS))
+ {
+ fprintf (vect_dump, "------>SLPing statement: ");
+ print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
+ }
+
+ stmt_info = vinfo_for_stmt (stmt);
+ gcc_assert (stmt_info);
+
+ /* Schedule all the SLP instances when the first SLP stmt is reached. */
+ if (STMT_SLP_TYPE (stmt_info))
+ {
+ vect_schedule_slp (NULL, bb_vinfo);
+ break;
+ }
+ }
+
+ mark_sym_for_renaming (gimple_vop (cfun));
+ /* The memory tags and pointers in vectorized statements need to
+ have their SSA forms updated. FIXME, why can't this be delayed
+ until all the loops have been transformed? */
+ update_ssa (TODO_update_ssa);
+
+ if (vect_print_dump_info (REPORT_DETAILS))
+ fprintf (vect_dump, "BASIC BLOCK VECTORIZED\n");
+
+ destroy_bb_vec_info (bb_vinfo);
+}
+
diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
index 06d51e2d318..586e906b1de 100644
--- a/gcc/tree-vect-stmts.c
+++ b/gcc/tree-vect-stmts.c
@@ -248,7 +248,7 @@ process_use (gimple stmt, tree use, loop_vec_info loop_vinfo, bool live_p,
if (!exist_non_indexing_operands_for_use_p (use, stmt))
return true;
- if (!vect_is_simple_use (use, loop_vinfo, &def_stmt, &def, &dt))
+ if (!vect_is_simple_use (use, loop_vinfo, NULL, &def_stmt, &def, &dt))
{
if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
fprintf (vect_dump, "not vectorized: unsupported use in stmt.");
@@ -300,19 +300,24 @@ process_use (gimple stmt, tree use, loop_vec_info loop_vinfo, bool live_p,
{
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "outer-loop def-stmt defining inner-loop stmt.");
+
switch (relevant)
{
case vect_unused_in_scope:
- relevant = (STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_reduction_def) ?
- vect_used_by_reduction : vect_unused_in_scope;
+ relevant = (STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_nested_cycle) ?
+ vect_used_in_scope : vect_unused_in_scope;
break;
+
case vect_used_in_outer_by_reduction:
+ gcc_assert (STMT_VINFO_DEF_TYPE (stmt_vinfo) != vect_reduction_def);
relevant = vect_used_by_reduction;
break;
+
case vect_used_in_outer:
+ gcc_assert (STMT_VINFO_DEF_TYPE (stmt_vinfo) != vect_reduction_def);
relevant = vect_used_in_scope;
break;
- case vect_used_by_reduction:
+
case vect_used_in_scope:
break;
@@ -332,15 +337,12 @@ process_use (gimple stmt, tree use, loop_vec_info loop_vinfo, bool live_p,
{
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "inner-loop def-stmt defining outer-loop stmt.");
+
switch (relevant)
{
case vect_unused_in_scope:
relevant = (STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_reduction_def) ?
- vect_used_in_outer_by_reduction : vect_unused_in_scope;
- break;
-
- case vect_used_in_outer_by_reduction:
- case vect_used_in_outer:
+ vect_used_in_outer_by_reduction : vect_unused_in_scope;
break;
case vect_used_by_reduction:
@@ -461,19 +463,7 @@ vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo)
those that are used by a reduction computation, and those that are
(also) used by a regular computation. This allows us later on to
identify stmts that are used solely by a reduction, and therefore the
- order of the results that they produce does not have to be kept.
-
- Reduction phis are expected to be used by a reduction stmt, or by
- in an outer loop; Other reduction stmts are expected to be
- in the loop, and possibly used by a stmt in an outer loop.
- Here are the expected values of "relevant" for reduction phis/stmts:
-
- relevance: phi stmt
- vect_unused_in_scope ok
- vect_used_in_outer_by_reduction ok ok
- vect_used_in_outer ok ok
- vect_used_by_reduction ok
- vect_used_in_scope */
+ order of the results that they produce does not have to be kept. */
if (STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_reduction_def)
{
@@ -485,28 +475,41 @@ vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo)
relevant = vect_used_by_reduction;
break;
- case vect_used_in_outer_by_reduction:
- case vect_used_in_outer:
- gcc_assert (gimple_code (stmt) != GIMPLE_ASSIGN
- || (gimple_assign_rhs_code (stmt) != WIDEN_SUM_EXPR
- && (gimple_assign_rhs_code (stmt)
- != DOT_PROD_EXPR)));
- break;
-
case vect_used_by_reduction:
if (gimple_code (stmt) == GIMPLE_PHI)
break;
/* fall through */
- case vect_used_in_scope:
+
default:
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "unsupported use of reduction.");
VEC_free (gimple, heap, worklist);
return false;
}
+
live_p = false;
}
+ else if (STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_nested_cycle)
+ {
+ enum vect_relevant tmp_relevant = relevant;
+ switch (tmp_relevant)
+ {
+ case vect_unused_in_scope:
+ case vect_used_in_outer_by_reduction:
+ case vect_used_in_outer:
+ break;
+
+ default:
+ if (vect_print_dump_info (REPORT_DETAILS))
+ fprintf (vect_dump, "unsupported use of nested cycle.");
+
+ VEC_free (gimple, heap, worklist);
+ return false;
+ }
+ live_p = false;
+ }
+
FOR_EACH_PHI_OR_STMT_USE (use_p, stmt, iter, SSA_OP_USE)
{
tree op = USE_FROM_PTR (use_p);
@@ -813,13 +816,29 @@ vect_init_vector (gimple stmt, tree vector_var, tree vector_type,
else
{
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
- struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
-
- if (nested_in_vect_loop_p (loop, stmt))
- loop = loop->inner;
- pe = loop_preheader_edge (loop);
- new_bb = gsi_insert_on_edge_immediate (pe, init_stmt);
- gcc_assert (!new_bb);
+
+ if (loop_vinfo)
+ {
+ struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+
+ if (nested_in_vect_loop_p (loop, stmt))
+ loop = loop->inner;
+
+ pe = loop_preheader_edge (loop);
+ new_bb = gsi_insert_on_edge_immediate (pe, init_stmt);
+ gcc_assert (!new_bb);
+ }
+ else
+ {
+ bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_vinfo);
+ basic_block bb;
+ gimple_stmt_iterator gsi_bb_start;
+
+ gcc_assert (bb_vinfo);
+ bb = BB_VINFO_BB (bb_vinfo);
+ gsi_bb_start = gsi_after_labels (bb);
+ gsi_insert_before (&gsi_bb_start, init_stmt, GSI_SAME_STMT);
+ }
}
if (vect_print_dump_info (REPORT_DETAILS))
@@ -832,6 +851,7 @@ vect_init_vector (gimple stmt, tree vector_var, tree vector_type,
return vec_oprnd;
}
+
/* Function vect_get_vec_def_for_operand.
OP is an operand in STMT. This function returns a (vector) def that will be
@@ -869,7 +889,8 @@ vect_get_vec_def_for_operand (tree op, gimple stmt, tree *scalar_def)
print_generic_expr (vect_dump, op, TDF_SLIM);
}
- is_simple_use = vect_is_simple_use (op, loop_vinfo, &def_stmt, &def, &dt);
+ is_simple_use = vect_is_simple_use (op, loop_vinfo, NULL, &def_stmt, &def,
+ &dt);
gcc_assert (is_simple_use);
if (vect_print_dump_info (REPORT_DETAILS))
{
@@ -953,6 +974,7 @@ vect_get_vec_def_for_operand (tree op, gimple stmt, tree *scalar_def)
/* Case 4: operand is defined by a loop header phi - reduction */
case vect_reduction_def:
+ case vect_nested_cycle:
{
struct loop *loop;
@@ -1122,12 +1144,14 @@ vect_finish_stmt_generation (gimple stmt, gimple vec_stmt,
{
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
+ bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info);
gcc_assert (gimple_code (stmt) != GIMPLE_LABEL);
gsi_insert_before (gsi, vec_stmt, GSI_SAME_STMT);
- set_vinfo_for_stmt (vec_stmt, new_stmt_vec_info (vec_stmt, loop_vinfo));
+ set_vinfo_for_stmt (vec_stmt, new_stmt_vec_info (vec_stmt, loop_vinfo,
+ bb_vinfo));
if (vect_print_dump_info (REPORT_DETAILS))
{
@@ -1191,6 +1215,9 @@ vectorizable_call (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt)
enum { NARROW, NONE, WIDEN } modifier;
size_t i, nargs;
+ /* FORNOW: unsupported in basic block SLP. */
+ gcc_assert (loop_vinfo);
+
if (!STMT_VINFO_RELEVANT_P (stmt_info))
return false;
@@ -1232,7 +1259,7 @@ vectorizable_call (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt)
}
rhs_type = TREE_TYPE (op);
- if (!vect_is_simple_use (op, loop_vinfo, &def_stmt, &def, &dt[i]))
+ if (!vect_is_simple_use (op, loop_vinfo, NULL, &def_stmt, &def, &dt[i]))
{
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "use not simple.");
@@ -1509,6 +1536,9 @@ vectorizable_conversion (gimple stmt, gimple_stmt_iterator *gsi,
/* Is STMT a vectorizable conversion? */
+ /* FORNOW: unsupported in basic block SLP. */
+ gcc_assert (loop_vinfo);
+
if (!STMT_VINFO_RELEVANT_P (stmt_info))
return false;
@@ -1575,7 +1605,7 @@ vectorizable_conversion (gimple stmt, gimple_stmt_iterator *gsi,
gcc_assert (ncopies >= 1);
/* Check the operands of the operation. */
- if (!vect_is_simple_use (op0, loop_vinfo, &def_stmt, &def, &dt[0]))
+ if (!vect_is_simple_use (op0, loop_vinfo, NULL, &def_stmt, &def, &dt[0]))
{
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "use not simple.");
@@ -1759,6 +1789,7 @@ vectorizable_assignment (gimple stmt, gimple_stmt_iterator *gsi,
int i;
VEC(tree,heap) *vec_oprnds = NULL;
tree vop;
+ bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info);
/* Multiple types in SLP are handled by creating the appropriate number of
vectorized stmts for each SLP node. Hence, NCOPIES is always 1 in
@@ -1772,7 +1803,7 @@ vectorizable_assignment (gimple stmt, gimple_stmt_iterator *gsi,
if (ncopies > 1)
return false; /* FORNOW */
- if (!STMT_VINFO_RELEVANT_P (stmt_info))
+ if (!STMT_VINFO_RELEVANT_P (stmt_info) && !bb_vinfo)
return false;
if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def)
@@ -1792,7 +1823,7 @@ vectorizable_assignment (gimple stmt, gimple_stmt_iterator *gsi,
else
return false;
- if (!vect_is_simple_use (op, loop_vinfo, &def_stmt, &def, &dt[0]))
+ if (!vect_is_simple_use (op, loop_vinfo, bb_vinfo, &def_stmt, &def, &dt[0]))
{
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "use not simple.");
@@ -1875,6 +1906,14 @@ vectorizable_operation (gimple stmt, gimple_stmt_iterator *gsi,
unsigned int k;
bool shift_p = false;
bool scalar_shift_arg = false;
+ bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info);
+ int vf;
+
+ if (loop_vinfo)
+ vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
+ else
+ /* FORNOW: multiple types are not supported in basic block SLP. */
+ vf = nunits_in;
/* Multiple types in SLP are handled by creating the appropriate number of
vectorized stmts for each SLP node. Hence, NCOPIES is always 1 in
@@ -1886,7 +1925,7 @@ vectorizable_operation (gimple stmt, gimple_stmt_iterator *gsi,
gcc_assert (ncopies >= 1);
- if (!STMT_VINFO_RELEVANT_P (stmt_info))
+ if (!STMT_VINFO_RELEVANT_P (stmt_info) && !bb_vinfo)
return false;
if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def)
@@ -1924,7 +1963,7 @@ vectorizable_operation (gimple stmt, gimple_stmt_iterator *gsi,
}
op0 = gimple_assign_rhs1 (stmt);
- if (!vect_is_simple_use (op0, loop_vinfo, &def_stmt, &def, &dt[0]))
+ if (!vect_is_simple_use (op0, loop_vinfo, bb_vinfo, &def_stmt, &def, &dt[0]))
{
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "use not simple.");
@@ -1934,7 +1973,8 @@ vectorizable_operation (gimple stmt, gimple_stmt_iterator *gsi,
if (op_type == binary_op)
{
op1 = gimple_assign_rhs2 (stmt);
- if (!vect_is_simple_use (op1, loop_vinfo, &def_stmt, &def, &dt[1]))
+ if (!vect_is_simple_use (op1, loop_vinfo, bb_vinfo, &def_stmt, &def,
+ &dt[1]))
{
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "use not simple.");
@@ -2016,8 +2056,7 @@ vectorizable_operation (gimple stmt, gimple_stmt_iterator *gsi,
fprintf (vect_dump, "op not supported by target.");
/* Check only during analysis. */
if (GET_MODE_SIZE (vec_mode) != UNITS_PER_WORD
- || (LOOP_VINFO_VECT_FACTOR (loop_vinfo)
- < vect_min_worthwhile_factor (code)
+ || (vf < vect_min_worthwhile_factor (code)
&& !vec_stmt))
return false;
if (vect_print_dump_info (REPORT_DETAILS))
@@ -2026,8 +2065,7 @@ vectorizable_operation (gimple stmt, gimple_stmt_iterator *gsi,
/* Worthwhile without SIMD support? Check only during analysis. */
if (!VECTOR_MODE_P (TYPE_MODE (vectype))
- && LOOP_VINFO_VECT_FACTOR (loop_vinfo)
- < vect_min_worthwhile_factor (code)
+ && vf < vect_min_worthwhile_factor (code)
&& !vec_stmt)
{
if (vect_print_dump_info (REPORT_DETAILS))
@@ -2333,6 +2371,9 @@ vectorizable_type_demotion (gimple stmt, gimple_stmt_iterator *gsi,
VEC (tree, heap) *vec_dsts = NULL, *interm_types = NULL, *tmp_vec_dsts = NULL;
tree last_oprnd, intermediate_type;
+ /* FORNOW: not supported by basic block SLP vectorization. */
+ gcc_assert (loop_vinfo);
+
if (!STMT_VINFO_RELEVANT_P (stmt_info))
return false;
@@ -2371,7 +2412,6 @@ vectorizable_type_demotion (gimple stmt, gimple_stmt_iterator *gsi,
ncopies = 1;
else
ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits_out;
-
gcc_assert (ncopies >= 1);
if (! ((INTEGRAL_TYPE_P (TREE_TYPE (scalar_dest))
@@ -2382,7 +2422,7 @@ vectorizable_type_demotion (gimple stmt, gimple_stmt_iterator *gsi,
return false;
/* Check the operands of the operation. */
- if (!vect_is_simple_use (op0, loop_vinfo, &def_stmt, &def, &dt[0]))
+ if (!vect_is_simple_use (op0, loop_vinfo, NULL, &def_stmt, &def, &dt[0]))
{
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "use not simple.");
@@ -2562,7 +2602,7 @@ vect_create_vectorized_promotion_stmts (VEC (tree, heap) **vec_oprnds0,
prev_stmt_info);
}
}
-
+
/* Function vectorizable_type_promotion
@@ -2600,6 +2640,9 @@ vectorizable_type_promotion (gimple stmt, gimple_stmt_iterator *gsi,
VEC (tree, heap) *vec_oprnds0 = NULL, *vec_oprnds1 = NULL;
VEC (tree, heap) *vec_dsts = NULL, *interm_types = NULL, *tmp_vec_dsts = NULL;
+ /* FORNOW: not supported by basic block SLP vectorization. */
+ gcc_assert (loop_vinfo);
+
if (!STMT_VINFO_RELEVANT_P (stmt_info))
return false;
@@ -2650,7 +2693,7 @@ vectorizable_type_promotion (gimple stmt, gimple_stmt_iterator *gsi,
return false;
/* Check the operands of the operation. */
- if (!vect_is_simple_use (op0, loop_vinfo, &def_stmt, &def, &dt[0]))
+ if (!vect_is_simple_use (op0, loop_vinfo, NULL, &def_stmt, &def, &dt[0]))
{
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "use not simple.");
@@ -2661,7 +2704,7 @@ vectorizable_type_promotion (gimple stmt, gimple_stmt_iterator *gsi,
if (op_type == binary_op)
{
op1 = gimple_assign_rhs2 (stmt);
- if (!vect_is_simple_use (op1, loop_vinfo, &def_stmt, &def, &dt[1]))
+ if (!vect_is_simple_use (op1, loop_vinfo, NULL, &def_stmt, &def, &dt[1]))
{
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "use not simple.");
@@ -2806,7 +2849,7 @@ vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info), *first_dr = NULL;
tree vectype = STMT_VINFO_VECTYPE (stmt_info);
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
- struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+ struct loop *loop = NULL;
enum machine_mode vec_mode;
tree dummy;
enum dr_alignment_support alignment_support_scheme;
@@ -2827,6 +2870,10 @@ vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
bool slp = (slp_node != NULL);
stmt_vec_info first_stmt_vinfo;
unsigned int vec_num;
+ bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info);
+
+ if (loop_vinfo)
+ loop = LOOP_VINFO_LOOP (loop_vinfo);
/* Multiple types in SLP are handled by creating the appropriate number of
vectorized stmts for each SLP node. Hence, NCOPIES is always 1 in
@@ -2839,14 +2886,14 @@ vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
gcc_assert (ncopies >= 1);
/* FORNOW. This restriction should be relaxed. */
- if (nested_in_vect_loop_p (loop, stmt) && ncopies > 1)
+ if (loop && nested_in_vect_loop_p (loop, stmt) && ncopies > 1)
{
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "multiple types in nested loop.");
return false;
}
- if (!STMT_VINFO_RELEVANT_P (stmt_info))
+ if (!STMT_VINFO_RELEVANT_P (stmt_info) && !bb_vinfo)
return false;
if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def)
@@ -2860,12 +2907,14 @@ vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
scalar_dest = gimple_assign_lhs (stmt);
if (TREE_CODE (scalar_dest) != ARRAY_REF
&& TREE_CODE (scalar_dest) != INDIRECT_REF
- && !STMT_VINFO_STRIDED_ACCESS (stmt_info))
+ && TREE_CODE (scalar_dest) != COMPONENT_REF
+ && TREE_CODE (scalar_dest) != IMAGPART_EXPR
+ && TREE_CODE (scalar_dest) != REALPART_EXPR)
return false;
gcc_assert (gimple_assign_single_p (stmt));
op = gimple_assign_rhs1 (stmt);
- if (!vect_is_simple_use (op, loop_vinfo, &def_stmt, &def, &dt))
+ if (!vect_is_simple_use (op, loop_vinfo, bb_vinfo, &def_stmt, &def, &dt))
{
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "use not simple.");
@@ -2907,7 +2956,8 @@ vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
{
gcc_assert (gimple_assign_single_p (next_stmt));
op = gimple_assign_rhs1 (next_stmt);
- if (!vect_is_simple_use (op, loop_vinfo, &def_stmt, &def, &dt))
+ if (!vect_is_simple_use (op, loop_vinfo, bb_vinfo, &def_stmt,
+ &def, &dt))
{
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "use not simple.");
@@ -2935,7 +2985,7 @@ vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
DR_GROUP_STORE_COUNT (vinfo_for_stmt (first_stmt))++;
/* FORNOW */
- gcc_assert (!nested_in_vect_loop_p (loop, stmt));
+ gcc_assert (!loop || !nested_in_vect_loop_p (loop, stmt));
/* We vectorize all the stmts of the interleaving group when we
reach the last stmt in the group. */
@@ -2972,7 +3022,6 @@ vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
alignment_support_scheme = vect_supportable_dr_alignment (first_dr);
gcc_assert (alignment_support_scheme);
- gcc_assert (alignment_support_scheme == dr_aligned); /* FORNOW */
/* In case the vectorization factor (VF) is bigger than the number
of elements that we can fit in a vectype (nunits), we have to generate
@@ -3063,7 +3112,7 @@ vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
dataref_ptr = vect_create_data_ref_ptr (first_stmt, NULL, NULL_TREE,
&dummy, &ptr_incr, false,
&inv_p);
- gcc_assert (!inv_p);
+ gcc_assert (bb_vinfo || !inv_p);
}
else
{
@@ -3077,7 +3126,8 @@ vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
for (i = 0; i < group_size; i++)
{
op = VEC_index (tree, oprnds, i);
- vect_is_simple_use (op, loop_vinfo, &def_stmt, &def, &dt);
+ vect_is_simple_use (op, loop_vinfo, bb_vinfo, &def_stmt, &def,
+ &dt);
vec_oprnd = vect_get_vec_def_for_stmt_copy (dt, op);
VEC_replace(tree, dr_chain, i, vec_oprnd);
VEC_replace(tree, oprnds, i, vec_oprnd);
@@ -3110,7 +3160,16 @@ vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
vect_permute_store_chain(). */
vec_oprnd = VEC_index (tree, result_chain, i);
- data_ref = build_fold_indirect_ref (dataref_ptr);
+ if (aligned_access_p (first_dr))
+ data_ref = build_fold_indirect_ref (dataref_ptr);
+ else
+ {
+ int mis = DR_MISALIGNMENT (first_dr);
+ tree tmis = (mis == -1 ? size_zero_node : size_int (mis));
+ tmis = size_binop (MULT_EXPR, tmis, size_int (BITS_PER_UNIT));
+ data_ref = build2 (MISALIGNED_INDIRECT_REF, vectype, dataref_ptr, tmis);
+ }
+
/* If accesses through a pointer to vectype do not alias the original
memory reference we have a problem. This should never happen. */
gcc_assert (alias_sets_conflict_p (get_alias_set (data_ref),
@@ -3162,9 +3221,9 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
stmt_vec_info prev_stmt_info;
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
- struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+ struct loop *loop = NULL;
struct loop *containing_loop = (gimple_bb (stmt))->loop_father;
- bool nested_in_vect_loop = nested_in_vect_loop_p (loop, stmt);
+ bool nested_in_vect_loop = false;
struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info), *first_dr;
tree vectype = STMT_VINFO_VECTYPE (stmt_info);
tree new_temp;
@@ -3192,6 +3251,18 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
bool slp = (slp_node != NULL);
bool slp_perm = false;
enum tree_code code;
+ bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info);
+ int vf;
+
+ if (loop_vinfo)
+ {
+ loop = LOOP_VINFO_LOOP (loop_vinfo);
+ nested_in_vect_loop = nested_in_vect_loop_p (loop, stmt);
+ vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
+ }
+ else
+ /* FORNOW: multiple types are not supported in basic block SLP. */
+ vf = nunits;
/* Multiple types in SLP are handled by creating the appropriate number of
vectorized stmts for each SLP node. Hence, NCOPIES is always 1 in
@@ -3211,10 +3282,7 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
return false;
}
- if (slp && SLP_INSTANCE_LOAD_PERMUTATION (slp_node_instance))
- slp_perm = true;
-
- if (!STMT_VINFO_RELEVANT_P (stmt_info))
+ if (!STMT_VINFO_RELEVANT_P (stmt_info) && !bb_vinfo)
return false;
if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def)
@@ -3231,7 +3299,9 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
code = gimple_assign_rhs_code (stmt);
if (code != ARRAY_REF
&& code != INDIRECT_REF
- && !STMT_VINFO_STRIDED_ACCESS (stmt_info))
+ && code != COMPONENT_REF
+ && code != IMAGPART_EXPR
+ && code != REALPART_EXPR)
return false;
if (!STMT_VINFO_DATA_REF (stmt_info))
@@ -3300,7 +3370,9 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
{
strided_load = false;
vec_num = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node);
- }
+ if (SLP_INSTANCE_LOAD_PERMUTATION (slp_node_instance))
+ slp_perm = true;
+ }
else
vec_num = group_size;
@@ -3419,7 +3491,7 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
This can only occur when vectorizing memory accesses in the inner-loop
nested within an outer-loop that is being vectorized. */
- if (nested_in_vect_loop_p (loop, stmt)
+ if (loop && nested_in_vect_loop_p (loop, stmt)
&& (TREE_INT_CST_LOW (DR_STEP (dr))
% GET_MODE_SIZE (TYPE_MODE (vectype)) != 0))
{
@@ -3551,7 +3623,7 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
}
/* 4. Handle invariant-load. */
- if (inv_p)
+ if (inv_p && !bb_vinfo)
{
gcc_assert (!strided_load);
gcc_assert (nested_in_vect_loop_p (loop, stmt));
@@ -3598,8 +3670,7 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
if (slp_perm)
{
- if (!vect_transform_slp_perm_load (stmt, dr_chain, gsi,
- LOOP_VINFO_VECT_FACTOR (loop_vinfo),
+ if (!vect_transform_slp_perm_load (stmt, dr_chain, gsi, vf,
slp_node_instance, false))
{
VEC_free (tree, heap, dr_chain);
@@ -3659,7 +3730,8 @@ vect_is_simple_cond (tree cond, loop_vec_info loop_vinfo)
if (TREE_CODE (lhs) == SSA_NAME)
{
gimple lhs_def_stmt = SSA_NAME_DEF_STMT (lhs);
- if (!vect_is_simple_use (lhs, loop_vinfo, &lhs_def_stmt, &def, &dt))
+ if (!vect_is_simple_use (lhs, loop_vinfo, NULL, &lhs_def_stmt, &def,
+ &dt))
return false;
}
else if (TREE_CODE (lhs) != INTEGER_CST && TREE_CODE (lhs) != REAL_CST
@@ -3669,7 +3741,8 @@ vect_is_simple_cond (tree cond, loop_vec_info loop_vinfo)
if (TREE_CODE (rhs) == SSA_NAME)
{
gimple rhs_def_stmt = SSA_NAME_DEF_STMT (rhs);
- if (!vect_is_simple_use (rhs, loop_vinfo, &rhs_def_stmt, &def, &dt))
+ if (!vect_is_simple_use (rhs, loop_vinfo, NULL, &rhs_def_stmt, &def,
+ &dt))
return false;
}
else if (TREE_CODE (rhs) != INTEGER_CST && TREE_CODE (rhs) != REAL_CST
@@ -3709,6 +3782,9 @@ vectorizable_condition (gimple stmt, gimple_stmt_iterator *gsi,
int ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits;
enum tree_code code;
+ /* FORNOW: unsupported in basic block SLP. */
+ gcc_assert (loop_vinfo);
+
gcc_assert (ncopies >= 1);
if (ncopies > 1)
return false; /* FORNOW */
@@ -3757,7 +3833,7 @@ vectorizable_condition (gimple stmt, gimple_stmt_iterator *gsi,
if (TREE_CODE (then_clause) == SSA_NAME)
{
gimple then_def_stmt = SSA_NAME_DEF_STMT (then_clause);
- if (!vect_is_simple_use (then_clause, loop_vinfo,
+ if (!vect_is_simple_use (then_clause, loop_vinfo, NULL,
&then_def_stmt, &def, &dt))
return false;
}
@@ -3769,7 +3845,7 @@ vectorizable_condition (gimple stmt, gimple_stmt_iterator *gsi,
if (TREE_CODE (else_clause) == SSA_NAME)
{
gimple else_def_stmt = SSA_NAME_DEF_STMT (else_clause);
- if (!vect_is_simple_use (else_clause, loop_vinfo,
+ if (!vect_is_simple_use (else_clause, loop_vinfo, NULL,
&else_def_stmt, &def, &dt))
return false;
}
@@ -3819,11 +3895,14 @@ vectorizable_condition (gimple stmt, gimple_stmt_iterator *gsi,
/* Make sure the statement is vectorizable. */
bool
-vect_analyze_stmt (gimple stmt, bool *need_to_vectorize)
+vect_analyze_stmt (gimple stmt, bool *need_to_vectorize, slp_tree node)
{
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
- enum vect_relevant relevance = STMT_VINFO_RELEVANT (stmt_info);
+ bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info);
+ enum vect_relevant relevance = STMT_VINFO_RELEVANT (stmt_info);
bool ok;
+ HOST_WIDE_INT dummy;
+ tree scalar_type, vectype;
if (vect_print_dump_info (REPORT_DETAILS))
{
@@ -3831,15 +3910,15 @@ vect_analyze_stmt (gimple stmt, bool *need_to_vectorize)
print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
}
- /* Skip stmts that do not need to be vectorized. In loops this is expected
+ /* Skip stmts that do not need to be vectorized. In loops this is expected
to include:
- the COND_EXPR which is the loop exit condition
- any LABEL_EXPRs in the loop
- - computations that are used only for array indexing or loop control.
+ - computations that are used only for array indexing or loop control.
In basic blocks we only analyze statements that are a part of some SLP
instance, therefore, all the statements are relevant. */
- if (!STMT_VINFO_RELEVANT_P (stmt_info)
+ if (!STMT_VINFO_RELEVANT_P (stmt_info)
&& !STMT_VINFO_LIVE_P (stmt_info))
{
if (vect_print_dump_info (REPORT_DETAILS))
@@ -3854,9 +3933,10 @@ vect_analyze_stmt (gimple stmt, bool *need_to_vectorize)
break;
case vect_reduction_def:
- gcc_assert (relevance == vect_used_in_outer
+ case vect_nested_cycle:
+ gcc_assert (!bb_vinfo && (relevance == vect_used_in_outer
|| relevance == vect_used_in_outer_by_reduction
- || relevance == vect_unused_in_scope);
+ || relevance == vect_unused_in_scope));
break;
case vect_induction_def:
@@ -3867,6 +3947,37 @@ vect_analyze_stmt (gimple stmt, bool *need_to_vectorize)
gcc_unreachable ();
}
+ if (bb_vinfo)
+ {
+ gcc_assert (PURE_SLP_STMT (stmt_info));
+
+ scalar_type = vect_get_smallest_scalar_type (stmt, &dummy, &dummy);
+ if (vect_print_dump_info (REPORT_DETAILS))
+ {
+ fprintf (vect_dump, "get vectype for scalar type: ");
+ print_generic_expr (vect_dump, scalar_type, TDF_SLIM);
+ }
+
+ vectype = get_vectype_for_scalar_type (scalar_type);
+ if (!vectype)
+ {
+ if (vect_print_dump_info (REPORT_DETAILS))
+ {
+ fprintf (vect_dump, "not SLPed: unsupported data-type ");
+ print_generic_expr (vect_dump, scalar_type, TDF_SLIM);
+ }
+ return false;
+ }
+
+ if (vect_print_dump_info (REPORT_DETAILS))
+ {
+ fprintf (vect_dump, "vectype: ");
+ print_generic_expr (vect_dump, vectype, TDF_SLIM);
+ }
+
+ STMT_VINFO_VECTYPE (stmt_info) = vectype;
+ }
+
if (STMT_VINFO_RELEVANT_P (stmt_info))
{
gcc_assert (!VECTOR_MODE_P (TYPE_MODE (gimple_expr_type (stmt))));
@@ -3875,8 +3986,9 @@ vect_analyze_stmt (gimple stmt, bool *need_to_vectorize)
}
ok = true;
- if (STMT_VINFO_RELEVANT_P (stmt_info)
- || STMT_VINFO_DEF_TYPE (stmt_info) == vect_reduction_def)
+ if (!bb_vinfo
+ && (STMT_VINFO_RELEVANT_P (stmt_info)
+ || STMT_VINFO_DEF_TYPE (stmt_info) == vect_reduction_def))
ok = (vectorizable_type_promotion (stmt, NULL, NULL, NULL)
|| vectorizable_type_demotion (stmt, NULL, NULL, NULL)
|| vectorizable_conversion (stmt, NULL, NULL, NULL)
@@ -3887,6 +3999,14 @@ vect_analyze_stmt (gimple stmt, bool *need_to_vectorize)
|| vectorizable_store (stmt, NULL, NULL, NULL)
|| vectorizable_condition (stmt, NULL, NULL)
|| vectorizable_reduction (stmt, NULL, NULL));
+ else
+ {
+ if (bb_vinfo)
+ ok = (vectorizable_operation (stmt, NULL, NULL, node)
+ || vectorizable_assignment (stmt, NULL, NULL, node)
+ || vectorizable_load (stmt, NULL, NULL, node, NULL)
+ || vectorizable_store (stmt, NULL, NULL, node));
+ }
if (!ok)
{
@@ -3896,10 +4016,13 @@ vect_analyze_stmt (gimple stmt, bool *need_to_vectorize)
fprintf (vect_dump, "supported: ");
print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
}
-
+
return false;
}
+ if (bb_vinfo)
+ return true;
+
/* Stmts that are (also) "live" (i.e. - that are used out of the loop)
need extra handling, except for vectorizable reductions. */
if (STMT_VINFO_LIVE_P (stmt_info)
@@ -3914,16 +4037,16 @@ vect_analyze_stmt (gimple stmt, bool *need_to_vectorize)
fprintf (vect_dump, "supported: ");
print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
}
-
+
return false;
}
if (!PURE_SLP_STMT (stmt_info))
{
- /* Groups of strided accesses whose size is not a power of 2 are not
- vectorizable yet using loop-vectorization. Therefore, if this stmt
- feeds non-SLP-able stmts (i.e., this stmt has to be both SLPed and
- loop-based vectorized), the loop cannot be vectorized. */
+ /* Groups of strided accesses whose size is not a power of 2 are not
+ vectorizable yet using loop-vectorization. Therefore, if this stmt
+ feeds non-SLP-able stmts (i.e., this stmt has to be both SLPed and
+ loop-based vectorized), the loop cannot be vectorized. */
if (STMT_VINFO_STRIDED_ACCESS (stmt_info)
&& exact_log2 (DR_GROUP_SIZE (vinfo_for_stmt (
DR_GROUP_FIRST_DR (stmt_info)))) == -1)
@@ -3938,7 +4061,7 @@ vect_analyze_stmt (gimple stmt, bool *need_to_vectorize)
return false;
}
}
-
+
return true;
}
@@ -3957,8 +4080,6 @@ vect_transform_stmt (gimple stmt, gimple_stmt_iterator *gsi,
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
gimple orig_stmt_in_pattern;
bool done;
- loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
- struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
switch (STMT_VINFO_TYPE (stmt_info))
{
@@ -4045,19 +4166,23 @@ vect_transform_stmt (gimple stmt, gimple_stmt_iterator *gsi,
/* Handle inner-loop stmts whose DEF is used in the loop-nest that
is being vectorized, but outside the immediately enclosing loop. */
if (vec_stmt
- && nested_in_vect_loop_p (loop, stmt)
+ && STMT_VINFO_LOOP_VINFO (stmt_info)
+ && nested_in_vect_loop_p (LOOP_VINFO_LOOP (
+ STMT_VINFO_LOOP_VINFO (stmt_info)), stmt)
&& STMT_VINFO_TYPE (stmt_info) != reduc_vec_info_type
&& (STMT_VINFO_RELEVANT (stmt_info) == vect_used_in_outer
- || STMT_VINFO_RELEVANT (stmt_info) == vect_used_in_outer_by_reduction))
+ || STMT_VINFO_RELEVANT (stmt_info) ==
+ vect_used_in_outer_by_reduction))
{
- struct loop *innerloop = loop->inner;
+ struct loop *innerloop = LOOP_VINFO_LOOP (
+ STMT_VINFO_LOOP_VINFO (stmt_info))->inner;
imm_use_iterator imm_iter;
use_operand_p use_p;
tree scalar_dest;
gimple exit_phi;
if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "Record the vdef for outer-loop vectorization.");
+ fprintf (vect_dump, "Record the vdef for outer-loop vectorization.");
/* Find the relevant loop-exit phi-node, and reord the vec_stmt there
(to be used when vectorizing outer-loop stmts that use the DEF of
@@ -4137,7 +4262,8 @@ vect_remove_stores (gimple first_stmt)
Create and initialize a new stmt_vec_info struct for STMT. */
stmt_vec_info
-new_stmt_vec_info (gimple stmt, loop_vec_info loop_vinfo)
+new_stmt_vec_info (gimple stmt, loop_vec_info loop_vinfo,
+ bb_vec_info bb_vinfo)
{
stmt_vec_info res;
res = (stmt_vec_info) xcalloc (1, sizeof (struct _stmt_vec_info));
@@ -4145,6 +4271,7 @@ new_stmt_vec_info (gimple stmt, loop_vec_info loop_vinfo)
STMT_VINFO_TYPE (res) = undef_vec_info_type;
STMT_VINFO_STMT (res) = stmt;
STMT_VINFO_LOOP_VINFO (res) = loop_vinfo;
+ STMT_VINFO_BB_VINFO (res) = bb_vinfo;
STMT_VINFO_RELEVANT (res) = vect_unused_in_scope;
STMT_VINFO_LIVE_P (res) = false;
STMT_VINFO_VECTYPE (res) = NULL;
@@ -4267,23 +4394,30 @@ get_vectype_for_scalar_type (tree scalar_type)
/* Function vect_is_simple_use.
Input:
- LOOP - the loop that is being vectorized.
- OPERAND - operand of a stmt in LOOP.
+ LOOP_VINFO - the vect info of the loop that is being vectorized.
+ BB_VINFO - the vect info of the basic block that is being vectorized.
+ OPERAND - operand of a stmt in the loop or bb.
DEF - the defining stmt in case OPERAND is an SSA_NAME.
Returns whether a stmt with OPERAND can be vectorized.
- Supportable operands are constants, loop invariants, and operands that are
- defined by the current iteration of the loop. Unsupportable operands are
- those that are defined by a previous iteration of the loop (as is the case
- in reduction/induction computations). */
+ For loops, supportable operands are constants, loop invariants, and operands
+ that are defined by the current iteration of the loop. Unsupportable
+ operands are those that are defined by a previous iteration of the loop (as
+ is the case in reduction/induction computations).
+ For basic blocks, supportable operands are constants and bb invariants.
+ For now, operands defined outside the basic block are not supported. */
bool
-vect_is_simple_use (tree operand, loop_vec_info loop_vinfo, gimple *def_stmt,
+vect_is_simple_use (tree operand, loop_vec_info loop_vinfo,
+ bb_vec_info bb_vinfo, gimple *def_stmt,
tree *def, enum vect_def_type *dt)
{
basic_block bb;
stmt_vec_info stmt_vinfo;
- struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+ struct loop *loop = NULL;
+
+ if (loop_vinfo)
+ loop = LOOP_VINFO_LOOP (loop_vinfo);
*def_stmt = NULL;
*def = NULL_TREE;
@@ -4299,6 +4433,7 @@ vect_is_simple_use (tree operand, loop_vec_info loop_vinfo, gimple *def_stmt,
*dt = vect_constant_def;
return true;
}
+
if (is_gimple_min_invariant (operand))
{
*def = operand;
@@ -4312,6 +4447,7 @@ vect_is_simple_use (tree operand, loop_vec_info loop_vinfo, gimple *def_stmt,
fprintf (vect_dump, "non-associatable copy.");
operand = TREE_OPERAND (operand, 0);
}
+
if (TREE_CODE (operand) != SSA_NAME)
{
if (vect_print_dump_info (REPORT_DETAILS))
@@ -4343,7 +4479,10 @@ vect_is_simple_use (tree operand, loop_vec_info loop_vinfo, gimple *def_stmt,
}
bb = gimple_bb (*def_stmt);
- if (!flow_bb_inside_loop_p (loop, bb))
+
+ if ((loop && !flow_bb_inside_loop_p (loop, bb))
+ || (!loop && bb != BB_VINFO_BB (bb_vinfo))
+ || (!loop && gimple_code (*def_stmt) == GIMPLE_PHI))
*dt = vect_external_def;
else
{
diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c
index b4985475d78..2c2103eda0a 100644
--- a/gcc/tree-vectorizer.c
+++ b/gcc/tree-vectorizer.c
@@ -68,6 +68,7 @@ along with GCC; see the file COPYING3. If not see
#include "cfglayout.h"
#include "tree-vectorizer.h"
#include "tree-pass.h"
+#include "timevar.h"
/* vect_dump will be set to stderr or dump_file if exist. */
FILE *vect_dump;
@@ -75,13 +76,11 @@ FILE *vect_dump;
/* vect_verbosity_level set to an invalid value
to mark that it's uninitialized. */
static enum verbosity_levels vect_verbosity_level = MAX_VERBOSITY_LEVEL;
+static enum verbosity_levels user_vect_verbosity_level = MAX_VERBOSITY_LEVEL;
-/* Loop location. */
+/* Loop or bb location. */
LOC vect_location;
-/* Bitmap of virtual variables to be renamed. */
-bitmap vect_memsyms_to_rename;
-
/* Vector mapping GIMPLE stmt to stmt_vec_info. */
VEC(vec_void_p,heap) *stmt_vec_info_vec;
@@ -99,9 +98,10 @@ vect_set_verbosity_level (const char *val)
vl = atoi (val);
if (vl < MAX_VERBOSITY_LEVEL)
- vect_verbosity_level = (enum verbosity_levels) vl;
+ user_vect_verbosity_level = (enum verbosity_levels) vl;
else
- vect_verbosity_level = (enum verbosity_levels) (MAX_VERBOSITY_LEVEL - 1);
+ user_vect_verbosity_level
+ = (enum verbosity_levels) (MAX_VERBOSITY_LEVEL - 1);
}
@@ -115,17 +115,33 @@ vect_set_verbosity_level (const char *val)
print to stderr, otherwise print to the dump file. */
static void
-vect_set_dump_settings (void)
+vect_set_dump_settings (bool slp)
{
vect_dump = dump_file;
/* Check if the verbosity level was defined by the user: */
- if (vect_verbosity_level != MAX_VERBOSITY_LEVEL)
+ if (user_vect_verbosity_level != MAX_VERBOSITY_LEVEL)
{
- /* If there is no dump file, print to stderr. */
- if (!dump_file)
- vect_dump = stderr;
- return;
+ vect_verbosity_level = user_vect_verbosity_level;
+ /* Ignore user defined verbosity if dump flags require higher level of
+ verbosity. */
+ if (dump_file)
+ {
+ if (((dump_flags & TDF_DETAILS)
+ && vect_verbosity_level >= REPORT_DETAILS)
+ || ((dump_flags & TDF_STATS)
+ && vect_verbosity_level >= REPORT_UNVECTORIZED_LOCATIONS))
+ return;
+ }
+ else
+ {
+ /* If there is no dump file, print to stderr in case of loop
+ vectorization. */
+ if (!slp)
+ vect_dump = stderr;
+
+ return;
+ }
}
/* User didn't specify verbosity level: */
@@ -185,11 +201,7 @@ vectorize_loops (void)
return 0;
/* Fix the verbosity level if not defined explicitly by the user. */
- vect_set_dump_settings ();
-
- /* Allocate the bitmap that records which virtual variables
- need to be renamed. */
- vect_memsyms_to_rename = BITMAP_ALLOC (NULL);
+ vect_set_dump_settings (false);
init_stmt_vec_info_vec ();
@@ -225,7 +237,7 @@ vectorize_loops (void)
/* ----------- Finalize. ----------- */
- BITMAP_FREE (vect_memsyms_to_rename);
+ mark_sym_for_renaming (gimple_vop (cfun));
for (i = 1; i < vect_loops_num; i++)
{
@@ -245,6 +257,68 @@ vectorize_loops (void)
}
+/* Entry point to basic block SLP phase. */
+
+static unsigned int
+execute_vect_slp (void)
+{
+ basic_block bb;
+
+ /* Fix the verbosity level if not defined explicitly by the user. */
+ vect_set_dump_settings (true);
+
+ init_stmt_vec_info_vec ();
+
+ FOR_EACH_BB (bb)
+ {
+ vect_location = find_bb_location (bb);
+
+ if (vect_slp_analyze_bb (bb))
+ {
+ vect_slp_transform_bb (bb);
+
+ if (vect_print_dump_info (REPORT_VECTORIZED_LOCATIONS))
+ fprintf (vect_dump, "basic block vectorized using SLP\n");
+ }
+ }
+
+ free_stmt_vec_info_vec ();
+ return 0;
+}
+
+static bool
+gate_vect_slp (void)
+{
+ /* Apply SLP either if the vectorizer is on and the user didn't specify
+ whether to run SLP or not, or if the SLP flag was set by the user. */
+ return ((flag_tree_vectorize != 0 && flag_tree_slp_vectorize != 0)
+ || flag_tree_slp_vectorize == 1);
+}
+
+struct gimple_opt_pass pass_slp_vectorize =
+{
+ {
+ GIMPLE_PASS,
+ "slp", /* name */
+ gate_vect_slp, /* gate */
+ execute_vect_slp, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ TV_TREE_SLP_VECTORIZATION, /* tv_id */
+ PROP_ssa | PROP_cfg, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_ggc_collect
+ | TODO_verify_ssa
+ | TODO_dump_func
+ | TODO_update_ssa
+ | TODO_verify_stmts /* todo_flags_finish */
+ }
+};
+
+
/* Increase alignment of global arrays to improve vectorization potential.
TODO:
- Consider also structs that have an array field.
diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
index 2422f4416e1..6e8f879caf3 100644
--- a/gcc/tree-vectorizer.h
+++ b/gcc/tree-vectorizer.h
@@ -61,6 +61,7 @@ enum vect_def_type {
vect_internal_def,
vect_induction_def,
vect_reduction_def,
+ vect_nested_cycle,
vect_unknown_def_type
};
@@ -239,33 +240,38 @@ typedef struct _loop_vec_info {
} *loop_vec_info;
/* Access Functions. */
-#define LOOP_VINFO_LOOP(L) (L)->loop
-#define LOOP_VINFO_BBS(L) (L)->bbs
-#define LOOP_VINFO_NITERS(L) (L)->num_iters
+#define LOOP_VINFO_LOOP(L) (L)->loop
+#define LOOP_VINFO_BBS(L) (L)->bbs
+#define LOOP_VINFO_NITERS(L) (L)->num_iters
/* Since LOOP_VINFO_NITERS can change after prologue peeling
retain total unchanged scalar loop iterations for cost model. */
-#define LOOP_VINFO_NITERS_UNCHANGED(L) (L)->num_iters_unchanged
-#define LOOP_VINFO_COST_MODEL_MIN_ITERS(L) (L)->min_profitable_iters
-#define LOOP_VINFO_VECTORIZABLE_P(L) (L)->vectorizable
-#define LOOP_VINFO_VECT_FACTOR(L) (L)->vectorization_factor
-#define LOOP_VINFO_PTR_MASK(L) (L)->ptr_mask
-#define LOOP_VINFO_DATAREFS(L) (L)->datarefs
-#define LOOP_VINFO_DDRS(L) (L)->ddrs
-#define LOOP_VINFO_INT_NITERS(L) (TREE_INT_CST_LOW ((L)->num_iters))
-#define LOOP_PEELING_FOR_ALIGNMENT(L) (L)->peeling_for_alignment
-#define LOOP_VINFO_UNALIGNED_DR(L) (L)->unaligned_dr
-#define LOOP_VINFO_MAY_MISALIGN_STMTS(L) (L)->may_misalign_stmts
-#define LOOP_VINFO_LOC(L) (L)->loop_line_number
-#define LOOP_VINFO_MAY_ALIAS_DDRS(L) (L)->may_alias_ddrs
-#define LOOP_VINFO_STRIDED_STORES(L) (L)->strided_stores
-#define LOOP_VINFO_SLP_INSTANCES(L) (L)->slp_instances
+#define LOOP_VINFO_NITERS_UNCHANGED(L) (L)->num_iters_unchanged
+#define LOOP_VINFO_COST_MODEL_MIN_ITERS(L) (L)->min_profitable_iters
+#define LOOP_VINFO_VECTORIZABLE_P(L) (L)->vectorizable
+#define LOOP_VINFO_VECT_FACTOR(L) (L)->vectorization_factor
+#define LOOP_VINFO_PTR_MASK(L) (L)->ptr_mask
+#define LOOP_VINFO_DATAREFS(L) (L)->datarefs
+#define LOOP_VINFO_DDRS(L) (L)->ddrs
+#define LOOP_VINFO_INT_NITERS(L) (TREE_INT_CST_LOW ((L)->num_iters))
+#define LOOP_PEELING_FOR_ALIGNMENT(L) (L)->peeling_for_alignment
+#define LOOP_VINFO_UNALIGNED_DR(L) (L)->unaligned_dr
+#define LOOP_VINFO_MAY_MISALIGN_STMTS(L) (L)->may_misalign_stmts
+#define LOOP_VINFO_LOC(L) (L)->loop_line_number
+#define LOOP_VINFO_MAY_ALIAS_DDRS(L) (L)->may_alias_ddrs
+#define LOOP_VINFO_STRIDED_STORES(L) (L)->strided_stores
+#define LOOP_VINFO_SLP_INSTANCES(L) (L)->slp_instances
#define LOOP_VINFO_SLP_UNROLLING_FACTOR(L) (L)->slp_unrolling_factor
+#define LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT(L) \
+VEC_length (gimple, (L)->may_misalign_stmts) > 0
+#define LOOP_REQUIRES_VERSIONING_FOR_ALIAS(L) \
+VEC_length (ddr_p, (L)->may_alias_ddrs) > 0
+
#define NITERS_KNOWN_P(n) \
(host_integerp ((n),0) \
&& TREE_INT_CST_LOW ((n)) > 0)
-#define LOOP_VINFO_NITERS_KNOWN_P(L) \
+#define LOOP_VINFO_NITERS_KNOWN_P(L) \
NITERS_KNOWN_P((L)->num_iters)
static inline loop_vec_info
@@ -281,6 +287,36 @@ nested_in_vect_loop_p (struct loop *loop, gimple stmt)
&& (loop->inner == (gimple_bb (stmt))->loop_father));
}
+typedef struct _bb_vec_info {
+
+ basic_block bb;
+ /* All interleaving chains of stores in the basic block, represented by the
+ first stmt in the chain. */
+ VEC(gimple, heap) *strided_stores;
+
+ /* All SLP instances in the basic block. This is a subset of the set of
+ STRIDED_STORES of the basic block. */
+ VEC(slp_instance, heap) *slp_instances;
+
+ /* All data references in the basic block. */
+ VEC (data_reference_p, heap) *datarefs;
+
+ /* All data dependences in the basic block. */
+ VEC (ddr_p, heap) *ddrs;
+} *bb_vec_info;
+
+#define BB_VINFO_BB(B) (B)->bb
+#define BB_VINFO_STRIDED_STORES(B) (B)->strided_stores
+#define BB_VINFO_SLP_INSTANCES(B) (B)->slp_instances
+#define BB_VINFO_DATAREFS(B) (B)->datarefs
+#define BB_VINFO_DDRS(B) (B)->ddrs
+
+static inline bb_vec_info
+vec_info_for_bb (basic_block bb)
+{
+ return (bb_vec_info) bb->aux;
+}
+
/*-----------------------------------------------------------------*/
/* Info on vectorized defs. */
/*-----------------------------------------------------------------*/
@@ -304,7 +340,11 @@ enum stmt_vec_info_type {
block. */
enum vect_relevant {
vect_unused_in_scope = 0,
+ /* The def is in the inner loop, and the use is in the outer loop, and the
+ use is a reduction stmt. */
vect_used_in_outer_by_reduction,
+ /* The def is in the inner loop, and the use is in the outer loop (and is
+ not part of reduction). */
vect_used_in_outer,
/* defs that feed computations that end up (only) in a reduction. These
@@ -437,12 +477,16 @@ typedef struct _stmt_vec_info {
/* Whether the stmt is SLPed, loop-based vectorized, or both. */
enum slp_vect_type slp_type;
+
+ /* The bb_vec_info with respect to which STMT is vectorized. */
+ bb_vec_info bb_vinfo;
} *stmt_vec_info;
/* Access Functions. */
#define STMT_VINFO_TYPE(S) (S)->type
#define STMT_VINFO_STMT(S) (S)->stmt
#define STMT_VINFO_LOOP_VINFO(S) (S)->loop_vinfo
+#define STMT_VINFO_BB_VINFO(S) (S)->bb_vinfo
#define STMT_VINFO_RELEVANT(S) (S)->relevant
#define STMT_VINFO_LIVE_P(S) (S)->live
#define STMT_VINFO_VECTYPE(S) (S)->vectype
@@ -694,9 +738,6 @@ known_alignment_for_access_p (struct data_reference *data_ref_info)
extern FILE *vect_dump;
extern LOC vect_loop_location;
-/* Bitmap of virtual variables to be renamed. */
-extern bitmap vect_memsyms_to_rename;
-
/*-----------------------------------------------------------------*/
/* Function prototypes. */
/*-----------------------------------------------------------------*/
@@ -707,15 +748,15 @@ extern void slpeel_make_loop_iterate_ntimes (struct loop *, tree);
extern bool slpeel_can_duplicate_loop_p (const struct loop *, const_edge);
extern void vect_loop_versioning (loop_vec_info, bool, tree *, gimple_seq *);
extern void vect_do_peeling_for_loop_bound (loop_vec_info, tree *,
- tree, gimple_seq);
+ tree, gimple_seq);
extern void vect_do_peeling_for_alignment (loop_vec_info);
extern LOC find_loop_location (struct loop *);
extern bool vect_can_advance_ivs_p (loop_vec_info);
/* In tree-vect-stmts.c. */
extern tree get_vectype_for_scalar_type (tree);
-extern bool vect_is_simple_use (tree, loop_vec_info, gimple *, tree *,
- enum vect_def_type *);
+extern bool vect_is_simple_use (tree, loop_vec_info, bb_vec_info, gimple *,
+ tree *, enum vect_def_type *);
extern bool supportable_widening_operation (enum tree_code, gimple, tree,
tree *, tree *, enum tree_code *,
enum tree_code *, int *,
@@ -723,7 +764,8 @@ extern bool supportable_widening_operation (enum tree_code, gimple, tree,
extern bool supportable_narrowing_operation (enum tree_code, const_gimple,
tree, enum tree_code *, int *,
VEC (tree, heap) **);
-extern stmt_vec_info new_stmt_vec_info (gimple stmt, loop_vec_info);
+extern stmt_vec_info new_stmt_vec_info (gimple stmt, loop_vec_info,
+ bb_vec_info);
extern void free_stmt_vec_info (gimple stmt);
extern tree vectorizable_function (gimple, tree, tree);
extern void vect_model_simple_cost (stmt_vec_info, int, enum vect_def_type *,
@@ -742,7 +784,7 @@ extern tree vect_get_vec_def_for_stmt_copy (enum vect_def_type, tree);
extern bool vect_transform_stmt (gimple, gimple_stmt_iterator *,
bool *, slp_tree, slp_instance);
extern void vect_remove_stores (gimple);
-extern bool vect_analyze_stmt (gimple, bool *);
+extern bool vect_analyze_stmt (gimple, bool *, slp_tree);
/* In tree-vect-data-refs.c. */
extern bool vect_can_force_dr_alignment_p (const_tree, unsigned int);
@@ -750,14 +792,15 @@ extern enum dr_alignment_support vect_supportable_dr_alignment
(struct data_reference *);
extern tree vect_get_smallest_scalar_type (gimple, HOST_WIDE_INT *,
HOST_WIDE_INT *);
-extern bool vect_analyze_data_ref_dependences (loop_vec_info);
+extern bool vect_analyze_data_ref_dependences (loop_vec_info, bb_vec_info);
extern bool vect_enhance_data_refs_alignment (loop_vec_info);
-extern bool vect_analyze_data_refs_alignment (loop_vec_info);
-extern bool vect_analyze_data_ref_accesses (loop_vec_info);
+extern bool vect_analyze_data_refs_alignment (loop_vec_info, bb_vec_info);
+extern bool vect_verify_datarefs_alignment (loop_vec_info, bb_vec_info);
+extern bool vect_analyze_data_ref_accesses (loop_vec_info, bb_vec_info);
extern bool vect_prune_runtime_alias_test_list (loop_vec_info);
-extern bool vect_analyze_data_refs (loop_vec_info);
+extern bool vect_analyze_data_refs (loop_vec_info, bb_vec_info);
extern tree vect_create_data_ref_ptr (gimple, struct loop *, tree, tree *,
- gimple *, bool, bool *);
+ gimple *, bool, bool *);
extern tree bump_vector_ptr (tree, gimple, gimple_stmt_iterator *, gimple, tree);
extern tree vect_create_destination_var (tree, tree);
extern bool vect_strided_store_supported (tree);
@@ -779,7 +822,7 @@ extern tree vect_create_addr_base_for_vector_ref (gimple, gimple_seq *,
/* In tree-vect-loop.c. */
/* FORNOW: Used in tree-parloops.c. */
extern void destroy_loop_vec_info (loop_vec_info, bool);
-extern gimple vect_is_simple_reduction (loop_vec_info, gimple);
+extern gimple vect_is_simple_reduction (loop_vec_info, gimple, bool);
/* Drive for loop analysis stage. */
extern loop_vec_info vect_analyze_loop (struct loop *);
/* Drive for loop transformation stage. */
@@ -799,13 +842,16 @@ extern void vect_free_slp_instance (slp_instance);
extern bool vect_transform_slp_perm_load (gimple, VEC (tree, heap) *,
gimple_stmt_iterator *, int,
slp_instance, bool);
-extern bool vect_schedule_slp (loop_vec_info);
+extern bool vect_schedule_slp (loop_vec_info, bb_vec_info);
extern void vect_update_slp_costs_according_to_vf (loop_vec_info);
-extern bool vect_analyze_slp (loop_vec_info);
+extern bool vect_analyze_slp (loop_vec_info, bb_vec_info);
extern void vect_make_slp_decision (loop_vec_info);
extern void vect_detect_hybrid_slp (loop_vec_info);
extern void vect_get_slp_defs (slp_tree, VEC (tree,heap) **,
VEC (tree,heap) **);
+extern LOC find_bb_location (basic_block);
+extern bb_vec_info vect_slp_analyze_bb (basic_block);
+extern void vect_slp_transform_bb (basic_block);
/* In tree-vect-patterns.c. */
/* Pattern recognition functions.
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 8f1280cfb37..3aafe3327c5 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -121,7 +121,7 @@ DEF_VEC_ALLOC_O(switch_update, heap);
static VEC (switch_update, heap) *to_update_switch_stmts;
-/* Return the maximum value for TYPEs base type. */
+/* Return the maximum value for TYPE. */
static inline tree
vrp_val_max (const_tree type)
@@ -129,14 +129,10 @@ vrp_val_max (const_tree type)
if (!INTEGRAL_TYPE_P (type))
return NULL_TREE;
- /* For integer sub-types the values for the base type are relevant. */
- if (TREE_TYPE (type))
- type = TREE_TYPE (type);
-
return TYPE_MAX_VALUE (type);
}
-/* Return the minimum value for TYPEs base type. */
+/* Return the minimum value for TYPE. */
static inline tree
vrp_val_min (const_tree type)
@@ -144,10 +140,6 @@ vrp_val_min (const_tree type)
if (!INTEGRAL_TYPE_P (type))
return NULL_TREE;
- /* For integer sub-types the values for the base type are relevant. */
- if (TREE_TYPE (type))
- type = TREE_TYPE (type);
-
return TYPE_MIN_VALUE (type);
}
@@ -188,11 +180,7 @@ vrp_val_is_min (const_tree val)
static inline bool
needs_overflow_infinity (const_tree type)
{
- return (INTEGRAL_TYPE_P (type)
- && !TYPE_OVERFLOW_WRAPS (type)
- /* Integer sub-types never overflow as they are never
- operands of arithmetic operators. */
- && !(TREE_TYPE (type) && TREE_TYPE (type) != type));
+ return INTEGRAL_TYPE_P (type) && !TYPE_OVERFLOW_WRAPS (type);
}
/* Return whether TYPE can support our overflow infinity
@@ -2702,13 +2690,6 @@ extract_range_from_unary_expr (value_range_t *vr, enum tree_code code,
tree inner_type = TREE_TYPE (op0);
tree outer_type = type;
- /* Always use base-types here. This is important for the
- correct signedness. */
- if (TREE_TYPE (inner_type))
- inner_type = TREE_TYPE (inner_type);
- if (TREE_TYPE (outer_type))
- outer_type = TREE_TYPE (outer_type);
-
/* If VR0 is varying and we increase the type precision, assume
a full range for the following transformation. */
if (vr0.type == VR_VARYING
@@ -4993,7 +4974,7 @@ insert_range_assertions (void)
IGNORE_OFF_BY_ONE is true if the ARRAY_REF is inside a ADDR_EXPR. */
static void
-check_array_ref (tree ref, location_t location, bool ignore_off_by_one)
+check_array_ref (location_t location, tree ref, bool ignore_off_by_one)
{
value_range_t* vr = NULL;
tree low_sub, up_sub;
@@ -5089,7 +5070,7 @@ search_for_addr_array (tree t, location_t location)
do
{
if (TREE_CODE (t) == ARRAY_REF)
- check_array_ref (t, location, true /*ignore_off_by_one*/);
+ check_array_ref (location, t, true /*ignore_off_by_one*/);
t = TREE_OPERAND (t, 0);
}
@@ -5107,16 +5088,24 @@ check_array_bounds (tree *tp, int *walk_subtree, void *data)
{
tree t = *tp;
struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
- const location_t *location = (const location_t *) wi->info;
+ location_t location;
+
+ if (EXPR_HAS_LOCATION (t))
+ location = EXPR_LOCATION (t);
+ else
+ {
+ location_t *locp = (location_t *) wi->info;
+ location = *locp;
+ }
*walk_subtree = TRUE;
if (TREE_CODE (t) == ARRAY_REF)
- check_array_ref (t, *location, false /*ignore_off_by_one*/);
+ check_array_ref (location, t, false /*ignore_off_by_one*/);
if (TREE_CODE (t) == INDIRECT_REF
|| (TREE_CODE (t) == RETURN_EXPR && TREE_OPERAND (t, 0)))
- search_for_addr_array (TREE_OPERAND (t, 0), *location);
+ search_for_addr_array (TREE_OPERAND (t, 0), location);
if (TREE_CODE (t) == ADDR_EXPR)
*walk_subtree = FALSE;
diff --git a/gcc/tree.c b/gcc/tree.c
index ec4a4952015..d29b6a3e792 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -1827,6 +1827,23 @@ build_tree_list_stat (tree parm, tree value MEM_STAT_DECL)
return t;
}
+/* Build a chain of TREE_LIST nodes from a vector. */
+
+tree
+build_tree_list_vec_stat (const VEC(tree,gc) *vec MEM_STAT_DECL)
+{
+ tree ret = NULL_TREE;
+ tree *pp = &ret;
+ unsigned int i;
+ tree t;
+ for (i = 0; VEC_iterate (tree, vec, i, t); ++i)
+ {
+ *pp = build_tree_list_stat (NULL, t PASS_MEM_STAT);
+ pp = &TREE_CHAIN (*pp);
+ }
+ return ret;
+}
+
/* Return a newly created TREE_LIST node whose
purpose and value fields are PURPOSE and VALUE
and whose TREE_CHAIN is CHAIN. */
@@ -1870,6 +1887,22 @@ ctor_to_list (tree ctor)
return list;
}
+
+/* Return the values of the elements of a CONSTRUCTOR as a vector of
+ trees. */
+
+VEC(tree,gc) *
+ctor_to_vec (tree ctor)
+{
+ VEC(tree, gc) *vec = VEC_alloc (tree, gc, CONSTRUCTOR_NELTS (ctor));
+ unsigned int ix;
+ tree val;
+
+ FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (ctor), ix, val)
+ VEC_quick_push (tree, vec, val);
+
+ return vec;
+}
/* Return the size nominally occupied by an object of type TYPE
when it resides in memory. The value is measured in units of bytes,
@@ -2319,6 +2352,7 @@ save_expr (tree expr)
return t;
t = build1 (SAVE_EXPR, TREE_TYPE (expr), t);
+ SET_EXPR_LOCATION (t, EXPR_LOCATION (expr));
/* This expression might be placed ahead of a jump to ensure that the
value was computed on both sides of the jump. So make sure it isn't
@@ -3482,19 +3516,40 @@ build_nt_call_list (tree fn, tree arglist)
CALL_EXPR_ARG (t, i) = TREE_VALUE (arglist);
return t;
}
+
+/* Similar to build_nt, but for creating a CALL_EXPR object with a
+ tree VEC. */
+
+tree
+build_nt_call_vec (tree fn, VEC(tree,gc) *args)
+{
+ tree ret, t;
+ unsigned int ix;
+
+ ret = build_vl_exp (CALL_EXPR, VEC_length (tree, args) + 3);
+ CALL_EXPR_FN (ret) = fn;
+ CALL_EXPR_STATIC_CHAIN (ret) = NULL_TREE;
+ for (ix = 0; VEC_iterate (tree, args, ix, t); ++ix)
+ CALL_EXPR_ARG (ret, ix) = t;
+ return ret;
+}
/* Create a DECL_... node of code CODE, name NAME and data type TYPE.
We do NOT enter this node in any sort of symbol table.
+ LOC is the location of the decl.
+
layout_decl is used to set up the decl's storage layout.
Other slots are initialized to 0 or null pointers. */
tree
-build_decl_stat (enum tree_code code, tree name, tree type MEM_STAT_DECL)
+build_decl_stat (location_t loc, enum tree_code code, tree name,
+ tree type MEM_STAT_DECL)
{
tree t;
t = make_node_stat (code PASS_MEM_STAT);
+ DECL_SOURCE_LOCATION (t) = loc;
/* if (type == error_mark_node)
type = integer_type_node; */
@@ -3516,7 +3571,7 @@ tree
build_fn_decl (const char *name, tree type)
{
tree id = get_identifier (name);
- tree decl = build_decl (FUNCTION_DECL, id, type);
+ tree decl = build_decl (input_location, FUNCTION_DECL, id, type);
DECL_EXTERNAL (decl) = 1;
TREE_PUBLIC (decl) = 1;
@@ -4024,6 +4079,7 @@ handle_dll_attribute (tree * pnode, tree name, tree args, int flags,
bool *no_add_attrs)
{
tree node = *pnode;
+ bool is_dllimport;
/* These attributes may apply to structure and union types being created,
but otherwise should pass to the declaration involved. */
@@ -4071,9 +4127,11 @@ handle_dll_attribute (tree * pnode, tree name, tree args, int flags,
return NULL_TREE;
}
+ is_dllimport = is_attribute_p ("dllimport", name);
+
/* Report error on dllimport ambiguities seen now before they cause
any damage. */
- else if (is_attribute_p ("dllimport", name))
+ if (is_dllimport)
{
/* Honor any target-specific overrides. */
if (!targetm.valid_dllimport_attribute_p (node))
@@ -4115,6 +4173,10 @@ handle_dll_attribute (tree * pnode, tree name, tree args, int flags,
if (*no_add_attrs == false)
DECL_DLLIMPORT_P (node) = 1;
}
+ else if (TREE_CODE (node) == FUNCTION_DECL
+ && DECL_DECLARED_INLINE_P (node))
+ /* An exported function, even if inline, must be emitted. */
+ DECL_EXTERNAL (node) = 0;
/* Report error if symbol is not accessible at global scope. */
if (!TREE_PUBLIC (node)
@@ -5365,11 +5427,13 @@ iterative_hash_expr (const_tree t, hashval_t val)
return val;
}
case FUNCTION_DECL:
- /* When referring to a built-in FUNCTION_DECL, use the
- __builtin__ form. Otherwise nodes that compare equal
- according to operand_equal_p might get different
- hash codes. */
- if (DECL_BUILT_IN (t) && built_in_decls[DECL_FUNCTION_CODE (t)])
+ /* When referring to a built-in FUNCTION_DECL, use the __builtin__ form.
+ Otherwise nodes that compare equal according to operand_equal_p might
+ get different hash codes. However, don't do this for machine specific
+ or front end builtins, since the function code is overloaded in those
+ cases. */
+ if (DECL_BUILT_IN_CLASS (t) == BUILT_IN_NORMAL
+ && built_in_decls[DECL_FUNCTION_CODE (t)])
{
t = built_in_decls[DECL_FUNCTION_CODE (t)];
code = TREE_CODE (t);
@@ -5695,6 +5759,57 @@ build_range_type (tree type, tree lowval, tree highval)
return itype;
}
+/* Return true if the debug information for TYPE, a subtype, should be emitted
+ as a subrange type. If so, set LOWVAL to the low bound and HIGHVAL to the
+ high bound, respectively. Sometimes doing so unnecessarily obfuscates the
+ debug info and doesn't reflect the source code. */
+
+bool
+subrange_type_for_debug_p (const_tree type, tree *lowval, tree *highval)
+{
+ tree base_type = TREE_TYPE (type), low, high;
+
+ /* Subrange types have a base type which is an integral type. */
+ if (!INTEGRAL_TYPE_P (base_type))
+ return false;
+
+ /* Get the real bounds of the subtype. */
+ if (lang_hooks.types.get_subrange_bounds)
+ lang_hooks.types.get_subrange_bounds (type, &low, &high);
+ else
+ {
+ low = TYPE_MIN_VALUE (type);
+ high = TYPE_MAX_VALUE (type);
+ }
+
+ /* If the type and its base type have the same representation and the same
+ name, then the type is not a subrange but a copy of the base type. */
+ if ((TREE_CODE (base_type) == INTEGER_TYPE
+ || TREE_CODE (base_type) == BOOLEAN_TYPE)
+ && int_size_in_bytes (type) == int_size_in_bytes (base_type)
+ && tree_int_cst_equal (low, TYPE_MIN_VALUE (base_type))
+ && tree_int_cst_equal (high, TYPE_MAX_VALUE (base_type)))
+ {
+ tree type_name = TYPE_NAME (type);
+ tree base_type_name = TYPE_NAME (base_type);
+
+ if (type_name && TREE_CODE (type_name) == TYPE_DECL)
+ type_name = DECL_NAME (type_name);
+
+ if (base_type_name && TREE_CODE (base_type_name) == TYPE_DECL)
+ base_type_name = DECL_NAME (base_type_name);
+
+ if (type_name == base_type_name)
+ return false;
+ }
+
+ if (lowval)
+ *lowval = low;
+ if (highval)
+ *highval = high;
+ return true;
+}
+
/* Just like build_index_type, but takes lowval and highval instead
of just highval (maxval). */
@@ -6225,7 +6340,8 @@ build_complex_type (tree component_type)
name = 0;
if (name != 0)
- TYPE_NAME (t) = build_decl (TYPE_DECL, get_identifier (name), t);
+ TYPE_NAME (t) = build_decl (UNKNOWN_LOCATION, TYPE_DECL,
+ get_identifier (name), t);
}
return build_qualified_type (t, TYPE_QUALS (component_type));
@@ -7146,7 +7262,7 @@ tree_range_check_failed (const_tree node, const char *file, int line,
{
char *buffer;
unsigned length = 0;
- enum tree_code c;
+ unsigned int c;
for (c = c1; c <= c2; ++c)
length += 4 + strlen (tree_code_name[c]);
@@ -7207,7 +7323,7 @@ omp_clause_range_check_failed (const_tree node, const char *file, int line,
{
char *buffer;
unsigned length = 0;
- enum omp_clause_code c;
+ unsigned int c;
for (c = c1; c <= c2; ++c)
length += 4 + strlen (omp_clause_code_name[c]);
@@ -7336,10 +7452,12 @@ make_vector_type (tree innertype, int nunits, enum machine_mode mode)
{
tree index = build_int_cst (NULL_TREE, nunits - 1);
- tree array = build_array_type (innertype, build_index_type (index));
+ tree array = build_array_type (TYPE_MAIN_VARIANT (innertype),
+ build_index_type (index));
tree rt = make_node (RECORD_TYPE);
- TYPE_FIELDS (rt) = build_decl (FIELD_DECL, get_identifier ("f"), array);
+ TYPE_FIELDS (rt) = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
+ get_identifier ("f"), array);
DECL_CONTEXT (TYPE_FIELDS (rt)) = rt;
layout_type (rt);
TYPE_DEBUG_REPRESENTATION_TYPE (t) = rt;
@@ -7810,7 +7928,7 @@ build_common_builtin_nodes (void)
complex. Further, we can do slightly better with folding these
beasties if the real and complex parts of the arguments are separate. */
{
- enum machine_mode mode;
+ int mode;
for (mode = MIN_MODE_COMPLEX_FLOAT; mode <= MAX_MODE_COMPLEX_FLOAT; ++mode)
{
@@ -7819,7 +7937,7 @@ build_common_builtin_nodes (void)
enum built_in_function mcode, dcode;
tree type, inner_type;
- type = lang_hooks.types.type_for_mode (mode, 0);
+ type = lang_hooks.types.type_for_mode ((enum machine_mode) mode, 0);
if (type == NULL)
continue;
inner_type = TREE_TYPE (type);
@@ -8027,19 +8145,22 @@ initializer_zerop (const_tree init)
}
}
-/* Build an empty statement. */
+/* Build an empty statement at location LOC. */
tree
-build_empty_stmt (void)
+build_empty_stmt (location_t loc)
{
- return build1 (NOP_EXPR, void_type_node, size_zero_node);
+ tree t = build1 (NOP_EXPR, void_type_node, size_zero_node);
+ SET_EXPR_LOCATION (t, loc);
+ return t;
}
-/* Build an OpenMP clause with code CODE. */
+/* Build an OpenMP clause with code CODE. LOC is the location of the
+ clause. */
tree
-build_omp_clause (enum omp_clause_code code)
+build_omp_clause (location_t loc, enum omp_clause_code code)
{
tree t;
int size, length;
@@ -8051,6 +8172,7 @@ build_omp_clause (enum omp_clause_code code)
memset (t, 0, size);
TREE_SET_CODE (t, OMP_CLAUSE);
OMP_CLAUSE_SET_CODE (t, code);
+ OMP_CLAUSE_LOCATION (t) = loc;
#ifdef GATHER_STATISTICS
tree_node_counts[(int) omp_clause_kind]++;
@@ -8188,7 +8310,7 @@ build_call_valist (tree return_type, tree fn, int nargs, va_list args)
which are specified as a tree array ARGS. */
tree
-build_call_array (tree return_type, tree fn, int nargs, tree *args)
+build_call_array (tree return_type, tree fn, int nargs, const tree *args)
{
tree t;
int i;
@@ -8203,6 +8325,24 @@ build_call_array (tree return_type, tree fn, int nargs, tree *args)
return t;
}
+/* Like build_call_array, but takes a VEC. */
+
+tree
+build_call_vec (tree return_type, tree fn, VEC(tree,gc) *args)
+{
+ tree ret, t;
+ unsigned int ix;
+
+ ret = build_vl_exp (CALL_EXPR, VEC_length (tree, args) + 3);
+ TREE_TYPE (ret) = return_type;
+ CALL_EXPR_FN (ret) = fn;
+ CALL_EXPR_STATIC_CHAIN (ret) = NULL_TREE;
+ for (ix = 0; VEC_iterate (tree, args, ix, t); ++ix)
+ CALL_EXPR_ARG (ret, ix) = t;
+ process_call_operands (ret);
+ return ret;
+}
+
/* Returns true if it is possible to prove that the index of
an array access REF (an ARRAY_REF expression) falls into the
@@ -8348,6 +8488,36 @@ int_cst_value (const_tree x)
return val;
}
+/* Return value of a constant X and sign-extend it. */
+
+HOST_WIDEST_INT
+widest_int_cst_value (const_tree x)
+{
+ unsigned bits = TYPE_PRECISION (TREE_TYPE (x));
+ unsigned HOST_WIDEST_INT val = TREE_INT_CST_LOW (x);
+
+#if HOST_BITS_PER_WIDEST_INT > HOST_BITS_PER_WIDE_INT
+ gcc_assert (HOST_BITS_PER_WIDEST_INT >= 2 * HOST_BITS_PER_WIDE_INT);
+ val |= (((unsigned HOST_WIDEST_INT) TREE_INT_CST_HIGH (x))
+ << HOST_BITS_PER_WIDE_INT);
+#else
+ /* Make sure the sign-extended value will fit in a HOST_WIDE_INT. */
+ gcc_assert (TREE_INT_CST_HIGH (x) == 0
+ || TREE_INT_CST_HIGH (x) == -1);
+#endif
+
+ if (bits < HOST_BITS_PER_WIDEST_INT)
+ {
+ bool negative = ((val >> (bits - 1)) & 1) != 0;
+ if (negative)
+ val |= (~(unsigned HOST_WIDEST_INT) 0) << (bits - 1) << 1;
+ else
+ val &= ~((~(unsigned HOST_WIDEST_INT) 0) << (bits - 1) << 1);
+ }
+
+ return val;
+}
+
/* If TYPE is an integral type, return an equivalent type which is
unsigned iff UNSIGNEDP is true. If TYPE is not an integral type,
return TYPE itself. */
@@ -8835,10 +9005,6 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, len));
}
- case CHANGE_DYNAMIC_TYPE_EXPR:
- WALK_SUBTREE (CHANGE_DYNAMIC_TYPE_NEW_TYPE (*tp));
- WALK_SUBTREE_TAIL (CHANGE_DYNAMIC_TYPE_LOCATION (*tp));
-
case DECL_EXPR:
/* If this is a TYPE_DECL, walk into the fields of the type that it's
defining. We only want to walk into these fields of a type in this
@@ -8982,13 +9148,15 @@ call_expr_arglist (tree exp)
}
-/* Create a nameless artificial label and put it in the current function
- context. Returns the newly created label. */
+/* Create a nameless artificial label and put it in the current
+ function context. The label has a location of LOC. Returns the
+ newly created label. */
tree
-create_artificial_label (void)
+create_artificial_label (location_t loc)
{
- tree lab = build_decl (LABEL_DECL, NULL_TREE, void_type_node);
+ tree lab = build_decl (loc,
+ LABEL_DECL, NULL_TREE, void_type_node);
DECL_ARTIFICIAL (lab) = 1;
DECL_IGNORED_P (lab) = 1;
@@ -9098,32 +9266,12 @@ block_nonartificial_location (tree block)
location_t
tree_nonartificial_location (tree exp)
{
- tree block = TREE_BLOCK (exp);
+ location_t *loc = block_nonartificial_location (TREE_BLOCK (exp));
- while (block
- && TREE_CODE (block) == BLOCK
- && BLOCK_ABSTRACT_ORIGIN (block))
- {
- tree ao = BLOCK_ABSTRACT_ORIGIN (block);
-
- do
- {
- if (TREE_CODE (ao) == FUNCTION_DECL
- && DECL_DECLARED_INLINE_P (ao)
- && lookup_attribute ("artificial", DECL_ATTRIBUTES (ao)))
- return BLOCK_SOURCE_LOCATION (block);
- else if (TREE_CODE (ao) == BLOCK
- && BLOCK_SUPERCONTEXT (ao) != ao)
- ao = BLOCK_SUPERCONTEXT (ao);
- else
- break;
- }
- while (ao);
-
- block = BLOCK_SUPERCONTEXT (block);
- }
-
- return EXPR_LOCATION (exp);
+ if (loc)
+ return *loc;
+ else
+ return EXPR_LOCATION (exp);
}
diff --git a/gcc/tree.def b/gcc/tree.def
index c002e4b36e8..08f6b7eb505 100644
--- a/gcc/tree.def
+++ b/gcc/tree.def
@@ -913,15 +913,6 @@ DEFTREECODE (CATCH_EXPR, "catch_expr", tcc_statement, 2)
expanding. */
DEFTREECODE (EH_FILTER_EXPR, "eh_filter_expr", tcc_statement, 2)
-/* Indicates a change in the dynamic type of a memory location. This
- has no value and generates no executable code. It is only used for
- type based alias analysis. This is generated by C++ placement new.
- CHANGE_DYNAMIC_TYPE_NEW_TYPE, the first operand, is the new type.
- CHANGE_DYNAMIC_TYPE_LOCATION, the second operand, is the location
- whose type is being changed. */
-DEFTREECODE (CHANGE_DYNAMIC_TYPE_EXPR, "change_dynamic_type_expr",
- tcc_statement, 2)
-
/* Node used for describing a property that is known at compile
time. */
DEFTREECODE (SCEV_KNOWN, "scev_known", tcc_expression, 0)
diff --git a/gcc/tree.h b/gcc/tree.h
index 2064c937a45..2ba7001cdd0 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -373,8 +373,10 @@ struct GTY(()) tree_base {
unsigned lang_flag_6 : 1;
unsigned visited : 1;
+ unsigned packed_flag : 1;
+ unsigned user_align : 1;
- unsigned spare : 23;
+ unsigned spare : 21;
union tree_ann_d *ann;
};
@@ -1502,6 +1504,11 @@ struct GTY(()) tree_vec {
_ce___->value = VALUE; \
} while (0)
+/* True if NODE, a FIELD_DECL, is to be processed as a bitfield for
+ constructor output purposes. */
+#define CONSTRUCTOR_BITFIELD_P(NODE) \
+ (DECL_BIT_FIELD (FIELD_DECL_CHECK (NODE)) && DECL_MODE (NODE) != BLKmode)
+
/* A single element of a CONSTRUCTOR. VALUE holds the actual value of the
element. INDEX can optionally design the position of VALUE: in arrays,
it is the index where VALUE has to be placed; in structures, it is the
@@ -1566,7 +1573,7 @@ struct GTY(()) tree_constructor {
/* True if a tree is an expression or statement that can have a
location. */
-#define CAN_HAVE_LOCATION_P(NODE) (EXPR_P (NODE))
+#define CAN_HAVE_LOCATION_P(NODE) ((NODE) && EXPR_P (NODE))
extern void protected_set_expr_location (tree, location_t);
@@ -1658,12 +1665,6 @@ extern void protected_set_expr_location (tree, location_t);
#define EH_FILTER_MUST_NOT_THROW(NODE) \
(EH_FILTER_EXPR_CHECK (NODE)->base.static_flag)
-/* CHANGE_DYNAMIC_TYPE_EXPR accessors. */
-#define CHANGE_DYNAMIC_TYPE_NEW_TYPE(NODE) \
- TREE_OPERAND (CHANGE_DYNAMIC_TYPE_EXPR_CHECK (NODE), 0)
-#define CHANGE_DYNAMIC_TYPE_LOCATION(NODE) \
- TREE_OPERAND (CHANGE_DYNAMIC_TYPE_EXPR_CHECK (NODE), 1)
-
/* OBJ_TYPE_REF accessors. */
#define OBJ_TYPE_REF_EXPR(NODE) TREE_OPERAND (OBJ_TYPE_REF_CHECK (NODE), 0)
#define OBJ_TYPE_REF_OBJECT(NODE) TREE_OPERAND (OBJ_TYPE_REF_CHECK (NODE), 1)
@@ -1734,6 +1735,9 @@ extern void protected_set_expr_location (tree, location_t);
OMP_CLAUSE_OPERAND (OMP_CLAUSE_RANGE_CHECK (OMP_CLAUSE_CHECK (NODE), \
OMP_CLAUSE_PRIVATE, \
OMP_CLAUSE_COPYPRIVATE), 0)
+#define OMP_CLAUSE_HAS_LOCATION(NODE) \
+ ((OMP_CLAUSE_CHECK (NODE))->omp_clause.locus != UNKNOWN_LOCATION)
+#define OMP_CLAUSE_LOCATION(NODE) (OMP_CLAUSE_CHECK (NODE))->omp_clause.locus
/* True on an OMP_SECTION statement that was the last lexical member.
This status is meaningful in the implementation of lastprivate. */
@@ -1928,6 +1932,7 @@ struct GTY(()) phi_arg_d {
struct GTY(()) tree_omp_clause {
struct tree_common common;
+ location_t locus;
enum omp_clause_code code;
union omp_clause_subcode {
enum omp_clause_default_kind default_kind;
@@ -2119,7 +2124,7 @@ extern enum machine_mode vector_type_mode (const_tree);
/* 1 if the alignment for this type was requested by "aligned" attribute,
0 if it is the default for this type. */
-#define TYPE_USER_ALIGN(NODE) (TYPE_CHECK (NODE)->type.user_align)
+#define TYPE_USER_ALIGN(NODE) (TYPE_CHECK (NODE)->common.base.user_align)
/* The alignment for NODE, in bytes. */
#define TYPE_ALIGN_UNIT(NODE) (TYPE_ALIGN (NODE) / BITS_PER_UNIT)
@@ -2230,7 +2235,7 @@ extern enum machine_mode vector_type_mode (const_tree);
/* Indicated that objects of this type should be laid out in as
compact a way as possible. */
-#define TYPE_PACKED(NODE) (TYPE_CHECK (NODE)->type.packed_flag)
+#define TYPE_PACKED(NODE) (TYPE_CHECK (NODE)->common.base.packed_flag)
/* Used by type_contains_placeholder_p to avoid recomputation.
Values are: 0 (unknown), 1 (false), 2 (true). Never access
@@ -2248,17 +2253,16 @@ struct GTY(()) tree_type {
tree attributes;
unsigned int uid;
- unsigned int precision : 9;
- ENUM_BITFIELD(machine_mode) mode : 7;
-
- unsigned string_flag : 1;
+ unsigned int precision : 10;
unsigned no_force_blk_flag : 1;
unsigned needs_constructing_flag : 1;
unsigned transparent_union_flag : 1;
- unsigned packed_flag : 1;
unsigned restrict_flag : 1;
unsigned contains_placeholder_bits : 2;
+ ENUM_BITFIELD(machine_mode) mode : 8;
+
+ unsigned string_flag : 1;
unsigned lang_flag_0 : 1;
unsigned lang_flag_1 : 1;
unsigned lang_flag_2 : 1;
@@ -2266,7 +2270,6 @@ struct GTY(()) tree_type {
unsigned lang_flag_4 : 1;
unsigned lang_flag_5 : 1;
unsigned lang_flag_6 : 1;
- unsigned user_align : 1;
unsigned int align;
alias_set_type alias_set;
@@ -2520,7 +2523,7 @@ struct GTY(()) tree_decl_minimal {
#define DECL_ALIGN_UNIT(NODE) (DECL_ALIGN (NODE) / BITS_PER_UNIT)
/* Set if the alignment of this DECL has been set by the user, for
example with an 'aligned' attribute. */
-#define DECL_USER_ALIGN(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.user_align)
+#define DECL_USER_ALIGN(NODE) (DECL_COMMON_CHECK (NODE)->common.base.user_align)
/* Holds the machine mode corresponding to the declaration of a variable or
field. Always equal to TYPE_MODE (TREE_TYPE (decl)) except for a
FIELD_DECL. */
@@ -2557,7 +2560,7 @@ struct GTY(()) tree_decl_minimal {
example, for a FUNCTION_DECL, DECL_SAVED_TREE may be non-NULL and
DECL_EXTERNAL may be true simultaneously; that can be the case for
a C99 "extern inline" function. */
-#define DECL_EXTERNAL(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.decl_flag_2)
+#define DECL_EXTERNAL(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.decl_flag_1)
/* Nonzero in a ..._DECL means this variable is ref'd from a nested function.
For VAR_DECL nodes, PARM_DECL nodes, and FUNCTION_DECL nodes.
@@ -2615,11 +2618,6 @@ struct GTY(()) tree_decl_minimal {
#define DECL_GIMPLE_REG_P(DECL) \
DECL_COMMON_CHECK (DECL)->decl_common.gimple_reg_flag
-/* For a DECL with pointer type, this is set if Type Based Alias
- Analysis should not be applied to this DECL. */
-#define DECL_NO_TBAA_P(DECL) \
- DECL_COMMON_CHECK (DECL)->decl_common.no_tbaa_flag
-
struct GTY(()) tree_decl_common {
struct tree_decl_minimal common;
tree size;
@@ -2631,7 +2629,6 @@ struct GTY(()) tree_decl_common {
unsigned ignored_flag : 1;
unsigned abstract_flag : 1;
unsigned artificial_flag : 1;
- unsigned user_align : 1;
unsigned preserve_flag: 1;
unsigned debug_expr_is_from : 1;
@@ -2647,24 +2644,20 @@ struct GTY(()) tree_decl_common {
/* In LABEL_DECL, this is DECL_ERROR_ISSUED.
In VAR_DECL and PARM_DECL, this is DECL_REGISTER. */
unsigned decl_flag_0 : 1;
- /* In FIELD_DECL, this is DECL_PACKED. */
- unsigned decl_flag_1 : 1;
/* In FIELD_DECL, this is DECL_BIT_FIELD
In VAR_DECL and FUNCTION_DECL, this is DECL_EXTERNAL.
- In TYPE_DECL, this is TYPE_DECL_SUPRESS_DEBUG. */
- unsigned decl_flag_2 : 1;
+ In TYPE_DECL, this is TYPE_DECL_SUPPRESS_DEBUG. */
+ unsigned decl_flag_1 : 1;
/* In FIELD_DECL, this is DECL_NONADDRESSABLE_P
- In VAR_DECL and PARM_DECL, this is DECL_HAS_VALUE_EXPR. */
- unsigned decl_flag_3 : 1;
+ In VAR_DECL and PARM_DECL, this is DECL_HAS_VALUE_EXPR_P. */
+ unsigned decl_flag_2 : 1;
/* Logically, these two would go in a theoretical base shared by var and
parm decl. */
unsigned gimple_reg_flag : 1;
- /* In a DECL with pointer type, set if no TBAA should be done. */
- unsigned no_tbaa_flag : 1;
/* In VAR_DECL, PARM_DECL and RESULT_DECL, this is DECL_BY_REFERENCE. */
unsigned decl_by_reference_flag : 1;
/* Padding so that 'off_align' can be on a 32-bit boundary. */
- unsigned decl_common_unused : 1;
+ unsigned decl_common_unused : 4;
/* DECL_OFFSET_ALIGN, used only for FIELD_DECLs. */
unsigned int off_align : 8;
@@ -2690,7 +2683,7 @@ extern void decl_value_expr_insert (tree, tree);
decl itself. This should only be used for debugging; once this field has
been set, the decl itself may not legitimately appear in the function. */
#define DECL_HAS_VALUE_EXPR_P(NODE) \
- (TREE_CHECK2 (NODE, VAR_DECL, PARM_DECL)->decl_common.decl_flag_3)
+ (TREE_CHECK2 (NODE, VAR_DECL, PARM_DECL)->decl_common.decl_flag_2)
#define DECL_VALUE_EXPR(NODE) \
(decl_value_expr_lookup (DECL_WRTL_CHECK (NODE)))
#define SET_DECL_VALUE_EXPR(NODE, VAL) \
@@ -2768,11 +2761,11 @@ struct GTY(()) tree_decl_with_rtl {
#define DECL_FCONTEXT(NODE) (FIELD_DECL_CHECK (NODE)->field_decl.fcontext)
/* In a FIELD_DECL, indicates this field should be bit-packed. */
-#define DECL_PACKED(NODE) (FIELD_DECL_CHECK (NODE)->decl_common.decl_flag_1)
+#define DECL_PACKED(NODE) (FIELD_DECL_CHECK (NODE)->common.base.packed_flag)
/* Nonzero in a FIELD_DECL means it is a bit field, and must be accessed
specially. */
-#define DECL_BIT_FIELD(NODE) (FIELD_DECL_CHECK (NODE)->decl_common.decl_flag_2)
+#define DECL_BIT_FIELD(NODE) (FIELD_DECL_CHECK (NODE)->decl_common.decl_flag_1)
/* Used in a FIELD_DECL to indicate that we cannot form the address of
this component. This makes it possible for Type-Based Alias Analysis
@@ -2790,7 +2783,7 @@ struct GTY(()) tree_decl_with_rtl {
accesses to s.i must not be given the alias set of the type of 'i'
(int) but instead directly that of the type of 's' (struct S). */
#define DECL_NONADDRESSABLE_P(NODE) \
- (FIELD_DECL_CHECK (NODE)->decl_common.decl_flag_3)
+ (FIELD_DECL_CHECK (NODE)->decl_common.decl_flag_2)
struct GTY(()) tree_field_decl {
struct tree_decl_common common;
@@ -2885,6 +2878,8 @@ extern void decl_restrict_base_insert (tree, tree);
something which is DECL_COMDAT. */
#define DECL_COMDAT(NODE) (DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.comdat_flag)
+#define DECL_COMDAT_GROUP(NODE) (DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.comdat_group)
+
/* A replaceable function is one which may be replaced at link-time
with an entirely different definition, provided that the
replacement has the same type. For example, functions declared
@@ -2953,12 +2948,13 @@ extern void decl_restrict_base_insert (tree, tree);
/* Used in TREE_PUBLIC decls to indicate that copies of this DECL in
multiple translation units should be merged. */
-#define DECL_ONE_ONLY(NODE) (DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.one_only)
+#define DECL_ONE_ONLY(NODE) (DECL_COMDAT_GROUP (NODE) != NULL_TREE)
struct GTY(()) tree_decl_with_vis {
struct tree_decl_with_rtl common;
tree assembler_name;
tree section_name;
+ tree comdat_group;
/* Belong to VAR_DECL exclusively. */
unsigned defer_output:1;
@@ -2978,12 +2974,11 @@ struct GTY(()) tree_decl_with_vis {
ENUM_BITFIELD(symbol_visibility) visibility : 2;
unsigned visibility_specified : 1;
/* Belong to FUNCTION_DECL exclusively. */
- unsigned one_only : 1;
unsigned init_priority_p:1;
/* Belongs to VAR_DECL exclusively. */
ENUM_BITFIELD(tls_model) tls_model : 3;
- /* 13 unused bits. */
+ /* 14 unused bits. */
};
/* In a VAR_DECL that's static,
@@ -3260,7 +3255,7 @@ struct GTY(()) tree_function_decl {
into stabs. Instead it will generate cross reference ('x') of names.
This uses the same flag as DECL_EXTERNAL. */
#define TYPE_DECL_SUPPRESS_DEBUG(NODE) \
- (TYPE_DECL_CHECK (NODE)->decl_common.decl_flag_2)
+ (TYPE_DECL_CHECK (NODE)->decl_common.decl_flag_1)
/* Getter of the imported declaration associated to the
IMPORTED_DECL node. */
@@ -3843,6 +3838,7 @@ extern tree maybe_get_identifier (const char *);
extern tree build_nt (enum tree_code, ...);
extern tree build_nt_call_list (tree, tree);
+extern tree build_nt_call_vec (tree, VEC(tree,gc) *);
extern tree build0_stat (enum tree_code, tree MEM_STAT_DECL);
#define build0(c,t) build0_stat (c,t MEM_STAT_INFO)
@@ -3884,12 +3880,15 @@ extern tree build_one_cst (tree);
extern tree build_string (int, const char *);
extern tree build_tree_list_stat (tree, tree MEM_STAT_DECL);
#define build_tree_list(t,q) build_tree_list_stat(t,q MEM_STAT_INFO)
-extern tree build_decl_stat (enum tree_code, tree, tree MEM_STAT_DECL);
+extern tree build_tree_list_vec_stat (const VEC(tree,gc) * MEM_STAT_DECL);
+#define build_tree_list_vec(v) build_tree_list_vec_stat (v MEM_STAT_INFO)
+extern tree build_decl_stat (location_t, enum tree_code,
+ tree, tree MEM_STAT_DECL);
extern tree build_fn_decl (const char *, tree);
-#define build_decl(c,t,q) build_decl_stat (c,t,q MEM_STAT_INFO)
+#define build_decl(l,c,t,q) build_decl_stat (l,c,t,q MEM_STAT_INFO)
extern tree build_block (tree, tree, tree, tree);
-extern tree build_empty_stmt (void);
-extern tree build_omp_clause (enum omp_clause_code);
+extern tree build_empty_stmt (location_t);
+extern tree build_omp_clause (location_t, enum omp_clause_code);
extern tree build_vl_exp_stat (enum tree_code, int MEM_STAT_DECL);
#define build_vl_exp(c,n) build_vl_exp_stat (c,n MEM_STAT_INFO)
@@ -3897,7 +3896,8 @@ extern tree build_vl_exp_stat (enum tree_code, int MEM_STAT_DECL);
extern tree build_call_list (tree, tree, tree);
extern tree build_call_nary (tree, tree, int, ...);
extern tree build_call_valist (tree, tree, int, va_list);
-extern tree build_call_array (tree, tree, int, tree*);
+extern tree build_call_array (tree, tree, int, const tree *);
+extern tree build_call_vec (tree, tree, VEC(tree,gc) *);
/* Construct various nodes representing data types. */
@@ -4324,6 +4324,10 @@ extern bool initializer_zerop (const_tree);
extern tree ctor_to_list (tree);
+/* Given a CONSTRUCTOR CTOR, return the element values as a vector. */
+
+extern VEC(tree,gc) *ctor_to_vec (tree);
+
/* Examine CTOR to discover:
* how many scalar fields are set to nonzero values,
and place it in *P_NZ_ELTS;
@@ -4636,7 +4640,7 @@ extern int operand_equal_for_phi_arg_p (const_tree, const_tree);
extern tree call_expr_arg (tree, int);
extern tree *call_expr_argp (tree, int);
extern tree call_expr_arglist (tree);
-extern tree create_artificial_label (void);
+extern tree create_artificial_label (location_t);
extern const char *get_name (tree);
extern bool stdarg_p (tree);
extern bool prototype_p (tree);
@@ -4834,6 +4838,10 @@ extern bool is_builtin_name (const char*);
extern int get_object_alignment (tree, unsigned int, unsigned int);
extern tree fold_call_stmt (gimple, bool);
extern tree gimple_fold_builtin_snprintf_chk (gimple, tree, enum built_in_function);
+extern tree make_range (tree, int *, tree *, tree *, bool *);
+extern tree build_range_check (tree, tree, int, tree, tree);
+extern bool merge_ranges (int *, tree *, tree *, int, tree, tree, int,
+ tree, tree);
/* In convert.c */
extern tree strip_float_extensions (tree);
@@ -4874,7 +4882,9 @@ extern void build_common_tree_nodes_2 (int);
extern void build_common_builtin_nodes (void);
extern tree build_nonstandard_integer_type (unsigned HOST_WIDE_INT, int);
extern tree build_range_type (tree, tree, tree);
+extern bool subrange_type_for_debug_p (const_tree, tree *, tree *);
extern HOST_WIDE_INT int_cst_value (const_tree);
+extern HOST_WIDEST_INT widest_int_cst_value (const_tree);
extern bool fields_compatible_p (const_tree, const_tree);
extern tree find_compatible_field (tree, tree);
@@ -5001,7 +5011,7 @@ extern unsigned int update_alignment_for_field (record_layout_info, tree,
unsigned int);
/* varasm.c */
extern void make_decl_rtl (tree);
-extern void make_decl_one_only (tree);
+extern void make_decl_one_only (tree, tree);
extern int supports_one_only (void);
extern void resolve_unique_section (tree, int, int);
extern void mark_referenced (tree);
@@ -5034,7 +5044,7 @@ extern tree tree_overlaps_hard_reg_set (tree, HARD_REG_SET *);
/* Generate a new label for the CFI info to refer to. */
-extern char *dwarf2out_cfi_label (void);
+extern char *dwarf2out_cfi_label (bool);
/* Entry point to update the canonical frame address (CFA). */
@@ -5181,9 +5191,9 @@ struct GTY(()) tree_priority_map {
#define tree_priority_map_marked_p tree_map_base_marked_p
/* In tree-ssa-ccp.c */
-extern tree maybe_fold_offset_to_reference (tree, tree, tree);
-extern tree maybe_fold_offset_to_address (tree, tree, tree);
-extern tree maybe_fold_stmt_addition (tree, tree, tree);
+extern tree maybe_fold_offset_to_reference (location_t, tree, tree, tree);
+extern tree maybe_fold_offset_to_address (location_t, tree, tree, tree);
+extern tree maybe_fold_stmt_addition (location_t, tree, tree, tree);
/* In tree-ssa-address.c. */
extern tree tree_mem_ref_addr (tree, tree);
@@ -5204,6 +5214,9 @@ extern unsigned HOST_WIDE_INT highest_pow2_factor (const_tree);
void init_inline_once (void);
+/* In ipa-reference.c. Used for parsing attributes of asm code. */
+extern GTY(()) tree memory_identifier_string;
+
/* Compute the number of operands in an expression node NODE. For
tcc_vl_exp nodes like CALL_EXPRs, this is stored in the node itself,
otherwise it is looked up from the node's code. */
diff --git a/gcc/unwind-dw2-fde.c b/gcc/unwind-dw2-fde.c
index fcac25f7259..4aa9d82af8d 100644
--- a/gcc/unwind-dw2-fde.c
+++ b/gcc/unwind-dw2-fde.c
@@ -318,8 +318,9 @@ static int
fde_unencoded_compare (struct object *ob __attribute__((unused)),
const fde *x, const fde *y)
{
- const _Unwind_Ptr x_ptr = *(const _Unwind_Ptr *) x->pc_begin;
- const _Unwind_Ptr y_ptr = *(const _Unwind_Ptr *) y->pc_begin;
+ _Unwind_Ptr x_ptr, y_ptr;
+ memcpy (&x_ptr, x->pc_begin, sizeof (_Unwind_Ptr));
+ memcpy (&y_ptr, y->pc_begin, sizeof (_Unwind_Ptr));
if (x_ptr > y_ptr)
return 1;
@@ -674,7 +675,9 @@ add_fdes (struct object *ob, struct fde_accumulator *accu, const fde *this_fde)
if (encoding == DW_EH_PE_absptr)
{
- if (*(const _Unwind_Ptr *) this_fde->pc_begin == 0)
+ _Unwind_Ptr ptr;
+ memcpy (&ptr, this_fde->pc_begin, sizeof (_Unwind_Ptr));
+ if (ptr == 0)
continue;
}
else
@@ -792,8 +795,9 @@ linear_search_fdes (struct object *ob, const fde *this_fde, void *pc)
if (encoding == DW_EH_PE_absptr)
{
- pc_begin = ((const _Unwind_Ptr *) this_fde->pc_begin)[0];
- pc_range = ((const _Unwind_Ptr *) this_fde->pc_begin)[1];
+ const _Unwind_Ptr *pc_array = (const _Unwind_Ptr *) this_fde->pc_begin;
+ pc_begin = pc_array[0];
+ pc_range = pc_array[1];
if (pc_begin == 0)
continue;
}
@@ -840,8 +844,10 @@ binary_search_unencoded_fdes (struct object *ob, void *pc)
{
size_t i = (lo + hi) / 2;
const fde *const f = vec->array[i];
- const void *pc_begin = ((const void *const*) f->pc_begin)[0];
- const uaddr pc_range = ((const uaddr *) f->pc_begin)[1];
+ void *pc_begin;
+ uaddr pc_range;
+ memcpy (&pc_begin, (const void * const *) f->pc_begin, sizeof (void *));
+ memcpy (&pc_range, (const uaddr *) f->pc_begin + 1, sizeof (uaddr));
if (pc < pc_begin)
hi = i;
diff --git a/gcc/unwind-dw2.c b/gcc/unwind-dw2.c
index dd3dd549cd1..68a1a282b34 100644
--- a/gcc/unwind-dw2.c
+++ b/gcc/unwind-dw2.c
@@ -1473,18 +1473,31 @@ uw_init_context_1 (struct _Unwind_Context *context,
context->ra = __builtin_extract_return_addr (outer_ra);
}
+static void _Unwind_DebugHook (void *, void *) __attribute__ ((__noinline__));
+
+/* This function is called during unwinding. It is intended as a hook
+ for a debugger to intercept exceptions. CFA is the CFA of the
+ target frame. HANDLER is the PC to which control will be
+ transferred. */
+static void
+_Unwind_DebugHook (void *cfa __attribute__ ((__unused__)),
+ void *handler __attribute__ ((__unused__)))
+{
+ asm ("");
+}
/* Install TARGET into CURRENT so that we can return to it. This is a
macro because __builtin_eh_return must be invoked in the context of
our caller. */
-#define uw_install_context(CURRENT, TARGET) \
- do \
- { \
- long offset = uw_install_context_1 ((CURRENT), (TARGET)); \
- void *handler = __builtin_frob_return_addr ((TARGET)->ra); \
- __builtin_eh_return (offset, handler); \
- } \
+#define uw_install_context(CURRENT, TARGET) \
+ do \
+ { \
+ long offset = uw_install_context_1 ((CURRENT), (TARGET)); \
+ void *handler = __builtin_frob_return_addr ((TARGET)->ra); \
+ _Unwind_DebugHook ((TARGET)->cfa, handler); \
+ __builtin_eh_return (offset, handler); \
+ } \
while (0)
static long
diff --git a/gcc/varasm.c b/gcc/varasm.c
index c85cf9ddf27..c749f959c78 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -114,7 +114,6 @@ static void output_constant_def_contents (rtx);
static void output_addressed_constants (tree);
static unsigned HOST_WIDE_INT array_size_for_constructor (tree);
static unsigned min_align (unsigned, unsigned);
-static void output_constructor (tree, unsigned HOST_WIDE_INT, unsigned int);
static void globalize_decl (tree);
#ifdef BSS_SECTION_ASM_OP
#ifdef ASM_OUTPUT_BSS
@@ -240,24 +239,28 @@ default_emutls_var_fields (tree type, tree *name ATTRIBUTE_UNUSED)
{
tree word_type_node, field, next_field;
- field = build_decl (FIELD_DECL, get_identifier ("__templ"), ptr_type_node);
+ field = build_decl (UNKNOWN_LOCATION,
+ FIELD_DECL, get_identifier ("__templ"), ptr_type_node);
DECL_CONTEXT (field) = type;
next_field = field;
- field = build_decl (FIELD_DECL, get_identifier ("__offset"),
+ field = build_decl (UNKNOWN_LOCATION,
+ FIELD_DECL, get_identifier ("__offset"),
ptr_type_node);
DECL_CONTEXT (field) = type;
TREE_CHAIN (field) = next_field;
next_field = field;
word_type_node = lang_hooks.types.type_for_mode (word_mode, 1);
- field = build_decl (FIELD_DECL, get_identifier ("__align"),
+ field = build_decl (UNKNOWN_LOCATION,
+ FIELD_DECL, get_identifier ("__align"),
word_type_node);
DECL_CONTEXT (field) = type;
TREE_CHAIN (field) = next_field;
next_field = field;
- field = build_decl (FIELD_DECL, get_identifier ("__size"), word_type_node);
+ field = build_decl (UNKNOWN_LOCATION,
+ FIELD_DECL, get_identifier ("__size"), word_type_node);
DECL_CONTEXT (field) = type;
TREE_CHAIN (field) = next_field;
@@ -281,7 +284,8 @@ get_emutls_object_type (void)
field = targetm.emutls.var_fields (type, &type_name);
if (!type_name)
type_name = get_identifier ("__emutls_object");
- type_name = build_decl (TYPE_DECL, type_name, type);
+ type_name = build_decl (UNKNOWN_LOCATION,
+ TYPE_DECL, type_name, type);
TYPE_NAME (type) = type_name;
TYPE_FIELDS (type) = field;
layout_type (type);
@@ -310,7 +314,8 @@ get_emutls_init_templ_addr (tree decl)
name = prefix_name (prefix, name);
}
- to = build_decl (VAR_DECL, name, TREE_TYPE (decl));
+ to = build_decl (DECL_SOURCE_LOCATION (decl),
+ VAR_DECL, name, TREE_TYPE (decl));
SET_DECL_ASSEMBLER_NAME (to, DECL_NAME (to));
DECL_TLS_MODEL (to) = TLS_MODEL_EMULATED;
DECL_ARTIFICIAL (to) = 1;
@@ -323,7 +328,7 @@ get_emutls_init_templ_addr (tree decl)
DECL_WEAK (to) = DECL_WEAK (decl);
if (DECL_ONE_ONLY (decl))
{
- make_decl_one_only (to);
+ make_decl_one_only (to, DECL_ASSEMBLER_NAME (to));
TREE_STATIC (to) = TREE_STATIC (decl);
TREE_PUBLIC (to) = TREE_PUBLIC (decl);
DECL_VISIBILITY (to) = DECL_VISIBILITY (decl);
@@ -370,7 +375,8 @@ emutls_decl (tree decl)
to = h->to;
else
{
- to = build_decl (VAR_DECL, get_emutls_object_name (name),
+ to = build_decl (DECL_SOURCE_LOCATION (decl),
+ VAR_DECL, get_emutls_object_name (name),
get_emutls_object_type ());
h = GGC_NEW (struct tree_map);
@@ -385,7 +391,7 @@ emutls_decl (tree decl)
TREE_READONLY (to) = 0;
SET_DECL_ASSEMBLER_NAME (to, DECL_NAME (to));
if (DECL_ONE_ONLY (decl))
- make_decl_one_only (to);
+ make_decl_one_only (to, DECL_ASSEMBLER_NAME (to));
DECL_CONTEXT (to) = DECL_CONTEXT (decl);
if (targetm.emutls.var_align_fixed)
/* If we're not allowed to change the proxy object's
@@ -4366,6 +4372,55 @@ initializer_constant_valid_p (tree value, tree endtype)
return 0;
}
+/* Return true if VALUE is a valid constant-valued expression
+ for use in initializing a static bit-field; one that can be
+ an element of a "constant" initializer. */
+
+bool
+initializer_constant_valid_for_bitfield_p (tree value)
+{
+ /* For bitfields we support integer constants or possibly nested aggregates
+ of such. */
+ switch (TREE_CODE (value))
+ {
+ case CONSTRUCTOR:
+ {
+ unsigned HOST_WIDE_INT idx;
+ tree elt;
+
+ FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (value), idx, elt)
+ if (!initializer_constant_valid_for_bitfield_p (elt))
+ return false;
+ return true;
+ }
+
+ case INTEGER_CST:
+ return true;
+
+ case VIEW_CONVERT_EXPR:
+ case NON_LVALUE_EXPR:
+ return
+ initializer_constant_valid_for_bitfield_p (TREE_OPERAND (value, 0));
+
+ default:
+ break;
+ }
+
+ return false;
+}
+
+/* output_constructor outer state of relevance in recursive calls, typically
+ for nested aggregate bitfields. */
+
+typedef struct {
+ unsigned int bit_offset; /* current position in ... */
+ int byte; /* ... the outer byte buffer. */
+} oc_outer_state;
+
+static unsigned HOST_WIDE_INT
+ output_constructor (tree, unsigned HOST_WIDE_INT, unsigned int,
+ oc_outer_state *);
+
/* Output assembler code for constant EXP to FILE, with no label.
This includes the pseudo-op such as ".int" or ".byte", and a newline.
Assumes output_addressed_constants has been done on EXP already.
@@ -4504,7 +4559,7 @@ output_constant (tree exp, unsigned HOST_WIDE_INT size, unsigned int align)
switch (TREE_CODE (exp))
{
case CONSTRUCTOR:
- output_constructor (exp, size, align);
+ output_constructor (exp, size, align, NULL);
return;
case STRING_CST:
thissize = MIN ((unsigned HOST_WIDE_INT)TREE_STRING_LENGTH (exp),
@@ -4542,7 +4597,7 @@ output_constant (tree exp, unsigned HOST_WIDE_INT size, unsigned int align)
case RECORD_TYPE:
case UNION_TYPE:
gcc_assert (TREE_CODE (exp) == CONSTRUCTOR);
- output_constructor (exp, size, align);
+ output_constructor (exp, size, align, NULL);
return;
case ERROR_MARK:
@@ -4598,316 +4653,462 @@ array_size_for_constructor (tree val)
return tree_low_cst (i, 1);
}
-/* Subroutine of output_constant, used for CONSTRUCTORs (aggregate constants).
- Generate at least SIZE bytes, padding if necessary. */
+/* Other datastructures + helpers for output_constructor. */
-static void
-output_constructor (tree exp, unsigned HOST_WIDE_INT size,
- unsigned int align)
-{
- tree type = TREE_TYPE (exp);
- tree field = 0;
- tree min_index = 0;
- /* Number of bytes output or skipped so far.
- In other words, current position within the constructor. */
- HOST_WIDE_INT total_bytes = 0;
- /* Nonzero means BYTE contains part of a byte, to be output. */
- int byte_buffer_in_use = 0;
- int byte = 0;
- unsigned HOST_WIDE_INT cnt;
- constructor_elt *ce;
+/* output_constructor local state to support interaction with helpers. */
- gcc_assert (HOST_BITS_PER_WIDE_INT >= BITS_PER_UNIT);
+typedef struct {
- if (TREE_CODE (type) == RECORD_TYPE)
- field = TYPE_FIELDS (type);
+ /* Received arguments. */
+ tree exp; /* Constructor expression. */
+ unsigned HOST_WIDE_INT size; /* # bytes to output - pad if necessary. */
+ unsigned int align; /* Known initial alignment. */
- if (TREE_CODE (type) == ARRAY_TYPE
- && TYPE_DOMAIN (type) != 0)
- min_index = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
+ /* Constructor expression data. */
+ tree type; /* Expression type. */
+ tree field; /* Current field decl in a record. */
+ tree min_index; /* Lower bound if specified for an array. */
- /* As LINK goes through the elements of the constant,
- FIELD goes through the structure fields, if the constant is a structure.
- if the constant is a union, then we override this,
- by getting the field from the TREE_LIST element.
- But the constant could also be an array. Then FIELD is zero.
+ /* Output processing state. */
+ HOST_WIDE_INT total_bytes; /* # bytes output so far / current position. */
+ bool byte_buffer_in_use; /* Whether byte ... */
+ int byte; /* ... contains part of a bitfield byte yet to
+ be output. */
- There is always a maximum of one element in the chain LINK for unions
- (even if the initializer in a source program incorrectly contains
- more one). */
- for (cnt = 0;
- VEC_iterate (constructor_elt, CONSTRUCTOR_ELTS (exp), cnt, ce);
- cnt++, field = field ? TREE_CHAIN (field) : 0)
+ int last_relative_index; /* Implicit or explicit index of the last
+ array element output within a bitfield. */
+ /* Current element. */
+ tree val; /* Current element value. */
+ tree index; /* Current element index. */
+
+} oc_local_state;
+
+/* Helper for output_constructor. From the current LOCAL state, output a
+ RANGE_EXPR element. */
+
+static void
+output_constructor_array_range (oc_local_state *local)
+{
+ unsigned HOST_WIDE_INT fieldsize
+ = int_size_in_bytes (TREE_TYPE (local->type));
+
+ HOST_WIDE_INT lo_index
+ = tree_low_cst (TREE_OPERAND (local->index, 0), 0);
+ HOST_WIDE_INT hi_index
+ = tree_low_cst (TREE_OPERAND (local->index, 1), 0);
+ HOST_WIDE_INT index;
+
+ unsigned int align2
+ = min_align (local->align, fieldsize * BITS_PER_UNIT);
+
+ for (index = lo_index; index <= hi_index; index++)
{
- tree val = ce->value;
- tree index = 0;
+ /* Output the element's initial value. */
+ if (local->val == NULL_TREE)
+ assemble_zeros (fieldsize);
+ else
+ output_constant (local->val, fieldsize, align2);
+
+ /* Count its size. */
+ local->total_bytes += fieldsize;
+ }
+}
- /* The element in a union constructor specifies the proper field
- or index. */
- if ((TREE_CODE (type) == RECORD_TYPE || TREE_CODE (type) == UNION_TYPE
- || TREE_CODE (type) == QUAL_UNION_TYPE)
- && ce->index != 0)
- field = ce->index;
+/* Helper for output_constructor. From the current LOCAL state, output a
+ field element that is not true bitfield or part of an outer one. */
- else if (TREE_CODE (type) == ARRAY_TYPE)
- index = ce->index;
+static void
+output_constructor_regular_field (oc_local_state *local)
+{
+ /* Field size and position. Since this structure is static, we know the
+ positions are constant. */
+ unsigned HOST_WIDE_INT fieldsize;
+ HOST_WIDE_INT fieldpos;
-#ifdef ASM_COMMENT_START
- if (field && flag_verbose_asm)
- fprintf (asm_out_file, "%s %s:\n",
- ASM_COMMENT_START,
- DECL_NAME (field)
- ? IDENTIFIER_POINTER (DECL_NAME (field))
- : "<anonymous>");
-#endif
+ unsigned int align2;
- /* Eliminate the marker that makes a cast not be an lvalue. */
- if (val != 0)
- STRIP_NOPS (val);
+ if (local->index != NULL_TREE)
+ fieldpos = (tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (local->val)), 1)
+ * ((tree_low_cst (local->index, 0)
+ - tree_low_cst (local->min_index, 0))));
+ else if (local->field != NULL_TREE)
+ fieldpos = int_byte_position (local->field);
+ else
+ fieldpos = 0;
+
+ /* Output any buffered-up bit-fields preceding this element. */
+ if (local->byte_buffer_in_use)
+ {
+ assemble_integer (GEN_INT (local->byte), 1, BITS_PER_UNIT, 1);
+ local->total_bytes++;
+ local->byte_buffer_in_use = false;
+ }
+
+ /* Advance to offset of this element.
+ Note no alignment needed in an array, since that is guaranteed
+ if each element has the proper size. */
+ if ((local->field != NULL_TREE || local->index != NULL_TREE)
+ && fieldpos != local->total_bytes)
+ {
+ gcc_assert (fieldpos >= local->total_bytes);
+ assemble_zeros (fieldpos - local->total_bytes);
+ local->total_bytes = fieldpos;
+ }
+
+ /* Find the alignment of this element. */
+ align2 = min_align (local->align, BITS_PER_UNIT * fieldpos);
- if (index && TREE_CODE (index) == RANGE_EXPR)
+ /* Determine size this element should occupy. */
+ if (local->field)
+ {
+ fieldsize = 0;
+
+ /* If this is an array with an unspecified upper bound,
+ the initializer determines the size. */
+ /* ??? This ought to only checked if DECL_SIZE_UNIT is NULL,
+ but we cannot do this until the deprecated support for
+ initializing zero-length array members is removed. */
+ if (TREE_CODE (TREE_TYPE (local->field)) == ARRAY_TYPE
+ && TYPE_DOMAIN (TREE_TYPE (local->field))
+ && ! TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (local->field))))
{
- unsigned HOST_WIDE_INT fieldsize
- = int_size_in_bytes (TREE_TYPE (type));
- HOST_WIDE_INT lo_index = tree_low_cst (TREE_OPERAND (index, 0), 0);
- HOST_WIDE_INT hi_index = tree_low_cst (TREE_OPERAND (index, 1), 0);
- HOST_WIDE_INT index;
- unsigned int align2 = min_align (align, fieldsize * BITS_PER_UNIT);
-
- for (index = lo_index; index <= hi_index; index++)
- {
- /* Output the element's initial value. */
- if (val == 0)
- assemble_zeros (fieldsize);
- else
- output_constant (val, fieldsize, align2);
-
- /* Count its size. */
- total_bytes += fieldsize;
- }
+ fieldsize = array_size_for_constructor (local->val);
+ /* Given a non-empty initialization, this field had
+ better be last. */
+ gcc_assert (!fieldsize || !TREE_CHAIN (local->field));
}
- else if (field == 0 || !DECL_BIT_FIELD (field))
+ else if (DECL_SIZE_UNIT (local->field))
{
- /* An element that is not a bit-field. */
+ /* ??? This can't be right. If the decl size overflows
+ a host integer we will silently emit no data. */
+ if (host_integerp (DECL_SIZE_UNIT (local->field), 1))
+ fieldsize = tree_low_cst (DECL_SIZE_UNIT (local->field), 1);
+ }
+ }
+ else
+ fieldsize = int_size_in_bytes (TREE_TYPE (local->type));
+
+ /* Output the element's initial value. */
+ if (local->val == NULL_TREE)
+ assemble_zeros (fieldsize);
+ else
+ output_constant (local->val, fieldsize, align2);
- unsigned HOST_WIDE_INT fieldsize;
- /* Since this structure is static,
- we know the positions are constant. */
- HOST_WIDE_INT pos = field ? int_byte_position (field) : 0;
- unsigned int align2;
+ /* Count its size. */
+ local->total_bytes += fieldsize;
+}
- if (index != 0)
- pos = (tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (val)), 1)
- * (tree_low_cst (index, 0) - tree_low_cst (min_index, 0)));
+/* Helper for output_constructor. From the current LOCAL and OUTER states,
+ output an element that is a true bitfield or part of an outer one. */
- /* Output any buffered-up bit-fields preceding this element. */
- if (byte_buffer_in_use)
- {
- assemble_integer (GEN_INT (byte), 1, BITS_PER_UNIT, 1);
- total_bytes++;
- byte_buffer_in_use = 0;
- }
-
- /* Advance to offset of this element.
- Note no alignment needed in an array, since that is guaranteed
- if each element has the proper size. */
- if ((field != 0 || index != 0) && pos != total_bytes)
- {
- gcc_assert (pos >= total_bytes);
- assemble_zeros (pos - total_bytes);
- total_bytes = pos;
- }
+static void
+output_constructor_bitfield (oc_local_state *local, oc_outer_state *outer)
+{
+ /* Bit size of this element. */
+ HOST_WIDE_INT ebitsize
+ = (local->field
+ ? tree_low_cst (DECL_SIZE (local->field), 1)
+ : tree_low_cst (TYPE_SIZE (TREE_TYPE (local->type)), 1));
+
+ /* Relative index of this element if this is an array component. */
+ HOST_WIDE_INT relative_index
+ = (!local->field
+ ? (local->index
+ ? (tree_low_cst (local->index, 0)
+ - tree_low_cst (local->min_index, 0))
+ : local->last_relative_index + 1)
+ : 0);
+
+ /* Bit position of this element from the start of the containing
+ constructor. */
+ HOST_WIDE_INT constructor_relative_ebitpos
+ = (local->field
+ ? int_bit_position (local->field)
+ : ebitsize * relative_index);
+
+ /* Bit position of this element from the start of a possibly ongoing
+ outer byte buffer. */
+ HOST_WIDE_INT byte_relative_ebitpos
+ = ((outer ? outer->bit_offset : 0) + constructor_relative_ebitpos);
+
+ /* From the start of a possibly ongoing outer byte buffer, offsets to
+ the first bit of this element and to the first bit past the end of
+ this element. */
+ HOST_WIDE_INT next_offset = byte_relative_ebitpos;
+ HOST_WIDE_INT end_offset = byte_relative_ebitpos + ebitsize;
+
+ local->last_relative_index = relative_index;
+
+ if (local->val == NULL_TREE)
+ local->val = integer_zero_node;
+
+ while (TREE_CODE (local->val) == VIEW_CONVERT_EXPR
+ || TREE_CODE (local->val) == NON_LVALUE_EXPR)
+ local->val = TREE_OPERAND (local->val, 0);
+
+ if (TREE_CODE (local->val) != INTEGER_CST
+ && TREE_CODE (local->val) != CONSTRUCTOR)
+ {
+ error ("invalid initial value for member %qE", DECL_NAME (local->field));
+ return;
+ }
- /* Find the alignment of this element. */
- align2 = min_align (align, BITS_PER_UNIT * pos);
+ /* If this field does not start in this (or, next) byte,
+ skip some bytes. */
+ if (next_offset / BITS_PER_UNIT != local->total_bytes)
+ {
+ /* Output remnant of any bit field in previous bytes. */
+ if (local->byte_buffer_in_use)
+ {
+ assemble_integer (GEN_INT (local->byte), 1, BITS_PER_UNIT, 1);
+ local->total_bytes++;
+ local->byte_buffer_in_use = false;
+ }
+
+ /* If still not at proper byte, advance to there. */
+ if (next_offset / BITS_PER_UNIT != local->total_bytes)
+ {
+ gcc_assert (next_offset / BITS_PER_UNIT >= local->total_bytes);
+ assemble_zeros (next_offset / BITS_PER_UNIT - local->total_bytes);
+ local->total_bytes = next_offset / BITS_PER_UNIT;
+ }
+ }
+
+ /* Set up the buffer if necessary. */
+ if (!local->byte_buffer_in_use)
+ {
+ local->byte = 0;
+ if (ebitsize > 0)
+ local->byte_buffer_in_use = true;
+ }
+
+ /* If this is nested constructor, recurse passing the bit offset and the
+ pending data, then retrieve the new pending data afterwards. */
+ if (TREE_CODE (local->val) == CONSTRUCTOR)
+ {
+ oc_outer_state output_state;
- /* Determine size this element should occupy. */
- if (field)
+ output_state.bit_offset = next_offset % BITS_PER_UNIT;
+ output_state.byte = local->byte;
+ local->total_bytes
+ += output_constructor (local->val, 0, 0, &output_state);
+ local->byte = output_state.byte;
+ return;
+ }
+
+ /* Otherwise, we must split the element into pieces that fall within
+ separate bytes, and combine each byte with previous or following
+ bit-fields. */
+ while (next_offset < end_offset)
+ {
+ int this_time;
+ int shift;
+ HOST_WIDE_INT value;
+ HOST_WIDE_INT next_byte = next_offset / BITS_PER_UNIT;
+ HOST_WIDE_INT next_bit = next_offset % BITS_PER_UNIT;
+
+ /* Advance from byte to byte
+ within this element when necessary. */
+ while (next_byte != local->total_bytes)
+ {
+ assemble_integer (GEN_INT (local->byte), 1, BITS_PER_UNIT, 1);
+ local->total_bytes++;
+ local->byte = 0;
+ }
+
+ /* Number of bits we can process at once
+ (all part of the same byte). */
+ this_time = MIN (end_offset - next_offset,
+ BITS_PER_UNIT - next_bit);
+ if (BYTES_BIG_ENDIAN)
+ {
+ /* On big-endian machine, take the most significant bits
+ first (of the bits that are significant)
+ and put them into bytes from the most significant end. */
+ shift = end_offset - next_offset - this_time;
+
+ /* Don't try to take a bunch of bits that cross
+ the word boundary in the INTEGER_CST. We can
+ only select bits from the LOW or HIGH part
+ not from both. */
+ if (shift < HOST_BITS_PER_WIDE_INT
+ && shift + this_time > HOST_BITS_PER_WIDE_INT)
{
- fieldsize = 0;
-
- /* If this is an array with an unspecified upper bound,
- the initializer determines the size. */
- /* ??? This ought to only checked if DECL_SIZE_UNIT is NULL,
- but we cannot do this until the deprecated support for
- initializing zero-length array members is removed. */
- if (TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE
- && TYPE_DOMAIN (TREE_TYPE (field))
- && ! TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (field))))
- {
- fieldsize = array_size_for_constructor (val);
- /* Given a non-empty initialization, this field had
- better be last. */
- gcc_assert (!fieldsize || !TREE_CHAIN (field));
- }
- else if (DECL_SIZE_UNIT (field))
- {
- /* ??? This can't be right. If the decl size overflows
- a host integer we will silently emit no data. */
- if (host_integerp (DECL_SIZE_UNIT (field), 1))
- fieldsize = tree_low_cst (DECL_SIZE_UNIT (field), 1);
- }
+ this_time = shift + this_time - HOST_BITS_PER_WIDE_INT;
+ shift = HOST_BITS_PER_WIDE_INT;
}
+
+ /* Now get the bits from the appropriate constant word. */
+ if (shift < HOST_BITS_PER_WIDE_INT)
+ value = TREE_INT_CST_LOW (local->val);
else
- fieldsize = int_size_in_bytes (TREE_TYPE (type));
-
- /* Output the element's initial value. */
- if (val == 0)
- assemble_zeros (fieldsize);
- else
- output_constant (val, fieldsize, align2);
-
- /* Count its size. */
- total_bytes += fieldsize;
+ {
+ gcc_assert (shift < 2 * HOST_BITS_PER_WIDE_INT);
+ value = TREE_INT_CST_HIGH (local->val);
+ shift -= HOST_BITS_PER_WIDE_INT;
+ }
+
+ /* Get the result. This works only when:
+ 1 <= this_time <= HOST_BITS_PER_WIDE_INT. */
+ local->byte |= (((value >> shift)
+ & (((HOST_WIDE_INT) 2 << (this_time - 1)) - 1))
+ << (BITS_PER_UNIT - this_time - next_bit));
}
- else if (val != 0 && TREE_CODE (val) != INTEGER_CST)
- error ("invalid initial value for member %qE",
- DECL_NAME (field));
else
{
- /* Element that is a bit-field. */
+ /* On little-endian machines,
+ take first the least significant bits of the value
+ and pack them starting at the least significant
+ bits of the bytes. */
+ shift = next_offset - byte_relative_ebitpos;
+
+ /* Don't try to take a bunch of bits that cross
+ the word boundary in the INTEGER_CST. We can
+ only select bits from the LOW or HIGH part
+ not from both. */
+ if (shift < HOST_BITS_PER_WIDE_INT
+ && shift + this_time > HOST_BITS_PER_WIDE_INT)
+ this_time = (HOST_BITS_PER_WIDE_INT - shift);
+
+ /* Now get the bits from the appropriate constant word. */
+ if (shift < HOST_BITS_PER_WIDE_INT)
+ value = TREE_INT_CST_LOW (local->val);
+ else
+ {
+ gcc_assert (shift < 2 * HOST_BITS_PER_WIDE_INT);
+ value = TREE_INT_CST_HIGH (local->val);
+ shift -= HOST_BITS_PER_WIDE_INT;
+ }
+
+ /* Get the result. This works only when:
+ 1 <= this_time <= HOST_BITS_PER_WIDE_INT. */
+ local->byte |= (((value >> shift)
+ & (((HOST_WIDE_INT) 2 << (this_time - 1)) - 1))
+ << next_bit);
+ }
+
+ next_offset += this_time;
+ local->byte_buffer_in_use = true;
+ }
+}
- HOST_WIDE_INT next_offset = int_bit_position (field);
- HOST_WIDE_INT end_offset
- = (next_offset + tree_low_cst (DECL_SIZE (field), 1));
+/* Subroutine of output_constant, used for CONSTRUCTORs (aggregate constants).
+ Generate at least SIZE bytes, padding if necessary. OUTER designates the
+ caller output state of relevance in recursive invocations. */
- if (val == 0)
- val = integer_zero_node;
+static unsigned HOST_WIDE_INT
+output_constructor (tree exp, unsigned HOST_WIDE_INT size,
+ unsigned int align, oc_outer_state * outer)
+{
+ unsigned HOST_WIDE_INT cnt;
+ constructor_elt *ce;
- /* If this field does not start in this (or, next) byte,
- skip some bytes. */
- if (next_offset / BITS_PER_UNIT != total_bytes)
- {
- /* Output remnant of any bit field in previous bytes. */
- if (byte_buffer_in_use)
- {
- assemble_integer (GEN_INT (byte), 1, BITS_PER_UNIT, 1);
- total_bytes++;
- byte_buffer_in_use = 0;
- }
+ oc_local_state local;
- /* If still not at proper byte, advance to there. */
- if (next_offset / BITS_PER_UNIT != total_bytes)
- {
- gcc_assert (next_offset / BITS_PER_UNIT >= total_bytes);
- assemble_zeros (next_offset / BITS_PER_UNIT - total_bytes);
- total_bytes = next_offset / BITS_PER_UNIT;
- }
- }
+ /* Setup our local state to communicate with helpers. */
+ local.exp = exp;
+ local.size = size;
+ local.align = align;
- if (! byte_buffer_in_use)
- byte = 0;
+ local.total_bytes = 0;
+ local.byte_buffer_in_use = outer != NULL;
+ local.byte = outer ? outer->byte : 0;
- /* We must split the element into pieces that fall within
- separate bytes, and combine each byte with previous or
- following bit-fields. */
+ local.type = TREE_TYPE (exp);
- /* next_offset is the offset n fbits from the beginning of
- the structure to the next bit of this element to be processed.
- end_offset is the offset of the first bit past the end of
- this element. */
- while (next_offset < end_offset)
- {
- int this_time;
- int shift;
- HOST_WIDE_INT value;
- HOST_WIDE_INT next_byte = next_offset / BITS_PER_UNIT;
- HOST_WIDE_INT next_bit = next_offset % BITS_PER_UNIT;
-
- /* Advance from byte to byte
- within this element when necessary. */
- while (next_byte != total_bytes)
- {
- assemble_integer (GEN_INT (byte), 1, BITS_PER_UNIT, 1);
- total_bytes++;
- byte = 0;
- }
+ local.last_relative_index = -1;
- /* Number of bits we can process at once
- (all part of the same byte). */
- this_time = MIN (end_offset - next_offset,
- BITS_PER_UNIT - next_bit);
- if (BYTES_BIG_ENDIAN)
- {
- /* On big-endian machine, take the most significant bits
- first (of the bits that are significant)
- and put them into bytes from the most significant end. */
- shift = end_offset - next_offset - this_time;
-
- /* Don't try to take a bunch of bits that cross
- the word boundary in the INTEGER_CST. We can
- only select bits from the LOW or HIGH part
- not from both. */
- if (shift < HOST_BITS_PER_WIDE_INT
- && shift + this_time > HOST_BITS_PER_WIDE_INT)
- {
- this_time = shift + this_time - HOST_BITS_PER_WIDE_INT;
- shift = HOST_BITS_PER_WIDE_INT;
- }
-
- /* Now get the bits from the appropriate constant word. */
- if (shift < HOST_BITS_PER_WIDE_INT)
- value = TREE_INT_CST_LOW (val);
- else
- {
- gcc_assert (shift < 2 * HOST_BITS_PER_WIDE_INT);
- value = TREE_INT_CST_HIGH (val);
- shift -= HOST_BITS_PER_WIDE_INT;
- }
-
- /* Get the result. This works only when:
- 1 <= this_time <= HOST_BITS_PER_WIDE_INT. */
- byte |= (((value >> shift)
- & (((HOST_WIDE_INT) 2 << (this_time - 1)) - 1))
- << (BITS_PER_UNIT - this_time - next_bit));
- }
- else
- {
- /* On little-endian machines,
- take first the least significant bits of the value
- and pack them starting at the least significant
- bits of the bytes. */
- shift = next_offset - int_bit_position (field);
-
- /* Don't try to take a bunch of bits that cross
- the word boundary in the INTEGER_CST. We can
- only select bits from the LOW or HIGH part
- not from both. */
- if (shift < HOST_BITS_PER_WIDE_INT
- && shift + this_time > HOST_BITS_PER_WIDE_INT)
- this_time = (HOST_BITS_PER_WIDE_INT - shift);
-
- /* Now get the bits from the appropriate constant word. */
- if (shift < HOST_BITS_PER_WIDE_INT)
- value = TREE_INT_CST_LOW (val);
- else
- {
- gcc_assert (shift < 2 * HOST_BITS_PER_WIDE_INT);
- value = TREE_INT_CST_HIGH (val);
- shift -= HOST_BITS_PER_WIDE_INT;
- }
-
- /* Get the result. This works only when:
- 1 <= this_time <= HOST_BITS_PER_WIDE_INT. */
- byte |= (((value >> shift)
- & (((HOST_WIDE_INT) 2 << (this_time - 1)) - 1))
- << next_bit);
- }
+ local.min_index = NULL_TREE;
+ if (TREE_CODE (local.type) == ARRAY_TYPE
+ && TYPE_DOMAIN (local.type) != NULL_TREE)
+ local.min_index = TYPE_MIN_VALUE (TYPE_DOMAIN (local.type));
+
+ gcc_assert (HOST_BITS_PER_WIDE_INT >= BITS_PER_UNIT);
- next_offset += this_time;
- byte_buffer_in_use = 1;
- }
- }
- }
+ /* As CE goes through the elements of the constant, FIELD goes through the
+ structure fields if the constant is a structure. If the constant is a
+ union, we override this by getting the field from the TREE_LIST element.
+ But the constant could also be an array. Then FIELD is zero.
- if (byte_buffer_in_use)
+ There is always a maximum of one element in the chain LINK for unions
+ (even if the initializer in a source program incorrectly contains
+ more one). */
+
+ local.field = NULL_TREE;
+ if (TREE_CODE (local.type) == RECORD_TYPE)
+ local.field = TYPE_FIELDS (local.type);
+
+ for (cnt = 0;
+ VEC_iterate (constructor_elt, CONSTRUCTOR_ELTS (exp), cnt, ce);
+ cnt++, local.field = local.field ? TREE_CHAIN (local.field) : 0)
{
- assemble_integer (GEN_INT (byte), 1, BITS_PER_UNIT, 1);
- total_bytes++;
+ local.val = ce->value;
+ local.index = NULL_TREE;
+
+ /* The element in a union constructor specifies the proper field
+ or index. */
+ if ((TREE_CODE (local.type) == RECORD_TYPE
+ || TREE_CODE (local.type) == UNION_TYPE
+ || TREE_CODE (local.type) == QUAL_UNION_TYPE)
+ && ce->index != NULL_TREE)
+ local.field = ce->index;
+
+ else if (TREE_CODE (local.type) == ARRAY_TYPE)
+ local.index = ce->index;
+
+#ifdef ASM_COMMENT_START
+ if (local.field && flag_verbose_asm)
+ fprintf (asm_out_file, "%s %s:\n",
+ ASM_COMMENT_START,
+ DECL_NAME (local.field)
+ ? IDENTIFIER_POINTER (DECL_NAME (local.field))
+ : "<anonymous>");
+#endif
+
+ /* Eliminate the marker that makes a cast not be an lvalue. */
+ if (local.val != NULL_TREE)
+ STRIP_NOPS (local.val);
+
+ /* Output the current element, using the appropriate helper ... */
+
+ /* For an array slice not part of an outer bitfield. */
+ if (!outer
+ && local.index != NULL_TREE
+ && TREE_CODE (local.index) == RANGE_EXPR)
+ output_constructor_array_range (&local);
+
+ /* For a field that is neither a true bitfield nor part of an outer one,
+ known to be at least byte aligned and multiple-of-bytes long. */
+ else if (!outer
+ && (local.field == NULL_TREE
+ || !CONSTRUCTOR_BITFIELD_P (local.field)))
+ output_constructor_regular_field (&local);
+
+ /* For a true bitfield or part of an outer one. */
+ else
+ output_constructor_bitfield (&local, outer);
}
- if ((unsigned HOST_WIDE_INT)total_bytes < size)
- assemble_zeros (size - total_bytes);
+ /* If we are not at toplevel, save the pending data for our caller.
+ Otherwise output the pending data and padding zeros as needed. */
+ if (outer)
+ outer->byte = local.byte;
+ else
+ {
+ if (local.byte_buffer_in_use)
+ {
+ assemble_integer (GEN_INT (local.byte), 1, BITS_PER_UNIT, 1);
+ local.total_bytes++;
+ }
+
+ if ((unsigned HOST_WIDE_INT)local.total_bytes < local.size)
+ {
+ assemble_zeros (local.size - local.total_bytes);
+ local.total_bytes = local.size;
+ }
+ }
+
+ return local.total_bytes;
}
/* Mark DECL as weak. */
@@ -5075,7 +5276,8 @@ weak_finish (void)
if (! decl)
{
- decl = build_decl (TREE_CODE (alias_decl), target,
+ decl = build_decl (DECL_SOURCE_LOCATION (alias_decl),
+ TREE_CODE (alias_decl), target,
TREE_TYPE (alias_decl));
DECL_EXTERNAL (decl) = 1;
@@ -5506,7 +5708,7 @@ supports_one_only (void)
translation units without generating a linker error. */
void
-make_decl_one_only (tree decl)
+make_decl_one_only (tree decl, tree comdat_group)
{
gcc_assert (TREE_CODE (decl) == VAR_DECL
|| TREE_CODE (decl) == FUNCTION_DECL);
@@ -5518,7 +5720,7 @@ make_decl_one_only (tree decl)
#ifdef MAKE_DECL_ONE_ONLY
MAKE_DECL_ONE_ONLY (decl);
#endif
- DECL_ONE_ONLY (decl) = 1;
+ DECL_COMDAT_GROUP (decl) = comdat_group;
}
else if (TREE_CODE (decl) == VAR_DECL
&& (DECL_INITIAL (decl) == 0 || DECL_INITIAL (decl) == error_mark_node))
@@ -5779,7 +5981,7 @@ default_elf_asm_named_section (const char *name, unsigned int flags,
fprintf (asm_out_file, ",%d", flags & SECTION_ENTSIZE);
if (HAVE_COMDAT_GROUP && (flags & SECTION_LINKONCE))
fprintf (asm_out_file, ",%s,comdat",
- lang_hooks.decls.comdat_group (decl));
+ IDENTIFIER_POINTER (DECL_COMDAT_GROUP (decl)));
}
putc ('\n', asm_out_file);
diff --git a/gcc/vec.c b/gcc/vec.c
index 6563fd372b7..3e60580992d 100644
--- a/gcc/vec.c
+++ b/gcc/vec.c
@@ -227,7 +227,7 @@ vec_gc_o_reserve_1 (void *vec, int reserve, size_t vec_offset, size_t elt_size,
bool exact MEM_STAT_DECL)
{
struct vec_prefix *pfx = (struct vec_prefix *) vec;
- unsigned alloc = alloc = calculate_allocation (pfx, reserve, exact);
+ unsigned alloc = calculate_allocation (pfx, reserve, exact);
if (!alloc)
{
diff --git a/gcc/vec.h b/gcc/vec.h
index d408c6d1a1a..d16fdaacbb4 100644
--- a/gcc/vec.h
+++ b/gcc/vec.h
@@ -1229,9 +1229,15 @@ extern void *vec_stack_o_reserve_exact (void *, int, size_t, size_t
MEM_STAT_DECL);
extern void vec_stack_free (void *);
+#ifdef GATHER_STATISTICS
+#define VEC_stack_alloc(T,alloc,name,line,function) \
+ (VEC_OP (T,stack,alloc1) \
+ (alloc, XALLOCAVAR (VEC(T,stack), VEC_embedded_size (T, alloc))))
+#else
#define VEC_stack_alloc(T,alloc) \
(VEC_OP (T,stack,alloc1) \
(alloc, XALLOCAVAR (VEC(T,stack), VEC_embedded_size (T, alloc))))
+#endif
#define DEF_VEC_ALLOC_P_STACK(T) \
VEC_TA(T,base,stack); \
@@ -1241,9 +1247,9 @@ struct vec_swallow_trailing_semi
#define DEF_VEC_ALLOC_FUNC_P_STACK(T) \
static inline VEC(T,stack) *VEC_OP (T,stack,alloc1) \
- (int alloc_, VEC(T,stack)* space MEM_STAT_DECL) \
+ (int alloc_, VEC(T,stack)* space) \
{ \
- return (VEC(T,stack) *) vec_stack_p_reserve_exact_1 (alloc_, space); \
+ return (VEC(T,stack) *) vec_stack_p_reserve_exact_1 (alloc_, space); \
}
#define DEF_VEC_ALLOC_O_STACK(T) \
@@ -1254,9 +1260,9 @@ struct vec_swallow_trailing_semi
#define DEF_VEC_ALLOC_FUNC_O_STACK(T) \
static inline VEC(T,stack) *VEC_OP (T,stack,alloc1) \
- (int alloc_, VEC(T,stack)* space MEM_STAT_DECL) \
+ (int alloc_, VEC(T,stack)* space) \
{ \
- return ((VEC(T,stack) *) vec_stack_p_reserve_exact_1 (alloc_, space); \
+ return ((VEC(T,stack) *) vec_stack_p_reserve_exact_1 (alloc_, space); \
}
#define DEF_VEC_ALLOC_I_STACK(T) \
@@ -1267,9 +1273,9 @@ struct vec_swallow_trailing_semi
#define DEF_VEC_ALLOC_FUNC_I_STACK(T) \
static inline VEC(T,stack) *VEC_OP (T,stack,alloc1) \
- (int alloc_, VEC(T,stack)* space MEM_STAT_DECL) \
+ (int alloc_, VEC(T,stack)* space) \
{ \
- return ((VEC(T,stack) *) vec_stack_p_reserve_exact_1 (alloc_, space); \
+ return ((VEC(T,stack) *) vec_stack_p_reserve_exact_1 (alloc_, space); \
}
#endif /* GCC_VEC_H */
diff --git a/gcc/vmsdbgout.c b/gcc/vmsdbgout.c
index 134c7d99225..41a3420f9ed 100644
--- a/gcc/vmsdbgout.c
+++ b/gcc/vmsdbgout.c
@@ -173,7 +173,7 @@ static void vmsdbgout_end_source_file (unsigned int);
static void vmsdbgout_begin_block (unsigned int, unsigned int);
static void vmsdbgout_end_block (unsigned int, unsigned int);
static bool vmsdbgout_ignore_block (const_tree);
-static void vmsdbgout_source_line (unsigned int, const char *);
+static void vmsdbgout_source_line (unsigned int, const char *, int);
static void vmsdbgout_begin_prologue (unsigned int, const char *);
static void vmsdbgout_end_prologue (unsigned int, const char *);
static void vmsdbgout_end_function (unsigned int);
@@ -1297,7 +1297,7 @@ vmsdbgout_end_prologue (unsigned int line, const char *file)
ASM_OUTPUT_LABEL (asm_out_file, label);
/* VMS PCA expects every PC range to correlate to some line and file. */
- vmsdbgout_source_line (line, file);
+ vmsdbgout_source_line (line, file, 0);
}
}
@@ -1331,7 +1331,7 @@ vmsdbgout_end_epilogue (unsigned int line, const char *file)
ASM_OUTPUT_LABEL (asm_out_file, label);
/* VMS PCA expects every PC range to correlate to some line and file. */
- vmsdbgout_source_line (line, file);
+ vmsdbgout_source_line (line, file, 0);
}
}
@@ -1533,10 +1533,11 @@ lookup_filename (const char *file_name)
'line_info_table' for later output of the .debug_line section. */
static void
-vmsdbgout_source_line (register unsigned line, register const char *filename)
+vmsdbgout_source_line (register unsigned line, register const char *filename,
+ int discriminator)
{
if (write_symbols == VMS_AND_DWARF2_DEBUG)
- (*dwarf2_debug_hooks.source_line) (line, filename);
+ (*dwarf2_debug_hooks.source_line) (line, filename, discriminator);
if (debug_info_level >= DINFO_LEVEL_TERSE)
{
diff --git a/gcc/xcoffout.c b/gcc/xcoffout.c
index 8859b40730f..3c853544ec4 100644
--- a/gcc/xcoffout.c
+++ b/gcc/xcoffout.c
@@ -321,7 +321,8 @@ xcoffout_source_file (FILE *file, const char *filename, int inline_p)
/* Output a line number symbol entry for location (FILENAME, LINE). */
void
-xcoffout_source_line (unsigned int line, const char *filename)
+xcoffout_source_line (unsigned int line, const char *filename,
+ int discriminator ATTRIBUTE_UNUSED)
{
bool inline_p = (strcmp (xcoff_current_function_file, filename) != 0
|| (int) line < xcoff_begin_function_line);
diff --git a/gcc/xcoffout.h b/gcc/xcoffout.h
index a6da1596b18..caf8b08cc0b 100644
--- a/gcc/xcoffout.h
+++ b/gcc/xcoffout.h
@@ -182,4 +182,4 @@ extern void xcoffout_end_function (unsigned int);
extern void xcoffout_end_block (unsigned, unsigned);
extern int xcoff_assign_fundamental_type_number (tree);
extern void xcoffout_declare_function (FILE *, tree, const char *);
-extern void xcoffout_source_line (unsigned int, const char *);
+extern void xcoffout_source_line (unsigned int, const char *, int);
diff --git a/gnattools/ChangeLog b/gnattools/ChangeLog
index 695762a536e..d8cbe086f4a 100644
--- a/gnattools/ChangeLog
+++ b/gnattools/ChangeLog
@@ -1,6 +1,12 @@
+2009-05-18 Bechir Zalila <bechir.zalila@gmail.com>
+
+ PR ada/40166
+ * Makefile.in (TOOLS_TARGET_PAIRS): Use the correct path to the
+ target specific sources.
+
2009-04-10 Arnaud Charlet <charlet@adacore.com>
- * Makefile.in (stamp-tools): Add handling of snames.ad[sb]
+ * Makefile.in (stamp-tools): Add handling of snames.ad[sb].
2009-04-09 Jakub Jelinek <jakub@redhat.com>
diff --git a/gnattools/Makefile.in b/gnattools/Makefile.in
index e0cc4e1a110..92f4773b3d8 100644
--- a/gnattools/Makefile.in
+++ b/gnattools/Makefile.in
@@ -164,7 +164,7 @@ $(GCC_DIR)/stamp-tools:
-(cd $(GCC_DIR)/ada/tools; $(LN_S) ../sdefault.adb ../snames.ads ../snames.adb .)
-$(foreach PAIR,$(TOOLS_TARGET_PAIRS), \
rm -f $(GCC_DIR)/ada/tools/$(word 1,$(subst <, ,$(PAIR)));\
- $(LN_S) $(fsrcdir)/$(word 2,$(subst <, ,$(PAIR))) \
+ $(LN_S) $(fsrcdir)/ada/$(word 2,$(subst <, ,$(PAIR))) \
$(GCC_DIR)/ada/tools/$(word 1,$(subst <, ,$(PAIR)));)
touch $(GCC_DIR)/stamp-tools
diff --git a/include/ChangeLog b/include/ChangeLog
index a6cf609fe19..b680b436b00 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,20 @@
+2009-06-09 Ian Lance Taylor <ian@airs.com>
+
+ * ansidecl.h (ATTRIBUTE_UNUSED_LABEL): Define for C++.
+
+2009-06-03 Ian Lance Taylor <iant@google.com>
+
+ * ansidecl.h (EXPORTED_CONST): Define.
+
+2009-05-31 Ian Lance Taylor <iant@google.com>
+
+ * ansidecl.h: Add extern "C" when compiling with C++. Treat C++
+ the way we treat an ISO C compiler. Don't define inline as a
+ macdro when compiling with C++.
+ * dyn-string.h: Add header guard DYN_STRING_H. Add extern "C"
+ when compiling with C++.
+ * fibheap.h: Add extern "C" when compiling with C++.
+
2009-04-22 Taras Glek <tglek@mozilla.com>
* hashtab.h: Update GTY annotations to new syntax.
diff --git a/include/ansidecl.h b/include/ansidecl.h
index c19955a98a6..86b09447482 100644
--- a/include/ansidecl.h
+++ b/include/ansidecl.h
@@ -1,5 +1,6 @@
/* ANSI and traditional C compatability macros
- Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
+ Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+ 2002, 2003, 2004, 2005, 2006, 2007, 2009
Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -114,6 +115,10 @@ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
#ifndef _ANSIDECL_H
#define _ANSIDECL_H 1
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* Every source file includes this file,
so they will all get the switch for lint. */
/* LINTLIBRARY */
@@ -136,7 +141,7 @@ So instead we use the macro below and test it against specific values. */
#define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__)
#endif /* GCC_VERSION */
-#if defined (__STDC__) || defined (_AIX) || (defined (__mips) && defined (_SYSTYPE_SVR4)) || defined(_WIN32) || (defined(__alpha) && defined(__cplusplus))
+#if defined (__STDC__) || defined(__cplusplus) || defined (_AIX) || (defined (__mips) && defined (_SYSTYPE_SVR4)) || defined(_WIN32)
/* All known AIX compilers implement these things (but don't always
define __STDC__). The RISC/OS MIPS compiler defines these things
in SVR4 mode, but does not define __STDC__. */
@@ -173,7 +178,7 @@ So instead we use the macro below and test it against specific values. */
/* inline requires special treatment; it's in C99, and GCC >=2.7 supports
it too, but it's not in C89. */
#undef inline
-#if __STDC_VERSION__ > 199901L
+#if __STDC_VERSION__ > 199901L || defined(__cplusplus)
/* it's a keyword */
#else
# if GCC_VERSION >= 2007
@@ -256,14 +261,23 @@ So instead we use the macro below and test it against specific values. */
# endif /* GNUC >= 2.96 */
#endif /* ATTRIBUTE_MALLOC */
-/* Attributes on labels were valid as of gcc 2.93. */
+/* Attributes on labels were valid as of gcc 2.93 and g++ 4.5. For
+ g++ an attribute on a label must be followed by a semicolon. */
#ifndef ATTRIBUTE_UNUSED_LABEL
-# if (!defined (__cplusplus) && GCC_VERSION >= 2093)
-# define ATTRIBUTE_UNUSED_LABEL ATTRIBUTE_UNUSED
+# ifndef __cplusplus
+# if GCC_VERSION >= 2093
+# define ATTRIBUTE_UNUSED_LABEL ATTRIBUTE_UNUSED
+# else
+# define ATTRIBUTE_UNUSED_LABEL
+# endif
# else
-# define ATTRIBUTE_UNUSED_LABEL
-# endif /* !__cplusplus && GNUC >= 2.93 */
-#endif /* ATTRIBUTE_UNUSED_LABEL */
+# if GCC_VERSION >= 4005
+# define ATTRIBUTE_UNUSED_LABEL ATTRIBUTE_UNUSED ;
+# else
+# define ATTRIBUTE_UNUSED_LABEL
+# endif
+# endif
+#endif
#ifndef ATTRIBUTE_UNUSED
#define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
@@ -390,4 +404,20 @@ So instead we use the macro below and test it against specific values. */
#define __extension__
#endif
+/* This is used to declare a const variable which should be visible
+ outside of the current compilation unit. Use it as
+ EXPORTED_CONST int i = 1;
+ This is because the semantics of const are different in C and C++.
+ "extern const" is permitted in C but it looks strange, and gcc
+ warns about it when -Wc++-compat is not used. */
+#ifdef __cplusplus
+#define EXPORTED_CONST extern const
+#else
+#define EXPORTED_CONST const
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
#endif /* ansidecl.h */
diff --git a/include/dyn-string.h b/include/dyn-string.h
index 44e33deba3a..2b147271e5f 100644
--- a/include/dyn-string.h
+++ b/include/dyn-string.h
@@ -1,5 +1,6 @@
/* An abstract string datatype.
- Copyright (C) 1998, 1999, 2000, 2002, 2004 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000, 2002, 2004, 2005, 2009
+ Free Software Foundation, Inc.
Contributed by Mark Mitchell (mark@markmitchell.com).
This file is part of GCC.
@@ -19,6 +20,12 @@ along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 51 Franklin Street - Fifth Floor,
Boston, MA 02110-1301, USA. */
+#ifndef DYN_STRING_H
+#define DYN_STRING_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
typedef struct dyn_string
{
@@ -58,3 +65,9 @@ extern int dyn_string_append_cstr (dyn_string_t, const char *);
extern int dyn_string_append_char (dyn_string_t, int);
extern int dyn_string_substring (dyn_string_t, dyn_string_t, int, int);
extern int dyn_string_eq (dyn_string_t, dyn_string_t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !defined (DYN_STRING_H) */
diff --git a/include/fibheap.h b/include/fibheap.h
index 348c4ae2638..a3d09dd9db8 100644
--- a/include/fibheap.h
+++ b/include/fibheap.h
@@ -1,5 +1,6 @@
/* A Fibonacci heap datatype.
- Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2009
+ Free Software Foundation, Inc.
Contributed by Daniel Berlin (dan@cgsoftware.com).
This file is part of GCC.
@@ -42,6 +43,10 @@ Boston, MA 02110-1301, USA. */
#include "ansidecl.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
typedef long fibheapkey_t;
typedef struct fibheap
@@ -83,4 +88,8 @@ extern void *fibheap_delete_node (fibheap_t, fibnode_t);
extern void fibheap_delete (fibheap_t);
extern fibheap_t fibheap_union (fibheap_t, fibheap_t);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* _FIBHEAP_H_ */
diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog
index 4e21b581121..263d8441cc9 100644
--- a/libcpp/ChangeLog
+++ b/libcpp/ChangeLog
@@ -1,3 +1,41 @@
+2009-06-12 Ian Lance Taylor <iant@google.com>
+
+ * include/cpplib.h (struct cpp_options): Add
+ warn_cxx_operator_names field.
+ (NODE_WARN_OPERATOR): Define.
+ (struct cpp_hashnode): Increase flags field to 10 bits, decrease
+ type to 6 bits.
+ * init.c (mark_named_operators): Add flags parameter.
+ (cpp_post_options): Pick flags value to pass to
+ mark_named_operators.
+ * lex.c (lex_identifier): If NODE_WARN_OPERATOR is set, warn that
+ identifier is an operator name in C++.
+
+2009-06-01 Aldy Hernandez <aldyh@redhat.com>
+
+ * include/line-map.h (LAST_SOURCE_COLUMN): New.
+
+2009-06-01 Ian Lance Taylor <iant@google.com>
+
+ * include/cpp-id-data.h: Add extern "C".
+ * include/line-map.h: Likewise.
+ * include/mkdeps.h: Likewise.
+ * include/symtab.h: Likewise.
+ * internal.h: Likewise.
+
+2009-05-15 Ian Lance Taylor <iant@google.com>
+
+ * include/cpplib.h (enum cpp_builtin_type): Rename from enum
+ builtin_type. Change all uses.
+
+2009-05-14 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
+
+ PR cpp/36674
+ * directives (do_linemarker): Compensate for the increment in
+ location that occurs when we reach the end of line.
+ * files (_cpp_stack_include): Mention _cpp_find_file in the
+ comment.
+
2009-05-10 Joseph Myers <joseph@codesourcery.com>
* include/cpplib.h (enum cpp_token_fld_kind): Add
diff --git a/libcpp/directives.c b/libcpp/directives.c
index e71efb2bd94..74644ff6c77 100644
--- a/libcpp/directives.c
+++ b/libcpp/directives.c
@@ -1004,6 +1004,14 @@ do_linemarker (cpp_reader *pfile)
}
skip_rest_of_line (pfile);
+
+ /* Compensate for the increment in linemap_add that occurs in
+ _cpp_do_file_change. We're currently at the start of the line
+ *following* the #line directive. A separate source_location for this
+ location makes no sense (until we do the LC_LEAVE), and
+ complicates LAST_SOURCE_LINE_LOCATION. */
+ pfile->line_table->highest_location--;
+
_cpp_do_file_change (pfile, reason, new_file, new_lineno, new_sysp);
}
diff --git a/libcpp/files.c b/libcpp/files.c
index 06ccd0fd695..c8c19021f56 100644
--- a/libcpp/files.c
+++ b/libcpp/files.c
@@ -912,13 +912,14 @@ _cpp_stack_include (cpp_reader *pfile, const char *fname, int angle_brackets,
file = _cpp_find_file (pfile, fname, dir, false, angle_brackets);
- /* Compensate for the increment in linemap_add. In the case of a
- normal #include, we're currently at the start of the line
- *following* the #include. A separate source_location for this
- location makes no sense (until we do the LC_LEAVE), and
- complicates LAST_SOURCE_LINE_LOCATION. This does not apply if we
- found a PCH file (in which case linemap_add is not called) or we
- were included from the command-line. */
+ /* Compensate for the increment in linemap_add that occurs in
+ _cpp_stack_file. In the case of a normal #include, we're
+ currently at the start of the line *following* the #include. A
+ separate source_location for this location makes no sense (until
+ we do the LC_LEAVE), and complicates LAST_SOURCE_LINE_LOCATION.
+ This does not apply if we found a PCH file (in which case
+ linemap_add is not called) or we were included from the
+ command-line. */
if (file->pchname == NULL && file->err_no == 0 && type != IT_CMDLINE)
pfile->line_table->highest_location--;
diff --git a/libcpp/include/cpp-id-data.h b/libcpp/include/cpp-id-data.h
index a57edad521d..d2adbfaebdf 100644
--- a/libcpp/include/cpp-id-data.h
+++ b/libcpp/include/cpp-id-data.h
@@ -18,6 +18,10 @@ along with this program; see the file COPYING3. If not see
#include "cpplib.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#if !defined (HAVE_UCHAR) && !defined (IN_GCC)
typedef unsigned char uchar;
#endif
@@ -79,3 +83,7 @@ struct GTY(()) cpp_macro {
tokens. */
unsigned int extra_tokens : 1;
};
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h
index 83439c7341f..a91f1552158 100644
--- a/libcpp/include/cpplib.h
+++ b/libcpp/include/cpplib.h
@@ -397,6 +397,9 @@ struct cpp_options
/* Nonzero means handle C++ alternate operator names. */
unsigned char operator_names;
+ /* Nonzero means warn about use of C++ alternate operator names. */
+ unsigned char warn_cxx_operator_names;
+
/* True for traditional preprocessing. */
unsigned char traditional;
@@ -555,7 +558,8 @@ extern const char *progname;
identifier that behaves like an operator such as "xor".
NODE_DIAGNOSTIC is for speed in lex_token: it indicates a
diagnostic may be required for this node. Currently this only
- applies to __VA_ARGS__ and poisoned identifiers. */
+ applies to __VA_ARGS__, poisoned identifiers, and -Wc++-compat
+ warnings about NODE_OPERATOR. */
/* Hash node flags. */
#define NODE_OPERATOR (1 << 0) /* C++ named operator. */
@@ -567,6 +571,7 @@ extern const char *progname;
#define NODE_MACRO_ARG (1 << 6) /* Used during #define processing. */
#define NODE_USED (1 << 7) /* Dumped with -dU. */
#define NODE_CONDITIONAL (1 << 8) /* Conditional macro */
+#define NODE_WARN_OPERATOR (1 << 9) /* Warn about C++ named operator. */
/* Different flavors of hash node. */
enum node_type
@@ -578,7 +583,7 @@ enum node_type
/* Different flavors of builtin macro. _Pragma is an operator, but we
handle it with the builtin code for efficiency reasons. */
-enum builtin_type
+enum cpp_builtin_type
{
BT_SPECLINE = 0, /* `__LINE__' */
BT_DATE, /* `__DATE__' */
@@ -624,7 +629,7 @@ union GTY(()) _cpp_hashnode_value {
/* Answers to an assertion. */
struct answer * GTY ((tag ("NTV_ANSWER"))) answers;
/* Code for a builtin macro. */
- enum builtin_type GTY ((tag ("NTV_BUILTIN"))) builtin;
+ enum cpp_builtin_type GTY ((tag ("NTV_BUILTIN"))) builtin;
/* Macro argument index. */
unsigned short GTY ((tag ("NTV_ARGUMENT"))) arg_index;
};
@@ -636,8 +641,8 @@ struct GTY(()) cpp_hashnode {
then index into directive table.
Otherwise, a NODE_OPERATOR. */
unsigned char rid_code; /* Rid code - for front ends. */
- ENUM_BITFIELD(node_type) type : 7; /* CPP node type. */
- unsigned int flags : 9; /* CPP flags. */
+ ENUM_BITFIELD(node_type) type : 6; /* CPP node type. */
+ unsigned int flags : 10; /* CPP flags. */
union _cpp_hashnode_value GTY ((desc ("CPP_HASHNODE_VALUE_IDX (%1)"))) value;
};
diff --git a/libcpp/include/line-map.h b/libcpp/include/line-map.h
index b556013af62..09e72f14d4b 100644
--- a/libcpp/include/line-map.h
+++ b/libcpp/include/line-map.h
@@ -23,6 +23,10 @@ along with this program; see the file COPYING3. If not see
#ifndef LIBCPP_LINE_MAP_H
#define LIBCPP_LINE_MAP_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#ifndef GTY
#define GTY(x) /* nothing */
#endif
@@ -154,6 +158,8 @@ extern const struct line_map *linemap_lookup
of the #include, or other directive, that caused a map change. */
#define LAST_SOURCE_LINE(MAP) \
SOURCE_LINE (MAP, LAST_SOURCE_LINE_LOCATION (MAP))
+#define LAST_SOURCE_COLUMN(MAP) \
+ SOURCE_COLUMN (MAP, LAST_SOURCE_LINE_LOCATION (MAP))
#define LAST_SOURCE_LINE_LOCATION(MAP) \
((((MAP)[1].start_location - 1 - (MAP)->start_location) \
& ~((1 << (MAP)->column_bits) - 1)) \
@@ -184,4 +190,9 @@ extern const struct line_map *linemap_lookup
extern source_location
linemap_position_for_column (struct line_maps *set, unsigned int to_column);
+
+#ifdef __cplusplus
+}
+#endif
+
#endif /* !LIBCPP_LINE_MAP_H */
diff --git a/libcpp/include/mkdeps.h b/libcpp/include/mkdeps.h
index 50bcee40726..def7b5641f8 100644
--- a/libcpp/include/mkdeps.h
+++ b/libcpp/include/mkdeps.h
@@ -23,6 +23,10 @@ along with this program; see the file COPYING3. If not see
#ifndef LIBCPP_MKDEPS_H
#define LIBCPP_MKDEPS_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* This is the data structure used by all the functions in mkdeps.c.
It's quite straightforward, but should be treated as opaque. */
@@ -76,4 +80,8 @@ extern int deps_restore (struct deps *, FILE *, const char *);
automatic dependency schemes. */
extern void deps_phony_targets (const struct deps *, FILE *);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* ! LIBCPP_MKDEPS_H */
diff --git a/libcpp/include/symtab.h b/libcpp/include/symtab.h
index e7c593731bc..e1bc00cb6f6 100644
--- a/libcpp/include/symtab.h
+++ b/libcpp/include/symtab.h
@@ -20,6 +20,11 @@ along with this program; see the file COPYING3. If not see
#define LIBCPP_SYMTAB_H
#include "obstack.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#ifndef GTY
#define GTY(x) /* nothing */
#endif
@@ -99,4 +104,8 @@ extern void ht_load (hash_table *ht, hashnode *entries,
/* Dump allocation statistics to stderr. */
extern void ht_dump_statistics (hash_table *);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* LIBCPP_SYMTAB_H */
diff --git a/libcpp/init.c b/libcpp/init.c
index aef39981792..e5be4e2b1b4 100644
--- a/libcpp/init.c
+++ b/libcpp/init.c
@@ -28,7 +28,7 @@ along with this program; see the file COPYING3. If not see
#include "localedir.h"
static void init_library (void);
-static void mark_named_operators (cpp_reader *);
+static void mark_named_operators (cpp_reader *, int);
static void read_original_filename (cpp_reader *);
static void read_original_directory (cpp_reader *);
static void post_options (cpp_reader *);
@@ -366,7 +366,7 @@ static const struct builtin_operator operator_array[] =
/* Mark the C++ named operators in the hash table. */
static void
-mark_named_operators (cpp_reader *pfile)
+mark_named_operators (cpp_reader *pfile, int flags)
{
const struct builtin_operator *b;
@@ -375,7 +375,7 @@ mark_named_operators (cpp_reader *pfile)
b++)
{
cpp_hashnode *hp = cpp_lookup (pfile, b->name, b->len);
- hp->flags |= NODE_OPERATOR;
+ hp->flags |= flags;
hp->is_directive = 0;
hp->directive_index = b->value;
}
@@ -419,7 +419,7 @@ cpp_init_special_builtins (cpp_reader *pfile)
if (b->always_warn_if_redefined
|| CPP_OPTION (pfile, warn_builtin_macro_redefined))
hp->flags |= NODE_WARN;
- hp->value.builtin = (enum builtin_type) b->value;
+ hp->value.builtin = (enum cpp_builtin_type) b->value;
}
}
@@ -512,13 +512,20 @@ static void sanity_checks (cpp_reader *pfile)
void
cpp_post_options (cpp_reader *pfile)
{
+ int flags;
+
sanity_checks (pfile);
post_options (pfile);
/* Mark named operators before handling command line macros. */
+ flags = 0;
if (CPP_OPTION (pfile, cplusplus) && CPP_OPTION (pfile, operator_names))
- mark_named_operators (pfile);
+ flags |= NODE_OPERATOR;
+ if (CPP_OPTION (pfile, warn_cxx_operator_names))
+ flags |= NODE_DIAGNOSTIC | NODE_WARN_OPERATOR;
+ if (flags != 0)
+ mark_named_operators (pfile, flags);
}
/* Setup for processing input from the file named FNAME, or stdin if
diff --git a/libcpp/internal.h b/libcpp/internal.h
index 22e6d238906..21e51c6553c 100644
--- a/libcpp/internal.h
+++ b/libcpp/internal.h
@@ -33,6 +33,10 @@ along with this program; see the file COPYING3. If not see
typedef int iconv_t; /* dummy */
#endif
+#ifdef __cplusplus
+extern "C" {
+#endif
+
struct directive; /* Deliberately incomplete. */
struct pending_option;
struct op;
@@ -702,4 +706,8 @@ ufputs (const unsigned char *s, FILE *f)
return fputs ((const char *)s, f);
}
+#ifdef __cplusplus
+}
+#endif
+
#endif /* ! LIBCPP_INTERNAL_H */
diff --git a/libcpp/lex.c b/libcpp/lex.c
index ca2f2ca06f1..bab14a4baa3 100644
--- a/libcpp/lex.c
+++ b/libcpp/lex.c
@@ -560,6 +560,12 @@ lex_identifier (cpp_reader *pfile, const uchar *base, bool starts_ucn,
cpp_error (pfile, CPP_DL_PEDWARN,
"__VA_ARGS__ can only appear in the expansion"
" of a C99 variadic macro");
+
+ /* For -Wc++-compat, warn about use of C++ named operators. */
+ if (result->flags & NODE_WARN_OPERATOR)
+ cpp_error (pfile, CPP_DL_WARNING,
+ "identifier \"%s\" is a special operator name in C++",
+ NODE_NAME (result));
}
return result;
diff --git a/libdecnumber/ChangeLog b/libdecnumber/ChangeLog
index 12e21554698..74fba5990d6 100644
--- a/libdecnumber/ChangeLog
+++ b/libdecnumber/ChangeLog
@@ -1,3 +1,12 @@
+2009-05-31 Ian Lance Taylor <iant@google.com>
+
+ * decContext.h: Add extern "C" if compiling with C++.
+ * decDPD.h: Likewise.
+ * decNumber.h: Likewise.
+ * dpd/decimal32.h: Likewise.
+ * dpd/decimal64.h: Likewise.
+ * dpd/decimal128.h: Likewise.
+
2009-04-09 Nick Clifton <nickc@redhat.com>
* decRound.c: Change copyright header to refer to version 3 of
diff --git a/libdecnumber/decContext.h b/libdecnumber/decContext.h
index d6c75f12471..ae0ca07b859 100644
--- a/libdecnumber/decContext.h
+++ b/libdecnumber/decContext.h
@@ -245,6 +245,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#include "decContextSymbols.h"
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
+
extern decContext * decContextClearStatus(decContext *, uint32_t);
extern decContext * decContextDefault(decContext *, int32_t);
extern enum rounding decContextGetRounding(decContext *);
@@ -262,4 +266,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
extern uint32_t decContextTestStatus(decContext *, uint32_t);
extern decContext * decContextZeroStatus(decContext *);
+ #ifdef __cplusplus
+ }
+ #endif
+
#endif
diff --git a/libdecnumber/decDPD.h b/libdecnumber/decDPD.h
index 3b998d10043..db4d3434d03 100644
--- a/libdecnumber/decDPD.h
+++ b/libdecnumber/decDPD.h
@@ -59,6 +59,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#if defined(DEC_BCD2DPD) && DEC_BCD2DPD==1 && !defined(DECBCD2DPD)
#define DECBCD2DPD
+#ifdef __cplusplus
+extern "C" {
+#endif
+
const uint16_t BCD2DPD[2458]={ 0, 1, 2, 3, 4, 5, 6, 7,
8, 9, 0, 0, 0, 0, 0, 0, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 0, 0, 0, 0, 0, 0, 32, 33,
@@ -1206,5 +1210,9 @@ const uint8_t BIN2BCD8[4000]={
9,8,1,3, 9,8,2,3, 9,8,3,3, 9,8,4,3, 9,8,5,3, 9,8,6,3, 9,8,7,3, 9,8,8,3, 9,8,9,3,
9,9,0,3, 9,9,1,3, 9,9,2,3, 9,9,3,3, 9,9,4,3, 9,9,5,3, 9,9,6,3, 9,9,7,3, 9,9,8,3,
9,9,9,3};
+
+#ifdef __cplusplus
+}
#endif
+#endif
diff --git a/libdecnumber/decNumber.h b/libdecnumber/decNumber.h
index 73a2fd033e9..05ccb9fdf56 100644
--- a/libdecnumber/decNumber.h
+++ b/libdecnumber/decNumber.h
@@ -108,6 +108,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#include "decNumberSymbols.h"
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
+
/* Conversions */
decNumber * decNumberFromInt32(decNumber *, int32_t);
decNumber * decNumberFromUInt32(decNumber *, uint32_t);
@@ -192,4 +196,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
&& (((dn)->bits&DECSPECIAL)==0))
#define decNumberRadix(dn) (10)
+ #ifdef __cplusplus
+ }
+ #endif
+
#endif
diff --git a/libdecnumber/dpd/decimal128.h b/libdecnumber/dpd/decimal128.h
index 5214373cd1d..3c83c81fcaa 100644
--- a/libdecnumber/dpd/decimal128.h
+++ b/libdecnumber/dpd/decimal128.h
@@ -79,6 +79,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#include "decimal128Symbols.h"
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
+
/* String conversions */
decimal128 * decimal128FromString(decimal128 *, const char *, decContext *);
char * decimal128ToString(const decimal128 *, char *);
@@ -93,4 +97,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
uint32_t decimal128IsCanonical(const decimal128 *);
decimal128 * decimal128Canonical(decimal128 *, const decimal128 *);
+ #ifdef __cplusplus
+ }
+ #endif
+
#endif
diff --git a/libdecnumber/dpd/decimal32.h b/libdecnumber/dpd/decimal32.h
index ced33efc1f3..94ddeb80f3f 100644
--- a/libdecnumber/dpd/decimal32.h
+++ b/libdecnumber/dpd/decimal32.h
@@ -77,6 +77,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#include "decimal32Symbols.h"
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
+
/* String conversions */
decimal32 * decimal32FromString(decimal32 *, const char *, decContext *);
char * decimal32ToString(const decimal32 *, char *);
@@ -91,4 +95,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
uint32_t decimal32IsCanonical(const decimal32 *);
decimal32 * decimal32Canonical(decimal32 *, const decimal32 *);
+ #ifdef __cplusplus
+ }
+ #endif
+
#endif
diff --git a/libdecnumber/dpd/decimal64.h b/libdecnumber/dpd/decimal64.h
index a55a9c42906..c501415381e 100644
--- a/libdecnumber/dpd/decimal64.h
+++ b/libdecnumber/dpd/decimal64.h
@@ -79,6 +79,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#include "decimal64Symbols.h"
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
+
/* String conversions */
decimal64 * decimal64FromString(decimal64 *, const char *, decContext *);
char * decimal64ToString(const decimal64 *, char *);
@@ -93,4 +97,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
uint32_t decimal64IsCanonical(const decimal64 *);
decimal64 * decimal64Canonical(decimal64 *, const decimal64 *);
+ #ifdef __cplusplus
+ }
+ #endif
+
#endif
diff --git a/libffi/ChangeLog b/libffi/ChangeLog
index cadb600c9bf..b08b72720cc 100644
--- a/libffi/ChangeLog
+++ b/libffi/ChangeLog
@@ -1,3 +1,405 @@
+2009-06-16 Wim Lewis <wiml@hhhh.org>
+
+ * src/powerpc/ffi.c: Avoid clobbering cr3 and cr4, which are
+ supposed to be callee-saved.
+ * src/powerpc/sysv.S (small_struct_return_value): Fix overrun of
+ return buffer for odd-size structs.
+
+2009-06-16 Andreas Tobler <a.tobler@schweiz.org>
+
+ PR libffi/40444
+ * testsuite/lib/libffi-dg.exp (libffi_target_compile): Add
+ allow_stack_execute for Darwin.
+
+2009-06-16 Andrew Haley <aph@redhat.com>
+
+ * configure.ac (TARGETDIR): Add missing blank lines.
+ * configure: Regenerate.
+
+2009-06-16 Andrew Haley <aph@redhat.com>
+
+ * testsuite/libffi.call/cls_align_sint64.c,
+ testsuite/libffi.call/cls_align_uint64.c,
+ testsuite/libffi.call/cls_longdouble_va.c,
+ testsuite/libffi.call/cls_ulonglong.c,
+ testsuite/libffi.call/return_ll1.c,
+ testsuite/libffi.call/stret_medium2.c: Fix printf format
+ specifiers.
+ * testsuite/libffi.call/ffitest.h,
+ testsuite/libffi.special/ffitestcxx.h (PRIdLL, PRIuLL): Define.
+
+2009-06-15 Andrew Haley <aph@redhat.com>
+
+ * testsuite/libffi.call/err_bad_typedef.c: xfail everywhere.
+ * testsuite/libffi.call/err_bad_abi.c: Likewise.
+
+2009-06-12 Andrew Haley <aph@redhat.com>
+
+ * Makefile.am: Remove info_TEXINFOS.
+
+2009-06-12 Andrew Haley <aph@redhat.com>
+
+ * ChangeLog.libffi: testsuite/libffi.call/cls_align_sint64.c,
+ testsuite/libffi.call/cls_align_uint64.c,
+ testsuite/libffi.call/cls_ulonglong.c,
+ testsuite/libffi.call/return_ll1.c,
+ testsuite/libffi.call/stret_medium2.c: Fix printf format
+ specifiers.
+ testsuite/libffi.special/unwindtest.cc: include stdint.h.
+
+2009-06-11 Timothy Wall <twall@users.sf.net>
+
+ * Makefile.am,
+ configure.ac,
+ include/ffi.h.in,
+ include/ffi_common.h,
+ src/closures.c,
+ src/dlmalloc.c,
+ src/x86/ffi.c,
+ src/x86/ffitarget.h,
+ src/x86/win64.S (new),
+ README: Added win64 support (mingw or MSVC)
+ * Makefile.in,
+ include/Makefile.in,
+ man/Makefile.in,
+ testsuite/Makefile.in,
+ configure,
+ aclocal.m4: Regenerated
+ * ltcf-c.sh: properly escape cygwin/w32 path
+ * man/ffi_call.3: Clarify size requirements for return value.
+ * src/x86/ffi64.c: Fix filename in comment.
+ * src/x86/win32.S: Remove unused extern.
+
+ * testsuite/libffi.call/closure_fn0.c,
+ testsuite/libffi.call/closure_fn1.c,
+ testsuite/libffi.call/closure_fn2.c,
+ testsuite/libffi.call/closure_fn3.c,
+ testsuite/libffi.call/closure_fn4.c,
+ testsuite/libffi.call/closure_fn5.c,
+ testsuite/libffi.call/closure_fn6.c,
+ testsuite/libffi.call/closure_stdcall.c,
+ testsuite/libffi.call/cls_12byte.c,
+ testsuite/libffi.call/cls_16byte.c,
+ testsuite/libffi.call/cls_18byte.c,
+ testsuite/libffi.call/cls_19byte.c,
+ testsuite/libffi.call/cls_1_1byte.c,
+ testsuite/libffi.call/cls_20byte.c,
+ testsuite/libffi.call/cls_20byte1.c,
+ testsuite/libffi.call/cls_24byte.c,
+ testsuite/libffi.call/cls_2byte.c,
+ testsuite/libffi.call/cls_3_1byte.c,
+ testsuite/libffi.call/cls_3byte1.c,
+ testsuite/libffi.call/cls_3byte2.c,
+ testsuite/libffi.call/cls_4_1byte.c,
+ testsuite/libffi.call/cls_4byte.c,
+ testsuite/libffi.call/cls_5_1_byte.c,
+ testsuite/libffi.call/cls_5byte.c,
+ testsuite/libffi.call/cls_64byte.c,
+ testsuite/libffi.call/cls_6_1_byte.c,
+ testsuite/libffi.call/cls_6byte.c,
+ testsuite/libffi.call/cls_7_1_byte.c,
+ testsuite/libffi.call/cls_7byte.c,
+ testsuite/libffi.call/cls_8byte.c,
+ testsuite/libffi.call/cls_9byte1.c,
+ testsuite/libffi.call/cls_9byte2.c,
+ testsuite/libffi.call/cls_align_double.c,
+ testsuite/libffi.call/cls_align_float.c,
+ testsuite/libffi.call/cls_align_longdouble.c,
+ testsuite/libffi.call/cls_align_longdouble_split.c,
+ testsuite/libffi.call/cls_align_longdouble_split2.c,
+ testsuite/libffi.call/cls_align_pointer.c,
+ testsuite/libffi.call/cls_align_sint16.c,
+ testsuite/libffi.call/cls_align_sint32.c,
+ testsuite/libffi.call/cls_align_sint64.c,
+ testsuite/libffi.call/cls_align_uint16.c,
+ testsuite/libffi.call/cls_align_uint32.c,
+ testsuite/libffi.call/cls_align_uint64.c,
+ testsuite/libffi.call/cls_dbls_struct.c,
+ testsuite/libffi.call/cls_double.c,
+ testsuite/libffi.call/cls_double_va.c,
+ testsuite/libffi.call/cls_float.c,
+ testsuite/libffi.call/cls_longdouble.c,
+ testsuite/libffi.call/cls_longdouble_va.c,
+ testsuite/libffi.call/cls_multi_schar.c,
+ testsuite/libffi.call/cls_multi_sshort.c,
+ testsuite/libffi.call/cls_multi_sshortchar.c,
+ testsuite/libffi.call/cls_multi_uchar.c,
+ testsuite/libffi.call/cls_multi_ushort.c,
+ testsuite/libffi.call/cls_multi_ushortchar.c,
+ testsuite/libffi.call/cls_pointer.c,
+ testsuite/libffi.call/cls_pointer_stack.c,
+ testsuite/libffi.call/cls_schar.c,
+ testsuite/libffi.call/cls_sint.c,
+ testsuite/libffi.call/cls_sshort.c,
+ testsuite/libffi.call/cls_uchar.c,
+ testsuite/libffi.call/cls_uint.c,
+ testsuite/libffi.call/cls_ulonglong.c,
+ testsuite/libffi.call/cls_ushort.c,
+ testsuite/libffi.call/err_bad_abi.c,
+ testsuite/libffi.call/err_bad_typedef.c,
+ testsuite/libffi.call/float2.c,
+ testsuite/libffi.call/huge_struct.c,
+ testsuite/libffi.call/nested_struct.c,
+ testsuite/libffi.call/nested_struct1.c,
+ testsuite/libffi.call/nested_struct10.c,
+ testsuite/libffi.call/nested_struct2.c,
+ testsuite/libffi.call/nested_struct3.c,
+ testsuite/libffi.call/nested_struct4.c,
+ testsuite/libffi.call/nested_struct5.c,
+ testsuite/libffi.call/nested_struct6.c,
+ testsuite/libffi.call/nested_struct7.c,
+ testsuite/libffi.call/nested_struct8.c,
+ testsuite/libffi.call/nested_struct9.c,
+ testsuite/libffi.call/problem1.c,
+ testsuite/libffi.call/return_ldl.c,
+ testsuite/libffi.call/return_ll1.c,
+ testsuite/libffi.call/stret_large.c,
+ testsuite/libffi.call/stret_large2.c,
+ testsuite/libffi.call/stret_medium.c,
+ testsuite/libffi.call/stret_medium2.c,
+ testsuite/libffi.special/unwindtest.cc: use ffi_closure_alloc instead
+ of checking for MMAP. Use intptr_t instead of long casts.
+
+2009-06-11 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ * testsuite/libffi.call/cls_longdouble_va.c: Add xfail sh*-*-linux-*.
+ * testsuite/libffi.call/err_bad_abi.c: Add xfail sh*-*-*.
+ * testsuite/libffi.call/err_bad_typedef.c: Likewise.
+
+2009-06-09 Andrew Haley <aph@redhat.com>
+
+ * src/x86/freebsd.S: Add missing file.
+
+2009-06-08 Andrew Haley <aph@redhat.com>
+
+ Import from libffi 3.0.8:
+
+ * doc/libffi.texi: New file.
+ * doc/libffi.info: Likewise.
+ * doc/stamp-vti: Likewise.
+ * man/Makefile.am: New file.
+ * man/ffi_call.3: New file.
+
+ * Makefile.am (EXTRA_DIST): Add src/x86/darwin64.S,
+ src/dlmalloc.c.
+ (nodist_libffi_la_SOURCES): Add X86_FREEBSD.
+
+ * configure.ac: Bump version to 3.0.8.
+ parisc*-*-linux*: Add.
+ i386-*-freebsd* | i386-*-openbsd*: Add.
+ powerpc-*-beos*: Add.
+ AM_CONDITIONAL X86_FREEBSD: Add.
+ AC_CONFIG_FILES: Add man/Makefile.
+
+ * include/ffi.h.in (FFI_FN): Change void (*)() to void (*)(void).
+
+2009-06-08 Andrew Haley <aph@redhat.com>
+
+ * README: Import from libffi 3.0.8.
+
+2009-06-08 Andrew Haley <aph@redhat.com>
+
+ * testsuite/libffi.call/err_bad_abi.c: Add xfails.
+ * testsuite/libffi.call/cls_longdouble_va.c: Add xfails.
+ * testsuite/libffi.call/cls_dbls_struct.c: Add xfail x86_64-*-linux-*.
+ * testsuite/libffi.call/err_bad_typedef.c: Add xfails.
+
+ * testsuite/libffi.call/stret_medium2.c: Add __UNUSED__ to args.
+ * testsuite/libffi.call/stret_medium.c: Likewise.
+ * testsuite/libffi.call/stret_large2.c: Likewise.
+ * testsuite/libffi.call/stret_large.c: Likewise.
+
+2008-12-26 Timothy Wall <twall@users.sf.net>
+
+ * testsuite/libffi.call/cls_longdouble.c,
+ testsuite/libffi.call/cls_longdouble_va.c,
+ testsuite/libffi.call/cls_align_longdouble.c,
+ testsuite/libffi.call/cls_align_longdouble_split.c,
+ testsuite/libffi.call/cls_align_longdouble_split2.c: mark expected
+ failures on x86_64 cygwin/mingw.
+
+2008-12-22 Timothy Wall <twall@users.sf.net>
+
+ * testsuite/libffi.call/closure_fn0.c,
+ testsuite/libffi.call/closure_fn1.c,
+ testsuite/libffi.call/closure_fn2.c,
+ testsuite/libffi.call/closure_fn3.c,
+ testsuite/libffi.call/closure_fn4.c,
+ testsuite/libffi.call/closure_fn5.c,
+ testsuite/libffi.call/closure_fn6.c,
+ testsuite/libffi.call/closure_loc_fn0.c,
+ testsuite/libffi.call/closure_stdcall.c,
+ testsuite/libffi.call/cls_align_pointer.c,
+ testsuite/libffi.call/cls_pointer.c,
+ testsuite/libffi.call/cls_pointer_stack.c: use portable cast from
+ pointer to integer (intptr_t).
+ * testsuite/libffi.call/cls_longdouble.c: disable for win64.
+
+2008-07-24 Anthony Green <green@redhat.com>
+
+ * testsuite/libffi.call/cls_dbls_struct.c,
+ testsuite/libffi.call/cls_double_va.c,
+ testsuite/libffi.call/cls_longdouble.c,
+ testsuite/libffi.call/cls_longdouble_va.c,
+ testsuite/libffi.call/cls_pointer.c,
+ testsuite/libffi.call/cls_pointer_stack.c,
+ testsuite/libffi.call/err_bad_abi.c: Clean up failures from
+ compiler warnings.
+
+2008-03-04 Anthony Green <green@redhat.com>
+ Blake Chaffin
+ hos@tamanegi.org
+
+ * testsuite/libffi.call/cls_align_longdouble_split2.c
+ testsuite/libffi.call/cls_align_longdouble_split.c
+ testsuite/libffi.call/cls_dbls_struct.c
+ testsuite/libffi.call/cls_double_va.c
+ testsuite/libffi.call/cls_longdouble.c
+ testsuite/libffi.call/cls_longdouble_va.c
+ testsuite/libffi.call/cls_pointer.c
+ testsuite/libffi.call/cls_pointer_stack.c
+ testsuite/libffi.call/err_bad_abi.c
+ testsuite/libffi.call/err_bad_typedef.c
+ testsuite/libffi.call/stret_large2.c
+ testsuite/libffi.call/stret_large.c
+ testsuite/libffi.call/stret_medium2.c
+ testsuite/libffi.call/stret_medium.c: New tests from Apple.
+
+2009-06-05 Andrew Haley <aph@redhat.com>
+
+ * src/x86/ffitarget.h, src/x86/ffi.c: Merge stdcall changes from
+ libffi.
+
+2009-06-04 Andrew Haley <aph@redhat.com>
+
+ * src/x86/ffitarget.h, src/x86/win32.S, src/x86/ffi.c: Back out
+ stdcall changes.
+
+2008-02-26 Anthony Green <green@redhat.com>
+ Thomas Heller <theller@ctypes.org>
+
+ * src/x86/ffi.c (ffi_closure_SYSV_inner): Change C++ comment to C
+ comment.
+
+2008-02-03 Timothy Wall <twall@users.sf.net>
+
+ * src/x86/ffi.c (FFI_INIT_TRAMPOLINE_STDCALL): Calculate jump return
+ offset based on code pointer, not data pointer.
+
+2008-01-31 Timothy Wall <twall@users.sf.net>
+
+ * testsuite/libffi.call/closure_stdcall.c: Add test for stdcall
+ closures.
+ * src/x86/ffitarget.h: Increase size of trampoline for stdcall
+ closures.
+ * src/x86/win32.S: Add assembly for stdcall closure.
+ * src/x86/ffi.c: Initialize stdcall closure trampoline.
+
+2009-06-04 Andrew Haley <aph@redhat.com>
+
+ * include/ffi.h.in: Change void (*)() to void (*)(void).
+ * src/x86/ffi.c: Likewise.
+
+2009-06-04 Andrew Haley <aph@redhat.com>
+
+ * src/powerpc/ppc_closure.S: Insert licence header.
+ * src/powerpc/linux64_closure.S: Likewise.
+ * src/m68k/sysv.S: Likewise.
+
+ * src/sh64/ffi.c: Change void (*)() to void (*)(void).
+ * src/powerpc/ffi.c: Likewise.
+ * src/powerpc/ffi_darwin.c: Likewise.
+ * src/m32r/ffi.c: Likewise.
+ * src/sh64/ffi.c: Likewise.
+ * src/x86/ffi64.c: Likewise.
+ * src/alpha/ffi.c: Likewise.
+ * src/alpha/osf.S: Likewise.
+ * src/frv/ffi.c: Likewise.
+ * src/s390/ffi.c: Likewise.
+ * src/pa/ffi.c: Likewise.
+ * src/pa/hpux32.S: Likewise.
+ * src/ia64/unix.S: Likewise.
+ * src/ia64/ffi.c: Likewise.
+ * src/sparc/ffi.c: Likewise.
+ * src/mips/ffi.c: Likewise.
+ * src/sh/ffi.c: Likewise.
+
+2008-02-15 David Daney <ddaney@avtrex.com>
+
+ * src/mips/ffi.c (USE__BUILTIN___CLEAR_CACHE):
+ Define (conditionally), and use it to include cachectl.h.
+ (ffi_prep_closure_loc): Fix cache flushing.
+ * src/mips/ffitarget.h (_ABIN32, _ABI64, _ABIO32): Define.
+
+2009-06-04 Andrew Haley <aph@redhat.com>
+
+ include/ffi.h.in,
+ src/arm/ffitarget.h,
+ src/arm/ffi.c,
+ src/arm/sysv.S,
+ src/powerpc/ffitarget.h,
+ src/closures.c,
+ src/sh64/ffitarget.h,
+ src/sh64/ffi.c,
+ src/sh64/sysv.S,
+ src/types.c,
+ src/x86/ffi64.c,
+ src/x86/ffitarget.h,
+ src/x86/win32.S,
+ src/x86/darwin.S,
+ src/x86/ffi.c,
+ src/x86/sysv.S,
+ src/x86/unix64.S,
+ src/alpha/ffitarget.h,
+ src/alpha/ffi.c,
+ src/alpha/osf.S,
+ src/m68k/ffitarget.h,
+ src/frv/ffitarget.h,
+ src/frv/ffi.c,
+ src/s390/ffitarget.h,
+ src/s390/sysv.S,
+ src/cris/ffitarget.h,
+ src/pa/linux.S,
+ src/pa/ffitarget.h,
+ src/pa/ffi.c,
+ src/raw_api.c,
+ src/ia64/ffitarget.h,
+ src/ia64/unix.S,
+ src/ia64/ffi.c,
+ src/ia64/ia64_flags.h,
+ src/java_raw_api.c,
+ src/debug.c,
+ src/sparc/v9.S,
+ src/sparc/ffitarget.h,
+ src/sparc/ffi.c,
+ src/sparc/v8.S,
+ src/mips/ffitarget.h,
+ src/mips/n32.S,
+ src/mips/o32.S,
+ src/mips/ffi.c,
+ src/prep_cif.c,
+ src/sh/ffitarget.h,
+ src/sh/ffi.c,
+ src/sh/sysv.S: Update license text.
+
+2009-05-22 Dave Korn <dave.korn.cygwin@gmail.com>
+
+ * src/x86/win32.S (_ffi_closure_STDCALL): New function.
+ (.eh_frame): Add FDE for it.
+
+2009-05-22 Dave Korn <dave.korn.cygwin@gmail.com>
+
+ * configure.ac: Also check if assembler supports pc-relative
+ relocs on X86_WIN32 targets.
+ * configure: Regenerate.
+ * src/x86/win32.S (ffi_prep_args): Declare extern, not global.
+ (_ffi_call_SYSV): Add missing function type symbol .def and
+ add EH markup labels.
+ (_ffi_call_STDCALL): Likewise.
+ (_ffi_closure_SYSV): Likewise.
+ (_ffi_closure_raw_SYSV): Likewise.
+ (.eh_frame): Add hand-crafted EH data.
+
2009-04-09 Jakub Jelinek <jakub@redhat.com>
* testsuite/lib/libffi-dg.exp: Change copyright header to refer to
diff --git a/libffi/Makefile.am b/libffi/Makefile.am
index 6bc8c1b0ea3..9705c8f4a9e 100644
--- a/libffi/Makefile.am
+++ b/libffi/Makefile.am
@@ -3,7 +3,7 @@
AUTOMAKE_OPTIONS = foreign subdir-objects
ACLOCAL_AMFLAGS = -I .. -I ../config
-SUBDIRS = include testsuite
+SUBDIRS = include testsuite man
EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj configure.host \
src/alpha/ffi.c src/alpha/osf.S src/alpha/ffitarget.h \
@@ -25,11 +25,11 @@ EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj configure.host \
src/sh/ffi.c src/sh/sysv.S src/sh/ffitarget.h \
src/sh64/ffi.c src/sh64/sysv.S src/sh64/ffitarget.h \
src/sparc/v8.S src/sparc/v9.S src/sparc/ffitarget.h \
- src/sparc/ffi.c \
+ src/sparc/ffi.c src/x86/darwin64.S \
src/x86/ffi.c src/x86/sysv.S src/x86/win32.S src/x86/darwin.S \
src/x86/ffi64.c src/x86/unix64.S src/x86/ffitarget.h \
src/pa/ffitarget.h src/pa/ffi.c src/pa/linux.S src/pa/hpux32.S \
- src/frv/ffi.c src/frv/eabi.S src/frv/ffitarget.h
+ src/frv/ffi.c src/frv/eabi.S src/frv/ffitarget.h src/dlmalloc.c
## ################################################################
@@ -90,9 +90,15 @@ endif
if X86
nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/sysv.S
endif
+if X86_FREEBSD
+nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/freebsd.S
+endif
if X86_WIN32
nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/win32.S
endif
+if X86_WIN64
+nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/win64.S
+endif
if X86_DARWIN
nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/darwin.S src/x86/ffi64.c src/x86/darwin64.S
endif
diff --git a/libffi/Makefile.in b/libffi/Makefile.in
index bc7e33c2b93..32f1ebbfa62 100644
--- a/libffi/Makefile.in
+++ b/libffi/Makefile.in
@@ -39,26 +39,28 @@ host_triplet = @host@
target_triplet = @target@
@MIPS_TRUE@am__append_1 = src/mips/ffi.c src/mips/o32.S src/mips/n32.S
@X86_TRUE@am__append_2 = src/x86/ffi.c src/x86/sysv.S
-@X86_WIN32_TRUE@am__append_3 = src/x86/ffi.c src/x86/win32.S
-@X86_DARWIN_TRUE@am__append_4 = src/x86/ffi.c src/x86/darwin.S src/x86/ffi64.c src/x86/darwin64.S
-@SPARC_TRUE@am__append_5 = src/sparc/ffi.c src/sparc/v8.S src/sparc/v9.S
-@ALPHA_TRUE@am__append_6 = src/alpha/ffi.c src/alpha/osf.S
-@IA64_TRUE@am__append_7 = src/ia64/ffi.c src/ia64/unix.S
-@M32R_TRUE@am__append_8 = src/m32r/sysv.S src/m32r/ffi.c
-@M68K_TRUE@am__append_9 = src/m68k/ffi.c src/m68k/sysv.S
-@POWERPC_TRUE@am__append_10 = src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/ppc_closure.S src/powerpc/linux64.S src/powerpc/linux64_closure.S
-@POWERPC_AIX_TRUE@am__append_11 = src/powerpc/ffi_darwin.c src/powerpc/aix.S src/powerpc/aix_closure.S
-@POWERPC_DARWIN_TRUE@am__append_12 = src/powerpc/ffi_darwin.c src/powerpc/darwin.S src/powerpc/darwin_closure.S
-@POWERPC_FREEBSD_TRUE@am__append_13 = src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/ppc_closure.S
-@ARM_TRUE@am__append_14 = src/arm/sysv.S src/arm/ffi.c
-@LIBFFI_CRIS_TRUE@am__append_15 = src/cris/sysv.S src/cris/ffi.c
-@FRV_TRUE@am__append_16 = src/frv/eabi.S src/frv/ffi.c
-@S390_TRUE@am__append_17 = src/s390/sysv.S src/s390/ffi.c
-@X86_64_TRUE@am__append_18 = src/x86/ffi64.c src/x86/unix64.S src/x86/ffi.c src/x86/sysv.S
-@SH_TRUE@am__append_19 = src/sh/sysv.S src/sh/ffi.c
-@SH64_TRUE@am__append_20 = src/sh64/sysv.S src/sh64/ffi.c
-@PA_LINUX_TRUE@am__append_21 = src/pa/linux.S src/pa/ffi.c
-@PA_HPUX_TRUE@am__append_22 = src/pa/hpux32.S src/pa/ffi.c
+@X86_FREEBSD_TRUE@am__append_3 = src/x86/ffi.c src/x86/freebsd.S
+@X86_WIN32_TRUE@am__append_4 = src/x86/ffi.c src/x86/win32.S
+@X86_WIN64_TRUE@am__append_5 = src/x86/ffi.c src/x86/win64.S
+@X86_DARWIN_TRUE@am__append_6 = src/x86/ffi.c src/x86/darwin.S src/x86/ffi64.c src/x86/darwin64.S
+@SPARC_TRUE@am__append_7 = src/sparc/ffi.c src/sparc/v8.S src/sparc/v9.S
+@ALPHA_TRUE@am__append_8 = src/alpha/ffi.c src/alpha/osf.S
+@IA64_TRUE@am__append_9 = src/ia64/ffi.c src/ia64/unix.S
+@M32R_TRUE@am__append_10 = src/m32r/sysv.S src/m32r/ffi.c
+@M68K_TRUE@am__append_11 = src/m68k/ffi.c src/m68k/sysv.S
+@POWERPC_TRUE@am__append_12 = src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/ppc_closure.S src/powerpc/linux64.S src/powerpc/linux64_closure.S
+@POWERPC_AIX_TRUE@am__append_13 = src/powerpc/ffi_darwin.c src/powerpc/aix.S src/powerpc/aix_closure.S
+@POWERPC_DARWIN_TRUE@am__append_14 = src/powerpc/ffi_darwin.c src/powerpc/darwin.S src/powerpc/darwin_closure.S
+@POWERPC_FREEBSD_TRUE@am__append_15 = src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/ppc_closure.S
+@ARM_TRUE@am__append_16 = src/arm/sysv.S src/arm/ffi.c
+@LIBFFI_CRIS_TRUE@am__append_17 = src/cris/sysv.S src/cris/ffi.c
+@FRV_TRUE@am__append_18 = src/frv/eabi.S src/frv/ffi.c
+@S390_TRUE@am__append_19 = src/s390/sysv.S src/s390/ffi.c
+@X86_64_TRUE@am__append_20 = src/x86/ffi64.c src/x86/unix64.S src/x86/ffi.c src/x86/sysv.S
+@SH_TRUE@am__append_21 = src/sh/sysv.S src/sh/ffi.c
+@SH64_TRUE@am__append_22 = src/sh64/sysv.S src/sh64/ffi.c
+@PA_LINUX_TRUE@am__append_23 = src/pa/linux.S src/pa/ffi.c
+@PA_HPUX_TRUE@am__append_24 = src/pa/hpux32.S src/pa/ffi.c
DIST_COMMON = README $(am__configure_deps) $(srcdir)/../compile \
$(srcdir)/../config.guess $(srcdir)/../config.sub \
$(srcdir)/../depcomp $(srcdir)/../install-sh \
@@ -100,38 +102,40 @@ am_libffi_la_OBJECTS = src/debug.lo src/prep_cif.lo src/types.lo \
@MIPS_TRUE@am__objects_1 = src/mips/ffi.lo src/mips/o32.lo \
@MIPS_TRUE@ src/mips/n32.lo
@X86_TRUE@am__objects_2 = src/x86/ffi.lo src/x86/sysv.lo
-@X86_WIN32_TRUE@am__objects_3 = src/x86/ffi.lo src/x86/win32.lo
-@X86_DARWIN_TRUE@am__objects_4 = src/x86/ffi.lo src/x86/darwin.lo \
+@X86_FREEBSD_TRUE@am__objects_3 = src/x86/ffi.lo src/x86/freebsd.lo
+@X86_WIN32_TRUE@am__objects_4 = src/x86/ffi.lo src/x86/win32.lo
+@X86_WIN64_TRUE@am__objects_5 = src/x86/ffi.lo src/x86/win64.lo
+@X86_DARWIN_TRUE@am__objects_6 = src/x86/ffi.lo src/x86/darwin.lo \
@X86_DARWIN_TRUE@ src/x86/ffi64.lo src/x86/darwin64.lo
-@SPARC_TRUE@am__objects_5 = src/sparc/ffi.lo src/sparc/v8.lo \
+@SPARC_TRUE@am__objects_7 = src/sparc/ffi.lo src/sparc/v8.lo \
@SPARC_TRUE@ src/sparc/v9.lo
-@ALPHA_TRUE@am__objects_6 = src/alpha/ffi.lo src/alpha/osf.lo
-@IA64_TRUE@am__objects_7 = src/ia64/ffi.lo src/ia64/unix.lo
-@M32R_TRUE@am__objects_8 = src/m32r/sysv.lo src/m32r/ffi.lo
-@M68K_TRUE@am__objects_9 = src/m68k/ffi.lo src/m68k/sysv.lo
-@POWERPC_TRUE@am__objects_10 = src/powerpc/ffi.lo src/powerpc/sysv.lo \
+@ALPHA_TRUE@am__objects_8 = src/alpha/ffi.lo src/alpha/osf.lo
+@IA64_TRUE@am__objects_9 = src/ia64/ffi.lo src/ia64/unix.lo
+@M32R_TRUE@am__objects_10 = src/m32r/sysv.lo src/m32r/ffi.lo
+@M68K_TRUE@am__objects_11 = src/m68k/ffi.lo src/m68k/sysv.lo
+@POWERPC_TRUE@am__objects_12 = src/powerpc/ffi.lo src/powerpc/sysv.lo \
@POWERPC_TRUE@ src/powerpc/ppc_closure.lo \
@POWERPC_TRUE@ src/powerpc/linux64.lo \
@POWERPC_TRUE@ src/powerpc/linux64_closure.lo
-@POWERPC_AIX_TRUE@am__objects_11 = src/powerpc/ffi_darwin.lo \
+@POWERPC_AIX_TRUE@am__objects_13 = src/powerpc/ffi_darwin.lo \
@POWERPC_AIX_TRUE@ src/powerpc/aix.lo \
@POWERPC_AIX_TRUE@ src/powerpc/aix_closure.lo
-@POWERPC_DARWIN_TRUE@am__objects_12 = src/powerpc/ffi_darwin.lo \
+@POWERPC_DARWIN_TRUE@am__objects_14 = src/powerpc/ffi_darwin.lo \
@POWERPC_DARWIN_TRUE@ src/powerpc/darwin.lo \
@POWERPC_DARWIN_TRUE@ src/powerpc/darwin_closure.lo
-@POWERPC_FREEBSD_TRUE@am__objects_13 = src/powerpc/ffi.lo \
+@POWERPC_FREEBSD_TRUE@am__objects_15 = src/powerpc/ffi.lo \
@POWERPC_FREEBSD_TRUE@ src/powerpc/sysv.lo \
@POWERPC_FREEBSD_TRUE@ src/powerpc/ppc_closure.lo
-@ARM_TRUE@am__objects_14 = src/arm/sysv.lo src/arm/ffi.lo
-@LIBFFI_CRIS_TRUE@am__objects_15 = src/cris/sysv.lo src/cris/ffi.lo
-@FRV_TRUE@am__objects_16 = src/frv/eabi.lo src/frv/ffi.lo
-@S390_TRUE@am__objects_17 = src/s390/sysv.lo src/s390/ffi.lo
-@X86_64_TRUE@am__objects_18 = src/x86/ffi64.lo src/x86/unix64.lo \
+@ARM_TRUE@am__objects_16 = src/arm/sysv.lo src/arm/ffi.lo
+@LIBFFI_CRIS_TRUE@am__objects_17 = src/cris/sysv.lo src/cris/ffi.lo
+@FRV_TRUE@am__objects_18 = src/frv/eabi.lo src/frv/ffi.lo
+@S390_TRUE@am__objects_19 = src/s390/sysv.lo src/s390/ffi.lo
+@X86_64_TRUE@am__objects_20 = src/x86/ffi64.lo src/x86/unix64.lo \
@X86_64_TRUE@ src/x86/ffi.lo src/x86/sysv.lo
-@SH_TRUE@am__objects_19 = src/sh/sysv.lo src/sh/ffi.lo
-@SH64_TRUE@am__objects_20 = src/sh64/sysv.lo src/sh64/ffi.lo
-@PA_LINUX_TRUE@am__objects_21 = src/pa/linux.lo src/pa/ffi.lo
-@PA_HPUX_TRUE@am__objects_22 = src/pa/hpux32.lo src/pa/ffi.lo
+@SH_TRUE@am__objects_21 = src/sh/sysv.lo src/sh/ffi.lo
+@SH64_TRUE@am__objects_22 = src/sh64/sysv.lo src/sh64/ffi.lo
+@PA_LINUX_TRUE@am__objects_23 = src/pa/linux.lo src/pa/ffi.lo
+@PA_HPUX_TRUE@am__objects_24 = src/pa/hpux32.lo src/pa/ffi.lo
nodist_libffi_la_OBJECTS = $(am__objects_1) $(am__objects_2) \
$(am__objects_3) $(am__objects_4) $(am__objects_5) \
$(am__objects_6) $(am__objects_7) $(am__objects_8) \
@@ -139,22 +143,23 @@ nodist_libffi_la_OBJECTS = $(am__objects_1) $(am__objects_2) \
$(am__objects_12) $(am__objects_13) $(am__objects_14) \
$(am__objects_15) $(am__objects_16) $(am__objects_17) \
$(am__objects_18) $(am__objects_19) $(am__objects_20) \
- $(am__objects_21) $(am__objects_22)
+ $(am__objects_21) $(am__objects_22) $(am__objects_23) \
+ $(am__objects_24)
libffi_la_OBJECTS = $(am_libffi_la_OBJECTS) \
$(nodist_libffi_la_OBJECTS)
libffi_convenience_la_LIBADD =
-am__objects_23 = src/debug.lo src/prep_cif.lo src/types.lo \
+am__objects_25 = src/debug.lo src/prep_cif.lo src/types.lo \
src/raw_api.lo src/java_raw_api.lo src/closures.lo
-am_libffi_convenience_la_OBJECTS = $(am__objects_23)
-am__objects_24 = $(am__objects_1) $(am__objects_2) $(am__objects_3) \
+am_libffi_convenience_la_OBJECTS = $(am__objects_25)
+am__objects_26 = $(am__objects_1) $(am__objects_2) $(am__objects_3) \
$(am__objects_4) $(am__objects_5) $(am__objects_6) \
$(am__objects_7) $(am__objects_8) $(am__objects_9) \
$(am__objects_10) $(am__objects_11) $(am__objects_12) \
$(am__objects_13) $(am__objects_14) $(am__objects_15) \
$(am__objects_16) $(am__objects_17) $(am__objects_18) \
$(am__objects_19) $(am__objects_20) $(am__objects_21) \
- $(am__objects_22)
-nodist_libffi_convenience_la_OBJECTS = $(am__objects_24)
+ $(am__objects_22) $(am__objects_23) $(am__objects_24)
+nodist_libffi_convenience_la_OBJECTS = $(am__objects_26)
libffi_convenience_la_OBJECTS = $(am_libffi_convenience_la_OBJECTS) \
$(nodist_libffi_convenience_la_OBJECTS)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I.
@@ -313,9 +318,13 @@ X86_64_TRUE = @X86_64_TRUE@
X86_DARWIN_FALSE = @X86_DARWIN_FALSE@
X86_DARWIN_TRUE = @X86_DARWIN_TRUE@
X86_FALSE = @X86_FALSE@
+X86_FREEBSD_FALSE = @X86_FREEBSD_FALSE@
+X86_FREEBSD_TRUE = @X86_FREEBSD_TRUE@
X86_TRUE = @X86_TRUE@
X86_WIN32_FALSE = @X86_WIN32_FALSE@
X86_WIN32_TRUE = @X86_WIN32_TRUE@
+X86_WIN64_FALSE = @X86_WIN64_FALSE@
+X86_WIN64_TRUE = @X86_WIN64_TRUE@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_DSYMUTIL = @ac_ct_DSYMUTIL@
@@ -372,7 +381,7 @@ toolexecdir = @toolexecdir@
toolexeclibdir = @toolexeclibdir@
AUTOMAKE_OPTIONS = foreign subdir-objects
ACLOCAL_AMFLAGS = -I .. -I ../config
-SUBDIRS = include testsuite
+SUBDIRS = include testsuite man
EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj configure.host \
src/alpha/ffi.c src/alpha/osf.S src/alpha/ffitarget.h \
src/arm/ffi.c src/arm/sysv.S src/arm/ffitarget.h \
@@ -393,11 +402,11 @@ EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj configure.host \
src/sh/ffi.c src/sh/sysv.S src/sh/ffitarget.h \
src/sh64/ffi.c src/sh64/sysv.S src/sh64/ffitarget.h \
src/sparc/v8.S src/sparc/v9.S src/sparc/ffitarget.h \
- src/sparc/ffi.c \
+ src/sparc/ffi.c src/x86/darwin64.S \
src/x86/ffi.c src/x86/sysv.S src/x86/win32.S src/x86/darwin.S \
src/x86/ffi64.c src/x86/unix64.S src/x86/ffitarget.h \
src/pa/ffitarget.h src/pa/ffi.c src/pa/linux.S src/pa/hpux32.S \
- src/frv/ffi.c src/frv/eabi.S src/frv/ffitarget.h
+ src/frv/ffi.c src/frv/eabi.S src/frv/ffitarget.h src/dlmalloc.c
# Work around what appears to be a GNU make bug handling MAKEFLAGS
@@ -450,7 +459,8 @@ nodist_libffi_la_SOURCES = $(am__append_1) $(am__append_2) \
$(am__append_12) $(am__append_13) $(am__append_14) \
$(am__append_15) $(am__append_16) $(am__append_17) \
$(am__append_18) $(am__append_19) $(am__append_20) \
- $(am__append_21) $(am__append_22)
+ $(am__append_21) $(am__append_22) $(am__append_23) \
+ $(am__append_24)
libffi_convenience_la_SOURCES = $(libffi_la_SOURCES)
nodist_libffi_convenience_la_SOURCES = $(nodist_libffi_la_SOURCES)
AM_CFLAGS = -Wall -g -fexceptions
@@ -583,8 +593,12 @@ src/x86/ffi.lo: src/x86/$(am__dirstamp) \
src/x86/$(DEPDIR)/$(am__dirstamp)
src/x86/sysv.lo: src/x86/$(am__dirstamp) \
src/x86/$(DEPDIR)/$(am__dirstamp)
+src/x86/freebsd.lo: src/x86/$(am__dirstamp) \
+ src/x86/$(DEPDIR)/$(am__dirstamp)
src/x86/win32.lo: src/x86/$(am__dirstamp) \
src/x86/$(DEPDIR)/$(am__dirstamp)
+src/x86/win64.lo: src/x86/$(am__dirstamp) \
+ src/x86/$(DEPDIR)/$(am__dirstamp)
src/x86/darwin.lo: src/x86/$(am__dirstamp) \
src/x86/$(DEPDIR)/$(am__dirstamp)
src/x86/ffi64.lo: src/x86/$(am__dirstamp) \
@@ -846,12 +860,16 @@ mostlyclean-compile:
-rm -f src/x86/ffi.lo
-rm -f src/x86/ffi64.$(OBJEXT)
-rm -f src/x86/ffi64.lo
+ -rm -f src/x86/freebsd.$(OBJEXT)
+ -rm -f src/x86/freebsd.lo
-rm -f src/x86/sysv.$(OBJEXT)
-rm -f src/x86/sysv.lo
-rm -f src/x86/unix64.$(OBJEXT)
-rm -f src/x86/unix64.lo
-rm -f src/x86/win32.$(OBJEXT)
-rm -f src/x86/win32.lo
+ -rm -f src/x86/win64.$(OBJEXT)
+ -rm -f src/x86/win64.lo
distclean-compile:
-rm -f *.tab.c
@@ -1091,7 +1109,7 @@ distclean-tags:
distdir: $(DISTFILES)
$(am__remove_distdir)
mkdir $(distdir)
- $(mkdir_p) $(distdir)/.. $(distdir)/../config $(distdir)/include $(distdir)/src/alpha $(distdir)/src/arm $(distdir)/src/cris $(distdir)/src/frv $(distdir)/src/ia64 $(distdir)/src/m32r $(distdir)/src/m68k $(distdir)/src/mips $(distdir)/src/pa $(distdir)/src/powerpc $(distdir)/src/s390 $(distdir)/src/sh $(distdir)/src/sh64 $(distdir)/src/sparc $(distdir)/src/x86
+ $(mkdir_p) $(distdir)/.. $(distdir)/../config $(distdir)/include $(distdir)/src $(distdir)/src/alpha $(distdir)/src/arm $(distdir)/src/cris $(distdir)/src/frv $(distdir)/src/ia64 $(distdir)/src/m32r $(distdir)/src/m68k $(distdir)/src/mips $(distdir)/src/pa $(distdir)/src/powerpc $(distdir)/src/s390 $(distdir)/src/sh $(distdir)/src/sh64 $(distdir)/src/sparc $(distdir)/src/x86
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
diff --git a/libffi/README b/libffi/README
index f426c9df1e9..f102612d11c 100644
--- a/libffi/README
+++ b/libffi/README
@@ -4,10 +4,8 @@ shipped with GCC as convenience.
Status
======
-libffi-2.00 has not been released yet! This is a development snapshot!
-
-libffi-1.20 was released on October 5, 1998. Check the libffi web
-page for updates: <URL:http://sources.redhat.com/libffi/>.
+libffi-3.0.8 was released on December 19, 2008. Check the libffi web
+page for updates: <URL:http://sourceware.org/libffi/>.
What is libffi?
@@ -32,7 +30,7 @@ interface to various calling conventions. This allows a programmer to
call any function specified by a call interface description at run
time.
-Ffi stands for Foreign Function Interface. A foreign function
+FFI stands for Foreign Function Interface. A foreign function
interface is the popular name for the interface that allows code
written in one language to call code written in another language. The
libffi library really only provides the lowest, machine dependent
@@ -41,38 +39,37 @@ exist above libffi that handles type conversions for values passed
between the two languages.
-Supported Platforms and Prerequisites
-=====================================
-
-Libffi has been ported to:
-
- SunOS 4.1.3 & Solaris 2.x (SPARC-V8, SPARC-V9)
-
- Irix 5.3 & 6.2 (System V/o32 & n32)
-
- Intel x86 - Linux (System V ABI)
-
- Alpha - Linux and OSF/1
-
- m68k - Linux (System V ABI)
-
- PowerPC - Linux (System V ABI, Darwin, AIX)
-
- ARM - Linux (System V ABI)
-
-Libffi has been tested with the egcs 1.0.2 gcc compiler. Chances are
-that other versions will work. Libffi has also been built and tested
-with the SGI compiler tools.
-
-On PowerPC, the tests failed (see the note below).
-
-You must use GNU make to build libffi. SGI's make will not work.
-Sun's probably won't either.
-
-If you port libffi to another platform, please let me know! I assume
-that some will be easy (x86 NetBSD), and others will be more difficult
-(HP).
-
+Supported Platforms
+===================
+
+Libffi has been ported to many different platforms, although this
+release was only tested on:
+
+ arm oabi linux
+ arm eabi linux
+ hppa linux
+ mips o32 linux (little endian)
+ powerpc darwin
+ powerpc freebsd
+ powerpc64 linux
+ sparc solaris
+ sparc64 freebsd
+ sparc64 solaris
+ x86 cygwin
+ x86 darwin
+ x86 freebsd
+ x86 linux
+ x86 openbsd
+ x86 solaris
+ x86-64 mingw
+ x86-64 darwin
+ x86-64 linux
+ x86-64 OS X
+ x86-64 freebsd
+ x86-64 solaris
+
+Please send additional platform test results to
+libffi-discuss@sourceware.org.
Installing libffi
=================
@@ -101,216 +98,17 @@ Purify, as it will slow down the library.
Configure has many other options. Use "configure --help" to see them all.
Once configure has finished, type "make". Note that you must be using
-GNU make. SGI's make will not work. Sun's probably won't either.
-You can ftp GNU make from prep.ai.mit.edu:/pub/gnu.
+GNU make. You can ftp GNU make from prep.ai.mit.edu:/pub/gnu.
-To ensure that libffi is working as advertised, type "make test".
+To ensure that libffi is working as advertised, type "make check".
+This will require that you have DejaGNU installed.
To install the library and header files, type "make install".
-Using libffi
-============
-
- The Basics
- ----------
-
-Libffi assumes that you have a pointer to the function you wish to
-call and that you know the number and types of arguments to pass it,
-as well as the return type of the function.
-
-The first thing you must do is create an ffi_cif object that matches
-the signature of the function you wish to call. The cif in ffi_cif
-stands for Call InterFace. To prepare a call interface object, use the
-following function:
-
-ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi,
- unsigned int nargs,
- ffi_type *rtype, ffi_type **atypes);
-
- CIF is a pointer to the call interface object you wish
- to initialize.
-
- ABI is an enum that specifies the calling convention
- to use for the call. FFI_DEFAULT_ABI defaults
- to the system's native calling convention. Other
- ABI's may be used with care. They are system
- specific.
-
- NARGS is the number of arguments this function accepts.
- libffi does not yet support vararg functions.
-
- RTYPE is a pointer to an ffi_type structure that represents
- the return type of the function. Ffi_type objects
- describe the types of values. libffi provides
- ffi_type objects for many of the native C types:
- signed int, unsigned int, signed char, unsigned char,
- etc. There is also a pointer ffi_type object and
- a void ffi_type. Use &ffi_type_void for functions that
- don't return values.
-
- ATYPES is a vector of ffi_type pointers. ARGS must be NARGS long.
- If NARGS is 0, this is ignored.
-
-
-ffi_prep_cif will return a status code that you are responsible
-for checking. It will be one of the following:
-
- FFI_OK - All is good.
-
- FFI_BAD_TYPEDEF - One of the ffi_type objects that ffi_prep_cif
- came across is bad.
-
-
-Before making the call, the VALUES vector should be initialized
-with pointers to the appropriate argument values.
-
-To call the the function using the initialized ffi_cif, use the
-ffi_call function:
-
-void ffi_call(ffi_cif *cif, void *fn, void *rvalue, void **avalues);
-
- CIF is a pointer to the ffi_cif initialized specifically
- for this function.
-
- FN is a pointer to the function you want to call.
-
- RVALUE is a pointer to a chunk of memory that is to hold the
- result of the function call. Currently, it must be
- at least one word in size (except for the n32 version
- under Irix 6.x, which must be a pointer to an 8 byte
- aligned value (a long long). It must also be at least
- word aligned (depending on the return type, and the
- system's alignment requirements). If RTYPE is
- &ffi_type_void, this is ignored. If RVALUE is NULL,
- the return value is discarded.
-
- AVALUES is a vector of void* that point to the memory locations
- holding the argument values for a call.
- If NARGS is 0, this is ignored.
-
-
-If you are expecting a return value from FN it will have been stored
-at RVALUE.
-
-
-
- An Example
- ----------
-
-Here is a trivial example that calls puts() a few times.
-
- #include <stdio.h>
- #include <ffi.h>
-
- int main()
- {
- ffi_cif cif;
- ffi_type *args[1];
- void *values[1];
- char *s;
- int rc;
-
- /* Initialize the argument info vectors */
- args[0] = &ffi_type_pointer;
- values[0] = &s;
-
- /* Initialize the cif */
- if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
- &ffi_type_uint, args) == FFI_OK)
- {
- s = "Hello World!";
- ffi_call(&cif, puts, &rc, values);
- /* rc now holds the result of the call to puts */
-
- /* values holds a pointer to the function's arg, so to
- call puts() again all we need to do is change the
- value of s */
- s = "This is cool!";
- ffi_call(&cif, puts, &rc, values);
- }
-
- return 0;
- }
-
-
-
- Aggregate Types
- ---------------
-
-Although libffi has no special support for unions or bit-fields, it is
-perfectly happy passing structures back and forth. You must first
-describe the structure to libffi by creating a new ffi_type object
-for it. Here is the definition of ffi_type:
-
- typedef struct _ffi_type
- {
- unsigned size;
- short alignment;
- short type;
- struct _ffi_type **elements;
- } ffi_type;
-
-All structures must have type set to FFI_TYPE_STRUCT. You may set
-size and alignment to 0. These will be calculated and reset to the
-appropriate values by ffi_prep_cif().
-
-elements is a NULL terminated array of pointers to ffi_type objects
-that describe the type of the structure elements. These may, in turn,
-be structure elements.
-
-The following example initializes a ffi_type object representing the
-tm struct from Linux's time.h:
-
- struct tm {
- int tm_sec;
- int tm_min;
- int tm_hour;
- int tm_mday;
- int tm_mon;
- int tm_year;
- int tm_wday;
- int tm_yday;
- int tm_isdst;
- /* Those are for future use. */
- long int __tm_gmtoff__;
- __const char *__tm_zone__;
- };
-
- {
- ffi_type tm_type;
- ffi_type *tm_type_elements[12];
- int i;
-
- tm_type.size = tm_type.alignment = 0;
- tm_type.elements = &tm_type_elements;
-
- for (i = 0; i < 9; i++)
- tm_type_elements[i] = &ffi_type_sint;
-
- tm_type_elements[9] = &ffi_type_slong;
- tm_type_elements[10] = &ffi_type_pointer;
- tm_type_elements[11] = NULL;
-
- /* tm_type can now be used to represent tm argument types and
- return types for ffi_prep_cif() */
- }
-
-
-
Platform Specific Notes
=======================
- Intel x86
- ---------
-
-There are no known problems with the x86 port.
-
- Sun SPARC - SunOS 4.1.3 & Solaris 2.x
- -------------------------------------
-
-You must use GNU Make to build libffi on Sun platforms.
-
MIPS - Irix 5.3 & 6.x
---------------------
@@ -339,13 +137,6 @@ If you don't do this you are liable to get spurious bus errors.
You must use GNU Make to build libffi on SGI platforms.
- ARM - System V ABI
- ------------------
-
-The ARM port was performed on a NetWinder running ARM Linux ELF
-(2.0.31) and gcc 2.8.1.
-
-
PowerPC System V ABI
--------------------
@@ -375,6 +166,42 @@ arguments' test).
History
=======
+3.0.7 Nov-11-08
+ Fix for ppc FreeBSD.
+ (thanks to Andreas Tobler)
+
+3.0.6 Jul-17-08
+ Fix for closures on sh.
+ Mark the sh/sh64 stack as non-executable.
+ (both thanks to Kaz Kojima)
+
+3.0.5 Apr-3-08
+ Fix libffi.pc file.
+ Fix #define ARM for IcedTea users.
+ Fix x86 closure bug.
+
+3.0.4 Feb-24-08
+ Fix x86 OpenBSD configury.
+
+3.0.3 Feb-22-08
+ Enable x86 OpenBSD thanks to Thomas Heller, and
+ x86-64 FreeBSD thanks to Björn König and Andreas Tobler.
+ Clean up test instruction in README.
+
+3.0.2 Feb-21-08
+ Improved x86 FreeBSD support.
+ Thanks to Björn König.
+
+3.0.1 Feb-15-08
+ Fix instruction cache flushing bug on MIPS.
+ Thanks to David Daney.
+
+3.0.0 Feb-15-08
+ Many changes, mostly thanks to the GCC project.
+ Cygnus Solutions is now Red Hat.
+
+ [10 years go by...]
+
1.20 Oct-5-98
Raffaele Sena produces ARM port.
@@ -458,34 +285,56 @@ History
Authors & Credits
=================
-libffi was written by Anthony Green <green@cygnus.com>.
+libffi was originally written by Anthony Green <green@redhat.com>.
+
+The developers of the GNU Compiler Collection project have made
+innumerable valuable contributions. See the ChangeLog file for
+details.
-Portions of libffi were derived from Gianni Mariani's free gencall
-library for Silicon Graphics machines.
+Some of the ideas behind libffi were inspired by Gianni Mariani's free
+gencall library for Silicon Graphics machines.
The closure mechanism was designed and implemented by Kresten Krab
Thorup.
-The Sparc port was derived from code contributed by the fine folks at
-Visible Decisions Inc <http://www.vdi.com>. Further enhancements were
-made by Gordon Irlam at Cygnus Solutions <http://www.cygnus.com>.
-
-The Alpha port was written by Richard Henderson at Cygnus Solutions.
-
-Andreas Schwab ported libffi to m68k Linux and provided a number of
-bug fixes.
-
-Geoffrey Keating ported libffi to the PowerPC.
-
-Raffaele Sena ported libffi to the ARM.
+Major processor architecture ports were contributed by the following
+developers:
+
+alpha Richard Henderson
+arm Raffaele Sena
+cris Simon Posnjak, Hans-Peter Nilsson
+frv Anthony Green
+ia64 Hans Boehm
+m32r Kazuhiro Inaoka
+m68k Andreas Schwab
+mips Anthony Green, Casey Marshall
+mips64 David Daney
+pa Randolph Chung, Dave Anglin, Andreas Tobler
+powerpc Geoffrey Keating, Andreas Tobler,
+ David Edelsohn, John Hornkvist
+powerpc64 Jakub Jelinek
+s390 Gerhard Tonn, Ulrich Weigand
+sh Kaz Kojima
+sh64 Kaz Kojima
+sparc Anthony Green, Gordon Irlam
+x86 Anthony Green, Jon Beniston
+x86-64 Bo Thorsen
Jesper Skov and Andrew Haley both did more than their fair share of
stepping through the code and tracking down bugs.
-Thanks also to Tom Tromey for bug fixes and configuration help.
+Thanks also to Tom Tromey for bug fixes, documentation and
+configuration help.
Thanks to Jim Blandy, who provided some useful feedback on the libffi
interface.
+Andreas Tobler has done a tremendous amount of work on the testsuite.
+
+Alex Oliva solved the executable page problem for SElinux.
+
+The list above is almost certainly incomplete and inaccurate. I'm
+happy to make corrections or additions upon request.
+
If you have a problem, or have found a bug, please send a note to
-green@cygnus.com.
+green@redhat.com.
diff --git a/libffi/configure b/libffi/configure
index a1ec40bfe72..f8665f73163 100755
--- a/libffi/configure
+++ b/libffi/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.59 for libffi 2.1.
+# Generated by GNU Autoconf 2.59 for libffi 3.0.8.
#
# Report bugs to <http://gcc.gnu.org/bugs.html>.
#
@@ -418,8 +418,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
# Identity of this package.
PACKAGE_NAME='libffi'
PACKAGE_TARNAME='libffi'
-PACKAGE_VERSION='2.1'
-PACKAGE_STRING='libffi 2.1'
+PACKAGE_VERSION='3.0.8'
+PACKAGE_STRING='libffi 3.0.8'
PACKAGE_BUGREPORT='http://gcc.gnu.org/bugs.html'
# Factoring default headers for most tests.
@@ -459,7 +459,7 @@ ac_includes_default="\
# include <unistd.h>
#endif"
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS multi_basedir build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar CC ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CFLAGS CCAS CCASFLAGS LIBTOOL SED EGREP FGREP GREP LD DUMPBIN ac_ct_DUMPBIN NM LN_S OBJDUMP ac_ct_OBJDUMP AR ac_ct_AR RANLIB ac_ct_RANLIB lt_ECHO DSYMUTIL ac_ct_DSYMUTIL NMEDIT ac_ct_NMEDIT LIPO ac_ct_LIPO OTOOL ac_ct_OTOOL OTOOL64 ac_ct_OTOOL64 CPP CPPFLAGS MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT TESTSUBDIR_TRUE TESTSUBDIR_FALSE AM_RUNTESTFLAGS MIPS_TRUE MIPS_FALSE SPARC_TRUE SPARC_FALSE X86_TRUE X86_FALSE X86_WIN32_TRUE X86_WIN32_FALSE X86_DARWIN_TRUE X86_DARWIN_FALSE ALPHA_TRUE ALPHA_FALSE IA64_TRUE IA64_FALSE M32R_TRUE M32R_FALSE M68K_TRUE M68K_FALSE POWERPC_TRUE POWERPC_FALSE POWERPC_AIX_TRUE POWERPC_AIX_FALSE POWERPC_DARWIN_TRUE POWERPC_DARWIN_FALSE POWERPC_FREEBSD_TRUE POWERPC_FREEBSD_FALSE ARM_TRUE ARM_FALSE LIBFFI_CRIS_TRUE LIBFFI_CRIS_FALSE FRV_TRUE FRV_FALSE S390_TRUE S390_FALSE X86_64_TRUE X86_64_FALSE SH_TRUE SH_FALSE SH64_TRUE SH64_FALSE PA_LINUX_TRUE PA_LINUX_FALSE PA_HPUX_TRUE PA_HPUX_FALSE PA64_HPUX_TRUE PA64_HPUX_FALSE ALLOCA HAVE_LONG_DOUBLE TARGET TARGETDIR toolexecdir toolexeclibdir LIBOBJS LTLIBOBJS'
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS multi_basedir build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar CC ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CFLAGS CCAS CCASFLAGS LIBTOOL SED EGREP FGREP GREP LD DUMPBIN ac_ct_DUMPBIN NM LN_S OBJDUMP ac_ct_OBJDUMP AR ac_ct_AR RANLIB ac_ct_RANLIB lt_ECHO DSYMUTIL ac_ct_DSYMUTIL NMEDIT ac_ct_NMEDIT LIPO ac_ct_LIPO OTOOL ac_ct_OTOOL OTOOL64 ac_ct_OTOOL64 CPP CPPFLAGS MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT TESTSUBDIR_TRUE TESTSUBDIR_FALSE AM_RUNTESTFLAGS MIPS_TRUE MIPS_FALSE SPARC_TRUE SPARC_FALSE X86_TRUE X86_FALSE X86_FREEBSD_TRUE X86_FREEBSD_FALSE X86_WIN32_TRUE X86_WIN32_FALSE X86_WIN64_TRUE X86_WIN64_FALSE X86_DARWIN_TRUE X86_DARWIN_FALSE ALPHA_TRUE ALPHA_FALSE IA64_TRUE IA64_FALSE M32R_TRUE M32R_FALSE M68K_TRUE M68K_FALSE POWERPC_TRUE POWERPC_FALSE POWERPC_AIX_TRUE POWERPC_AIX_FALSE POWERPC_DARWIN_TRUE POWERPC_DARWIN_FALSE POWERPC_FREEBSD_TRUE POWERPC_FREEBSD_FALSE ARM_TRUE ARM_FALSE LIBFFI_CRIS_TRUE LIBFFI_CRIS_FALSE FRV_TRUE FRV_FALSE S390_TRUE S390_FALSE X86_64_TRUE X86_64_FALSE SH_TRUE SH_FALSE SH64_TRUE SH64_FALSE PA_LINUX_TRUE PA_LINUX_FALSE PA_HPUX_TRUE PA_HPUX_FALSE PA64_HPUX_TRUE PA64_HPUX_FALSE ALLOCA HAVE_LONG_DOUBLE TARGET TARGETDIR toolexecdir toolexeclibdir LIBOBJS LTLIBOBJS'
ac_subst_files=''
ac_pwd=`pwd`
@@ -925,7 +925,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures libffi 2.1 to adapt to many kinds of systems.
+\`configure' configures libffi 3.0.8 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -992,7 +992,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of libffi 2.1:";;
+ short | recursive ) echo "Configuration of libffi 3.0.8:";;
esac
cat <<\_ACEOF
@@ -1133,7 +1133,7 @@ fi
test -n "$ac_init_help" && exit 0
if $ac_init_version; then
cat <<\_ACEOF
-libffi configure 2.1
+libffi configure 3.0.8
generated by GNU Autoconf 2.59
Copyright (C) 2003 Free Software Foundation, Inc.
@@ -1147,7 +1147,7 @@ cat >&5 <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by libffi $as_me 2.1, which was
+It was created by libffi $as_me 3.0.8, which was
generated by GNU Autoconf 2.59. Invocation command line was
$ $0 $@
@@ -1945,7 +1945,7 @@ fi
# Define the identity of the package.
PACKAGE='libffi'
- VERSION='2.1'
+ VERSION='3.0.8'
cat >>confdefs.h <<_ACEOF
@@ -11025,7 +11025,7 @@ case "$host" in
TARGET=FRV; TARGETDIR=frv
;;
- hppa*-*-linux*)
+ hppa*-*-linux* | parisc*-*-linux*)
TARGET=PA_LINUX; TARGETDIR=pa
;;
hppa*64-*-hpux*)
@@ -11035,6 +11035,9 @@ case "$host" in
TARGET=PA_HPUX; TARGETDIR=pa
;;
+ i386-*-freebsd* | i386-*-openbsd*)
+ TARGET=X86_FREEBSD; TARGETDIR=x86
+ ;;
i?86-win32* | i?86-*-cygwin* | i?86-*-mingw*)
TARGET=X86_WIN32; TARGETDIR=x86
;;
@@ -11067,7 +11070,10 @@ case "$host" in
TARGET=MIPS; TARGETDIR=mips
;;
- powerpc*-*-linux*)
+ powerpc*-*-linux* | powerpc-*-sysv*)
+ TARGET=POWERPC; TARGETDIR=powerpc
+ ;;
+ powerpc-*-beos*)
TARGET=POWERPC; TARGETDIR=powerpc
;;
powerpc-*-darwin*)
@@ -11101,8 +11107,11 @@ case "$host" in
x86_64-*-darwin*)
TARGET=X86_DARWIN; TARGETDIR=x86
;;
+
x86_64-*-cygwin* | x86_64-*-mingw*)
+ TARGET=X86_WIN64; TARGETDIR=x86
;;
+
x86_64-*-*)
TARGET=X86_64; TARGETDIR=x86
;;
@@ -11148,6 +11157,16 @@ fi
+if test x$TARGET = xX86_FREEBSD; then
+ X86_FREEBSD_TRUE=
+ X86_FREEBSD_FALSE='#'
+else
+ X86_FREEBSD_TRUE='#'
+ X86_FREEBSD_FALSE=
+fi
+
+
+
if test x$TARGET = xX86_WIN32; then
X86_WIN32_TRUE=
X86_WIN32_FALSE='#'
@@ -11158,6 +11177,16 @@ fi
+if test x$TARGET = xX86_WIN64; then
+ X86_WIN64_TRUE=
+ X86_WIN64_FALSE='#'
+else
+ X86_WIN64_TRUE='#'
+ X86_WIN64_FALSE=
+fi
+
+
+
if test x$TARGET = xX86_DARWIN; then
X86_DARWIN_TRUE=
X86_DARWIN_FALSE='#'
@@ -13263,7 +13292,7 @@ _ACEOF
fi
fi
-if test x$TARGET = xX86 || test x$TARGET = xX86_64; then
+if test x$TARGET = xX86 || test x$TARGET = xX86_WIN32 || test x$TARGET = xX86_64; then
echo "$as_me:$LINENO: checking assembler supports pc related relocs" >&5
echo $ECHO_N "checking assembler supports pc related relocs... $ECHO_C" >&6
if test "${libffi_cv_as_x86_pcrel+set}" = set; then
@@ -13445,7 +13474,7 @@ fi
ac_config_links="$ac_config_links include/ffitarget.h:src/$TARGETDIR/ffitarget.h"
- ac_config_files="$ac_config_files include/Makefile include/ffi.h Makefile testsuite/Makefile"
+ ac_config_files="$ac_config_files include/Makefile include/ffi.h Makefile testsuite/Makefile man/Makefile"
cat >confcache <<\_ACEOF
@@ -13588,6 +13617,13 @@ echo "$as_me: error: conditional \"X86\" was never defined.
Usually this means the macro was only invoked conditionally." >&2;}
{ (exit 1); exit 1; }; }
fi
+if test -z "${X86_FREEBSD_TRUE}" && test -z "${X86_FREEBSD_FALSE}"; then
+ { { echo "$as_me:$LINENO: error: conditional \"X86_FREEBSD\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"X86_FREEBSD\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
if test -z "${X86_WIN32_TRUE}" && test -z "${X86_WIN32_FALSE}"; then
{ { echo "$as_me:$LINENO: error: conditional \"X86_WIN32\" was never defined.
Usually this means the macro was only invoked conditionally." >&5
@@ -13595,6 +13631,13 @@ echo "$as_me: error: conditional \"X86_WIN32\" was never defined.
Usually this means the macro was only invoked conditionally." >&2;}
{ (exit 1); exit 1; }; }
fi
+if test -z "${X86_WIN64_TRUE}" && test -z "${X86_WIN64_FALSE}"; then
+ { { echo "$as_me:$LINENO: error: conditional \"X86_WIN64\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"X86_WIN64\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
if test -z "${X86_DARWIN_TRUE}" && test -z "${X86_DARWIN_FALSE}"; then
{ { echo "$as_me:$LINENO: error: conditional \"X86_DARWIN\" was never defined.
Usually this means the macro was only invoked conditionally." >&5
@@ -13999,7 +14042,7 @@ _ASBOX
} >&5
cat >&5 <<_CSEOF
-This file was extended by libffi $as_me 2.1, which was
+This file was extended by libffi $as_me 3.0.8, which was
generated by GNU Autoconf 2.59. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -14065,7 +14108,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF
ac_cs_version="\\
-libffi config.status 2.1
+libffi config.status 3.0.8
configured by $0, generated by GNU Autoconf 2.59,
with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
@@ -14175,6 +14218,9 @@ ac_configure_args="${multilib_arg} ${ac_configure_args}"
multi_basedir="$multi_basedir"
CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
CC="$CC"
+CXX="$CXX"
+GFORTRAN="$GFORTRAN"
+GCJ="$GCJ"
AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
@@ -14446,6 +14492,7 @@ do
"include/ffi.h" ) CONFIG_FILES="$CONFIG_FILES include/ffi.h" ;;
"Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
"testsuite/Makefile" ) CONFIG_FILES="$CONFIG_FILES testsuite/Makefile" ;;
+ "man/Makefile" ) CONFIG_FILES="$CONFIG_FILES man/Makefile" ;;
"include/ffitarget.h" ) CONFIG_LINKS="$CONFIG_LINKS include/ffitarget.h:src/$TARGETDIR/ffitarget.h" ;;
"default-1" ) CONFIG_COMMANDS="$CONFIG_COMMANDS default-1" ;;
"depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
@@ -14631,8 +14678,12 @@ s,@SPARC_TRUE@,$SPARC_TRUE,;t t
s,@SPARC_FALSE@,$SPARC_FALSE,;t t
s,@X86_TRUE@,$X86_TRUE,;t t
s,@X86_FALSE@,$X86_FALSE,;t t
+s,@X86_FREEBSD_TRUE@,$X86_FREEBSD_TRUE,;t t
+s,@X86_FREEBSD_FALSE@,$X86_FREEBSD_FALSE,;t t
s,@X86_WIN32_TRUE@,$X86_WIN32_TRUE,;t t
s,@X86_WIN32_FALSE@,$X86_WIN32_FALSE,;t t
+s,@X86_WIN64_TRUE@,$X86_WIN64_TRUE,;t t
+s,@X86_WIN64_FALSE@,$X86_WIN64_FALSE,;t t
s,@X86_DARWIN_TRUE@,$X86_DARWIN_TRUE,;t t
s,@X86_DARWIN_FALSE@,$X86_DARWIN_FALSE,;t t
s,@ALPHA_TRUE@,$ALPHA_TRUE,;t t
diff --git a/libffi/configure.ac b/libffi/configure.ac
index 2dff35c060f..2ab5902746e 100644
--- a/libffi/configure.ac
+++ b/libffi/configure.ac
@@ -2,7 +2,7 @@ dnl Process this with autoconf to create configure
AC_PREREQ(2.59)
-AC_INIT([libffi], [2.1], [http://gcc.gnu.org/bugs.html])
+AC_INIT([libffi], [3.0.8], [http://gcc.gnu.org/bugs.html])
AC_CONFIG_HEADERS([fficonfig.h])
AM_ENABLE_MULTILIB(, ..)
@@ -63,7 +63,7 @@ case "$host" in
TARGET=FRV; TARGETDIR=frv
;;
- hppa*-*-linux*)
+ hppa*-*-linux* | parisc*-*-linux*)
TARGET=PA_LINUX; TARGETDIR=pa
;;
hppa*64-*-hpux*)
@@ -73,6 +73,9 @@ case "$host" in
TARGET=PA_HPUX; TARGETDIR=pa
;;
+ i386-*-freebsd* | i386-*-openbsd*)
+ TARGET=X86_FREEBSD; TARGETDIR=x86
+ ;;
i?86-win32* | i?86-*-cygwin* | i?86-*-mingw*)
TARGET=X86_WIN32; TARGETDIR=x86
;;
@@ -105,7 +108,10 @@ case "$host" in
TARGET=MIPS; TARGETDIR=mips
;;
- powerpc*-*-linux*)
+ powerpc*-*-linux* | powerpc-*-sysv*)
+ TARGET=POWERPC; TARGETDIR=powerpc
+ ;;
+ powerpc-*-beos*)
TARGET=POWERPC; TARGETDIR=powerpc
;;
powerpc-*-darwin*)
@@ -139,8 +145,11 @@ case "$host" in
x86_64-*-darwin*)
TARGET=X86_DARWIN; TARGETDIR=x86
;;
+
x86_64-*-cygwin* | x86_64-*-mingw*)
+ TARGET=X86_WIN64; TARGETDIR=x86
;;
+
x86_64-*-*)
TARGET=X86_64; TARGETDIR=x86
;;
@@ -155,7 +164,9 @@ fi
AM_CONDITIONAL(MIPS, test x$TARGET = xMIPS)
AM_CONDITIONAL(SPARC, test x$TARGET = xSPARC)
AM_CONDITIONAL(X86, test x$TARGET = xX86)
+AM_CONDITIONAL(X86_FREEBSD, test x$TARGET = xX86_FREEBSD)
AM_CONDITIONAL(X86_WIN32, test x$TARGET = xX86_WIN32)
+AM_CONDITIONAL(X86_WIN64, test x$TARGET = xX86_WIN64)
AM_CONDITIONAL(X86_DARWIN, test x$TARGET = xX86_DARWIN)
AM_CONDITIONAL(ALPHA, test x$TARGET = xALPHA)
AM_CONDITIONAL(IA64, test x$TARGET = xIA64)
@@ -240,7 +251,7 @@ if test x$TARGET = xSPARC; then
fi
fi
-if test x$TARGET = xX86 || test x$TARGET = xX86_64; then
+if test x$TARGET = xX86 || test x$TARGET = xX86_WIN32 || test x$TARGET = xX86_64; then
AC_CACHE_CHECK([assembler supports pc related relocs],
libffi_cv_as_x86_pcrel, [
libffi_cv_as_x86_pcrel=yes
@@ -370,6 +381,6 @@ test -d src/$TARGETDIR || mkdir src/$TARGETDIR
AC_CONFIG_LINKS(include/ffitarget.h:src/$TARGETDIR/ffitarget.h)
-AC_CONFIG_FILES(include/Makefile include/ffi.h Makefile testsuite/Makefile)
+AC_CONFIG_FILES(include/Makefile include/ffi.h Makefile testsuite/Makefile man/Makefile)
AC_OUTPUT
diff --git a/libffi/doc/libffi.info b/libffi/doc/libffi.info
new file mode 100644
index 00000000000..87dee8a13ad
--- /dev/null
+++ b/libffi/doc/libffi.info
@@ -0,0 +1,533 @@
+This is doc/libffi.info, produced by makeinfo version 4.12 from
+./doc/libffi.texi.
+
+This manual is for Libffi, a portable foreign-function interface
+library.
+
+ Copyright (C) 2008 Red Hat, Inc.
+
+ Permission is granted to copy, distribute and/or modify this
+ document under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or
+ (at your option) any later version. A copy of the license is
+ included in the section entitled "GNU General Public License".
+
+
+INFO-DIR-SECTION
+START-INFO-DIR-ENTRY
+* libffi: (libffi). Portable foreign-function interface library.
+END-INFO-DIR-ENTRY
+
+
+File: libffi.info, Node: Top, Next: Introduction, Up: (dir)
+
+libffi
+******
+
+This manual is for Libffi, a portable foreign-function interface
+library.
+
+ Copyright (C) 2008 Red Hat, Inc.
+
+ Permission is granted to copy, distribute and/or modify this
+ document under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or
+ (at your option) any later version. A copy of the license is
+ included in the section entitled "GNU General Public License".
+
+
+* Menu:
+
+* Introduction:: What is libffi?
+* Using libffi:: How to use libffi.
+* Missing Features:: Things libffi can't do.
+* Index:: Index.
+
+
+File: libffi.info, Node: Introduction, Next: Using libffi, Prev: Top, Up: Top
+
+1 What is libffi?
+*****************
+
+Compilers for high level languages generate code that follow certain
+conventions. These conventions are necessary, in part, for separate
+compilation to work. One such convention is the "calling convention".
+The calling convention is a set of assumptions made by the compiler
+about where function arguments will be found on entry to a function. A
+calling convention also specifies where the return value for a function
+is found. The calling convention is also sometimes called the "ABI" or
+"Application Binary Interface".
+
+ Some programs may not know at the time of compilation what arguments
+are to be passed to a function. For instance, an interpreter may be
+told at run-time about the number and types of arguments used to call a
+given function. `Libffi' can be used in such programs to provide a
+bridge from the interpreter program to compiled code.
+
+ The `libffi' library provides a portable, high level programming
+interface to various calling conventions. This allows a programmer to
+call any function specified by a call interface description at run time.
+
+ FFI stands for Foreign Function Interface. A foreign function
+interface is the popular name for the interface that allows code
+written in one language to call code written in another language. The
+`libffi' library really only provides the lowest, machine dependent
+layer of a fully featured foreign function interface. A layer must
+exist above `libffi' that handles type conversions for values passed
+between the two languages.
+
+
+File: libffi.info, Node: Using libffi, Next: Missing Features, Prev: Introduction, Up: Top
+
+2 Using libffi
+**************
+
+* Menu:
+
+* The Basics:: The basic libffi API.
+* Simple Example:: A simple example.
+* Types:: libffi type descriptions.
+* Multiple ABIs:: Different passing styles on one platform.
+* The Closure API:: Writing a generic function.
+
+
+File: libffi.info, Node: The Basics, Next: Simple Example, Up: Using libffi
+
+2.1 The Basics
+==============
+
+`Libffi' assumes that you have a pointer to the function you wish to
+call and that you know the number and types of arguments to pass it, as
+well as the return type of the function.
+
+ The first thing you must do is create an `ffi_cif' object that
+matches the signature of the function you wish to call. This is a
+separate step because it is common to make multiple calls using a
+single `ffi_cif'. The "cif" in `ffi_cif' stands for Call InterFace.
+To prepare a call interface object, use the function `ffi_prep_cif'.
+
+ -- Function: ffi_status ffi_prep_cif (ffi_cif *CIF, ffi_abi ABI,
+ unsigned int NARGS, ffi_type *RTYPE, ffi_type **ARGTYPES)
+ This initializes CIF according to the given parameters.
+
+ ABI is the ABI to use; normally `FFI_DEFAULT_ABI' is what you
+ want. *note Multiple ABIs:: for more information.
+
+ NARGS is the number of arguments that this function accepts.
+ `libffi' does not yet handle varargs functions; see *note Missing
+ Features:: for more information.
+
+ RTYPE is a pointer to an `ffi_type' structure that describes the
+ return type of the function. *Note Types::.
+
+ ARGTYPES is a vector of `ffi_type' pointers. ARGTYPES must have
+ NARGS elements. If NARGS is 0, this argument is ignored.
+
+ `ffi_prep_cif' returns a `libffi' status code, of type
+ `ffi_status'. This will be either `FFI_OK' if everything worked
+ properly; `FFI_BAD_TYPEDEF' if one of the `ffi_type' objects is
+ incorrect; or `FFI_BAD_ABI' if the ABI parameter is invalid.
+
+ To call a function using an initialized `ffi_cif', use the
+`ffi_call' function:
+
+ -- Function: void ffi_call (ffi_cif *CIF, void *FN, void *RVALUE, void
+ **AVALUES)
+ This calls the function FN according to the description given in
+ CIF. CIF must have already been prepared using `ffi_prep_cif'.
+
+ RVALUE is a pointer to a chunk of memory that will hold the result
+ of the function call. This must be large enough to hold the
+ result and must be suitably aligned; it is the caller's
+ responsibility to ensure this. If CIF declares that the function
+ returns `void' (using `ffi_type_void'), then RVALUE is ignored.
+ If RVALUE is `NULL', then the return value is discarded.
+
+ AVALUES is a vector of `void *' pointers that point to the memory
+ locations holding the argument values for a call. If CIF declares
+ that the function has no arguments (i.e., NARGS was 0), then
+ AVALUES is ignored.
+
+
+File: libffi.info, Node: Simple Example, Next: Types, Prev: The Basics, Up: Using libffi
+
+2.2 Simple Example
+==================
+
+Here is a trivial example that calls `puts' a few times.
+
+ #include <stdio.h>
+ #include <ffi.h>
+
+ int main()
+ {
+ ffi_cif cif;
+ ffi_type *args[1];
+ void *values[1];
+ char *s;
+ int rc;
+
+ /* Initialize the argument info vectors */
+ args[0] = &ffi_type_pointer;
+ values[0] = &s;
+
+ /* Initialize the cif */
+ if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ffi_type_uint, args) == FFI_OK)
+ {
+ s = "Hello World!";
+ ffi_call(&cif, puts, &rc, values);
+ /* rc now holds the result of the call to puts */
+
+ /* values holds a pointer to the function's arg, so to
+ call puts() again all we need to do is change the
+ value of s */
+ s = "This is cool!";
+ ffi_call(&cif, puts, &rc, values);
+ }
+
+ return 0;
+ }
+
+
+File: libffi.info, Node: Types, Next: Multiple ABIs, Prev: Simple Example, Up: Using libffi
+
+2.3 Types
+=========
+
+* Menu:
+
+* Primitive Types:: Built-in types.
+* Structures:: Structure types.
+* Type Example:: Structure type example.
+
+
+File: libffi.info, Node: Primitive Types, Next: Structures, Up: Types
+
+2.3.1 Primitive Types
+---------------------
+
+`Libffi' provides a number of built-in type descriptors that can be
+used to describe argument and return types:
+
+`ffi_type_void'
+ The type `void'. This cannot be used for argument types, only for
+ return values.
+
+`ffi_type_uint8'
+ An unsigned, 8-bit integer type.
+
+`ffi_type_sint8'
+ A signed, 8-bit integer type.
+
+`ffi_type_uint16'
+ An unsigned, 16-bit integer type.
+
+`ffi_type_sint16'
+ A signed, 16-bit integer type.
+
+`ffi_type_uint32'
+ An unsigned, 32-bit integer type.
+
+`ffi_type_sint32'
+ A signed, 32-bit integer type.
+
+`ffi_type_uint64'
+ An unsigned, 64-bit integer type.
+
+`ffi_type_sint64'
+ A signed, 64-bit integer type.
+
+`ffi_type_float'
+ The C `float' type.
+
+`ffi_type_double'
+ The C `double' type.
+
+`ffi_type_uchar'
+ The C `unsigned char' type.
+
+`ffi_type_schar'
+ The C `signed char' type. (Note that there is not an exact
+ equivalent to the C `char' type in `libffi'; ordinarily you should
+ either use `ffi_type_schar' or `ffi_type_uchar' depending on
+ whether `char' is signed.)
+
+`ffi_type_ushort'
+ The C `unsigned short' type.
+
+`ffi_type_sshort'
+ The C `short' type.
+
+`ffi_type_uint'
+ The C `unsigned int' type.
+
+`ffi_type_sint'
+ The C `int' type.
+
+`ffi_type_ulong'
+ The C `unsigned long' type.
+
+`ffi_type_slong'
+ The C `long' type.
+
+`ffi_type_longdouble'
+ On platforms that have a C `long double' type, this is defined.
+ On other platforms, it is not.
+
+`ffi_type_pointer'
+ A generic `void *' pointer. You should use this for all pointers,
+ regardless of their real type.
+
+ Each of these is of type `ffi_type', so you must take the address
+when passing to `ffi_prep_cif'.
+
+
+File: libffi.info, Node: Structures, Next: Type Example, Prev: Primitive Types, Up: Types
+
+2.3.2 Structures
+----------------
+
+Although `libffi' has no special support for unions or bit-fields, it
+is perfectly happy passing structures back and forth. You must first
+describe the structure to `libffi' by creating a new `ffi_type' object
+for it.
+
+ -- ffi_type:
+ The `ffi_type' has the following members:
+ `size_t size'
+ This is set by `libffi'; you should initialize it to zero.
+
+ `unsigned short alignment'
+ This is set by `libffi'; you should initialize it to zero.
+
+ `unsigned short type'
+ For a structure, this should be set to `FFI_TYPE_STRUCT'.
+
+ `ffi_type **elements'
+ This is a `NULL'-terminated array of pointers to `ffi_type'
+ objects. There is one element per field of the struct.
+
+
+File: libffi.info, Node: Type Example, Prev: Structures, Up: Types
+
+2.3.3 Type Example
+------------------
+
+The following example initializes a `ffi_type' object representing the
+`tm' struct from Linux's `time.h'.
+
+ Here is how the struct is defined:
+
+ struct tm {
+ int tm_sec;
+ int tm_min;
+ int tm_hour;
+ int tm_mday;
+ int tm_mon;
+ int tm_year;
+ int tm_wday;
+ int tm_yday;
+ int tm_isdst;
+ /* Those are for future use. */
+ long int __tm_gmtoff__;
+ __const char *__tm_zone__;
+ };
+
+ Here is the corresponding code to describe this struct to `libffi':
+
+ {
+ ffi_type tm_type;
+ ffi_type *tm_type_elements[12];
+ int i;
+
+ tm_type.size = tm_type.alignment = 0;
+ tm_type.elements = &tm_type_elements;
+
+ for (i = 0; i < 9; i++)
+ tm_type_elements[i] = &ffi_type_sint;
+
+ tm_type_elements[9] = &ffi_type_slong;
+ tm_type_elements[10] = &ffi_type_pointer;
+ tm_type_elements[11] = NULL;
+
+ /* tm_type can now be used to represent tm argument types and
+ return types for ffi_prep_cif() */
+ }
+
+
+File: libffi.info, Node: Multiple ABIs, Next: The Closure API, Prev: Types, Up: Using libffi
+
+2.4 Multiple ABIs
+=================
+
+A given platform may provide multiple different ABIs at once. For
+instance, the x86 platform has both `stdcall' and `fastcall' functions.
+
+ `libffi' provides some support for this. However, this is
+necessarily platform-specific.
+
+
+File: libffi.info, Node: The Closure API, Prev: Multiple ABIs, Up: Using libffi
+
+2.5 The Closure API
+===================
+
+`libffi' also provides a way to write a generic function - a function
+that can accept and decode any combination of arguments. This can be
+useful when writing an interpreter, or to provide wrappers for
+arbitrary functions.
+
+ This facility is called the "closure API". Closures are not
+supported on all platforms; you can check the `FFI_CLOSURES' define to
+determine whether they are supported on the current platform.
+
+ Because closures work by assembling a tiny function at runtime, they
+require special allocation on platforms that have a non-executable
+heap. Memory management for closures is handled by a pair of functions:
+
+ -- Function: void *ffi_closure_alloc (size_t SIZE, void **CODE)
+ Allocate a chunk of memory holding SIZE bytes. This returns a
+ pointer to the writable address, and sets *CODE to the
+ corresponding executable address.
+
+ SIZE should be sufficient to hold a `ffi_closure' object.
+
+ -- Function: void ffi_closure_free (void *WRITABLE)
+ Free memory allocated using `ffi_closure_alloc'. The argument is
+ the writable address that was returned.
+
+ Once you have allocated the memory for a closure, you must construct
+a `ffi_cif' describing the function call. Finally you can prepare the
+closure function:
+
+ -- Function: ffi_status ffi_prep_closure_loc (ffi_closure *CLOSURE,
+ ffi_cif *CIF, void (*FUN) (ffi_cif *CIF, void *RET, void
+ **ARGS, void *USER_DATA), void *USER_DATA, void *CODELOC)
+ Prepare a closure function.
+
+ CLOSURE is the address of a `ffi_closure' object; this is the
+ writable address returned by `ffi_closure_alloc'.
+
+ CIF is the `ffi_cif' describing the function parameters.
+
+ USER_DATA is an arbitrary datum that is passed, uninterpreted, to
+ your closure function.
+
+ CODELOC is the executable address returned by `ffi_closure_alloc'.
+
+ FUN is the function which will be called when the closure is
+ invoked. It is called with the arguments:
+ CIF
+ The `ffi_cif' passed to `ffi_prep_closure_loc'.
+
+ RET
+ A pointer to the memory used for the function's return value.
+ FUN must fill this, unless the function is declared as
+ returning `void'.
+
+ ARGS
+ A vector of pointers to memory holding the arguments to the
+ function.
+
+ USER_DATA
+ The same USER_DATA that was passed to `ffi_prep_closure_loc'.
+
+ `ffi_prep_closure_loc' will return `FFI_OK' if everything went ok,
+ and something else on error.
+
+ After calling `ffi_prep_closure_loc', you can cast CODELOC to the
+ appropriate pointer-to-function type.
+
+ You may see old code referring to `ffi_prep_closure'. This function
+is deprecated, as it cannot handle the need for separate writable and
+executable addresses.
+
+
+File: libffi.info, Node: Missing Features, Next: Index, Prev: Using libffi, Up: Top
+
+3 Missing Features
+******************
+
+`libffi' is missing a few features. We welcome patches to add support
+for these.
+
+ * There is no support for calling varargs functions. This may work
+ on some platforms, depending on how the ABI is defined, but it is
+ not reliable.
+
+ * There is no support for bit fields in structures.
+
+ * The closure API is
+
+ * The "raw" API is undocumented.
+
+
+File: libffi.info, Node: Index, Prev: Missing Features, Up: Top
+
+Index
+*****
+
+
+* Menu:
+
+* : Structures. (line 12)
+* ABI: Introduction. (line 13)
+* Application Binary Interface: Introduction. (line 13)
+* calling convention: Introduction. (line 13)
+* cif: The Basics. (line 14)
+* closure API: The Closure API. (line 13)
+* closures: The Closure API. (line 13)
+* FFI: Introduction. (line 31)
+* ffi_call: The Basics. (line 41)
+* ffi_closure_alloca: The Closure API. (line 19)
+* ffi_closure_free: The Closure API. (line 26)
+* FFI_CLOSURES: The Closure API. (line 13)
+* ffi_prep_cif: The Basics. (line 16)
+* ffi_prep_closure_loc: The Closure API. (line 34)
+* ffi_status <1>: The Closure API. (line 37)
+* ffi_status: The Basics. (line 18)
+* ffi_type: Structures. (line 11)
+* ffi_type_double: Primitive Types. (line 41)
+* ffi_type_float: Primitive Types. (line 38)
+* ffi_type_longdouble: Primitive Types. (line 71)
+* ffi_type_pointer: Primitive Types. (line 75)
+* ffi_type_schar: Primitive Types. (line 47)
+* ffi_type_sint: Primitive Types. (line 62)
+* ffi_type_sint16: Primitive Types. (line 23)
+* ffi_type_sint32: Primitive Types. (line 29)
+* ffi_type_sint64: Primitive Types. (line 35)
+* ffi_type_sint8: Primitive Types. (line 17)
+* ffi_type_slong: Primitive Types. (line 68)
+* ffi_type_sshort: Primitive Types. (line 56)
+* ffi_type_uchar: Primitive Types. (line 44)
+* ffi_type_uint: Primitive Types. (line 59)
+* ffi_type_uint16: Primitive Types. (line 20)
+* ffi_type_uint32: Primitive Types. (line 26)
+* ffi_type_uint64: Primitive Types. (line 32)
+* ffi_type_uint8: Primitive Types. (line 14)
+* ffi_type_ulong: Primitive Types. (line 65)
+* ffi_type_ushort: Primitive Types. (line 53)
+* ffi_type_void: Primitive Types. (line 10)
+* Foreign Function Interface: Introduction. (line 31)
+* void <1>: The Closure API. (line 20)
+* void: The Basics. (line 43)
+
+
+
+Tag Table:
+Node: Top670
+Node: Introduction1406
+Node: Using libffi3042
+Node: The Basics3477
+Node: Simple Example6084
+Node: Types7111
+Node: Primitive Types7394
+Node: Structures9214
+Node: Type Example10074
+Node: Multiple ABIs11297
+Node: The Closure API11668
+Node: Missing Features14588
+Node: Index15081
+
+End Tag Table
diff --git a/libffi/doc/libffi.texi b/libffi/doc/libffi.texi
new file mode 100644
index 00000000000..90c676afb9a
--- /dev/null
+++ b/libffi/doc/libffi.texi
@@ -0,0 +1,541 @@
+\input texinfo @c -*-texinfo-*-
+@c %**start of header
+@setfilename libffi.info
+@settitle libffi
+@setchapternewpage off
+@c %**end of header
+
+@c Merge the standard indexes into a single one.
+@syncodeindex fn cp
+@syncodeindex vr cp
+@syncodeindex ky cp
+@syncodeindex pg cp
+@syncodeindex tp cp
+
+@include version.texi
+
+@copying
+
+This manual is for Libffi, a portable foreign-function interface
+library.
+
+Copyright @copyright{} 2008 Red Hat, Inc.
+
+@quotation
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version. A copy of the license is included in the
+section entitled ``GNU General Public License''.
+
+@end quotation
+@end copying
+
+@dircategory
+@direntry
+* libffi: (libffi). Portable foreign-function interface library.
+@end direntry
+
+@titlepage
+@title Libffi
+@page
+@vskip 0pt plus 1filll
+@insertcopying
+@end titlepage
+
+
+@ifnottex
+@node Top
+@top libffi
+
+@insertcopying
+
+@menu
+* Introduction:: What is libffi?
+* Using libffi:: How to use libffi.
+* Missing Features:: Things libffi can't do.
+* Index:: Index.
+@end menu
+
+@end ifnottex
+
+
+@node Introduction
+@chapter What is libffi?
+
+Compilers for high level languages generate code that follow certain
+conventions. These conventions are necessary, in part, for separate
+compilation to work. One such convention is the @dfn{calling
+convention}. The calling convention is a set of assumptions made by
+the compiler about where function arguments will be found on entry to
+a function. A calling convention also specifies where the return
+value for a function is found. The calling convention is also
+sometimes called the @dfn{ABI} or @dfn{Application Binary Interface}.
+@cindex calling convention
+@cindex ABI
+@cindex Application Binary Interface
+
+Some programs may not know at the time of compilation what arguments
+are to be passed to a function. For instance, an interpreter may be
+told at run-time about the number and types of arguments used to call
+a given function. @samp{Libffi} can be used in such programs to
+provide a bridge from the interpreter program to compiled code.
+
+The @samp{libffi} library provides a portable, high level programming
+interface to various calling conventions. This allows a programmer to
+call any function specified by a call interface description at run
+time.
+
+@acronym{FFI} stands for Foreign Function Interface. A foreign
+function interface is the popular name for the interface that allows
+code written in one language to call code written in another language.
+The @samp{libffi} library really only provides the lowest, machine
+dependent layer of a fully featured foreign function interface. A
+layer must exist above @samp{libffi} that handles type conversions for
+values passed between the two languages.
+@cindex FFI
+@cindex Foreign Function Interface
+
+
+@node Using libffi
+@chapter Using libffi
+
+@menu
+* The Basics:: The basic libffi API.
+* Simple Example:: A simple example.
+* Types:: libffi type descriptions.
+* Multiple ABIs:: Different passing styles on one platform.
+* The Closure API:: Writing a generic function.
+@end menu
+
+
+@node The Basics
+@section The Basics
+
+@samp{Libffi} assumes that you have a pointer to the function you wish
+to call and that you know the number and types of arguments to pass
+it, as well as the return type of the function.
+
+The first thing you must do is create an @code{ffi_cif} object that
+matches the signature of the function you wish to call. This is a
+separate step because it is common to make multiple calls using a
+single @code{ffi_cif}. The @dfn{cif} in @code{ffi_cif} stands for
+Call InterFace. To prepare a call interface object, use the function
+@code{ffi_prep_cif}.
+@cindex cif
+
+@findex ffi_prep_cif
+@defun ffi_status ffi_prep_cif (ffi_cif *@var{cif}, ffi_abi @var{abi}, unsigned int @var{nargs}, ffi_type *@var{rtype}, ffi_type **@var{argtypes})
+This initializes @var{cif} according to the given parameters.
+
+@var{abi} is the ABI to use; normally @code{FFI_DEFAULT_ABI} is what
+you want. @ref{Multiple ABIs} for more information.
+
+@var{nargs} is the number of arguments that this function accepts.
+@samp{libffi} does not yet handle varargs functions; see @ref{Missing
+Features} for more information.
+
+@var{rtype} is a pointer to an @code{ffi_type} structure that
+describes the return type of the function. @xref{Types}.
+
+@var{argtypes} is a vector of @code{ffi_type} pointers.
+@var{argtypes} must have @var{nargs} elements. If @var{nargs} is 0,
+this argument is ignored.
+
+@code{ffi_prep_cif} returns a @code{libffi} status code, of type
+@code{ffi_status}. This will be either @code{FFI_OK} if everything
+worked properly; @code{FFI_BAD_TYPEDEF} if one of the @code{ffi_type}
+objects is incorrect; or @code{FFI_BAD_ABI} if the @var{abi} parameter
+is invalid.
+@end defun
+
+
+To call a function using an initialized @code{ffi_cif}, use the
+@code{ffi_call} function:
+
+@findex ffi_call
+@defun void ffi_call (ffi_cif *@var{cif}, void *@var{fn}, void *@var{rvalue}, void **@var{avalues})
+This calls the function @var{fn} according to the description given in
+@var{cif}. @var{cif} must have already been prepared using
+@code{ffi_prep_cif}.
+
+@var{rvalue} is a pointer to a chunk of memory that will hold the
+result of the function call. This must be large enough to hold the
+result and must be suitably aligned; it is the caller's responsibility
+to ensure this. If @var{cif} declares that the function returns
+@code{void} (using @code{ffi_type_void}), then @var{rvalue} is
+ignored. If @var{rvalue} is @samp{NULL}, then the return value is
+discarded.
+
+@var{avalues} is a vector of @code{void *} pointers that point to the
+memory locations holding the argument values for a call. If @var{cif}
+declares that the function has no arguments (i.e., @var{nargs} was 0),
+then @var{avalues} is ignored.
+@end defun
+
+
+@node Simple Example
+@section Simple Example
+
+Here is a trivial example that calls @code{puts} a few times.
+
+@example
+#include <stdio.h>
+#include <ffi.h>
+
+int main()
+@{
+ ffi_cif cif;
+ ffi_type *args[1];
+ void *values[1];
+ char *s;
+ int rc;
+
+ /* Initialize the argument info vectors */
+ args[0] = &ffi_type_pointer;
+ values[0] = &s;
+
+ /* Initialize the cif */
+ if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ffi_type_uint, args) == FFI_OK)
+ @{
+ s = "Hello World!";
+ ffi_call(&cif, puts, &rc, values);
+ /* rc now holds the result of the call to puts */
+
+ /* values holds a pointer to the function's arg, so to
+ call puts() again all we need to do is change the
+ value of s */
+ s = "This is cool!";
+ ffi_call(&cif, puts, &rc, values);
+ @}
+
+ return 0;
+@}
+@end example
+
+
+@node Types
+@section Types
+
+@menu
+* Primitive Types:: Built-in types.
+* Structures:: Structure types.
+* Type Example:: Structure type example.
+@end menu
+
+@node Primitive Types
+@subsection Primitive Types
+
+@code{Libffi} provides a number of built-in type descriptors that can
+be used to describe argument and return types:
+
+@table @code
+@item ffi_type_void
+@tindex ffi_type_void
+The type @code{void}. This cannot be used for argument types, only
+for return values.
+
+@item ffi_type_uint8
+@tindex ffi_type_uint8
+An unsigned, 8-bit integer type.
+
+@item ffi_type_sint8
+@tindex ffi_type_sint8
+A signed, 8-bit integer type.
+
+@item ffi_type_uint16
+@tindex ffi_type_uint16
+An unsigned, 16-bit integer type.
+
+@item ffi_type_sint16
+@tindex ffi_type_sint16
+A signed, 16-bit integer type.
+
+@item ffi_type_uint32
+@tindex ffi_type_uint32
+An unsigned, 32-bit integer type.
+
+@item ffi_type_sint32
+@tindex ffi_type_sint32
+A signed, 32-bit integer type.
+
+@item ffi_type_uint64
+@tindex ffi_type_uint64
+An unsigned, 64-bit integer type.
+
+@item ffi_type_sint64
+@tindex ffi_type_sint64
+A signed, 64-bit integer type.
+
+@item ffi_type_float
+@tindex ffi_type_float
+The C @code{float} type.
+
+@item ffi_type_double
+@tindex ffi_type_double
+The C @code{double} type.
+
+@item ffi_type_uchar
+@tindex ffi_type_uchar
+The C @code{unsigned char} type.
+
+@item ffi_type_schar
+@tindex ffi_type_schar
+The C @code{signed char} type. (Note that there is not an exact
+equivalent to the C @code{char} type in @code{libffi}; ordinarily you
+should either use @code{ffi_type_schar} or @code{ffi_type_uchar}
+depending on whether @code{char} is signed.)
+
+@item ffi_type_ushort
+@tindex ffi_type_ushort
+The C @code{unsigned short} type.
+
+@item ffi_type_sshort
+@tindex ffi_type_sshort
+The C @code{short} type.
+
+@item ffi_type_uint
+@tindex ffi_type_uint
+The C @code{unsigned int} type.
+
+@item ffi_type_sint
+@tindex ffi_type_sint
+The C @code{int} type.
+
+@item ffi_type_ulong
+@tindex ffi_type_ulong
+The C @code{unsigned long} type.
+
+@item ffi_type_slong
+@tindex ffi_type_slong
+The C @code{long} type.
+
+@item ffi_type_longdouble
+@tindex ffi_type_longdouble
+On platforms that have a C @code{long double} type, this is defined.
+On other platforms, it is not.
+
+@item ffi_type_pointer
+@tindex ffi_type_pointer
+A generic @code{void *} pointer. You should use this for all
+pointers, regardless of their real type.
+@end table
+
+Each of these is of type @code{ffi_type}, so you must take the address
+when passing to @code{ffi_prep_cif}.
+
+
+@node Structures
+@subsection Structures
+
+Although @samp{libffi} has no special support for unions or
+bit-fields, it is perfectly happy passing structures back and forth.
+You must first describe the structure to @samp{libffi} by creating a
+new @code{ffi_type} object for it.
+
+@tindex ffi_type
+@deftp ffi_type
+The @code{ffi_type} has the following members:
+@table @code
+@item size_t size
+This is set by @code{libffi}; you should initialize it to zero.
+
+@item unsigned short alignment
+This is set by @code{libffi}; you should initialize it to zero.
+
+@item unsigned short type
+For a structure, this should be set to @code{FFI_TYPE_STRUCT}.
+
+@item ffi_type **elements
+This is a @samp{NULL}-terminated array of pointers to @code{ffi_type}
+objects. There is one element per field of the struct.
+@end table
+@end deftp
+
+
+@node Type Example
+@subsection Type Example
+
+The following example initializes a @code{ffi_type} object
+representing the @code{tm} struct from Linux's @file{time.h}.
+
+Here is how the struct is defined:
+
+@example
+struct tm @{
+ int tm_sec;
+ int tm_min;
+ int tm_hour;
+ int tm_mday;
+ int tm_mon;
+ int tm_year;
+ int tm_wday;
+ int tm_yday;
+ int tm_isdst;
+ /* Those are for future use. */
+ long int __tm_gmtoff__;
+ __const char *__tm_zone__;
+@};
+@end example
+
+Here is the corresponding code to describe this struct to
+@code{libffi}:
+
+@example
+ @{
+ ffi_type tm_type;
+ ffi_type *tm_type_elements[12];
+ int i;
+
+ tm_type.size = tm_type.alignment = 0;
+ tm_type.elements = &tm_type_elements;
+
+ for (i = 0; i < 9; i++)
+ tm_type_elements[i] = &ffi_type_sint;
+
+ tm_type_elements[9] = &ffi_type_slong;
+ tm_type_elements[10] = &ffi_type_pointer;
+ tm_type_elements[11] = NULL;
+
+ /* tm_type can now be used to represent tm argument types and
+ return types for ffi_prep_cif() */
+ @}
+@end example
+
+
+@node Multiple ABIs
+@section Multiple ABIs
+
+A given platform may provide multiple different ABIs at once. For
+instance, the x86 platform has both @samp{stdcall} and @samp{fastcall}
+functions.
+
+@code{libffi} provides some support for this. However, this is
+necessarily platform-specific.
+
+@c FIXME: document the platforms
+
+@node The Closure API
+@section The Closure API
+
+@code{libffi} also provides a way to write a generic function -- a
+function that can accept and decode any combination of arguments.
+This can be useful when writing an interpreter, or to provide wrappers
+for arbitrary functions.
+
+This facility is called the @dfn{closure API}. Closures are not
+supported on all platforms; you can check the @code{FFI_CLOSURES}
+define to determine whether they are supported on the current
+platform.
+@cindex closures
+@cindex closure API
+@findex FFI_CLOSURES
+
+Because closures work by assembling a tiny function at runtime, they
+require special allocation on platforms that have a non-executable
+heap. Memory management for closures is handled by a pair of
+functions:
+
+@findex ffi_closure_alloca
+@defun void *ffi_closure_alloc (size_t @var{size}, void **@var{code})
+Allocate a chunk of memory holding @var{size} bytes. This returns a
+pointer to the writable address, and sets *@var{code} to the
+corresponding executable address.
+
+@var{size} should be sufficient to hold a @code{ffi_closure} object.
+@end defun
+
+@findex ffi_closure_free
+@defun void ffi_closure_free (void *@var{writable})
+Free memory allocated using @code{ffi_closure_alloc}. The argument is
+the writable address that was returned.
+@end defun
+
+
+Once you have allocated the memory for a closure, you must construct a
+@code{ffi_cif} describing the function call. Finally you can prepare
+the closure function:
+
+@findex ffi_prep_closure_loc
+@defun ffi_status ffi_prep_closure_loc (ffi_closure *@var{closure}, ffi_cif *@var{cif}, void (*@var{fun}) (ffi_cif *@var{cif}, void *@var{ret}, void **@var{args}, void *@var{user_data}), void *@var{user_data}, void *@var{codeloc})
+Prepare a closure function.
+
+@var{closure} is the address of a @code{ffi_closure} object; this is
+the writable address returned by @code{ffi_closure_alloc}.
+
+@var{cif} is the @code{ffi_cif} describing the function parameters.
+
+@var{user_data} is an arbitrary datum that is passed, uninterpreted,
+to your closure function.
+
+@var{codeloc} is the executable address returned by
+@code{ffi_closure_alloc}.
+
+@var{fun} is the function which will be called when the closure is
+invoked. It is called with the arguments:
+@table @var
+@item cif
+The @code{ffi_cif} passed to @code{ffi_prep_closure_loc}.
+
+@item ret
+A pointer to the memory used for the function's return value.
+@var{fun} must fill this, unless the function is declared as returning
+@code{void}.
+@c FIXME: is this NULL for void-returning functions?
+
+@item args
+A vector of pointers to memory holding the arguments to the function.
+
+@item user_data
+The same @var{user_data} that was passed to
+@code{ffi_prep_closure_loc}.
+@end table
+
+@code{ffi_prep_closure_loc} will return @code{FFI_OK} if everything
+went ok, and something else on error.
+@c FIXME: what?
+
+After calling @code{ffi_prep_closure_loc}, you can cast @var{codeloc}
+to the appropriate pointer-to-function type.
+@end defun
+
+@c FIXME: example
+
+You may see old code referring to @code{ffi_prep_closure}. This
+function is deprecated, as it cannot handle the need for separate
+writable and executable addresses.
+
+
+@node Missing Features
+@chapter Missing Features
+
+@code{libffi} is missing a few features. We welcome patches to add
+support for these.
+
+@itemize @bullet
+@item
+There is no support for calling varargs functions. This may work on
+some platforms, depending on how the ABI is defined, but it is not
+reliable.
+
+@item
+There is no support for bit fields in structures.
+
+@item
+The closure API is
+
+@item
+The ``raw'' API is undocumented.
+@c argument promotion?
+@c unions?
+@c anything else?
+@end itemize
+
+
+@node Index
+@unnumbered Index
+
+@printindex cp
+
+@bye
diff --git a/libffi/doc/stamp-vti b/libffi/doc/stamp-vti
new file mode 100644
index 00000000000..81d0b79d2d8
--- /dev/null
+++ b/libffi/doc/stamp-vti
@@ -0,0 +1,4 @@
+@set UPDATED 14 February 2008
+@set UPDATED-MONTH February 2008
+@set EDITION 3.0.8
+@set VERSION 3.0.8
diff --git a/libffi/doc/version.texi b/libffi/doc/version.texi
new file mode 100644
index 00000000000..81d0b79d2d8
--- /dev/null
+++ b/libffi/doc/version.texi
@@ -0,0 +1,4 @@
+@set UPDATED 14 February 2008
+@set UPDATED-MONTH February 2008
+@set EDITION 3.0.8
+@set VERSION 3.0.8
diff --git a/libffi/include/Makefile.in b/libffi/include/Makefile.in
index cfaaca7fcf4..a81fb1aacd4 100644
--- a/libffi/include/Makefile.in
+++ b/libffi/include/Makefile.in
@@ -181,9 +181,13 @@ X86_64_TRUE = @X86_64_TRUE@
X86_DARWIN_FALSE = @X86_DARWIN_FALSE@
X86_DARWIN_TRUE = @X86_DARWIN_TRUE@
X86_FALSE = @X86_FALSE@
+X86_FREEBSD_FALSE = @X86_FREEBSD_FALSE@
+X86_FREEBSD_TRUE = @X86_FREEBSD_TRUE@
X86_TRUE = @X86_TRUE@
X86_WIN32_FALSE = @X86_WIN32_FALSE@
X86_WIN32_TRUE = @X86_WIN32_TRUE@
+X86_WIN64_FALSE = @X86_WIN64_FALSE@
+X86_WIN64_TRUE = @X86_WIN64_TRUE@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_DSYMUTIL = @ac_ct_DSYMUTIL@
diff --git a/libffi/include/ffi.h.in b/libffi/include/ffi.h.in
index 7784b2e395d..a06d626c2d7 100644
--- a/libffi/include/ffi.h.in
+++ b/libffi/include/ffi.h.in
@@ -1,5 +1,5 @@
/* -----------------------------------------------------------------*-C-*-
- libffi @VERSION@ - Copyright (c) 1996-2003, 2007 Red Hat, Inc.
+ libffi @VERSION@ - Copyright (c) 1996-2003, 2007, 2008 Red Hat, Inc.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
@@ -12,13 +12,14 @@
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
@@ -64,6 +65,10 @@ extern "C" {
#ifndef LIBFFI_ASM
+#ifdef _MSC_VER
+#define __attribute__(X)
+#endif
+
#include <stddef.h>
#include <limits.h>
@@ -221,7 +226,7 @@ typedef ffi_raw ffi_java_raw;
void ffi_raw_call (ffi_cif *cif,
- void (*fn)(),
+ void (*fn)(void),
void *rvalue,
ffi_raw *avalue);
@@ -234,7 +239,7 @@ size_t ffi_raw_size (ffi_cif *cif);
/* longs and doubles are followed by an empty 64-bit word. */
void ffi_java_raw_call (ffi_cif *cif,
- void (*fn)(),
+ void (*fn)(void),
void *rvalue,
ffi_java_raw *avalue);
@@ -348,12 +353,12 @@ ffi_status ffi_prep_cif(ffi_cif *cif,
ffi_type **atypes);
void ffi_call(ffi_cif *cif,
- void (*fn)(),
+ void (*fn)(void),
void *rvalue,
void **avalue);
/* Useful for eliminating compiler warnings */
-#define FFI_FN(f) ((void (*)())f)
+#define FFI_FN(f) ((void (*)(void))f)
/* ---- Definitions shared with assembly code ---------------------------- */
diff --git a/libffi/include/ffi_common.h b/libffi/include/ffi_common.h
index 6af4b5f21fa..16c5f8859f7 100644
--- a/libffi/include/ffi_common.h
+++ b/libffi/include/ffi_common.h
@@ -18,7 +18,10 @@ extern "C" {
/* Do not move this. Some versions of AIX are very picky about where
this is positioned. */
#ifdef __GNUC__
+/* mingw64 defines this already in malloc.h. */
+#ifndef alloca
# define alloca __builtin_alloca
+#endif
# define MAYBE_UNUSED __attribute__((__unused__))
#else
# define MAYBE_UNUSED
@@ -29,7 +32,11 @@ extern "C" {
#pragma alloca
# else
# ifndef alloca /* predefined by HP cc +Olibcalls */
+# ifdef _MSC_VER
+# define alloca _alloca
+# else
char *alloca ();
+# endif
# endif
# endif
# endif
@@ -77,6 +84,16 @@ typedef struct
} extended_cif;
/* Terse sized type definitions. */
+#ifdef _MSC_VER
+typedef unsigned char UINT8;
+typedef signed char SINT8;
+typedef unsigned short UINT16;
+typedef signed short SINT16;
+typedef unsigned int UINT32;
+typedef signed int SINT32;
+typedef unsigned __int64 UINT64;
+typedef signed __int64 SINT64;
+#else
typedef unsigned int UINT8 __attribute__((__mode__(__QI__)));
typedef signed int SINT8 __attribute__((__mode__(__QI__)));
typedef unsigned int UINT16 __attribute__((__mode__(__HI__)));
@@ -85,6 +102,7 @@ typedef unsigned int UINT32 __attribute__((__mode__(__SI__)));
typedef signed int SINT32 __attribute__((__mode__(__SI__)));
typedef unsigned int UINT64 __attribute__((__mode__(__DI__)));
typedef signed int SINT64 __attribute__((__mode__(__DI__)));
+#endif
typedef float FLOAT32;
diff --git a/libffi/man/Makefile.am b/libffi/man/Makefile.am
new file mode 100644
index 00000000000..25192774887
--- /dev/null
+++ b/libffi/man/Makefile.am
@@ -0,0 +1,8 @@
+## Process this with automake to create Makefile.in
+
+AUTOMAKE_OPTIONS=foreign
+
+EXTRA_DIST = ffi.3 ffi_call.3 ffi_prep_cif.3
+
+man_MANS = ffi.3 ffi_call.3 ffi_prep_cif.3
+
diff --git a/libffi/man/Makefile.in b/libffi/man/Makefile.in
new file mode 100644
index 00000000000..65d575cf2f7
--- /dev/null
+++ b/libffi/man/Makefile.in
@@ -0,0 +1,452 @@
+# Makefile.in generated by automake 1.9.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005 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.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = man
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/../config/depstand.m4 \
+ $(top_srcdir)/../config/lead-dot.m4 \
+ $(top_srcdir)/../config/multi.m4 \
+ $(top_srcdir)/../config/override.m4 \
+ $(top_srcdir)/../config/proginstall.m4 \
+ $(top_srcdir)/../libtool.m4 $(top_srcdir)/../ltoptions.m4 \
+ $(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \
+ $(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/acinclude.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/fficonfig.h
+CONFIG_CLEAN_FILES =
+SOURCES =
+DIST_SOURCES =
+man3dir = $(mandir)/man3
+am__installdirs = "$(DESTDIR)$(man3dir)"
+NROFF = nroff
+MANS = $(man_MANS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+ALPHA_FALSE = @ALPHA_FALSE@
+ALPHA_TRUE = @ALPHA_TRUE@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AM_RUNTESTFLAGS = @AM_RUNTESTFLAGS@
+AR = @AR@
+ARM_FALSE = @ARM_FALSE@
+ARM_TRUE = @ARM_TRUE@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCAS = @CCAS@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+FRV_FALSE = @FRV_FALSE@
+FRV_TRUE = @FRV_TRUE@
+GREP = @GREP@
+HAVE_LONG_DOUBLE = @HAVE_LONG_DOUBLE@
+IA64_FALSE = @IA64_FALSE@
+IA64_TRUE = @IA64_TRUE@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LIBFFI_CRIS_FALSE = @LIBFFI_CRIS_FALSE@
+LIBFFI_CRIS_TRUE = @LIBFFI_CRIS_TRUE@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+M32R_FALSE = @M32R_FALSE@
+M32R_TRUE = @M32R_TRUE@
+M68K_FALSE = @M68K_FALSE@
+M68K_TRUE = @M68K_TRUE@
+MAINT = @MAINT@
+MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
+MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
+MAKEINFO = @MAKEINFO@
+MIPS_FALSE = @MIPS_FALSE@
+MIPS_TRUE = @MIPS_TRUE@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PA64_HPUX_FALSE = @PA64_HPUX_FALSE@
+PA64_HPUX_TRUE = @PA64_HPUX_TRUE@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PA_HPUX_FALSE = @PA_HPUX_FALSE@
+PA_HPUX_TRUE = @PA_HPUX_TRUE@
+PA_LINUX_FALSE = @PA_LINUX_FALSE@
+PA_LINUX_TRUE = @PA_LINUX_TRUE@
+POWERPC_AIX_FALSE = @POWERPC_AIX_FALSE@
+POWERPC_AIX_TRUE = @POWERPC_AIX_TRUE@
+POWERPC_DARWIN_FALSE = @POWERPC_DARWIN_FALSE@
+POWERPC_DARWIN_TRUE = @POWERPC_DARWIN_TRUE@
+POWERPC_FALSE = @POWERPC_FALSE@
+POWERPC_FREEBSD_FALSE = @POWERPC_FREEBSD_FALSE@
+POWERPC_FREEBSD_TRUE = @POWERPC_FREEBSD_TRUE@
+POWERPC_TRUE = @POWERPC_TRUE@
+RANLIB = @RANLIB@
+S390_FALSE = @S390_FALSE@
+S390_TRUE = @S390_TRUE@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SH64_FALSE = @SH64_FALSE@
+SH64_TRUE = @SH64_TRUE@
+SHELL = @SHELL@
+SH_FALSE = @SH_FALSE@
+SH_TRUE = @SH_TRUE@
+SPARC_FALSE = @SPARC_FALSE@
+SPARC_TRUE = @SPARC_TRUE@
+STRIP = @STRIP@
+TARGET = @TARGET@
+TARGETDIR = @TARGETDIR@
+TESTSUBDIR_FALSE = @TESTSUBDIR_FALSE@
+TESTSUBDIR_TRUE = @TESTSUBDIR_TRUE@
+VERSION = @VERSION@
+X86_64_FALSE = @X86_64_FALSE@
+X86_64_TRUE = @X86_64_TRUE@
+X86_DARWIN_FALSE = @X86_DARWIN_FALSE@
+X86_DARWIN_TRUE = @X86_DARWIN_TRUE@
+X86_FALSE = @X86_FALSE@
+X86_FREEBSD_FALSE = @X86_FREEBSD_FALSE@
+X86_FREEBSD_TRUE = @X86_FREEBSD_TRUE@
+X86_TRUE = @X86_TRUE@
+X86_WIN32_FALSE = @X86_WIN32_FALSE@
+X86_WIN32_TRUE = @X86_WIN32_TRUE@
+X86_WIN64_FALSE = @X86_WIN64_FALSE@
+X86_WIN64_TRUE = @X86_WIN64_TRUE@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DSYMUTIL = @ac_ct_DSYMUTIL@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+ac_ct_LIPO = @ac_ct_LIPO@
+ac_ct_NMEDIT = @ac_ct_NMEDIT@
+ac_ct_OBJDUMP = @ac_ct_OBJDUMP@
+ac_ct_OTOOL = @ac_ct_OTOOL@
+ac_ct_OTOOL64 = @ac_ct_OTOOL64@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+multi_basedir = @multi_basedir@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+toolexecdir = @toolexecdir@
+toolexeclibdir = @toolexeclibdir@
+AUTOMAKE_OPTIONS = foreign
+EXTRA_DIST = ffi.3 ffi_call.3 ffi_prep_cif.3
+man_MANS = ffi.3 ffi_call.3 ffi_prep_cif.3
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign man/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --foreign man/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+ -rm -f libtool
+uninstall-info-am:
+install-man3: $(man3_MANS) $(man_MANS)
+ @$(NORMAL_INSTALL)
+ test -z "$(man3dir)" || $(mkdir_p) "$(DESTDIR)$(man3dir)"
+ @list='$(man3_MANS) $(dist_man3_MANS) $(nodist_man3_MANS)'; \
+ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
+ for i in $$l2; do \
+ case "$$i" in \
+ *.3*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+ else file=$$i; fi; \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ case "$$ext" in \
+ 3*) ;; \
+ *) ext='3' ;; \
+ esac; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed -e 's/^.*\///'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man3dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man3dir)/$$inst"; \
+ done
+uninstall-man3:
+ @$(NORMAL_UNINSTALL)
+ @list='$(man3_MANS) $(dist_man3_MANS) $(nodist_man3_MANS)'; \
+ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
+ for i in $$l2; do \
+ case "$$i" in \
+ *.3*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ case "$$ext" in \
+ 3*) ;; \
+ *) ext='3' ;; \
+ esac; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed -e 's/^.*\///'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " rm -f '$(DESTDIR)$(man3dir)/$$inst'"; \
+ rm -f "$(DESTDIR)$(man3dir)/$$inst"; \
+ done
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+ list='$(DISTFILES)'; for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+ esac; \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ dir="/$$dir"; \
+ $(mkdir_p) "$(distdir)$$dir"; \
+ else \
+ dir=''; \
+ fi; \
+ if test -d $$d/$$file; then \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(MANS)
+installdirs:
+ for dir in "$(DESTDIR)$(man3dir)"; do \
+ test -z "$$dir" || $(mkdir_p) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-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
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-libtool
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man
+
+install-exec-am:
+
+install-info: install-info-am
+
+install-man: install-man3
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-info-am uninstall-man
+
+uninstall-man: uninstall-man3
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+ distclean distclean-generic distclean-libtool distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-data install-data-am install-exec install-exec-am \
+ install-info install-info-am install-man install-man3 \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ uninstall uninstall-am uninstall-info-am uninstall-man \
+ uninstall-man3
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/libffi/man/ffi.3 b/libffi/man/ffi.3
new file mode 100644
index 00000000000..18b5d5d2d4a
--- /dev/null
+++ b/libffi/man/ffi.3
@@ -0,0 +1,31 @@
+.Dd February 15, 2008
+.Dt FFI 3
+.Sh NAME
+.Nm FFI
+.Nd Foreign Function Interface
+.Sh LIBRARY
+libffi, -lffi
+.Sh SYNOPSIS
+.In ffi.h
+.Ft ffi_status
+.Fo ffi_prep_cif
+.Fa "ffi_cif *cif"
+.Fa "ffi_abi abi"
+.Fa "unsigned int nargs"
+.Fa "ffi_type *rtype"
+.Fa "ffi_type **atypes"
+.Fc
+.Ft void
+.Fo ffi_call
+.Fa "ffi_cif *cif"
+.Fa "void (*fn)(void)"
+.Fa "void *rvalue"
+.Fa "void **avalue"
+.Fc
+.Sh DESCRIPTION
+The foreign function interface provides a mechanism by which a function can
+generate a call to another function at runtime without requiring knowledge of
+the called function's interface at compile time.
+.Sh SEE ALSO
+.Xr ffi_prep_cif 3 ,
+.Xr ffi_call 3
diff --git a/libffi/man/ffi_call.3 b/libffi/man/ffi_call.3
new file mode 100644
index 00000000000..0b692c50002
--- /dev/null
+++ b/libffi/man/ffi_call.3
@@ -0,0 +1,103 @@
+.Dd February 15, 2008
+.Dt ffi_call 3
+.Sh NAME
+.Nm ffi_call
+.Nd Invoke a foreign function.
+.Sh SYNOPSIS
+.In ffi.h
+.Ft void
+.Fo ffi_call
+.Fa "ffi_cif *cif"
+.Fa "void (*fn)(void)"
+.Fa "void *rvalue"
+.Fa "void **avalue"
+.Fc
+.Sh DESCRIPTION
+The
+.Nm ffi_call
+function provides a simple mechanism for invoking a function without
+requiring knowledge of the function's interface at compile time.
+.Fa fn
+is called with the values retrieved from the pointers in the
+.Fa avalue
+array. The return value from
+.Fa fn
+is placed in storage pointed to by
+.Fa rvalue .
+.Fa cif
+contains information describing the data types, sizes and alignments of the
+arguments to and return value from
+.Fa fn ,
+and must be initialized with
+.Nm ffi_prep_cif
+before it is used with
+.Nm ffi_call .
+.Pp
+.Fa rvalue
+must point to storage that is sizeof(ffi_arg) or larger for non-floating point
+types. For smaller-sized return value types, the
+.Nm ffi_arg
+or
+.Nm ffi_sarg
+integral type must be used to hold
+the return value.
+.Sh EXAMPLES
+.Bd -literal
+#include <ffi/ffi.h>
+#include <stdio.h>
+
+unsigned char
+foo(unsigned int, float);
+
+int
+main(int argc, const char **argv)
+{
+ ffi_cif cif;
+ ffi_type *arg_types[2];
+ void *arg_values[2];
+ ffi_status status;
+
+ // Because the return value from foo() is smaller than sizeof(long), it
+ // must be passed as ffi_arg or ffi_sarg.
+ ffi_arg result;
+
+ // Specify the data type of each argument. Available types are defined
+ // in <ffi/ffi.h>.
+ arg_types[0] = &ffi_type_uint;
+ arg_types[1] = &ffi_type_float;
+
+ // Prepare the ffi_cif structure.
+ if ((status = ffi_prep_cif(&cif, FFI_DEFAULT_ABI,
+ 2, &ffi_type_uint8, arg_types)) != FFI_OK)
+ {
+ // Handle the ffi_status error.
+ }
+
+ // Specify the values of each argument.
+ unsigned int arg1 = 42;
+ float arg2 = 5.1;
+
+ arg_values[0] = &arg1;
+ arg_values[1] = &arg2;
+
+ // Invoke the function.
+ ffi_call(&cif, FFI_FN(foo), &result, arg_values);
+
+ // The ffi_arg 'result' now contains the unsigned char returned from foo(),
+ // which can be accessed by a typecast.
+ printf("result is %hhu", (unsigned char)result);
+
+ return 0;
+}
+
+// The target function.
+unsigned char
+foo(unsigned int x, float y)
+{
+ unsigned char result = x - y;
+ return result;
+}
+.Ed
+.Sh SEE ALSO
+.Xr ffi 3 ,
+.Xr ffi_prep_cif 3
diff --git a/libffi/man/ffi_prep_cif.3 b/libffi/man/ffi_prep_cif.3
new file mode 100644
index 00000000000..9436b31191e
--- /dev/null
+++ b/libffi/man/ffi_prep_cif.3
@@ -0,0 +1,66 @@
+.Dd February 15, 2008
+.Dt ffi_prep_cif 3
+.Sh NAME
+.Nm ffi_prep_cif
+.Nd Prepare a
+.Nm ffi_cif
+structure for use with
+.Nm ffi_call
+.
+.Sh SYNOPSIS
+.In ffi.h
+.Ft ffi_status
+.Fo ffi_prep_cif
+.Fa "ffi_cif *cif"
+.Fa "ffi_abi abi"
+.Fa "unsigned int nargs"
+.Fa "ffi_type *rtype"
+.Fa "ffi_type **atypes"
+.Fc
+.Sh DESCRIPTION
+The
+.Nm ffi_prep_cif
+function prepares a
+.Nm ffi_cif
+structure for use with
+.Nm ffi_call
+.
+.Fa abi
+specifies a set of calling conventions to use.
+.Fa atypes
+is an array of
+.Fa nargs
+pointers to
+.Nm ffi_type
+structs that describe the data type, size and alignment of each argument.
+.Fa rtype
+points to an
+.Nm ffi_type
+that describes the data type, size and alignment of the
+return value.
+.Sh RETURN VALUES
+Upon successful completion,
+.Nm ffi_prep_cif
+returns
+.Nm FFI_OK .
+It will return
+.Nm FFI_BAD_TYPEDEF
+if
+.Fa cif
+is
+.Nm NULL
+or
+.Fa atypes
+or
+.Fa rtype
+is malformed. If
+.Fa abi
+does not refer to a valid ABI,
+.Nm FFI_BAD_ABI
+will be returned. Available ABIs are
+defined in
+.Nm <ffitarget.h>
+.
+.Sh SEE ALSO
+.Xr ffi 3 ,
+.Xr ffi_call 3
diff --git a/libffi/src/alpha/ffi.c b/libffi/src/alpha/ffi.c
index cfa7b69e839..8d6b2ba279e 100644
--- a/libffi/src/alpha/ffi.c
+++ b/libffi/src/alpha/ffi.c
@@ -1,5 +1,5 @@
/* -----------------------------------------------------------------------
- ffi.c - Copyright (c) 1998, 2001, 2007 Red Hat, Inc.
+ ffi.c - Copyright (c) 1998, 2001, 2007, 2008 Red Hat, Inc.
Alpha Foreign Function Interface
@@ -14,13 +14,14 @@
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#include <ffi.h>
@@ -38,7 +39,7 @@
# define FFI_TYPE_LONGDOUBLE 4
#endif
-extern void ffi_call_osf(void *, unsigned long, unsigned, void *, void (*)())
+extern void ffi_call_osf(void *, unsigned long, unsigned, void *, void (*)(void))
FFI_HIDDEN;
extern void ffi_closure_osf(void) FFI_HIDDEN;
@@ -75,7 +76,7 @@ ffi_prep_cif_machdep(ffi_cif *cif)
void
-ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
+ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
{
unsigned long *stack, *argp;
long i, avn;
diff --git a/libffi/src/alpha/ffitarget.h b/libffi/src/alpha/ffitarget.h
index 9ec82dab1c5..7d06eb0bc22 100644
--- a/libffi/src/alpha/ffitarget.h
+++ b/libffi/src/alpha/ffitarget.h
@@ -13,13 +13,14 @@
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
diff --git a/libffi/src/alpha/osf.S b/libffi/src/alpha/osf.S
index a6a7b1fc249..d0e77828f5c 100644
--- a/libffi/src/alpha/osf.S
+++ b/libffi/src/alpha/osf.S
@@ -1,5 +1,5 @@
/* -----------------------------------------------------------------------
- osf.S - Copyright (c) 1998, 2001, 2007 Red Hat
+ osf.S - Copyright (c) 1998, 2001, 2007, 2008 Red Hat
Alpha/OSF Foreign Function Interface
@@ -14,13 +14,14 @@
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#define LIBFFI_ASM
@@ -31,7 +32,7 @@
.text
/* ffi_call_osf (void *args, unsigned long bytes, unsigned flags,
- void *raddr, void (*fnaddr)());
+ void *raddr, void (*fnaddr)(void));
Bit o trickiness here -- ARGS+BYTES is the base of the stack frame
for this function. This has been allocated by ffi_call. We also
diff --git a/libffi/src/arm/ffi.c b/libffi/src/arm/ffi.c
index 35b2c3477a4..f6a64758f73 100644
--- a/libffi/src/arm/ffi.c
+++ b/libffi/src/arm/ffi.c
@@ -1,5 +1,5 @@
/* -----------------------------------------------------------------------
- ffi.c - Copyright (c) 1998 Red Hat, Inc.
+ ffi.c - Copyright (c) 1998, 2008 Red Hat, Inc.
ARM Foreign Function Interface
@@ -14,13 +14,14 @@
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#include <ffi.h>
@@ -148,9 +149,9 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
}
extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *,
- unsigned, unsigned, unsigned *, void (*fn)());
+ unsigned, unsigned, unsigned *, void (*fn)(void));
-void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
+void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
{
extended_cif ecif;
diff --git a/libffi/src/arm/ffitarget.h b/libffi/src/arm/ffitarget.h
index 7ba04468a7d..a9574266954 100644
--- a/libffi/src/arm/ffitarget.h
+++ b/libffi/src/arm/ffitarget.h
@@ -13,13 +13,14 @@
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
diff --git a/libffi/src/arm/sysv.S b/libffi/src/arm/sysv.S
index 7062addef18..34481c8c46c 100644
--- a/libffi/src/arm/sysv.S
+++ b/libffi/src/arm/sysv.S
@@ -1,5 +1,5 @@
/* -----------------------------------------------------------------------
- sysv.S - Copyright (c) 1998 Red Hat, Inc.
+ sysv.S - Copyright (c) 1998, 2008 Red Hat, Inc.
ARM Foreign Function Interface
@@ -14,13 +14,14 @@
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#define LIBFFI_ASM
diff --git a/libffi/src/closures.c b/libffi/src/closures.c
index c441b870f70..7692c857162 100644
--- a/libffi/src/closures.c
+++ b/libffi/src/closures.c
@@ -15,13 +15,14 @@
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#if defined __linux__ && !defined _GNU_SOURCE
@@ -41,6 +42,13 @@
locations in the virtual memory space, one location writable and
another executable. */
# define FFI_MMAP_EXEC_WRIT 1
+# define HAVE_MNTENT 1
+# endif
+# if defined(X86_WIN32) || defined(X86_WIN64)
+/* Windows systems may have Data Execution Protection (DEP) enabled,
+ which requires the use of VirtualMalloc/VirtualFree to alloc/free
+ executable memory. */
+# define FFI_MMAP_EXEC_WRIT 1
# endif
#endif
@@ -59,7 +67,11 @@
#define USE_LOCKS 1
#define USE_DL_PREFIX 1
+#ifdef __GNUC__
+#ifndef USE_BUILTIN_FFS
#define USE_BUILTIN_FFS 1
+#endif
+#endif
/* We need to use mmap, not sbrk. */
#define HAVE_MORECORE 0
@@ -89,10 +101,15 @@
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
+#ifndef _MSC_VER
#include <unistd.h>
+#endif
#include <string.h>
#include <stdio.h>
+#if !defined(X86_WIN32) && !defined(X86_WIN64)
+#ifdef HAVE_MNTENT
#include <mntent.h>
+#endif /* HAVE_MNTENT */
#include <sys/param.h>
#include <pthread.h>
@@ -149,6 +166,7 @@ selinux_enabled_check (void)
#define is_selinux_enabled() 0
#endif
+#endif /* !defined(X86_WIN32) && !defined(X86_WIN64) */
/* Declare all functions defined in dlmalloc.c as static. */
static void *dlmalloc(size_t);
@@ -167,9 +185,11 @@ static int dlmalloc_trim(size_t) MAYBE_UNUSED;
static size_t dlmalloc_usable_size(void*) MAYBE_UNUSED;
static void dlmalloc_stats(void) MAYBE_UNUSED;
+#if !defined(X86_WIN32) && !defined(X86_WIN64)
/* Use these for mmap and munmap within dlmalloc.c. */
static void *dlmmap(void *, size_t, int, int, int, off_t);
static int dlmunmap(void *, size_t);
+#endif /* !defined(X86_WIN32) && !defined(X86_WIN64) */
#define mmap dlmmap
#define munmap dlmunmap
@@ -179,6 +199,8 @@ static int dlmunmap(void *, size_t);
#undef mmap
#undef munmap
+#if !defined(X86_WIN32) && !defined(X86_WIN64)
+
/* A mutex used to synchronize access to *exec* variables in this file. */
static pthread_mutex_t open_temp_exec_file_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -231,6 +253,7 @@ open_temp_exec_file_env (const char *envvar)
return open_temp_exec_file_dir (value);
}
+#ifdef HAVE_MNTENT
/* Open a temporary file in an executable and writable mount point
listed in the mounts file. Subsequent calls with the same mounts
keep searching for mount points in the same file. Providing NULL
@@ -277,6 +300,7 @@ open_temp_exec_file_mnt (const char *mounts)
return fd;
}
}
+#endif /* HAVE_MNTENT */
/* Instructions to look for a location to hold a temporary file that
can be mapped in for execution. */
@@ -291,8 +315,10 @@ static struct
{ open_temp_exec_file_dir, "/var/tmp", 0 },
{ open_temp_exec_file_dir, "/dev/shm", 0 },
{ open_temp_exec_file_env, "HOME", 0 },
+#ifdef HAVE_MNTENT
{ open_temp_exec_file_mnt, "/etc/mtab", 1 },
{ open_temp_exec_file_mnt, "/proc/mounts", 1 },
+#endif /* HAVE_MNTENT */
};
/* Current index into open_temp_exec_file_opts. */
@@ -488,6 +514,8 @@ segment_holding_code (mstate m, char* addr)
}
#endif
+#endif /* !defined(X86_WIN32) && !defined(X86_WIN64) */
+
/* Allocate a chunk of memory with the given size. Returns a pointer
to the writable address, and sets *CODE to the executable
corresponding virtual address. */
diff --git a/libffi/src/cris/ffitarget.h b/libffi/src/cris/ffitarget.h
index 3fb937c16dc..4257f10a73c 100644
--- a/libffi/src/cris/ffitarget.h
+++ b/libffi/src/cris/ffitarget.h
@@ -13,13 +13,14 @@
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
diff --git a/libffi/src/debug.c b/libffi/src/debug.c
index f15eb91abcb..51dcfcf2297 100644
--- a/libffi/src/debug.c
+++ b/libffi/src/debug.c
@@ -12,13 +12,14 @@
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#include <ffi.h>
diff --git a/libffi/src/dlmalloc.c b/libffi/src/dlmalloc.c
index c95e64a7e37..783c5c2a6f9 100644
--- a/libffi/src/dlmalloc.c
+++ b/libffi/src/dlmalloc.c
@@ -1140,9 +1140,9 @@ int mspace_mallopt(int, int);
/*------------------------------ internal #includes ---------------------- */
-#ifdef WIN32
+#ifdef _MSC_VER
#pragma warning( disable : 4146 ) /* no "unsigned" warnings */
-#endif /* WIN32 */
+#endif /* _MSC_VER */
#include <stdio.h> /* for printing in malloc_stats */
@@ -1315,14 +1315,14 @@ static int dev_zero_fd = -1; /* Cached file descriptor for /dev/zero. */
/* Win32 MMAP via VirtualAlloc */
static void* win32mmap(size_t size) {
- void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
+ void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE);
return (ptr != 0)? ptr: MFAIL;
}
/* For direct MMAP, use MEM_TOP_DOWN to minimize interference */
static void* win32direct_mmap(size_t size) {
void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN,
- PAGE_READWRITE);
+ PAGE_EXECUTE_READWRITE);
return (ptr != 0)? ptr: MFAIL;
}
diff --git a/libffi/src/frv/ffi.c b/libffi/src/frv/ffi.c
index e9dc6762561..5698c89c351 100644
--- a/libffi/src/frv/ffi.c
+++ b/libffi/src/frv/ffi.c
@@ -1,6 +1,7 @@
/* -----------------------------------------------------------------------
- ffi.c - Copyright (c) 2004 Anthony Green
+ ffi.c - Copyright (C) 2004 Anthony Green
Copyright (C) 2007 Free Software Foundation, Inc.
+ Copyright (C) 2008 Red Hat, Inc.
FR-V Foreign Function Interface
@@ -15,13 +16,14 @@
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#include <ffi.h>
@@ -125,10 +127,10 @@ extern void ffi_call_EABI(void *(*)(char *, extended_cif *),
extended_cif *,
unsigned, unsigned,
unsigned *,
- void (*fn)());
+ void (*fn)(void));
void ffi_call(ffi_cif *cif,
- void (*fn)(),
+ void (*fn)(void),
void *rvalue,
void **avalue)
{
diff --git a/libffi/src/frv/ffitarget.h b/libffi/src/frv/ffitarget.h
index d235697d641..1c319ea9488 100644
--- a/libffi/src/frv/ffitarget.h
+++ b/libffi/src/frv/ffitarget.h
@@ -13,13 +13,14 @@
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
diff --git a/libffi/src/ia64/ffi.c b/libffi/src/ia64/ffi.c
index 09021def3a4..3f8fcc5318b 100644
--- a/libffi/src/ia64/ffi.c
+++ b/libffi/src/ia64/ffi.c
@@ -1,5 +1,5 @@
/* -----------------------------------------------------------------------
- ffi.c - Copyright (c) 1998, 2007 Red Hat, Inc.
+ ffi.c - Copyright (c) 1998, 2007, 2008 Red Hat, Inc.
Copyright (c) 2000 Hewlett Packard Company
IA64 Foreign Function Interface
@@ -15,13 +15,14 @@
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#include <ffi.h>
@@ -269,10 +270,10 @@ ffi_prep_cif_machdep(ffi_cif *cif)
return FFI_OK;
}
-extern int ffi_call_unix (struct ia64_args *, PTR64, void (*)(), UINT64);
+extern int ffi_call_unix (struct ia64_args *, PTR64, void (*)(void), UINT64);
void
-ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
+ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
{
struct ia64_args *stack;
long i, avn, gpcount, fpcount;
diff --git a/libffi/src/ia64/ffitarget.h b/libffi/src/ia64/ffitarget.h
index 0d820b3a59e..d85c049ba39 100644
--- a/libffi/src/ia64/ffitarget.h
+++ b/libffi/src/ia64/ffitarget.h
@@ -13,13 +13,14 @@
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
diff --git a/libffi/src/ia64/ia64_flags.h b/libffi/src/ia64/ia64_flags.h
index 1dd6d7e3feb..9d652cef14c 100644
--- a/libffi/src/ia64/ia64_flags.h
+++ b/libffi/src/ia64/ia64_flags.h
@@ -16,13 +16,14 @@
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
/* "Type" codes used between assembly and C. When used as a part of
diff --git a/libffi/src/ia64/unix.S b/libffi/src/ia64/unix.S
index 45dabb74c9e..4d2a86d421f 100644
--- a/libffi/src/ia64/unix.S
+++ b/libffi/src/ia64/unix.S
@@ -1,5 +1,5 @@
/* -----------------------------------------------------------------------
- unix.S - Copyright (c) 1998 Red Hat, Inc.
+ unix.S - Copyright (c) 1998, 2008 Red Hat, Inc.
Copyright (c) 2000 Hewlett Packard Company
IA64/unix Foreign Function Interface
@@ -19,13 +19,14 @@
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#define LIBFFI_ASM
@@ -37,7 +38,7 @@
.text
/* int ffi_call_unix (struct ia64_args *stack, PTR64 rvalue,
- void (*fn)(), int flags);
+ void (*fn)(void), int flags);
*/
.align 16
@@ -553,3 +554,7 @@ ffi_closure_unix:
data8 @pcrel(.Lld_hfa_float) // FFI_IA64_TYPE_HFA_FLOAT
data8 @pcrel(.Lld_hfa_double) // FFI_IA64_TYPE_HFA_DOUBLE
data8 @pcrel(.Lld_hfa_ldouble) // FFI_IA64_TYPE_HFA_LDOUBLE
+
+#if defined __ELF__ && defined __linux__
+ .section .note.GNU-stack,"",@progbits
+#endif
diff --git a/libffi/src/java_raw_api.c b/libffi/src/java_raw_api.c
index 4fef115e0a6..1f8f9833186 100644
--- a/libffi/src/java_raw_api.c
+++ b/libffi/src/java_raw_api.c
@@ -1,5 +1,5 @@
/* -----------------------------------------------------------------------
- java_raw_api.c - Copyright (c) 1999, 2007 Red Hat, Inc.
+ java_raw_api.c - Copyright (c) 1999, 2007, 2008 Red Hat, Inc.
Cloned from raw_api.c
@@ -19,13 +19,14 @@
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
/* This defines a Java- and 64-bit specific variant of the raw API. */
@@ -294,7 +295,7 @@ ffi_java_raw_to_rvalue (ffi_cif *cif, void *rvalue)
* these following couple of functions will handle the translation forth
* and back automatically. */
-void ffi_java_raw_call (ffi_cif *cif, void (*fn)(), void *rvalue,
+void ffi_java_raw_call (ffi_cif *cif, void (*fn)(void), void *rvalue,
ffi_java_raw *raw)
{
void **avalue = (void**) alloca (cif->nargs * sizeof (void*));
diff --git a/libffi/src/m32r/ffi.c b/libffi/src/m32r/ffi.c
index c3e8204e84b..300006349bf 100644
--- a/libffi/src/m32r/ffi.c
+++ b/libffi/src/m32r/ffi.c
@@ -1,5 +1,6 @@
/* -----------------------------------------------------------------------
ffi.c - Copyright (c) 2004 Renesas Technology
+ Copyright (c) 2008 Red Hat, Inc.
M32R Foreign Function Interface
@@ -172,9 +173,9 @@ ffi_prep_cif_machdep(ffi_cif *cif)
}
extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *,
- unsigned, unsigned, unsigned *, void (*fn)());
+ unsigned, unsigned, unsigned *, void (*fn)(void));
-void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
+void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
{
extended_cif ecif;
diff --git a/libffi/src/m68k/ffitarget.h b/libffi/src/m68k/ffitarget.h
index 9a072db404f..633717bbfa8 100644
--- a/libffi/src/m68k/ffitarget.h
+++ b/libffi/src/m68k/ffitarget.h
@@ -13,13 +13,14 @@
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
diff --git a/libffi/src/m68k/sysv.S b/libffi/src/m68k/sysv.S
index 3face83837c..58822e0aa17 100644
--- a/libffi/src/m68k/sysv.S
+++ b/libffi/src/m68k/sysv.S
@@ -1,7 +1,28 @@
/* -----------------------------------------------------------------------
- sysv.S
+ sysv.S - Copyright (c) 1998 Andreas Schwab
+ Copyright (c) 2008 Red Hat, Inc.
m68k Foreign Function Interface
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#define LIBFFI_ASM
diff --git a/libffi/src/mips/ffi.c b/libffi/src/mips/ffi.c
index d0ce201a151..b6887be839b 100644
--- a/libffi/src/mips/ffi.c
+++ b/libffi/src/mips/ffi.c
@@ -1,5 +1,6 @@
/* -----------------------------------------------------------------------
- ffi.c - Copyright (c) 1996, 2007 Red Hat, Inc.
+ ffi.c - Copyright (c) 1996, 2007, 2008 Red Hat, Inc.
+ Copyright (c) 2008 David Daney
MIPS Foreign Function Interface
@@ -14,13 +15,14 @@
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#include <ffi.h>
@@ -28,6 +30,16 @@
#include <stdlib.h>
+#ifdef __GNUC__
+# if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3))
+# define USE__BUILTIN___CLEAR_CACHE 1
+# endif
+#endif
+
+#ifndef USE__BUILTIN___CLEAR_CACHE
+#include <sys/cachectl.h>
+#endif
+
#ifdef FFI_DEBUG
# define FFI_MIPS_STOP_HERE() ffi_stop_here()
#else
@@ -482,14 +494,14 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
/* Low level routine for calling O32 functions */
extern int ffi_call_O32(void (*)(char *, extended_cif *, int, int),
extended_cif *, unsigned,
- unsigned, unsigned *, void (*)());
+ unsigned, unsigned *, void (*)(void));
/* Low level routine for calling N32 functions */
extern int ffi_call_N32(void (*)(char *, extended_cif *, int, int),
extended_cif *, unsigned,
- unsigned, unsigned *, void (*)());
+ unsigned, unsigned *, void (*)(void));
-void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
+void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
{
extended_cif ecif;
@@ -615,8 +627,11 @@ ffi_prep_closure_loc (ffi_closure *closure,
closure->fun = fun;
closure->user_data = user_data;
+#ifdef USE__BUILTIN___CLEAR_CACHE
__builtin___clear_cache(clear_location, clear_location + FFI_TRAMPOLINE_SIZE);
-
+#else
+ cacheflush (clear_location, FFI_TRAMPOLINE_SIZE, ICACHE);
+#endif
return FFI_OK;
}
diff --git a/libffi/src/mips/ffitarget.h b/libffi/src/mips/ffitarget.h
index ccfc82b9d48..214afe46560 100644
--- a/libffi/src/mips/ffitarget.h
+++ b/libffi/src/mips/ffitarget.h
@@ -13,19 +13,33 @@
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#ifndef LIBFFI_TARGET_H
#define LIBFFI_TARGET_H
+#ifdef linux
+#include <asm/sgidefs.h>
+# ifndef _ABIN32
+# define _ABIN32 _MIPS_SIM_NABI32
+# endif
+# ifndef _ABI64
+# define _ABI64 _MIPS_SIM_ABI64
+# endif
+# ifndef _ABIO32
+# define _ABIO32 _MIPS_SIM_ABI32
+# endif
+#endif
+
#if !defined(_MIPS_SIM)
-- something is very wrong --
#else
diff --git a/libffi/src/mips/n32.S b/libffi/src/mips/n32.S
index 2f9edb48a9b..477f30b77b3 100644
--- a/libffi/src/mips/n32.S
+++ b/libffi/src/mips/n32.S
@@ -14,13 +14,14 @@
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#define LIBFFI_ASM
diff --git a/libffi/src/mips/o32.S b/libffi/src/mips/o32.S
index f6363cb6c54..eb279813a76 100644
--- a/libffi/src/mips/o32.S
+++ b/libffi/src/mips/o32.S
@@ -14,13 +14,14 @@
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#define LIBFFI_ASM
diff --git a/libffi/src/pa/ffi.c b/libffi/src/pa/ffi.c
index 8f1789bace0..c7a14359a0b 100644
--- a/libffi/src/pa/ffi.c
+++ b/libffi/src/pa/ffi.c
@@ -1,5 +1,6 @@
/* -----------------------------------------------------------------------
ffi.c - (c) 2003-2004 Randolph Chung <tausq@debian.org>
+ (c) 2008 Red Hat, Inc.
HPPA Foreign Function Interface
HP-UX PA ABI support (c) 2006 Free Software Foundation, Inc.
@@ -15,13 +16,14 @@
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#include <ffi.h>
@@ -367,9 +369,9 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
extern void ffi_call_pa32(void (*)(UINT32 *, extended_cif *, unsigned),
extended_cif *, unsigned, unsigned, unsigned *,
- void (*fn)());
+ void (*fn)(void));
-void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
+void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
{
extended_cif ecif;
diff --git a/libffi/src/pa/ffitarget.h b/libffi/src/pa/ffitarget.h
index 95ac48060c6..001f8917d87 100644
--- a/libffi/src/pa/ffitarget.h
+++ b/libffi/src/pa/ffitarget.h
@@ -13,13 +13,14 @@
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
diff --git a/libffi/src/pa/hpux32.S b/libffi/src/pa/hpux32.S
index 8f6b4613e66..40528bad751 100644
--- a/libffi/src/pa/hpux32.S
+++ b/libffi/src/pa/hpux32.S
@@ -1,5 +1,6 @@
/* -----------------------------------------------------------------------
hpux32.S - Copyright (c) 2006 Free Software Foundation, Inc.
+ (c) 2008 Red Hat, Inc.
based on src/pa/linux.S
HP-UX PA Foreign Function Interface
@@ -40,7 +41,7 @@
unsigned bytes,
unsigned flags,
unsigned *rvalue,
- void (*fn)());
+ void (*fn)(void));
*/
.export ffi_call_pa32,ENTRY,PRIV_LEV=3
diff --git a/libffi/src/pa/linux.S b/libffi/src/pa/linux.S
index 20be177a9f6..f11ae768074 100644
--- a/libffi/src/pa/linux.S
+++ b/libffi/src/pa/linux.S
@@ -1,5 +1,6 @@
/* -----------------------------------------------------------------------
linux.S - (c) 2003-2004 Randolph Chung <tausq@debian.org>
+ (c) 2008 Red Hat, Inc.
HPPA Foreign Function Interface
@@ -17,7 +18,7 @@
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ IN NO EVENT SHALL RENESAS TECHNOLOGY BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
@@ -36,7 +37,7 @@
unsigned bytes,
unsigned flags,
unsigned *rvalue,
- void (*fn)());
+ void (*fn)(void));
*/
.export ffi_call_pa32,code
diff --git a/libffi/src/powerpc/ffi.c b/libffi/src/powerpc/ffi.c
index 73c1dd20766..fbbfbe2e2ea 100644
--- a/libffi/src/powerpc/ffi.c
+++ b/libffi/src/powerpc/ffi.c
@@ -1,6 +1,7 @@
/* -----------------------------------------------------------------------
ffi.c - Copyright (c) 1998 Geoffrey Keating
Copyright (C) 2007, 2008 Free Software Foundation, Inc
+ Copyright (C) 2008 Red Hat, Inc
PowerPC Foreign Function Interface
@@ -42,11 +43,12 @@ enum {
FLAG_RETURNS_64BITS = 1 << (31-28),
FLAG_RETURNS_128BITS = 1 << (31-27), /* cr6 */
-
- FLAG_SYSV_SMST_R4 = 1 << (31-16), /* cr4, use r4 for FFI_SYSV 8 byte
+ FLAG_SYSV_SMST_R4 = 1 << (31-26), /* use r4 for FFI_SYSV 8 byte
structs. */
- FLAG_SYSV_SMST_R3 = 1 << (31-15), /* cr3, use r3 for FFI_SYSV 4 byte
+ FLAG_SYSV_SMST_R3 = 1 << (31-25), /* use r3 for FFI_SYSV 4 byte
structs. */
+ /* Bits (31-24) through (31-19) store shift value for SMST */
+
FLAG_ARG_NEEDS_COPY = 1 << (31- 7),
FLAG_FP_ARGUMENTS = 1 << (31- 6), /* cr1.eq; specified by ABI */
FLAG_4_GPR_ARGUMENTS = 1 << (31- 5),
@@ -684,14 +686,14 @@ ffi_prep_cif_machdep (ffi_cif *cif)
if (size <= 4)
{
flags |= FLAG_SYSV_SMST_R3;
- flags |= 8 * (4 - size) << 4;
+ flags |= 8 * (4 - size) << 8;
break;
}
/* These structs are returned in r3 and r4. See above. */
if (size <= 8)
{
- flags |= FLAG_SYSV_SMST_R4;
- flags |= 8 * (8 - size) << 4;
+ flags |= FLAG_SYSV_SMST_R3 | FLAG_SYSV_SMST_R4;
+ flags |= 8 * (8 - size) << 8;
break;
}
}
@@ -875,13 +877,13 @@ ffi_prep_cif_machdep (ffi_cif *cif)
}
extern void ffi_call_SYSV(extended_cif *, unsigned, unsigned, unsigned *,
- void (*fn)());
+ void (*fn)(void));
extern void FFI_HIDDEN ffi_call_LINUX64(extended_cif *, unsigned long,
unsigned long, unsigned long *,
- void (*fn)());
+ void (*fn)(void));
void
-ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
+ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
{
extended_cif ecif;
diff --git a/libffi/src/powerpc/ffi_darwin.c b/libffi/src/powerpc/ffi_darwin.c
index 6d1b73e7f75..501035d75d0 100644
--- a/libffi/src/powerpc/ffi_darwin.c
+++ b/libffi/src/powerpc/ffi_darwin.c
@@ -425,11 +425,11 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
}
extern void ffi_call_AIX(extended_cif *, unsigned, unsigned, unsigned *,
- void (*fn)(), void (*fn2)());
+ void (*fn)(void), void (*fn2)(void));
extern void ffi_call_DARWIN(extended_cif *, unsigned, unsigned, unsigned *,
- void (*fn)(), void (*fn2)());
+ void (*fn)(void), void (*fn2)(void));
-void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
+void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
{
extended_cif ecif;
diff --git a/libffi/src/powerpc/ffitarget.h b/libffi/src/powerpc/ffitarget.h
index a39a6267166..269f573987c 100644
--- a/libffi/src/powerpc/ffitarget.h
+++ b/libffi/src/powerpc/ffitarget.h
@@ -14,13 +14,14 @@
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
diff --git a/libffi/src/powerpc/linux64.S b/libffi/src/powerpc/linux64.S
index 2cfebbf1c57..57b56cbb266 100644
--- a/libffi/src/powerpc/linux64.S
+++ b/libffi/src/powerpc/linux64.S
@@ -1,5 +1,6 @@
/* -----------------------------------------------------------------------
sysv.h - Copyright (c) 2003 Jakub Jelinek <jakub@redhat.com>
+ Copyright (c) 2008 Red Hat, Inc.
PowerPC64 Assembly glue.
@@ -14,13 +15,14 @@
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#define LIBFFI_ASM
@@ -179,3 +181,7 @@ ffi_call_LINUX64:
.align 3
.LEFDE1:
#endif
+
+#if defined __ELF__ && defined __linux__
+ .section .note.GNU-stack,"",@progbits
+#endif
diff --git a/libffi/src/powerpc/linux64_closure.S b/libffi/src/powerpc/linux64_closure.S
index b19bc718b50..f7aa2c98efc 100644
--- a/libffi/src/powerpc/linux64_closure.S
+++ b/libffi/src/powerpc/linux64_closure.S
@@ -1,3 +1,29 @@
+/* -----------------------------------------------------------------------
+ sysv.h - Copyright (c) 2003 Jakub Jelinek <jakub@redhat.com>
+ Copyright (c) 2008 Red Hat, Inc.
+
+ PowerPC64 Assembly glue.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
#define LIBFFI_ASM
#include <fficonfig.h>
#include <ffi.h>
@@ -204,3 +230,7 @@ ffi_closure_LINUX64:
.align 3
.LEFDE1:
#endif
+
+#if defined __ELF__ && defined __linux__
+ .section .note.GNU-stack,"",@progbits
+#endif
diff --git a/libffi/src/powerpc/ppc_closure.S b/libffi/src/powerpc/ppc_closure.S
index f65784bab1f..56f7d1af2c8 100644
--- a/libffi/src/powerpc/ppc_closure.S
+++ b/libffi/src/powerpc/ppc_closure.S
@@ -1,3 +1,29 @@
+/* -----------------------------------------------------------------------
+ sysv.h - Copyright (c) 2003 Jakub Jelinek <jakub@redhat.com>
+ Copyright (c) 2008 Red Hat, Inc.
+
+ PowerPC Assembly glue.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
#define LIBFFI_ASM
#include <fficonfig.h>
#include <ffi.h>
diff --git a/libffi/src/powerpc/sysv.S b/libffi/src/powerpc/sysv.S
index d402067aab0..96ea22b0b40 100644
--- a/libffi/src/powerpc/sysv.S
+++ b/libffi/src/powerpc/sysv.S
@@ -15,13 +15,14 @@
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#define LIBFFI_ASM
@@ -135,29 +136,18 @@ L(float_return_value):
b L(done_return_value)
L(small_struct_return_value):
- mtcrf 0x10,%r31 /* cr3 */
- bt- 15,L(smst_one_register)
- mtcrf 0x08,%r31 /* cr4 */
- bt- 16,L(smst_two_register)
- b L(done_return_value)
-
-L(smst_one_register):
- rlwinm %r5,%r31,5+23,32-5,31 /* Extract the value to shift. */
- slw %r3,%r3,%r5
- stw %r3,0(%r30)
- b L(done_return_value)
-L(smst_two_register):
- rlwinm %r5,%r31,5+23,32-5,31 /* Extract the value to shift. */
- cmpwi %r5,0
- subfic %r9,%r5,32
- slw %r29,%r3,%r5
- srw %r9,%r4,%r9
- beq- L(smst_8byte)
- or %r3,%r9,%r29
- slw %r4,%r4,%r5
-L(smst_8byte):
- stw %r3,0(%r30)
- stw %r4,4(%r30)
+ extrwi %r6,%r31,2,19 /* number of bytes padding = shift/8 */
+ mtcrf 0x02,%r31 /* copy flags to cr[24:27] (cr6) */
+ extrwi %r5,%r31,5,19 /* r5 <- number of bits of padding */
+ subfic %r6,%r6,4 /* r6 <- number of useful bytes in r3 */
+ bf- 25,L(done_return_value) /* struct in r3 ? if not, done. */
+/* smst_one_register: */
+ slw %r3,%r3,%r5 /* Left-justify value in r3 */
+ mtxer %r6 /* move byte count to XER ... */
+ stswx %r3,0,%r30 /* ... and store that many bytes */
+ bf+ 26,L(done_return_value) /* struct in r3:r4 ? */
+ add %r6,%r6,%r30 /* adjust pointer */
+ stswi %r4,%r6,4 /* store last four bytes */
b L(done_return_value)
.LFE1:
diff --git a/libffi/src/prep_cif.c b/libffi/src/prep_cif.c
index b6bc52a3999..eb78f9a2ed1 100644
--- a/libffi/src/prep_cif.c
+++ b/libffi/src/prep_cif.c
@@ -12,13 +12,14 @@
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#include <ffi.h>
diff --git a/libffi/src/raw_api.c b/libffi/src/raw_api.c
index b3ca511463e..ce21372e299 100644
--- a/libffi/src/raw_api.c
+++ b/libffi/src/raw_api.c
@@ -1,10 +1,8 @@
/* -----------------------------------------------------------------------
- raw_api.c - Copyright (c) 1999 Red Hat, Inc.
+ raw_api.c - Copyright (c) 1999, 2008 Red Hat, Inc.
Author: Kresten Krab Thorup <krab@gnu.org>
- $Id $
-
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including
@@ -16,13 +14,14 @@
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
/* This file defines generic functions for use with the raw api. */
@@ -189,7 +188,7 @@ ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw)
* these following couple of functions will handle the translation forth
* and back automatically. */
-void ffi_raw_call (ffi_cif *cif, void (*fn)(), void *rvalue, ffi_raw *raw)
+void ffi_raw_call (ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *raw)
{
void **avalue = (void**) alloca (cif->nargs * sizeof (void*));
ffi_raw_to_ptrarray (cif, raw, avalue);
diff --git a/libffi/src/s390/ffi.c b/libffi/src/s390/ffi.c
index d17f7905419..ca2675bc89d 100644
--- a/libffi/src/s390/ffi.c
+++ b/libffi/src/s390/ffi.c
@@ -1,5 +1,6 @@
/* -----------------------------------------------------------------------
ffi.c - Copyright (c) 2000, 2007 Software AG
+ Copyright (c) 2008 Red Hat, Inc
S390 Foreign Function Interface
@@ -88,7 +89,7 @@ extern void ffi_call_SYSV(unsigned,
void (*)(unsigned char *, extended_cif *),
unsigned,
void *,
- void (*fn)());
+ void (*fn)(void));
extern void ffi_closure_SYSV(void);
@@ -498,7 +499,7 @@ ffi_prep_cif_machdep(ffi_cif *cif)
void
ffi_call(ffi_cif *cif,
- void (*fn)(),
+ void (*fn)(void),
void *rvalue,
void **avalue)
{
diff --git a/libffi/src/s390/ffitarget.h b/libffi/src/s390/ffitarget.h
index 5ec8ade028b..78f3c6537d0 100644
--- a/libffi/src/s390/ffitarget.h
+++ b/libffi/src/s390/ffitarget.h
@@ -13,13 +13,14 @@
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
diff --git a/libffi/src/s390/sysv.S b/libffi/src/s390/sysv.S
index 09cdec14ac4..4731a3177b3 100644
--- a/libffi/src/s390/sysv.S
+++ b/libffi/src/s390/sysv.S
@@ -1,5 +1,6 @@
/* -----------------------------------------------------------------------
sysv.S - Copyright (c) 2000 Software AG
+ Copyright (c) 2008 Red Hat, Inc.
S390 Foreign Function Interface
@@ -14,13 +15,14 @@
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#define LIBFFI_ASM
diff --git a/libffi/src/sh/ffi.c b/libffi/src/sh/ffi.c
index 850fde0a022..69bd025fb8f 100644
--- a/libffi/src/sh/ffi.c
+++ b/libffi/src/sh/ffi.c
@@ -1,6 +1,6 @@
/* -----------------------------------------------------------------------
- ffi.c - Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
- Kaz Kojima
+ ffi.c - Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Kaz Kojima
+ Copyright (c) 2008 Red Hat, Inc.
SuperH Foreign Function Interface
@@ -15,13 +15,14 @@
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#include <ffi.h>
@@ -406,9 +407,9 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
}
extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *,
- unsigned, unsigned, unsigned *, void (*fn)());
+ unsigned, unsigned, unsigned *, void (*fn)(void));
-void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
+void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
{
extended_cif ecif;
UINT64 trvalue;
diff --git a/libffi/src/sh/ffitarget.h b/libffi/src/sh/ffitarget.h
index f8492a1c06f..218ae3d0a4a 100644
--- a/libffi/src/sh/ffitarget.h
+++ b/libffi/src/sh/ffitarget.h
@@ -13,13 +13,14 @@
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
diff --git a/libffi/src/sh/sysv.S b/libffi/src/sh/sysv.S
index 80df0061d4f..5be7516d655 100644
--- a/libffi/src/sh/sysv.S
+++ b/libffi/src/sh/sysv.S
@@ -14,13 +14,14 @@
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#define LIBFFI_ASM
diff --git a/libffi/src/sh64/ffi.c b/libffi/src/sh64/ffi.c
index 9886883d327..8fbc05ca6eb 100644
--- a/libffi/src/sh64/ffi.c
+++ b/libffi/src/sh64/ffi.c
@@ -1,5 +1,6 @@
/* -----------------------------------------------------------------------
ffi.c - Copyright (c) 2003, 2004, 2006, 2007 Kaz Kojima
+ Copyright (c) 2008 Anthony Green
SuperH SHmedia Foreign Function Interface
@@ -14,13 +15,14 @@
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#include <ffi.h>
@@ -236,11 +238,20 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
return FFI_OK;
}
-extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *,
- unsigned, unsigned, long long, unsigned *,
- void (*fn)());
-
-void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
+/*@-declundef@*/
+/*@-exportheader@*/
+extern void ffi_call_SYSV(void (*)(char *, extended_cif *),
+ /*@out@*/ extended_cif *,
+ unsigned, unsigned, long long,
+ /*@out@*/ unsigned *,
+ void (*fn)(void));
+/*@=declundef@*/
+/*@=exportheader@*/
+
+void ffi_call(/*@dependent@*/ ffi_cif *cif,
+ void (*fn)(void),
+ /*@out@*/ void *rvalue,
+ /*@dependent@*/ void **avalue)
{
extended_cif ecif;
UINT64 trvalue;
diff --git a/libffi/src/sh64/ffitarget.h b/libffi/src/sh64/ffitarget.h
index a174d09b90d..4e922fc79f1 100644
--- a/libffi/src/sh64/ffitarget.h
+++ b/libffi/src/sh64/ffitarget.h
@@ -13,13 +13,14 @@
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
diff --git a/libffi/src/sh64/sysv.S b/libffi/src/sh64/sysv.S
index 5bf6101bbbc..c4587d5f3e7 100644
--- a/libffi/src/sh64/sysv.S
+++ b/libffi/src/sh64/sysv.S
@@ -14,13 +14,15 @@
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#define LIBFFI_ASM
diff --git a/libffi/src/sparc/ffi.c b/libffi/src/sparc/ffi.c
index fea0330e4e6..3b73f0c4775 100644
--- a/libffi/src/sparc/ffi.c
+++ b/libffi/src/sparc/ffi.c
@@ -1,5 +1,5 @@
/* -----------------------------------------------------------------------
- ffi.c - Copyright (c) 1996, 2003, 2004, 2007 Red Hat, Inc.
+ ffi.c - Copyright (c) 1996, 2003, 2004, 2007, 2008 Red Hat, Inc.
SPARC Foreign Function Interface
@@ -14,13 +14,14 @@
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#include <ffi.h>
@@ -368,13 +369,13 @@ int ffi_v9_layout_struct(ffi_type *arg, int off, char *ret, char *intg, char *fl
#ifdef SPARC64
extern int ffi_call_v9(void *, extended_cif *, unsigned,
- unsigned, unsigned *, void (*fn)());
+ unsigned, unsigned *, void (*fn)(void));
#else
extern int ffi_call_v8(void *, extended_cif *, unsigned,
- unsigned, unsigned *, void (*fn)());
+ unsigned, unsigned *, void (*fn)(void));
#endif
-void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
+void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
{
extended_cif ecif;
void *rval = rvalue;
diff --git a/libffi/src/sparc/ffitarget.h b/libffi/src/sparc/ffitarget.h
index f4514e55d78..1a1a1ac8d98 100644
--- a/libffi/src/sparc/ffitarget.h
+++ b/libffi/src/sparc/ffitarget.h
@@ -13,13 +13,14 @@
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
diff --git a/libffi/src/sparc/v8.S b/libffi/src/sparc/v8.S
index 38307599bf5..2c4eb60a0fb 100644
--- a/libffi/src/sparc/v8.S
+++ b/libffi/src/sparc/v8.S
@@ -1,5 +1,5 @@
/* -----------------------------------------------------------------------
- v8.S - Copyright (c) 1996, 1997, 2003, 2004 Red Hat, Inc.
+ v8.S - Copyright (c) 1996, 1997, 2003, 2004, 2008 Red Hat, Inc.
SPARC Foreign Function Interface
@@ -14,13 +14,14 @@
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#define LIBFFI_ASM
diff --git a/libffi/src/sparc/v9.S b/libffi/src/sparc/v9.S
index a8e8bf98d1e..489ff0293f2 100644
--- a/libffi/src/sparc/v9.S
+++ b/libffi/src/sparc/v9.S
@@ -1,5 +1,5 @@
/* -----------------------------------------------------------------------
- v9.S - Copyright (c) 2000, 2003, 2004 Red Hat, Inc.
+ v9.S - Copyright (c) 2000, 2003, 2004, 2008 Red Hat, Inc.
SPARC 64-bit Foreign Function Interface
@@ -14,13 +14,14 @@
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#define LIBFFI_ASM
diff --git a/libffi/src/types.c b/libffi/src/types.c
index 6d3048870c8..0a11eb0fb4b 100644
--- a/libffi/src/types.c
+++ b/libffi/src/types.c
@@ -14,13 +14,14 @@
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
/* Hide the basic type definitions from the header file, so that we
diff --git a/libffi/src/x86/darwin.S b/libffi/src/x86/darwin.S
index eeee8020383..8f0f0707aaf 100644
--- a/libffi/src/x86/darwin.S
+++ b/libffi/src/x86/darwin.S
@@ -15,14 +15,16 @@
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
- ----------------------------------------------------------------------- */
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+ -----------------------------------------------------------------------
+ */
#ifndef __x86_64__
diff --git a/libffi/src/x86/darwin64.S b/libffi/src/x86/darwin64.S
index 5ba0a5f8492..2f7394ef4bf 100644
--- a/libffi/src/x86/darwin64.S
+++ b/libffi/src/x86/darwin64.S
@@ -1,5 +1,6 @@
/* -----------------------------------------------------------------------
darwin64.S - Copyright (c) 2006 Free Software Foundation, Inc.
+ Copyright (c) 2008 Red Hat, Inc.
derived from unix64.S
x86-64 Foreign Function Interface for Darwin.
@@ -33,7 +34,7 @@
.text
/* ffi_call_unix64 (void *args, unsigned long bytes, unsigned flags,
- void *raddr, void (*fnaddr)());
+ void *raddr, void (*fnaddr)(void));
Bit o trickiness here -- ARGS+BYTES is the base of the stack frame
for this function. This has been allocated by ffi_call. We also
diff --git a/libffi/src/x86/ffi.c b/libffi/src/x86/ffi.c
index a4d4798b83b..c89c8fc7475 100644
--- a/libffi/src/x86/ffi.c
+++ b/libffi/src/x86/ffi.c
@@ -1,9 +1,9 @@
/* -----------------------------------------------------------------------
- ffi.c - Copyright (c) 1996, 1998, 1999, 2001, 2007 Red Hat, Inc.
+ ffi.c - Copyright (c) 1996, 1998, 1999, 2001, 2007, 2008 Red Hat, Inc.
Copyright (c) 2002 Ranjit Mathew
Copyright (c) 2002 Bo Thorsen
Copyright (c) 2002 Roger Sayle
- Copyright (C) 2008 Free Software Foundation, Inc.
+ Copyright (C) 2008 Free Software Foundation, Inc.
x86 Foreign Function Interface
@@ -18,16 +18,21 @@
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
-#ifndef __x86_64__
+#if !defined(__x86_64__) || defined(_WIN64)
+
+#ifdef _WIN64
+#include <windows.h>
+#endif
#include <ffi.h>
#include <ffi_common.h>
@@ -46,10 +51,15 @@ void ffi_prep_args(char *stack, extended_cif *ecif)
argp = stack;
- if (ecif->cif->flags == FFI_TYPE_STRUCT)
+ if (ecif->cif->flags == FFI_TYPE_STRUCT
+#ifdef X86_WIN64
+ && (ecif->cif->rtype->size != 1 && ecif->cif->rtype->size != 2
+ && ecif->cif->rtype->size != 4 && ecif->cif->rtype->size != 8)
+#endif
+ )
{
*(void **) argp = ecif->rvalue;
- argp += 4;
+ argp += sizeof(void*);
}
p_argv = ecif->avalue;
@@ -61,53 +71,75 @@ void ffi_prep_args(char *stack, extended_cif *ecif)
size_t z;
/* Align if necessary */
- if ((sizeof(int) - 1) & (unsigned) argp)
- argp = (char *) ALIGN(argp, sizeof(int));
+ if ((sizeof(void*) - 1) & (size_t) argp)
+ argp = (char *) ALIGN(argp, sizeof(void*));
z = (*p_arg)->size;
- if (z < sizeof(int))
- {
- z = sizeof(int);
- switch ((*p_arg)->type)
- {
- case FFI_TYPE_SINT8:
- *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
- break;
-
- case FFI_TYPE_UINT8:
- *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
- break;
-
- case FFI_TYPE_SINT16:
- *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
- break;
-
- case FFI_TYPE_UINT16:
- *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
- break;
-
- case FFI_TYPE_SINT32:
- *(signed int *) argp = (signed int)*(SINT32 *)(* p_argv);
- break;
-
- case FFI_TYPE_UINT32:
- *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
- break;
-
- case FFI_TYPE_STRUCT:
- *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
- break;
-
- default:
- FFI_ASSERT(0);
- }
- }
+#ifdef X86_WIN64
+ if (z > sizeof(ffi_arg)
+ || ((*p_arg)->type == FFI_TYPE_STRUCT
+ && (z != 1 && z != 2 && z != 4 && z != 8))
+#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE
+ || ((*p_arg)->type == FFI_TYPE_LONGDOUBLE)
+#endif
+ )
+ {
+ z = sizeof(ffi_arg);
+ *(void **)argp = *p_argv;
+ }
+ else if ((*p_arg)->type == FFI_TYPE_FLOAT)
+ {
+ memcpy(argp, *p_argv, z);
+ }
+ else
+#endif
+ if (z < sizeof(ffi_arg))
+ {
+ z = sizeof(ffi_arg);
+ switch ((*p_arg)->type)
+ {
+ case FFI_TYPE_SINT8:
+ *(ffi_sarg *) argp = (ffi_sarg)*(SINT8 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT8:
+ *(ffi_arg *) argp = (ffi_arg)*(UINT8 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_SINT16:
+ *(ffi_sarg *) argp = (ffi_sarg)*(SINT16 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT16:
+ *(ffi_arg *) argp = (ffi_arg)*(UINT16 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_SINT32:
+ *(ffi_sarg *) argp = (ffi_sarg)*(SINT32 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT32:
+ *(ffi_arg *) argp = (ffi_arg)*(UINT32 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_STRUCT:
+ *(ffi_arg *) argp = *(ffi_arg *)(* p_argv);
+ break;
+
+ default:
+ FFI_ASSERT(0);
+ }
+ }
else
- {
- memcpy(argp, *p_argv, z);
- }
+ {
+ memcpy(argp, *p_argv, z);
+ }
p_argv++;
+#ifdef X86_WIN64
+ argp += (z + sizeof(void*) - 1) & ~(sizeof(void*) - 1);
+#else
argp += z;
+#endif
}
return;
@@ -123,21 +155,32 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
#ifdef X86
case FFI_TYPE_STRUCT:
#endif
-#if defined(X86) || defined(X86_DARWIN)
+#if defined(X86) || defined(X86_DARWIN) || defined(X86_WIN64)
case FFI_TYPE_UINT8:
case FFI_TYPE_UINT16:
case FFI_TYPE_SINT8:
case FFI_TYPE_SINT16:
#endif
+#ifdef X86_WIN64
+ case FFI_TYPE_UINT32:
+ case FFI_TYPE_SINT32:
+#endif
case FFI_TYPE_SINT64:
case FFI_TYPE_FLOAT:
case FFI_TYPE_DOUBLE:
+#ifndef X86_WIN64
+#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE
case FFI_TYPE_LONGDOUBLE:
+#endif
+#endif
cif->flags = (unsigned) cif->rtype->type;
break;
case FFI_TYPE_UINT64:
+#ifdef X86_WIN64
+ case FFI_TYPE_POINTER:
+#endif
cif->flags = FFI_TYPE_SINT64;
break;
@@ -153,7 +196,11 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
}
else if (cif->rtype->size == 4)
{
+#ifdef X86_WIN64
+ cif->flags = FFI_TYPE_SMALL_STRUCT_4B;
+#else
cif->flags = FFI_TYPE_INT; /* same as int type */
+#endif
}
else if (cif->rtype->size == 8)
{
@@ -162,12 +209,23 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
else
{
cif->flags = FFI_TYPE_STRUCT;
+#ifdef X86_WIN64
+ // allocate space for return value pointer
+ cif->bytes += ALIGN(sizeof(void*), FFI_SIZEOF_ARG);
+#endif
}
break;
#endif
default:
+#ifdef X86_WIN64
+ cif->flags = FFI_TYPE_SINT64;
+ break;
+ case FFI_TYPE_INT:
+ cif->flags = FFI_TYPE_SINT32;
+#else
cif->flags = FFI_TYPE_INT;
+#endif
break;
}
@@ -175,49 +233,106 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
cif->bytes = (cif->bytes + 15) & ~0xF;
#endif
+#ifdef X86_WIN64
+ {
+ unsigned int i;
+ ffi_type **ptr;
+
+ for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
+ {
+ if (((*ptr)->alignment - 1) & cif->bytes)
+ cif->bytes = ALIGN(cif->bytes, (*ptr)->alignment);
+ cif->bytes += ALIGN((*ptr)->size, FFI_SIZEOF_ARG);
+ }
+ }
+ // ensure space for storing four registers
+ cif->bytes += 4 * sizeof(ffi_arg);
+#endif
+
return FFI_OK;
}
extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *,
- unsigned, unsigned, unsigned *, void (*fn)());
+ unsigned, unsigned, unsigned *, void (*fn)(void));
#ifdef X86_WIN32
extern void ffi_call_STDCALL(void (*)(char *, extended_cif *), extended_cif *,
- unsigned, unsigned, unsigned *, void (*fn)());
+ unsigned, unsigned, unsigned *, void (*fn)(void));
#endif /* X86_WIN32 */
+#ifdef X86_WIN64
+extern int
+ffi_call_win64(void (*)(char *, extended_cif *), extended_cif *,
+ unsigned, unsigned, unsigned *, void (*fn)(void));
+#endif
-void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
+void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
{
extended_cif ecif;
ecif.cif = cif;
ecif.avalue = avalue;
- /* If the return value is a struct and we don't have a return */
- /* value address then we need to make one */
-
- if ((rvalue == NULL) &&
- (cif->flags == FFI_TYPE_STRUCT))
+ /* If the return value is a struct and we don't have a return */
+ /* value address then we need to make one */
+
+#ifdef X86_WIN64
+ if (rvalue == NULL
+ && cif->flags == FFI_TYPE_STRUCT
+ && cif->rtype->size != 1 && cif->rtype->size != 2
+ && cif->rtype->size != 4 && cif->rtype->size != 8)
+ {
+ ecif.rvalue = alloca((cif->rtype->size + 0xF) & ~0xF);
+ }
+#else
+ if (rvalue == NULL
+ && cif->flags == FFI_TYPE_STRUCT)
{
ecif.rvalue = alloca(cif->rtype->size);
}
+#endif
else
ecif.rvalue = rvalue;
switch (cif->abi)
{
+#ifdef X86_WIN64
+ case FFI_WIN64:
+ {
+ // Make copies of all struct arguments
+ // NOTE: not sure if responsibility should be here or in caller
+ unsigned int i;
+ for (i=0; i < cif->nargs;i++) {
+ size_t size = cif->arg_types[i]->size;
+ if ((cif->arg_types[i]->type == FFI_TYPE_STRUCT
+ && (size != 1 && size != 2 && size != 4 && size != 8))
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+ || cif->arg_types[i]->type == FFI_TYPE_LONGDOUBLE
+#endif
+ )
+ {
+ void *local = alloca(size);
+ memcpy(local, avalue[i], size);
+ avalue[i] = local;
+ }
+ }
+ ffi_call_win64(ffi_prep_args, &ecif, cif->bytes,
+ cif->flags, ecif.rvalue, fn);
+ }
+ break;
+#else
case FFI_SYSV:
ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue,
- fn);
+ fn);
break;
#ifdef X86_WIN32
case FFI_STDCALL:
ffi_call_STDCALL(ffi_prep_args, &ecif, cif->bytes, cif->flags,
- ecif.rvalue, fn);
+ ecif.rvalue, fn);
break;
#endif /* X86_WIN32 */
+#endif /* X86_WIN64 */
default:
FFI_ASSERT(0);
break;
@@ -228,23 +343,60 @@ void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
/** private members **/
static void ffi_prep_incoming_args_SYSV (char *stack, void **ret,
- void** args, ffi_cif* cif);
+ void** args, ffi_cif* cif);
void FFI_HIDDEN ffi_closure_SYSV (ffi_closure *)
__attribute__ ((regparm(1)));
unsigned int FFI_HIDDEN ffi_closure_SYSV_inner (ffi_closure *, void **, void *)
__attribute__ ((regparm(1)));
void FFI_HIDDEN ffi_closure_raw_SYSV (ffi_raw_closure *)
__attribute__ ((regparm(1)));
+#ifdef X86_WIN32
+void FFI_HIDDEN ffi_closure_STDCALL (ffi_closure *)
+ __attribute__ ((regparm(1)));
+#endif
+#ifdef X86_WIN64
+void FFI_HIDDEN ffi_closure_win64 (ffi_closure *);
+#endif
/* This function is jumped to by the trampoline */
+#ifdef X86_WIN64
+void * FFI_HIDDEN
+ffi_closure_win64_inner (ffi_closure *closure, void *args) {
+ ffi_cif *cif;
+ void **arg_area;
+ void *result;
+ void *resp = &result;
+
+ cif = closure->cif;
+ arg_area = (void**) alloca (cif->nargs * sizeof (void*));
+
+ /* this call will initialize ARG_AREA, such that each
+ * element in that array points to the corresponding
+ * value on the stack; and if the function returns
+ * a structure, it will change RESP to point to the
+ * structure return address. */
+
+ ffi_prep_incoming_args_SYSV(args, &resp, arg_area, cif);
+
+ (closure->fun) (cif, resp, arg_area, closure->user_data);
+
+ /* The result is returned in rax. This does the right thing for
+ result types except for floats; we have to 'mov xmm0, rax' in the
+ caller to correct this.
+ TODO: structure sizes of 3 5 6 7 are returned by reference, too!!!
+ */
+ return cif->rtype->size > sizeof(void *) ? resp : *(void **)resp;
+}
+
+#else
unsigned int FFI_HIDDEN
ffi_closure_SYSV_inner (closure, respp, args)
ffi_closure *closure;
void **respp;
void *args;
{
- // our various things...
+ /* our various things... */
ffi_cif *cif;
void **arg_area;
@@ -254,7 +406,7 @@ ffi_closure_SYSV_inner (closure, respp, args)
/* this call will initialize ARG_AREA, such that each
* element in that array points to the corresponding
* value on the stack; and if the function returns
- * a structure, it will re-set RESP to point to the
+ * a structure, it will change RESP to point to the
* structure return address. */
ffi_prep_incoming_args_SYSV(args, respp, arg_area, cif);
@@ -263,10 +415,11 @@ ffi_closure_SYSV_inner (closure, respp, args)
return cif->flags;
}
+#endif /* !X86_WIN64 */
static void
ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue,
- ffi_cif *cif)
+ ffi_cif *cif)
{
register unsigned int i;
register void **p_argv;
@@ -275,10 +428,20 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue,
argp = stack;
+#ifdef X86_WIN64
+ if (cif->rtype->size > sizeof(ffi_arg)
+ || (cif->flags == FFI_TYPE_STRUCT
+ && (cif->rtype->size != 1 && cif->rtype->size != 2
+ && cif->rtype->size != 4 && cif->rtype->size != 8))) {
+ *rvalue = *(void **) argp;
+ argp += sizeof(void *);
+ }
+#else
if ( cif->flags == FFI_TYPE_STRUCT ) {
*rvalue = *(void **) argp;
- argp += 4;
+ argp += sizeof(void *);
}
+#endif
p_argv = avalue;
@@ -287,51 +450,125 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue,
size_t z;
/* Align if necessary */
- if ((sizeof(int) - 1) & (unsigned) argp) {
- argp = (char *) ALIGN(argp, sizeof(int));
+ if ((sizeof(void*) - 1) & (size_t) argp) {
+ argp = (char *) ALIGN(argp, sizeof(void*));
}
- z = (*p_arg)->size;
-
- /* because we're little endian, this is what it turns into. */
-
- *p_argv = (void*) argp;
-
+#ifdef X86_WIN64
+ if ((*p_arg)->size > sizeof(ffi_arg)
+ || ((*p_arg)->type == FFI_TYPE_STRUCT
+ && ((*p_arg)->size != 1 && (*p_arg)->size != 2
+ && (*p_arg)->size != 4 && (*p_arg)->size != 8)))
+ {
+ z = sizeof(void *);
+ *p_argv = *(void **)argp;
+ }
+ else
+#endif
+ {
+ z = (*p_arg)->size;
+
+ /* because we're little endian, this is what it turns into. */
+
+ *p_argv = (void*) argp;
+ }
+
p_argv++;
+#ifdef X86_WIN64
+ argp += (z + sizeof(void*) - 1) & ~(sizeof(void*) - 1);
+#else
argp += z;
+#endif
}
return;
}
+#define FFI_INIT_TRAMPOLINE_WIN64(TRAMP,FUN,CTX,MASK) \
+{ unsigned char *__tramp = (unsigned char*)(TRAMP); \
+ void* __fun = (void*)(FUN); \
+ void* __ctx = (void*)(CTX); \
+ *(unsigned char*) &__tramp[0] = 0x41; \
+ *(unsigned char*) &__tramp[1] = 0xbb; \
+ *(unsigned int*) &__tramp[2] = MASK; /* mov $mask, %r11 */ \
+ *(unsigned char*) &__tramp[6] = 0x48; \
+ *(unsigned char*) &__tramp[7] = 0xb8; \
+ *(void**) &__tramp[8] = __ctx; /* mov __ctx, %rax */ \
+ *(unsigned char *) &__tramp[16] = 0x49; \
+ *(unsigned char *) &__tramp[17] = 0xba; \
+ *(void**) &__tramp[18] = __fun; /* mov __fun, %r10 */ \
+ *(unsigned char *) &__tramp[26] = 0x41; \
+ *(unsigned char *) &__tramp[27] = 0xff; \
+ *(unsigned char *) &__tramp[28] = 0xe2; /* jmp %r10 */ \
+ }
+
/* How to make a trampoline. Derived from gcc/config/i386/i386.c. */
#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX) \
({ unsigned char *__tramp = (unsigned char*)(TRAMP); \
unsigned int __fun = (unsigned int)(FUN); \
unsigned int __ctx = (unsigned int)(CTX); \
- unsigned int __dis = __fun - (__ctx + FFI_TRAMPOLINE_SIZE); \
+ unsigned int __dis = __fun - (__ctx + 10); \
*(unsigned char*) &__tramp[0] = 0xb8; \
*(unsigned int*) &__tramp[1] = __ctx; /* movl __ctx, %eax */ \
*(unsigned char *) &__tramp[5] = 0xe9; \
*(unsigned int*) &__tramp[6] = __dis; /* jmp __fun */ \
})
+#define FFI_INIT_TRAMPOLINE_STDCALL(TRAMP,FUN,CTX,SIZE) \
+({ unsigned char *__tramp = (unsigned char*)(TRAMP); \
+ unsigned int __fun = (unsigned int)(FUN); \
+ unsigned int __ctx = (unsigned int)(CTX); \
+ unsigned int __dis = __fun - (__ctx + 10); \
+ unsigned short __size = (unsigned short)(SIZE); \
+ *(unsigned char*) &__tramp[0] = 0xb8; \
+ *(unsigned int*) &__tramp[1] = __ctx; /* movl __ctx, %eax */ \
+ *(unsigned char *) &__tramp[5] = 0xe8; \
+ *(unsigned int*) &__tramp[6] = __dis; /* call __fun */ \
+ *(unsigned char *) &__tramp[10] = 0xc2; \
+ *(unsigned short*) &__tramp[11] = __size; /* ret __size */ \
+ })
/* the cif must already be prep'ed */
ffi_status
ffi_prep_closure_loc (ffi_closure* closure,
- ffi_cif* cif,
- void (*fun)(ffi_cif*,void*,void**,void*),
- void *user_data,
- void *codeloc)
+ ffi_cif* cif,
+ void (*fun)(ffi_cif*,void*,void**,void*),
+ void *user_data,
+ void *codeloc)
{
- FFI_ASSERT (cif->abi == FFI_SYSV);
-
- FFI_INIT_TRAMPOLINE (&closure->tramp[0], \
- &ffi_closure_SYSV, \
- codeloc);
+#ifdef X86_WIN64
+#define ISFLOAT(IDX) (cif->arg_types[IDX]->type == FFI_TYPE_FLOAT || cif->arg_types[IDX]->type == FFI_TYPE_DOUBLE)
+#define FLAG(IDX) (cif->nargs>(IDX)&&ISFLOAT(IDX)?(1<<(IDX)):0)
+ if (cif->abi == FFI_WIN64)
+ {
+ int mask = FLAG(0)|FLAG(1)|FLAG(2)|FLAG(3);
+ FFI_INIT_TRAMPOLINE_WIN64 (&closure->tramp[0],
+ &ffi_closure_win64,
+ codeloc, mask);
+ /* make sure we can execute here */
+ }
+#else
+ if (cif->abi == FFI_SYSV)
+ {
+ FFI_INIT_TRAMPOLINE (&closure->tramp[0],
+ &ffi_closure_SYSV,
+ (void*)codeloc);
+ }
+#ifdef X86_WIN32
+ else if (cif->abi == FFI_STDCALL)
+ {
+ FFI_INIT_TRAMPOLINE_STDCALL (&closure->tramp[0],
+ &ffi_closure_STDCALL,
+ (void*)codeloc, cif->bytes);
+ }
+#endif /* X86_WIN32 */
+#endif /* !X86_WIN64 */
+ else
+ {
+ return FFI_BAD_ABI;
+ }
closure->cif = cif;
closure->user_data = user_data;
@@ -346,14 +583,16 @@ ffi_prep_closure_loc (ffi_closure* closure,
ffi_status
ffi_prep_raw_closure_loc (ffi_raw_closure* closure,
- ffi_cif* cif,
- void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
- void *user_data,
- void *codeloc)
+ ffi_cif* cif,
+ void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
+ void *user_data,
+ void *codeloc)
{
int i;
- FFI_ASSERT (cif->abi == FFI_SYSV);
+ if (cif->abi != FFI_SYSV) {
+ return FFI_BAD_ABI;
+ }
// we currently don't support certain kinds of arguments for raw
// closures. This should be implemented by a separate assembly language
@@ -368,7 +607,7 @@ ffi_prep_raw_closure_loc (ffi_raw_closure* closure,
FFI_INIT_TRAMPOLINE (&closure->tramp[0], &ffi_closure_raw_SYSV,
- codeloc);
+ codeloc);
closure->cif = cif;
closure->user_data = user_data;
@@ -390,16 +629,16 @@ ffi_prep_args_raw(char *stack, extended_cif *ecif)
extern void
ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *, unsigned,
- unsigned, unsigned *, void (*fn)());
+ unsigned, unsigned *, void (*fn)(void));
#ifdef X86_WIN32
extern void
ffi_call_STDCALL(void (*)(char *, extended_cif *), extended_cif *, unsigned,
- unsigned, unsigned *, void (*fn)());
+ unsigned, unsigned *, void (*fn)(void));
#endif /* X86_WIN32 */
void
-ffi_raw_call(ffi_cif *cif, void (*fn)(), void *rvalue, ffi_raw *fake_avalue)
+ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *fake_avalue)
{
extended_cif ecif;
void **avalue = (void **)fake_avalue;
@@ -407,8 +646,8 @@ ffi_raw_call(ffi_cif *cif, void (*fn)(), void *rvalue, ffi_raw *fake_avalue)
ecif.cif = cif;
ecif.avalue = avalue;
- /* If the return value is a struct and we don't have a return */
- /* value address then we need to make one */
+ /* If the return value is a struct and we don't have a return */
+ /* value address then we need to make one */
if ((rvalue == NULL) &&
(cif->rtype->type == FFI_TYPE_STRUCT))
@@ -423,12 +662,12 @@ ffi_raw_call(ffi_cif *cif, void (*fn)(), void *rvalue, ffi_raw *fake_avalue)
{
case FFI_SYSV:
ffi_call_SYSV(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags,
- ecif.rvalue, fn);
+ ecif.rvalue, fn);
break;
#ifdef X86_WIN32
case FFI_STDCALL:
ffi_call_STDCALL(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags,
- ecif.rvalue, fn);
+ ecif.rvalue, fn);
break;
#endif /* X86_WIN32 */
default:
@@ -439,4 +678,5 @@ ffi_raw_call(ffi_cif *cif, void (*fn)(), void *rvalue, ffi_raw *fake_avalue)
#endif
-#endif /* __x86_64__ */
+#endif /* !__x86_64__ || X86_WIN64 */
+
diff --git a/libffi/src/x86/ffi64.c b/libffi/src/x86/ffi64.c
index 0bb18c6ac44..116c636598d 100644
--- a/libffi/src/x86/ffi64.c
+++ b/libffi/src/x86/ffi64.c
@@ -1,5 +1,6 @@
/* -----------------------------------------------------------------------
- ffi.c - Copyright (c) 2002, 2007 Bo Thorsen <bo@suse.de>
+ ffi64.c - Copyright (c) 2002, 2007 Bo Thorsen <bo@suse.de>
+ Copyright (c) 2008 Red Hat, Inc.
x86-64 Foreign Function Interface
@@ -14,13 +15,14 @@
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#include <ffi.h>
@@ -42,7 +44,7 @@ struct register_args
};
extern void ffi_call_unix64 (void *args, unsigned long bytes, unsigned flags,
- void *raddr, void (*fnaddr)(), unsigned ssecount);
+ void *raddr, void (*fnaddr)(void), unsigned ssecount);
/* All reference to register classes here is identical to the code in
gcc/config/i386/i386.c. Do *not* change one without the other. */
@@ -339,7 +341,7 @@ ffi_prep_cif_machdep (ffi_cif *cif)
}
void
-ffi_call (ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
+ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
{
enum x86_64_reg_class classes[MAX_CLASSES];
char *stack, *argp;
diff --git a/libffi/src/x86/ffitarget.h b/libffi/src/x86/ffitarget.h
index 3a1427c3c9b..b1d3df88f14 100644
--- a/libffi/src/x86/ffitarget.h
+++ b/libffi/src/x86/ffitarget.h
@@ -15,13 +15,14 @@
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
@@ -35,11 +36,26 @@
#define X86
#endif
+#ifdef X86_WIN64
+#define FFI_SIZEOF_ARG 8
+#define USE_BUILTIN_FFS 0 // not yet implemented in mingw-64
+#endif
+
/* ---- Generic type definitions ----------------------------------------- */
#ifndef LIBFFI_ASM
+#ifdef X86_WIN64
+#ifdef _MSC_VER
+typedef unsigned __int64 ffi_arg;
+typedef __int64 ffi_sarg;
+#else
+typedef unsigned long long ffi_arg;
+typedef long long ffi_sarg;
+#endif
+#else
typedef unsigned long ffi_arg;
typedef signed long ffi_sarg;
+#endif
typedef enum ffi_abi {
FFI_FIRST_ABI = 0,
@@ -52,6 +68,11 @@ typedef enum ffi_abi {
FFI_DEFAULT_ABI = FFI_SYSV,
#endif
+#ifdef X86_WIN64
+ FFI_WIN64,
+ FFI_DEFAULT_ABI = FFI_WIN64,
+#else
+
/* ---- Intel x86 and AMD x86-64 - */
#if !defined(X86_WIN32) && (defined(__i386__) || defined(__x86_64__))
FFI_SYSV,
@@ -62,6 +83,7 @@ typedef enum ffi_abi {
FFI_DEFAULT_ABI = FFI_UNIX64,
#endif
#endif
+#endif /* X86_WIN64 */
FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
} ffi_abi;
@@ -72,14 +94,27 @@ typedef enum ffi_abi {
#define FFI_CLOSURES 1
#define FFI_TYPE_SMALL_STRUCT_1B (FFI_TYPE_LAST + 1)
#define FFI_TYPE_SMALL_STRUCT_2B (FFI_TYPE_LAST + 2)
+#define FFI_TYPE_SMALL_STRUCT_4B (FFI_TYPE_LAST + 3)
#if defined (X86_64) || (defined (__x86_64__) && defined (X86_DARWIN))
#define FFI_TRAMPOLINE_SIZE 24
#define FFI_NATIVE_RAW_API 0
#else
+#ifdef X86_WIN32
+#define FFI_TRAMPOLINE_SIZE 13
+#else
+#ifdef X86_WIN64
+#define FFI_TRAMPOLINE_SIZE 29
+#define FFI_NATIVE_RAW_API 0
+#define FFI_NO_RAW_API 1
+#else
#define FFI_TRAMPOLINE_SIZE 10
+#endif
+#endif
+#ifndef X86_WIN64
#define FFI_NATIVE_RAW_API 1 /* x86 has native raw api support */
#endif
+#endif
#endif
diff --git a/libffi/src/x86/freebsd.S b/libffi/src/x86/freebsd.S
new file mode 100644
index 00000000000..afde513164e
--- /dev/null
+++ b/libffi/src/x86/freebsd.S
@@ -0,0 +1,458 @@
+/* -----------------------------------------------------------------------
+ freebsd.S - Copyright (c) 1996, 1998, 2001, 2002, 2003, 2005 Red Hat, Inc.
+ Copyright (c) 2008 Björn König
+
+ X86 Foreign Function Interface for FreeBSD
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+----------------------------------------------------------------------- */
+
+#ifndef __x86_64__
+
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+
+.text
+
+.globl ffi_prep_args
+
+ .align 4
+.globl ffi_call_SYSV
+ .type ffi_call_SYSV,@function
+
+ffi_call_SYSV:
+.LFB1:
+ pushl %ebp
+.LCFI0:
+ movl %esp,%ebp
+.LCFI1:
+ /* Make room for all of the new args. */
+ movl 16(%ebp),%ecx
+ subl %ecx,%esp
+
+ movl %esp,%eax
+
+ /* Place all of the ffi_prep_args in position */
+ pushl 12(%ebp)
+ pushl %eax
+ call *8(%ebp)
+
+ /* Return stack to previous state and call the function */
+ addl $8,%esp
+
+ call *28(%ebp)
+
+ /* Load %ecx with the return type code */
+ movl 20(%ebp),%ecx
+
+ /* Protect %esi. We're going to pop it in the epilogue. */
+ pushl %esi
+
+ /* If the return value pointer is NULL, assume no return value. */
+ cmpl $0,24(%ebp)
+ jne 0f
+
+ /* Even if there is no space for the return value, we are
+ obliged to handle floating-point values. */
+ cmpl $FFI_TYPE_FLOAT,%ecx
+ jne noretval
+ fstp %st(0)
+
+ jmp epilogue
+
+0:
+ call 1f
+
+.Lstore_table:
+ .long noretval-.Lstore_table /* FFI_TYPE_VOID */
+ .long retint-.Lstore_table /* FFI_TYPE_INT */
+ .long retfloat-.Lstore_table /* FFI_TYPE_FLOAT */
+ .long retdouble-.Lstore_table /* FFI_TYPE_DOUBLE */
+ .long retlongdouble-.Lstore_table /* FFI_TYPE_LONGDOUBLE */
+ .long retuint8-.Lstore_table /* FFI_TYPE_UINT8 */
+ .long retsint8-.Lstore_table /* FFI_TYPE_SINT8 */
+ .long retuint16-.Lstore_table /* FFI_TYPE_UINT16 */
+ .long retsint16-.Lstore_table /* FFI_TYPE_SINT16 */
+ .long retint-.Lstore_table /* FFI_TYPE_UINT32 */
+ .long retint-.Lstore_table /* FFI_TYPE_SINT32 */
+ .long retint64-.Lstore_table /* FFI_TYPE_UINT64 */
+ .long retint64-.Lstore_table /* FFI_TYPE_SINT64 */
+ .long retstruct-.Lstore_table /* FFI_TYPE_STRUCT */
+ .long retint-.Lstore_table /* FFI_TYPE_POINTER */
+ .long retstruct1b-.Lstore_table /* FFI_TYPE_SMALL_STRUCT_1B */
+ .long retstruct2b-.Lstore_table /* FFI_TYPE_SMALL_STRUCT_2B */
+
+1:
+ pop %esi
+ add (%esi, %ecx, 4), %esi
+ jmp *%esi
+
+ /* Sign/zero extend as appropriate. */
+retsint8:
+ movsbl %al, %eax
+ jmp retint
+
+retsint16:
+ movswl %ax, %eax
+ jmp retint
+
+retuint8:
+ movzbl %al, %eax
+ jmp retint
+
+retuint16:
+ movzwl %ax, %eax
+ jmp retint
+
+retfloat:
+ /* Load %ecx with the pointer to storage for the return value */
+ movl 24(%ebp),%ecx
+ fstps (%ecx)
+ jmp epilogue
+
+retdouble:
+ /* Load %ecx with the pointer to storage for the return value */
+ movl 24(%ebp),%ecx
+ fstpl (%ecx)
+ jmp epilogue
+
+retlongdouble:
+ /* Load %ecx with the pointer to storage for the return value */
+ movl 24(%ebp),%ecx
+ fstpt (%ecx)
+ jmp epilogue
+
+retint64:
+ /* Load %ecx with the pointer to storage for the return value */
+ movl 24(%ebp),%ecx
+ movl %eax,0(%ecx)
+ movl %edx,4(%ecx)
+ jmp epilogue
+
+retstruct1b:
+ /* Load %ecx with the pointer to storage for the return value */
+ movl 24(%ebp),%ecx
+ movb %al,0(%ecx)
+ jmp epilogue
+
+retstruct2b:
+ /* Load %ecx with the pointer to storage for the return value */
+ movl 24(%ebp),%ecx
+ movw %ax,0(%ecx)
+ jmp epilogue
+
+retint:
+ /* Load %ecx with the pointer to storage for the return value */
+ movl 24(%ebp),%ecx
+ movl %eax,0(%ecx)
+
+retstruct:
+ /* Nothing to do! */
+
+noretval:
+epilogue:
+ popl %esi
+ movl %ebp,%esp
+ popl %ebp
+ ret
+.LFE1:
+.ffi_call_SYSV_end:
+ .size ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV
+
+ .align 4
+FFI_HIDDEN (ffi_closure_SYSV)
+.globl ffi_closure_SYSV
+ .type ffi_closure_SYSV, @function
+
+ffi_closure_SYSV:
+.LFB2:
+ pushl %ebp
+.LCFI2:
+ movl %esp, %ebp
+.LCFI3:
+ subl $40, %esp
+ leal -24(%ebp), %edx
+ movl %edx, -12(%ebp) /* resp */
+ leal 8(%ebp), %edx
+ movl %edx, 4(%esp) /* args = __builtin_dwarf_cfa () */
+ leal -12(%ebp), %edx
+ movl %edx, (%esp) /* &resp */
+#if defined HAVE_HIDDEN_VISIBILITY_ATTRIBUTE || !defined __PIC__
+ call ffi_closure_SYSV_inner
+#else
+ movl %ebx, 8(%esp)
+.LCFI7:
+ call 1f
+1: popl %ebx
+ addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx
+ call ffi_closure_SYSV_inner@PLT
+ movl 8(%esp), %ebx
+#endif
+ movl -12(%ebp), %ecx
+ cmpl $FFI_TYPE_INT, %eax
+ je .Lcls_retint
+
+ /* Handle FFI_TYPE_UINT8, FFI_TYPE_SINT8, FFI_TYPE_UINT16,
+ FFI_TYPE_SINT16, FFI_TYPE_UINT32, FFI_TYPE_SINT32. */
+ cmpl $FFI_TYPE_UINT64, %eax
+ jge 0f
+ cmpl $FFI_TYPE_UINT8, %eax
+ jge .Lcls_retint
+
+0: cmpl $FFI_TYPE_FLOAT, %eax
+ je .Lcls_retfloat
+ cmpl $FFI_TYPE_DOUBLE, %eax
+ je .Lcls_retdouble
+ cmpl $FFI_TYPE_LONGDOUBLE, %eax
+ je .Lcls_retldouble
+ cmpl $FFI_TYPE_SINT64, %eax
+ je .Lcls_retllong
+ cmpl $FFI_TYPE_SMALL_STRUCT_1B, %eax
+ je .Lcls_retstruct1b
+ cmpl $FFI_TYPE_SMALL_STRUCT_2B, %eax
+ je .Lcls_retstruct2b
+ cmpl $FFI_TYPE_STRUCT, %eax
+ je .Lcls_retstruct
+.Lcls_epilogue:
+ movl %ebp, %esp
+ popl %ebp
+ ret
+.Lcls_retint:
+ movl (%ecx), %eax
+ jmp .Lcls_epilogue
+.Lcls_retfloat:
+ flds (%ecx)
+ jmp .Lcls_epilogue
+.Lcls_retdouble:
+ fldl (%ecx)
+ jmp .Lcls_epilogue
+.Lcls_retldouble:
+ fldt (%ecx)
+ jmp .Lcls_epilogue
+.Lcls_retllong:
+ movl (%ecx), %eax
+ movl 4(%ecx), %edx
+ jmp .Lcls_epilogue
+.Lcls_retstruct1b:
+ movsbl (%ecx), %eax
+ jmp .Lcls_epilogue
+.Lcls_retstruct2b:
+ movswl (%ecx), %eax
+ jmp .Lcls_epilogue
+.Lcls_retstruct:
+ movl %ebp, %esp
+ popl %ebp
+ ret $4
+.LFE2:
+ .size ffi_closure_SYSV, .-ffi_closure_SYSV
+
+#if !FFI_NO_RAW_API
+
+#define RAW_CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) & ~3)
+#define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4)
+#define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4)
+#define CIF_FLAGS_OFFSET 20
+
+ .align 4
+FFI_HIDDEN (ffi_closure_raw_SYSV)
+.globl ffi_closure_raw_SYSV
+ .type ffi_closure_raw_SYSV, @function
+
+ffi_closure_raw_SYSV:
+.LFB3:
+ pushl %ebp
+.LCFI4:
+ movl %esp, %ebp
+.LCFI5:
+ pushl %esi
+.LCFI6:
+ subl $36, %esp
+ movl RAW_CLOSURE_CIF_OFFSET(%eax), %esi /* closure->cif */
+ movl RAW_CLOSURE_USER_DATA_OFFSET(%eax), %edx /* closure->user_data */
+ movl %edx, 12(%esp) /* user_data */
+ leal 8(%ebp), %edx /* __builtin_dwarf_cfa () */
+ movl %edx, 8(%esp) /* raw_args */
+ leal -24(%ebp), %edx
+ movl %edx, 4(%esp) /* &res */
+ movl %esi, (%esp) /* cif */
+ call *RAW_CLOSURE_FUN_OFFSET(%eax) /* closure->fun */
+ movl CIF_FLAGS_OFFSET(%esi), %eax /* rtype */
+ cmpl $FFI_TYPE_INT, %eax
+ je .Lrcls_retint
+
+ /* Handle FFI_TYPE_UINT8, FFI_TYPE_SINT8, FFI_TYPE_UINT16,
+ FFI_TYPE_SINT16, FFI_TYPE_UINT32, FFI_TYPE_SINT32. */
+ cmpl $FFI_TYPE_UINT64, %eax
+ jge 0f
+ cmpl $FFI_TYPE_UINT8, %eax
+ jge .Lrcls_retint
+0:
+ cmpl $FFI_TYPE_FLOAT, %eax
+ je .Lrcls_retfloat
+ cmpl $FFI_TYPE_DOUBLE, %eax
+ je .Lrcls_retdouble
+ cmpl $FFI_TYPE_LONGDOUBLE, %eax
+ je .Lrcls_retldouble
+ cmpl $FFI_TYPE_SINT64, %eax
+ je .Lrcls_retllong
+.Lrcls_epilogue:
+ addl $36, %esp
+ popl %esi
+ popl %ebp
+ ret
+.Lrcls_retint:
+ movl -24(%ebp), %eax
+ jmp .Lrcls_epilogue
+.Lrcls_retfloat:
+ flds -24(%ebp)
+ jmp .Lrcls_epilogue
+.Lrcls_retdouble:
+ fldl -24(%ebp)
+ jmp .Lrcls_epilogue
+.Lrcls_retldouble:
+ fldt -24(%ebp)
+ jmp .Lrcls_epilogue
+.Lrcls_retllong:
+ movl -24(%ebp), %eax
+ movl -20(%ebp), %edx
+ jmp .Lrcls_epilogue
+.LFE3:
+ .size ffi_closure_raw_SYSV, .-ffi_closure_raw_SYSV
+#endif
+
+ .section .eh_frame,EH_FRAME_FLAGS,@progbits
+.Lframe1:
+ .long .LECIE1-.LSCIE1 /* Length of Common Information Entry */
+.LSCIE1:
+ .long 0x0 /* CIE Identifier Tag */
+ .byte 0x1 /* CIE Version */
+#ifdef __PIC__
+ .ascii "zR\0" /* CIE Augmentation */
+#else
+ .ascii "\0" /* CIE Augmentation */
+#endif
+ .byte 0x1 /* .uleb128 0x1; CIE Code Alignment Factor */
+ .byte 0x7c /* .sleb128 -4; CIE Data Alignment Factor */
+ .byte 0x8 /* CIE RA Column */
+#ifdef __PIC__
+ .byte 0x1 /* .uleb128 0x1; Augmentation size */
+ .byte 0x1b /* FDE Encoding (pcrel sdata4) */
+#endif
+ .byte 0xc /* DW_CFA_def_cfa */
+ .byte 0x4 /* .uleb128 0x4 */
+ .byte 0x4 /* .uleb128 0x4 */
+ .byte 0x88 /* DW_CFA_offset, column 0x8 */
+ .byte 0x1 /* .uleb128 0x1 */
+ .align 4
+.LECIE1:
+.LSFDE1:
+ .long .LEFDE1-.LASFDE1 /* FDE Length */
+.LASFDE1:
+ .long .LASFDE1-.Lframe1 /* FDE CIE offset */
+#ifdef __PIC__
+ .long .LFB1-. /* FDE initial location */
+#else
+ .long .LFB1 /* FDE initial location */
+#endif
+ .long .LFE1-.LFB1 /* FDE address range */
+#ifdef __PIC__
+ .byte 0x0 /* .uleb128 0x0; Augmentation size */
+#endif
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .long .LCFI0-.LFB1
+ .byte 0xe /* DW_CFA_def_cfa_offset */
+ .byte 0x8 /* .uleb128 0x8 */
+ .byte 0x85 /* DW_CFA_offset, column 0x5 */
+ .byte 0x2 /* .uleb128 0x2 */
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .long .LCFI1-.LCFI0
+ .byte 0xd /* DW_CFA_def_cfa_register */
+ .byte 0x5 /* .uleb128 0x5 */
+ .align 4
+.LEFDE1:
+.LSFDE2:
+ .long .LEFDE2-.LASFDE2 /* FDE Length */
+.LASFDE2:
+ .long .LASFDE2-.Lframe1 /* FDE CIE offset */
+#ifdef __PIC__
+ .long .LFB2-. /* FDE initial location */
+#else
+ .long .LFB2
+#endif
+ .long .LFE2-.LFB2 /* FDE address range */
+#ifdef __PIC__
+ .byte 0x0 /* .uleb128 0x0; Augmentation size */
+#endif
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .long .LCFI2-.LFB2
+ .byte 0xe /* DW_CFA_def_cfa_offset */
+ .byte 0x8 /* .uleb128 0x8 */
+ .byte 0x85 /* DW_CFA_offset, column 0x5 */
+ .byte 0x2 /* .uleb128 0x2 */
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .long .LCFI3-.LCFI2
+ .byte 0xd /* DW_CFA_def_cfa_register */
+ .byte 0x5 /* .uleb128 0x5 */
+#if !defined HAVE_HIDDEN_VISIBILITY_ATTRIBUTE && defined __PIC__
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .long .LCFI7-.LCFI3
+ .byte 0x83 /* DW_CFA_offset, column 0x3 */
+ .byte 0xa /* .uleb128 0xa */
+#endif
+ .align 4
+.LEFDE2:
+
+#if !FFI_NO_RAW_API
+
+.LSFDE3:
+ .long .LEFDE3-.LASFDE3 /* FDE Length */
+.LASFDE3:
+ .long .LASFDE3-.Lframe1 /* FDE CIE offset */
+#ifdef __PIC__
+ .long .LFB3-. /* FDE initial location */
+#else
+ .long .LFB3
+#endif
+ .long .LFE3-.LFB3 /* FDE address range */
+#ifdef __PIC__
+ .byte 0x0 /* .uleb128 0x0; Augmentation size */
+#endif
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .long .LCFI4-.LFB3
+ .byte 0xe /* DW_CFA_def_cfa_offset */
+ .byte 0x8 /* .uleb128 0x8 */
+ .byte 0x85 /* DW_CFA_offset, column 0x5 */
+ .byte 0x2 /* .uleb128 0x2 */
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .long .LCFI5-.LCFI4
+ .byte 0xd /* DW_CFA_def_cfa_register */
+ .byte 0x5 /* .uleb128 0x5 */
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .long .LCFI6-.LCFI5
+ .byte 0x86 /* DW_CFA_offset, column 0x6 */
+ .byte 0x3 /* .uleb128 0x3 */
+ .align 4
+.LEFDE3:
+
+#endif
+
+#endif /* ifndef __x86_64__ */
diff --git a/libffi/src/x86/sysv.S b/libffi/src/x86/sysv.S
index 04564db9caa..f4b6c1e4415 100644
--- a/libffi/src/x86/sysv.S
+++ b/libffi/src/x86/sysv.S
@@ -1,6 +1,5 @@
/* -----------------------------------------------------------------------
- sysv.S - Copyright (c) 1996, 1998, 2001, 2002, 2003, 2005, 2008
- Red Hat, Inc.
+ sysv.S - Copyright (c) 1996, 1998, 2001-2003, 2005, 2008 Red Hat, Inc.
X86 Foreign Function Interface
@@ -15,13 +14,14 @@
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#ifndef __x86_64__
diff --git a/libffi/src/x86/unix64.S b/libffi/src/x86/unix64.S
index ec6030484ea..fe3f4fd6223 100644
--- a/libffi/src/x86/unix64.S
+++ b/libffi/src/x86/unix64.S
@@ -1,5 +1,6 @@
/* -----------------------------------------------------------------------
- unix64.S - Copyright (c) 2002, 2008 Bo Thorsen <bo@suse.de>
+ unix64.S - Copyright (c) 2002 Bo Thorsen <bo@suse.de>
+ Copyright (c) 2008 Red Hat, Inc
x86-64 Foreign Function Interface
@@ -14,13 +15,14 @@
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#ifdef __x86_64__
@@ -31,7 +33,7 @@
.text
/* ffi_call_unix64 (void *args, unsigned long bytes, unsigned flags,
- void *raddr, void (*fnaddr)());
+ void *raddr, void (*fnaddr)(void));
Bit o trickiness here -- ARGS+BYTES is the base of the stack frame
for this function. This has been allocated by ffi_call. We also
diff --git a/libffi/src/x86/win32.S b/libffi/src/x86/win32.S
index 496953e4344..a1de858d96a 100644
--- a/libffi/src/x86/win32.S
+++ b/libffi/src/x86/win32.S
@@ -1,5 +1,5 @@
/* -----------------------------------------------------------------------
- win32.S - Copyright (c) 1996, 1998, 2001, 2002 Red Hat, Inc.
+ win32.S - Copyright (c) 1996, 1998, 2001, 2002, 2009 Red Hat, Inc.
Copyright (c) 2001 John Beniton
Copyright (c) 2002 Ranjit Mathew
@@ -17,31 +17,33 @@
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
- ----------------------------------------------------------------------- */
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+ -----------------------------------------------------------------------
+ */
#define LIBFFI_ASM
#include <fficonfig.h>
#include <ffi.h>
-.text
-
-.globl ffi_prep_args
+ .text
# This assumes we are using gas.
.balign 16
-.globl _ffi_call_SYSV
-
+ .globl _ffi_call_SYSV
+ .def _ffi_call_SYSV; .scl 2; .type 32; .endef
_ffi_call_SYSV:
+.LFB1:
pushl %ebp
+.LCFI0:
movl %esp,%ebp
-
+.LCFI1:
# Make room for all of the new args.
movl 16(%ebp),%ecx
subl %ecx,%esp
@@ -144,17 +146,19 @@ epilogue:
movl %ebp,%esp
popl %ebp
ret
-
.ffi_call_SYSV_end:
+.LFE1:
# This assumes we are using gas.
.balign 16
-.globl _ffi_call_STDCALL
-
+ .globl _ffi_call_STDCALL
+ .def _ffi_call_STDCALL; .scl 2; .type 32; .endef
_ffi_call_STDCALL:
+.LFB2:
pushl %ebp
+.LCFI2:
movl %esp,%ebp
-
+.LCFI3:
# Make room for all of the new args.
movl 16(%ebp),%ecx
subl %ecx,%esp
@@ -255,13 +259,19 @@ sc_epilogue:
movl %ebp,%esp
popl %ebp
ret
-
.ffi_call_STDCALL_end:
+.LFE2:
- .globl _ffi_closure_SYSV
+ # This assumes we are using gas.
+ .balign 16
+ .globl _ffi_closure_SYSV
+ .def _ffi_closure_SYSV; .scl 2; .type 32; .endef
_ffi_closure_SYSV:
+.LFB3:
pushl %ebp
+.LCFI4:
movl %esp, %ebp
+.LCFI5:
subl $40, %esp
leal -24(%ebp), %edx
movl %edx, -12(%ebp) /* resp */
@@ -312,6 +322,7 @@ _ffi_closure_SYSV:
movswl (%ecx), %eax
jmp .Lcls_epilogue
.ffi_closure_SYSV_end:
+.LFE3:
#if !FFI_NO_RAW_API
@@ -320,12 +331,18 @@ _ffi_closure_SYSV:
#define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4)
#define CIF_FLAGS_OFFSET 20
- .balign 16
- .globl _ffi_closure_raw_SYSV
+ # This assumes we are using gas.
+ .balign 16
+ .globl _ffi_closure_raw_SYSV
+ .def _ffi_closure_raw_SYSV; .scl 2; .type 32; .endef
_ffi_closure_raw_SYSV:
+.LFB4:
pushl %ebp
+.LCFI6:
movl %esp, %ebp
+.LCFI7:
pushl %esi
+.LCFI8:
subl $36, %esp
movl RAW_CLOSURE_CIF_OFFSET(%eax), %esi /* closure->cif */
movl RAW_CLOSURE_USER_DATA_OFFSET(%eax), %edx /* closure->user_data */
@@ -369,5 +386,264 @@ _ffi_closure_raw_SYSV:
movl -20(%ebp), %edx
jmp .Lrcls_epilogue
.ffi_closure_raw_SYSV_end:
+.LFE4:
+
+#endif /* !FFI_NO_RAW_API */
+
+ # This assumes we are using gas.
+ .balign 16
+ .globl _ffi_closure_STDCALL
+ .def _ffi_closure_STDCALL; .scl 2; .type 32; .endef
+_ffi_closure_STDCALL:
+.LFB5:
+ pushl %ebp
+.LCFI9:
+ movl %esp, %ebp
+.LCFI10:
+ subl $40, %esp
+ leal -24(%ebp), %edx
+ movl %edx, -12(%ebp) /* resp */
+ leal 12(%ebp), %edx /* account for stub return address on stack */
+ movl %edx, 4(%esp) /* args */
+ leal -12(%ebp), %edx
+ movl %edx, (%esp) /* &resp */
+ call _ffi_closure_SYSV_inner
+ movl -12(%ebp), %ecx
+ /* It would be nice to just share this code with the
+ duplicate sequence in _ffi_closure_SYSV, if only
+ there were some way to represent that in the EH info. */
+ cmpl $FFI_TYPE_INT, %eax
+ je .Lscls_retint
+ cmpl $FFI_TYPE_FLOAT, %eax
+ je .Lscls_retfloat
+ cmpl $FFI_TYPE_DOUBLE, %eax
+ je .Lscls_retdouble
+ cmpl $FFI_TYPE_LONGDOUBLE, %eax
+ je .Lscls_retldouble
+ cmpl $FFI_TYPE_SINT64, %eax
+ je .Lscls_retllong
+ cmpl $FFI_TYPE_SINT8, %eax /* 1-byte struct */
+ je .Lscls_retstruct1
+ cmpl $FFI_TYPE_SINT16, %eax /* 2-bytes struct */
+ je .Lscls_retstruct2
+.Lscls_epilogue:
+ movl %ebp, %esp
+ popl %ebp
+ ret
+.Lscls_retint:
+ movl (%ecx), %eax
+ jmp .Lscls_epilogue
+.Lscls_retfloat:
+ flds (%ecx)
+ jmp .Lscls_epilogue
+.Lscls_retdouble:
+ fldl (%ecx)
+ jmp .Lscls_epilogue
+.Lscls_retldouble:
+ fldt (%ecx)
+ jmp .Lscls_epilogue
+.Lscls_retllong:
+ movl (%ecx), %eax
+ movl 4(%ecx), %edx
+ jmp .Lscls_epilogue
+.Lscls_retstruct1:
+ movsbl (%ecx), %eax
+ jmp .Lscls_epilogue
+.Lscls_retstruct2:
+ movswl (%ecx), %eax
+ jmp .Lscls_epilogue
+.ffi_closure_STDCALL_end:
+.LFE5:
+
+ .section .eh_frame,"w"
+.Lframe1:
+.LSCIE1:
+ .long .LECIE1-.LASCIE1 /* Length of Common Information Entry */
+.LASCIE1:
+ .long 0x0 /* CIE Identifier Tag */
+ .byte 0x1 /* CIE Version */
+#ifdef __PIC__
+ .ascii "zR\0" /* CIE Augmentation */
+#else
+ .ascii "\0" /* CIE Augmentation */
+#endif
+ .byte 0x1 /* .uleb128 0x1; CIE Code Alignment Factor */
+ .byte 0x7c /* .sleb128 -4; CIE Data Alignment Factor */
+ .byte 0x8 /* CIE RA Column */
+#ifdef __PIC__
+ .byte 0x1 /* .uleb128 0x1; Augmentation size */
+ .byte 0x1b /* FDE Encoding (pcrel sdata4) */
+#endif
+ .byte 0xc /* DW_CFA_def_cfa CFA = r4 + 4 = 4(%esp) */
+ .byte 0x4 /* .uleb128 0x4 */
+ .byte 0x4 /* .uleb128 0x4 */
+ .byte 0x88 /* DW_CFA_offset, column 0x8 %eip at CFA + 1 * -4 */
+ .byte 0x1 /* .uleb128 0x1 */
+ .align 4
+.LECIE1:
+
+.LSFDE1:
+ .long .LEFDE1-.LASFDE1 /* FDE Length */
+.LASFDE1:
+ .long .LASFDE1-.Lframe1 /* FDE CIE offset */
+#if defined __PIC__ && defined HAVE_AS_X86_PCREL
+ .long .LFB1-. /* FDE initial location */
+#else
+ .long .LFB1
+#endif
+ .long .LFE1-.LFB1 /* FDE address range */
+#ifdef __PIC__
+ .byte 0x0 /* .uleb128 0x0; Augmentation size */
+#endif
+ /* DW_CFA_xxx CFI instructions go here. */
+
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .long .LCFI0-.LFB1
+ .byte 0xe /* DW_CFA_def_cfa_offset CFA = r4 + 8 = 8(%esp) */
+ .byte 0x8 /* .uleb128 0x8 */
+ .byte 0x85 /* DW_CFA_offset, column 0x5 %ebp at CFA + 2 * -4 */
+ .byte 0x2 /* .uleb128 0x2 */
+
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .long .LCFI1-.LCFI0
+ .byte 0xd /* DW_CFA_def_cfa_register CFA = r5 = %ebp */
+ .byte 0x5 /* .uleb128 0x5 */
+
+ /* End of DW_CFA_xxx CFI instructions. */
+ .align 4
+.LEFDE1:
+
+
+.LSFDE2:
+ .long .LEFDE2-.LASFDE2 /* FDE Length */
+.LASFDE2:
+ .long .LASFDE2-.Lframe1 /* FDE CIE offset */
+#if defined __PIC__ && defined HAVE_AS_X86_PCREL
+ .long .LFB2-. /* FDE initial location */
+#else
+ .long .LFB2
+#endif
+ .long .LFE2-.LFB2 /* FDE address range */
+#ifdef __PIC__
+ .byte 0x0 /* .uleb128 0x0; Augmentation size */
+#endif
+ /* DW_CFA_xxx CFI instructions go here. */
+
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .long .LCFI2-.LFB2
+ .byte 0xe /* DW_CFA_def_cfa_offset CFA = r4 + 8 = 8(%esp) */
+ .byte 0x8 /* .uleb128 0x8 */
+ .byte 0x85 /* DW_CFA_offset, column 0x5 %ebp at CFA + 2 * -4 */
+ .byte 0x2 /* .uleb128 0x2 */
+
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .long .LCFI3-.LCFI2
+ .byte 0xd /* DW_CFA_def_cfa_register CFA = r5 = %ebp */
+ .byte 0x5 /* .uleb128 0x5 */
+
+ /* End of DW_CFA_xxx CFI instructions. */
+ .align 4
+.LEFDE2:
+
+.LSFDE3:
+ .long .LEFDE3-.LASFDE3 /* FDE Length */
+.LASFDE3:
+ .long .LASFDE3-.Lframe1 /* FDE CIE offset */
+#if defined __PIC__ && defined HAVE_AS_X86_PCREL
+ .long .LFB3-. /* FDE initial location */
+#else
+ .long .LFB3
#endif
+ .long .LFE3-.LFB3 /* FDE address range */
+#ifdef __PIC__
+ .byte 0x0 /* .uleb128 0x0; Augmentation size */
+#endif
+ /* DW_CFA_xxx CFI instructions go here. */
+
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .long .LCFI4-.LFB3
+ .byte 0xe /* DW_CFA_def_cfa_offset CFA = r4 + 8 = 8(%esp) */
+ .byte 0x8 /* .uleb128 0x8 */
+ .byte 0x85 /* DW_CFA_offset, column 0x5 %ebp at CFA + 2 * -4 */
+ .byte 0x2 /* .uleb128 0x2 */
+
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .long .LCFI5-.LCFI4
+ .byte 0xd /* DW_CFA_def_cfa_register CFA = r5 = %ebp */
+ .byte 0x5 /* .uleb128 0x5 */
+
+ /* End of DW_CFA_xxx CFI instructions. */
+ .align 4
+.LEFDE3:
+
+#if !FFI_NO_RAW_API
+
+.LSFDE4:
+ .long .LEFDE4-.LASFDE4 /* FDE Length */
+.LASFDE4:
+ .long .LASFDE4-.Lframe1 /* FDE CIE offset */
+#if defined __PIC__ && defined HAVE_AS_X86_PCREL
+ .long .LFB4-. /* FDE initial location */
+#else
+ .long .LFB4
+#endif
+ .long .LFE4-.LFB4 /* FDE address range */
+#ifdef __PIC__
+ .byte 0x0 /* .uleb128 0x0; Augmentation size */
+#endif
+ /* DW_CFA_xxx CFI instructions go here. */
+
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .long .LCFI6-.LFB4
+ .byte 0xe /* DW_CFA_def_cfa_offset CFA = r4 + 8 = 8(%esp) */
+ .byte 0x8 /* .uleb128 0x8 */
+ .byte 0x85 /* DW_CFA_offset, column 0x5 %ebp at CFA + 2 * -4 */
+ .byte 0x2 /* .uleb128 0x2 */
+
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .long .LCFI7-.LCFI6
+ .byte 0xd /* DW_CFA_def_cfa_register CFA = r5 = %ebp */
+ .byte 0x5 /* .uleb128 0x5 */
+
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .long .LCFI8-.LCFI7
+ .byte 0x86 /* DW_CFA_offset, column 0x6 %esi at CFA + 3 * -4 */
+ .byte 0x3 /* .uleb128 0x3 */
+
+ /* End of DW_CFA_xxx CFI instructions. */
+ .align 4
+.LEFDE4:
+
+#endif /* !FFI_NO_RAW_API */
+
+.LSFDE5:
+ .long .LEFDE5-.LASFDE5 /* FDE Length */
+.LASFDE5:
+ .long .LASFDE5-.Lframe1 /* FDE CIE offset */
+#if defined __PIC__ && defined HAVE_AS_X86_PCREL
+ .long .LFB5-. /* FDE initial location */
+#else
+ .long .LFB5
+#endif
+ .long .LFE5-.LFB5 /* FDE address range */
+#ifdef __PIC__
+ .byte 0x0 /* .uleb128 0x0; Augmentation size */
+#endif
+ /* DW_CFA_xxx CFI instructions go here. */
+
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .long .LCFI9-.LFB5
+ .byte 0xe /* DW_CFA_def_cfa_offset CFA = r4 + 8 = 8(%esp) */
+ .byte 0x8 /* .uleb128 0x8 */
+ .byte 0x85 /* DW_CFA_offset, column 0x5 %ebp at CFA + 2 * -4 */
+ .byte 0x2 /* .uleb128 0x2 */
+
+ .byte 0x4 /* DW_CFA_advance_loc4 */
+ .long .LCFI10-.LCFI9
+ .byte 0xd /* DW_CFA_def_cfa_register CFA = r5 = %ebp */
+ .byte 0x5 /* .uleb128 0x5 */
+
+ /* End of DW_CFA_xxx CFI instructions. */
+ .align 4
+.LEFDE5:
diff --git a/libffi/src/x86/win64.S b/libffi/src/x86/win64.S
new file mode 100644
index 00000000000..ae56c2edb00
--- /dev/null
+++ b/libffi/src/x86/win64.S
@@ -0,0 +1,462 @@
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+
+/* Constants for ffi_call_win64 */
+#define STACK 0
+#define PREP_ARGS_FN 32
+#define ECIF 40
+#define CIF_BYTES 48
+#define CIF_FLAGS 56
+#define RVALUE 64
+#define FN 72
+
+/* ffi_call_win64 (void (*prep_args_fn)(char *, extended_cif *),
+ extended_cif *ecif, unsigned bytes, unsigned flags,
+ unsigned *rvalue, void (*fn)());
+ */
+
+#ifdef _MSC_VER
+PUBLIC ffi_call_win64
+
+EXTRN __chkstk:NEAR
+EXTRN ffi_closure_win64_inner:NEAR
+
+_TEXT SEGMENT
+
+;;; ffi_closure_win64 will be called with these registers set:
+;;; rax points to 'closure'
+;;; r11 contains a bit mask that specifies which of the
+;;; first four parameters are float or double
+;;;
+;;; It must move the parameters passed in registers to their stack location,
+;;; call ffi_closure_win64_inner for the actual work, then return the result.
+;;;
+ffi_closure_win64 PROC FRAME
+ ;; copy register arguments onto stack
+ test r11, 1
+ jne first_is_float
+ mov QWORD PTR [rsp+8], rcx
+ jmp second
+first_is_float:
+ movlpd QWORD PTR [rsp+8], xmm0
+
+second:
+ test r11, 2
+ jne second_is_float
+ mov QWORD PTR [rsp+16], rdx
+ jmp third
+second_is_float:
+ movlpd QWORD PTR [rsp+16], xmm1
+
+third:
+ test r11, 4
+ jne third_is_float
+ mov QWORD PTR [rsp+24], r8
+ jmp fourth
+third_is_float:
+ movlpd QWORD PTR [rsp+24], xmm2
+
+fourth:
+ test r11, 8
+ jne fourth_is_float
+ mov QWORD PTR [rsp+32], r9
+ jmp done
+fourth_is_float:
+ movlpd QWORD PTR [rsp+32], xmm3
+
+done:
+ .ALLOCSTACK 40
+ sub rsp, 40
+ .ENDPROLOG
+ mov rcx, rax ; context is first parameter
+ mov rdx, rsp ; stack is second parameter
+ add rdx, 48 ; point to start of arguments
+ mov rax, ffi_closure_win64_inner
+ call rax ; call the real closure function
+ add rsp, 40
+ movd xmm0, rax ; If the closure returned a float,
+ ; ffi_closure_win64_inner wrote it to rax
+ ret 0
+ffi_closure_win64 ENDP
+
+ffi_call_win64 PROC FRAME
+ ;; copy registers onto stack
+ mov QWORD PTR [rsp+32], r9
+ mov QWORD PTR [rsp+24], r8
+ mov QWORD PTR [rsp+16], rdx
+ mov QWORD PTR [rsp+8], rcx
+ .PUSHREG rbp
+ push rbp
+ .ALLOCSTACK 48
+ sub rsp, 48 ; 00000030H
+ .SETFRAME rbp, 32
+ lea rbp, QWORD PTR [rsp+32]
+ .ENDPROLOG
+
+ mov eax, DWORD PTR CIF_BYTES[rbp]
+ add rax, 15
+ and rax, -16
+ call __chkstk
+ sub rsp, rax
+ lea rax, QWORD PTR [rsp+32]
+ mov QWORD PTR STACK[rbp], rax
+
+ mov rdx, QWORD PTR ECIF[rbp]
+ mov rcx, QWORD PTR STACK[rbp]
+ call QWORD PTR PREP_ARGS_FN[rbp]
+
+ mov rsp, QWORD PTR STACK[rbp]
+
+ movlpd xmm3, QWORD PTR [rsp+24]
+ movd r9, xmm3
+
+ movlpd xmm2, QWORD PTR [rsp+16]
+ movd r8, xmm2
+
+ movlpd xmm1, QWORD PTR [rsp+8]
+ movd rdx, xmm1
+
+ movlpd xmm0, QWORD PTR [rsp]
+ movd rcx, xmm0
+
+ call QWORD PTR FN[rbp]
+ret_struct4b$:
+ cmp DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_SMALL_STRUCT_4B
+ jne ret_struct2b$
+
+ mov rcx, QWORD PTR RVALUE[rbp]
+ mov DWORD PTR [rcx], eax
+ jmp ret_void$
+
+ret_struct2b$:
+ cmp DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_SMALL_STRUCT_2B
+ jne ret_struct1b$
+
+ mov rcx, QWORD PTR RVALUE[rbp]
+ mov WORD PTR [rcx], ax
+ jmp ret_void$
+
+ret_struct1b$:
+ cmp DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_SMALL_STRUCT_1B
+ jne ret_uint8$
+
+ mov rcx, QWORD PTR RVALUE[rbp]
+ mov BYTE PTR [rcx], al
+ jmp ret_void$
+
+ret_uint8$:
+ cmp DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_UINT8
+ jne ret_sint8$
+
+ mov rcx, QWORD PTR RVALUE[rbp]
+ movzx rax, al
+ mov QWORD PTR [rcx], rax
+ jmp ret_void$
+
+ret_sint8$:
+ cmp DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_SINT8
+ jne ret_uint16$
+
+ mov rcx, QWORD PTR RVALUE[rbp]
+ movsx rax, al
+ mov QWORD PTR [rcx], rax
+ jmp ret_void$
+
+ret_uint16$:
+ cmp DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_UINT16
+ jne ret_sint16$
+
+ mov rcx, QWORD PTR RVALUE[rbp]
+ movzx rax, ax
+ mov QWORD PTR [rcx], rax
+ jmp SHORT ret_void$
+
+ret_sint16$:
+ cmp DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_SINT16
+ jne ret_uint32$
+
+ mov rcx, QWORD PTR RVALUE[rbp]
+ movsx rax, ax
+ mov QWORD PTR [rcx], rax
+ jmp SHORT ret_void$
+
+ret_uint32$:
+ cmp DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_UINT32
+ jne ret_sint32$
+
+ mov rcx, QWORD PTR RVALUE[rbp]
+ mov eax, eax
+ mov QWORD PTR [rcx], rax
+ jmp SHORT ret_void$
+
+ret_sint32$:
+ cmp DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_SINT32
+ jne ret_float$
+
+ mov rcx, QWORD PTR RVALUE[rbp]
+ cdqe
+ mov QWORD PTR [rcx], rax
+ jmp SHORT ret_void$
+
+ret_float$:
+ cmp DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_FLOAT
+ jne SHORT ret_double$
+
+ mov rax, QWORD PTR RVALUE[rbp]
+ movss DWORD PTR [rax], xmm0
+ jmp SHORT ret_void$
+
+ret_double$:
+ cmp DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_DOUBLE
+ jne SHORT ret_sint64$
+
+ mov rax, QWORD PTR RVALUE[rbp]
+ movlpd QWORD PTR [rax], xmm0
+ jmp SHORT ret_void$
+
+ret_sint64$:
+ cmp DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_SINT64
+ jne ret_void$
+
+ mov rcx, QWORD PTR RVALUE[rbp]
+ mov QWORD PTR [rcx], rax
+ jmp SHORT ret_void$
+
+ret_void$:
+ xor rax, rax
+
+ lea rsp, QWORD PTR [rbp+16]
+ pop rbp
+ ret 0
+ffi_call_win64 ENDP
+_TEXT ENDS
+END
+#else
+.text
+
+.extern ___chkstk
+.extern _ffi_closure_win64_inner
+
+# ffi_closure_win64 will be called with these registers set:
+# rax points to 'closure'
+# r11 contains a bit mask that specifies which of the
+# first four parameters are float or double
+#
+# It must move the parameters passed in registers to their stack location,
+# call ffi_closure_win64_inner for the actual work, then return the result.
+#
+ .balign 16
+ .globl _ffi_closure_win64
+_ffi_closure_win64:
+ # copy register arguments onto stack
+ test $1,%r11
+ jne .Lfirst_is_float
+ mov %rcx, 8(%rsp)
+ jmp .Lsecond
+.Lfirst_is_float:
+ movlpd %xmm0, 8(%rsp)
+
+.Lsecond:
+ test $2, %r11
+ jne .Lsecond_is_float
+ mov %rdx, 16(%rsp)
+ jmp .Lthird
+.Lsecond_is_float:
+ movlpd %xmm1, 16(%rsp)
+
+.Lthird:
+ test $4, %r11
+ jne .Lthird_is_float
+ mov %r8,24(%rsp)
+ jmp .Lfourth
+.Lthird_is_float:
+ movlpd %xmm2, 24(%rsp)
+
+.Lfourth:
+ test $8, %r11
+ jne .Lfourth_is_float
+ mov %r9, 32(%rsp)
+ jmp .Ldone
+.Lfourth_is_float:
+ movlpd %xmm3, 32(%rsp)
+
+.Ldone:
+#.ALLOCSTACK 40
+ sub $40, %rsp
+#.ENDPROLOG
+ mov %rax, %rcx # context is first parameter
+ mov %rsp, %rdx # stack is second parameter
+ add $48, %rdx # point to start of arguments
+ mov $_ffi_closure_win64_inner, %rax
+ callq *%rax # call the real closure function
+ add $40, %rsp
+ movq %rax, %xmm0 # If the closure returned a float,
+ # ffi_closure_win64_inner wrote it to rax
+ retq
+.ffi_closure_win64_end:
+
+ .balign 16
+ .globl _ffi_call_win64
+_ffi_call_win64:
+ # copy registers onto stack
+ mov %r9,32(%rsp)
+ mov %r8,24(%rsp)
+ mov %rdx,16(%rsp)
+ mov %rcx,8(%rsp)
+ #.PUSHREG rbp
+ push %rbp
+ #.ALLOCSTACK 48
+ sub $48,%rsp
+ #.SETFRAME rbp, 32
+ lea 32(%rsp),%rbp
+ #.ENDPROLOG
+
+ mov CIF_BYTES(%rbp),%eax
+ add $15, %rax
+ and $-16, %rax
+ callq ___chkstk
+ cmpq $0x1000, %rax
+ jb Lch_done
+Lch_probe:
+ subq $0x1000,%rsp
+ orl $0x0, (%rsp)
+ subq $0x1000,%rax
+ cmpq $0x1000,%rax
+ ja Lch_probe
+Lch_done:
+ subq %rax, %rsp
+ orl $0x0, (%rsp)
+ lea 32(%rsp), %rax
+ mov %rax, STACK(%rbp)
+
+ mov ECIF(%rbp), %rdx
+ mov STACK(%rbp), %rcx
+ callq *PREP_ARGS_FN(%rbp)
+
+ mov STACK(%rbp), %rsp
+
+ movlpd 24(%rsp), %xmm3
+ movd %xmm3, %r9
+
+ movlpd 16(%rsp), %xmm2
+ movd %xmm2, %r8
+
+ movlpd 8(%rsp), %xmm1
+ movd %xmm1, %rdx
+
+ movlpd (%rsp), %xmm0
+ movd %xmm0, %rcx
+
+ callq *FN(%rbp)
+.Lret_struct4b:
+ cmpl $FFI_TYPE_SMALL_STRUCT_4B, CIF_FLAGS(%rbp)
+ jne .Lret_struct2b
+
+ mov RVALUE(%rbp), %rcx
+ mov %eax, (%rcx)
+ jmp .Lret_void
+
+.Lret_struct2b:
+ cmpl $FFI_TYPE_SMALL_STRUCT_2B, CIF_FLAGS(%rbp)
+ jne .Lret_struct1b
+
+ mov RVALUE(%rbp), %rcx
+ mov %ax, (%rcx)
+ jmp .Lret_void
+
+.Lret_struct1b:
+ cmpl $FFI_TYPE_SMALL_STRUCT_1B, CIF_FLAGS(%rbp)
+ jne .Lret_uint8
+
+ mov RVALUE(%rbp), %rcx
+ mov %al, (%rcx)
+ jmp .Lret_void
+
+.Lret_uint8:
+ cmpl $FFI_TYPE_UINT8, CIF_FLAGS(%rbp)
+ jne .Lret_sint8
+
+ mov RVALUE(%rbp), %rcx
+ movzbq %al, %rax
+ movq %rax, (%rcx)
+ jmp .Lret_void
+
+.Lret_sint8:
+ cmpl $FFI_TYPE_SINT8, CIF_FLAGS(%rbp)
+ jne .Lret_uint16
+
+ mov RVALUE(%rbp), %rcx
+ movsbq %al, %rax
+ movq %rax, (%rcx)
+ jmp .Lret_void
+
+.Lret_uint16:
+ cmpl $FFI_TYPE_UINT16, CIF_FLAGS(%rbp)
+ jne .Lret_sint16
+
+ mov RVALUE(%rbp), %rcx
+ movzwq %ax, %rax
+ movq %rax, (%rcx)
+ jmp .Lret_void
+
+.Lret_sint16:
+ cmpl $FFI_TYPE_SINT16, CIF_FLAGS(%rbp)
+ jne .Lret_uint32
+
+ mov RVALUE(%rbp), %rcx
+ movswq %ax, %rax
+ movq %rax, (%rcx)
+ jmp .Lret_void
+
+.Lret_uint32:
+ cmpl $FFI_TYPE_UINT32, CIF_FLAGS(%rbp)
+ jne .Lret_sint32
+
+ mov RVALUE(%rbp), %rcx
+ movl %eax, %eax
+ movq %rax, (%rcx)
+ jmp .Lret_void
+
+.Lret_sint32:
+ cmpl $FFI_TYPE_SINT32, CIF_FLAGS(%rbp)
+ jne .Lret_float
+
+ mov RVALUE(%rbp), %rcx
+ cltq
+ movq %rax, (%rcx)
+ jmp .Lret_void
+
+.Lret_float:
+ cmpl $FFI_TYPE_FLOAT, CIF_FLAGS(%rbp)
+ jne .Lret_double
+
+ mov RVALUE(%rbp), %rax
+ movss %xmm0, (%rax)
+ jmp .Lret_void
+
+.Lret_double:
+ cmpl $FFI_TYPE_DOUBLE, CIF_FLAGS(%rbp)
+ jne .Lret_sint64
+
+ mov RVALUE(%rbp), %rax
+ movlpd %xmm0, (%rax)
+ jmp .Lret_void
+
+.Lret_sint64:
+ cmpl $FFI_TYPE_SINT64, CIF_FLAGS(%rbp)
+ jne .Lret_void
+
+ mov RVALUE(%rbp), %rcx
+ mov %rax, (%rcx)
+ jmp .Lret_void
+
+.Lret_void:
+ xor %rax, %rax
+
+ lea 16(%rbp), %rsp
+ pop %rbp
+ retq
+.ffi_call_win64_end:
+#endif /* !_MSC_VER */
+
diff --git a/libffi/testsuite/Makefile.in b/libffi/testsuite/Makefile.in
index 9ac55faf0df..c6dd213abd0 100644
--- a/libffi/testsuite/Makefile.in
+++ b/libffi/testsuite/Makefile.in
@@ -170,9 +170,13 @@ X86_64_TRUE = @X86_64_TRUE@
X86_DARWIN_FALSE = @X86_DARWIN_FALSE@
X86_DARWIN_TRUE = @X86_DARWIN_TRUE@
X86_FALSE = @X86_FALSE@
+X86_FREEBSD_FALSE = @X86_FREEBSD_FALSE@
+X86_FREEBSD_TRUE = @X86_FREEBSD_TRUE@
X86_TRUE = @X86_TRUE@
X86_WIN32_FALSE = @X86_WIN32_FALSE@
X86_WIN32_TRUE = @X86_WIN32_TRUE@
+X86_WIN64_FALSE = @X86_WIN64_FALSE@
+X86_WIN64_TRUE = @X86_WIN64_TRUE@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_DSYMUTIL = @ac_ct_DSYMUTIL@
diff --git a/libffi/testsuite/lib/libffi-dg.exp b/libffi/testsuite/lib/libffi-dg.exp
index 5ec6c4dc76b..8db38c286a8 100644
--- a/libffi/testsuite/lib/libffi-dg.exp
+++ b/libffi/testsuite/lib/libffi-dg.exp
@@ -187,6 +187,13 @@ proc libffi_target_compile { source dest type options } {
lappend options "additional_flags=-I${libffi_include} -I${srcdir}/../include -I${libffi_include}/.."
lappend options "additional_flags=${libffi_link_flags}"
+ # Darwin needs a stack execution allowed flag.
+
+ if { [istarget "*-*-darwin9*"] || [istarget "*-*-darwin1*"]
+ || [istarget "*-*-darwin2*"] } {
+ lappend options "additional_flags=-Wl,-allow_stack_execute"
+ }
+
# If you're building the compiler with --prefix set to a place
# where it's not yet installed, then the linker won't be able to
# find the libgcc used by libffi.dylib. We could pass the
diff --git a/libffi/testsuite/libffi.call/closure_fn0.c b/libffi/testsuite/libffi.call/closure_fn0.c
index e4875270a0c..a579ff6c979 100644
--- a/libffi/testsuite/libffi.call/closure_fn0.c
+++ b/libffi/testsuite/libffi.call/closure_fn0.c
@@ -25,7 +25,7 @@ closure_test_fn0(ffi_cif* cif __UNUSED__, void* resp, void** args,
(int)(*(double *)args[8]) + (int)*(int *)args[9] +
(int)(*(int *)args[10]) + (int)(*(float *)args[11]) +
(int)*(int *)args[12] + (int)(*(int *)args[13]) +
- (int)(*(int *)args[14]) + *(int *)args[15] + (int)(long)userdata;
+ (int)(*(int *)args[14]) + *(int *)args[15] + (intptr_t)userdata;
printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
(int)*(unsigned long long *)args[0], (int)(*(int *)args[1]),
@@ -37,7 +37,7 @@ closure_test_fn0(ffi_cif* cif __UNUSED__, void* resp, void** args,
(int)(*(int *)args[10]), (int)(*(float *)args[11]),
(int)*(int *)args[12], (int)(*(int *)args[13]),
(int)(*(int *)args[14]),*(int *)args[15],
- (int)(long)userdata, (int)*(ffi_arg *)resp);
+ (int)(intptr_t)userdata, (int)*(ffi_arg *)resp);
}
@@ -49,19 +49,11 @@ typedef int (*closure_test_type0)(unsigned long long, int, unsigned long long,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void * code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
ffi_type * cl_arg_types[17];
int res;
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cl_arg_types[0] = &ffi_type_uint64;
cl_arg_types[1] = &ffi_type_sint;
cl_arg_types[2] = &ffi_type_uint64;
@@ -84,10 +76,10 @@ int main (void)
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
&ffi_type_sint, cl_arg_types) == FFI_OK);
- CHECK(ffi_prep_closure(pcl, &cif, closure_test_fn0,
- (void *) 3 /* userdata */) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn0,
+ (void *) 3 /* userdata */, code) == FFI_OK);
- res = (*((closure_test_type0)pcl))
+ res = (*((closure_test_type0)code))
(1LL, 2, 3LL, 4, 127, 429LL, 7, 8, 9.5, 10, 11, 12, 13,
19, 21, 1);
/* { dg-output "1 2 3 4 127 429 7 8 9 10 11 12 13 19 21 1 3: 680" } */
diff --git a/libffi/testsuite/libffi.call/closure_fn1.c b/libffi/testsuite/libffi.call/closure_fn1.c
index db26c4246e4..91231738c13 100644
--- a/libffi/testsuite/libffi.call/closure_fn1.c
+++ b/libffi/testsuite/libffi.call/closure_fn1.c
@@ -21,7 +21,7 @@ static void closure_test_fn1(ffi_cif* cif __UNUSED__, void* resp, void** args,
(int)(*(double*)args[8]) + (int)*(int *)args[9] +
(int)(*(int *)args[10]) + (int)(*(float *)args[11]) +
(int)*(int *)args[12] + (int)(*(int *)args[13]) +
- (int)(*(int *)args[14]) + *(int *)args[15] + (int)(long)userdata;
+ (int)(*(int *)args[14]) + *(int *)args[15] + (intptr_t)userdata;
printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
(int)*(float *)args[0], (int)(*(float *)args[1]),
@@ -32,7 +32,7 @@ static void closure_test_fn1(ffi_cif* cif __UNUSED__, void* resp, void** args,
(int)(*(int *)args[10]), (int)(*(float *)args[11]),
(int)*(int *)args[12], (int)(*(int *)args[13]),
(int)(*(int *)args[14]), *(int *)args[15],
- (int)(long)userdata, (int)*(ffi_arg *)resp);
+ (int)(intptr_t)userdata, (int)*(ffi_arg *)resp);
}
typedef int (*closure_test_type1)(float, float, float, float, signed short,
@@ -41,19 +41,11 @@ typedef int (*closure_test_type1)(float, float, float, float, signed short,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
ffi_type * cl_arg_types[17];
int res;
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cl_arg_types[0] = &ffi_type_float;
cl_arg_types[1] = &ffi_type_float;
cl_arg_types[2] = &ffi_type_float;
@@ -76,10 +68,10 @@ int main (void)
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
&ffi_type_sint, cl_arg_types) == FFI_OK);
- CHECK(ffi_prep_closure(pcl, &cif, closure_test_fn1,
- (void *) 3 /* userdata */) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn1,
+ (void *) 3 /* userdata */, code) == FFI_OK);
- res = (*((closure_test_type1)pcl))
+ res = (*((closure_test_type1)code))
(1.1, 2.2, 3.3, 4.4, 127, 5.5, 6.6, 8, 9, 10, 11, 12.0, 13,
19, 21, 1);
/* { dg-output "1 2 3 4 127 5 6 8 9 10 11 12 13 19 21 1 3: 255" } */
diff --git a/libffi/testsuite/libffi.call/closure_fn2.c b/libffi/testsuite/libffi.call/closure_fn2.c
index cbf73856113..08ff9d92274 100644
--- a/libffi/testsuite/libffi.call/closure_fn2.c
+++ b/libffi/testsuite/libffi.call/closure_fn2.c
@@ -20,7 +20,7 @@ static void closure_test_fn2(ffi_cif* cif __UNUSED__, void* resp, void** args,
(int)(*(double *)args[8]) + (int)*(int *)args[9] +
(int)(*(int *)args[10]) + (int)(*(float *)args[11]) +
(int)*(int *)args[12] + (int)(*(float *)args[13]) +
- (int)(*(int *)args[14]) + *(int *)args[15] + (int)(long)userdata;
+ (int)(*(int *)args[14]) + *(int *)args[15] + (intptr_t)userdata;
printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
(int)*(double *)args[0], (int)(*(double *)args[1]),
@@ -30,7 +30,7 @@ static void closure_test_fn2(ffi_cif* cif __UNUSED__, void* resp, void** args,
(int)(*(double*)args[8]), (int)*(int *)args[9],
(int)(*(int *)args[10]), (int)(*(float *)args[11]),
(int)*(int *)args[12], (int)(*(float *)args[13]),
- (int)(*(int *)args[14]), *(int *)args[15], (int)(long)userdata,
+ (int)(*(int *)args[14]), *(int *)args[15], (int)(intptr_t)userdata,
(int)*(ffi_arg *)resp);
}
@@ -41,19 +41,11 @@ typedef int (*closure_test_type2)(double, double, double, double, signed short,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
ffi_type * cl_arg_types[17];
int res;
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cl_arg_types[0] = &ffi_type_double;
cl_arg_types[1] = &ffi_type_double;
cl_arg_types[2] = &ffi_type_double;
@@ -76,10 +68,10 @@ int main (void)
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
&ffi_type_sint, cl_arg_types) == FFI_OK);
- CHECK(ffi_prep_closure(pcl, &cif, closure_test_fn2,
- (void *) 3 /* userdata */) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn2,
+ (void *) 3 /* userdata */, code) == FFI_OK);
- res = (*((closure_test_type2)pcl))
+ res = (*((closure_test_type2)code))
(1, 2, 3, 4, 127, 5, 6, 8, 9, 10, 11, 12.0, 13,
19.0, 21, 1);
/* { dg-output "1 2 3 4 127 5 6 8 9 10 11 12 13 19 21 1 3: 255" } */
diff --git a/libffi/testsuite/libffi.call/closure_fn3.c b/libffi/testsuite/libffi.call/closure_fn3.c
index 1fb32a86db6..9b54d805c82 100644
--- a/libffi/testsuite/libffi.call/closure_fn3.c
+++ b/libffi/testsuite/libffi.call/closure_fn3.c
@@ -20,7 +20,7 @@ static void closure_test_fn3(ffi_cif* cif __UNUSED__, void* resp, void** args,
(int)(*(double *)args[8]) + (int)*(int *)args[9] +
(int)(*(float *)args[10]) + (int)(*(float *)args[11]) +
(int)*(int *)args[12] + (int)(*(float *)args[13]) +
- (int)(*(float *)args[14]) + *(int *)args[15] + (int)(long)userdata;
+ (int)(*(float *)args[14]) + *(int *)args[15] + (intptr_t)userdata;
printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
(int)*(float *)args[0], (int)(*(float *)args[1]),
@@ -30,7 +30,7 @@ static void closure_test_fn3(ffi_cif* cif __UNUSED__, void* resp, void** args,
(int)(*(double *)args[8]), (int)*(int *)args[9],
(int)(*(float *)args[10]), (int)(*(float *)args[11]),
(int)*(int *)args[12], (int)(*(float *)args[13]),
- (int)(*(float *)args[14]), *(int *)args[15], (int)(long)userdata,
+ (int)(*(float *)args[14]), *(int *)args[15], (int)(intptr_t)userdata,
(int)*(ffi_arg *)resp);
}
@@ -42,19 +42,11 @@ typedef int (*closure_test_type3)(float, float, float, float, float, float,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
ffi_type * cl_arg_types[17];
int res;
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cl_arg_types[0] = &ffi_type_float;
cl_arg_types[1] = &ffi_type_float;
cl_arg_types[2] = &ffi_type_float;
@@ -77,10 +69,10 @@ int main (void)
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
&ffi_type_sint, cl_arg_types) == FFI_OK);
- CHECK(ffi_prep_closure(pcl, &cif, closure_test_fn3,
- (void *) 3 /* userdata */) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn3,
+ (void *) 3 /* userdata */, code) == FFI_OK);
- res = (*((closure_test_type3)pcl))
+ res = (*((closure_test_type3)code))
(1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9, 10, 11.11, 12.0, 13,
19.19, 21.21, 1);
/* { dg-output "1 2 3 4 5 6 7 8 9 10 11 12 13 19 21 1 3: 135" } */
diff --git a/libffi/testsuite/libffi.call/closure_fn4.c b/libffi/testsuite/libffi.call/closure_fn4.c
index 74506f31a0e..d4a1530b065 100644
--- a/libffi/testsuite/libffi.call/closure_fn4.c
+++ b/libffi/testsuite/libffi.call/closure_fn4.c
@@ -25,7 +25,7 @@ closure_test_fn0(ffi_cif* cif __UNUSED__, void* resp, void** args,
(int)*(unsigned long long *)args[12] +
(int)*(unsigned long long *)args[13] +
(int)*(unsigned long long *)args[14] +
- *(int *)args[15] + (int)(long)userdata;
+ *(int *)args[15] + (intptr_t)userdata;
printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
(int)*(unsigned long long *)args[0],
@@ -44,7 +44,7 @@ closure_test_fn0(ffi_cif* cif __UNUSED__, void* resp, void** args,
(int)*(unsigned long long *)args[13],
(int)*(unsigned long long *)args[14],
*(int *)args[15],
- (int)(long)userdata, (int)*(ffi_arg *)resp);
+ (int)(intptr_t)userdata, (int)*(ffi_arg *)resp);
}
@@ -60,19 +60,11 @@ typedef int (*closure_test_type0)(unsigned long long, unsigned long long,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
ffi_type * cl_arg_types[17];
int i, res;
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
for (i = 0; i < 15; i++) {
cl_arg_types[i] = &ffi_type_uint64;
}
@@ -83,10 +75,10 @@ int main (void)
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
&ffi_type_sint, cl_arg_types) == FFI_OK);
- CHECK(ffi_prep_closure(pcl, &cif, closure_test_fn0,
- (void *) 3 /* userdata */) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn0,
+ (void *) 3 /* userdata */, code) == FFI_OK);
- res = (*((closure_test_type0)pcl))
+ res = (*((closure_test_type0)code))
(1LL, 2LL, 3LL, 4LL, 127LL, 429LL, 7LL, 8LL, 9LL, 10LL, 11LL, 12LL,
13LL, 19LL, 21LL, 1);
/* { dg-output "1 2 3 4 127 429 7 8 9 10 11 12 13 19 21 1 3: 680" } */
diff --git a/libffi/testsuite/libffi.call/closure_fn5.c b/libffi/testsuite/libffi.call/closure_fn5.c
index c64ee8dfd66..99074426c67 100644
--- a/libffi/testsuite/libffi.call/closure_fn5.c
+++ b/libffi/testsuite/libffi.call/closure_fn5.c
@@ -24,7 +24,7 @@ closure_test_fn5(ffi_cif* cif __UNUSED__, void* resp, void** args,
(int)*(unsigned long long *)args[12] +
(int)*(unsigned long long *)args[13] +
(int)*(unsigned long long *)args[14] +
- *(int *)args[15] + (int)(long)userdata;
+ *(int *)args[15] + (intptr_t)userdata;
printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
(int)*(unsigned long long *)args[0],
@@ -43,7 +43,7 @@ closure_test_fn5(ffi_cif* cif __UNUSED__, void* resp, void** args,
(int)*(unsigned long long *)args[13],
(int)*(unsigned long long *)args[14],
*(int *)args[15],
- (int)(long)userdata, (int)*(ffi_arg *)resp);
+ (int)(intptr_t)userdata, (int)*(ffi_arg *)resp);
}
@@ -59,17 +59,10 @@ typedef int (*closure_test_type0)(unsigned long long, unsigned long long,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
ffi_type * cl_arg_types[17];
int i, res;
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
for (i = 0; i < 10; i++) {
cl_arg_types[i] = &ffi_type_uint64;
@@ -85,10 +78,10 @@ int main (void)
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
&ffi_type_sint, cl_arg_types) == FFI_OK);
- CHECK(ffi_prep_closure(pcl, &cif, closure_test_fn5,
- (void *) 3 /* userdata */) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn5,
+ (void *) 3 /* userdata */, code) == FFI_OK);
- res = (*((closure_test_type0)pcl))
+ res = (*((closure_test_type0)code))
(1LL, 2LL, 3LL, 4LL, 127LL, 429LL, 7LL, 8LL, 9LL, 10LL, 11, 12LL,
13LL, 19LL, 21LL, 1);
/* { dg-output "1 2 3 4 127 429 7 8 9 10 11 12 13 19 21 1 3: 680" } */
diff --git a/libffi/testsuite/libffi.call/closure_fn6.c b/libffi/testsuite/libffi.call/closure_fn6.c
index 16c52fdf20e..73c54fd6b16 100644
--- a/libffi/testsuite/libffi.call/closure_fn6.c
+++ b/libffi/testsuite/libffi.call/closure_fn6.c
@@ -23,7 +23,7 @@ closure_test_fn0(ffi_cif* cif __UNUSED__, void* resp, void** args,
(int)(*(int *)args[10]) + (int)(*(float *)args[11]) +
(int)*(int *)args[12] + (int)(*(int *)args[13]) +
(int)(*(double *)args[14]) + (int)*(double *)args[15] +
- (int)(long)userdata;
+ (intptr_t)userdata;
printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
(int)*(unsigned long long *)args[0],
@@ -36,7 +36,7 @@ closure_test_fn0(ffi_cif* cif __UNUSED__, void* resp, void** args,
(int)(*(int *)args[10]), (int)(*(float *)args[11]),
(int)*(int *)args[12], (int)(*(int *)args[13]),
(int)(*(double *)args[14]), (int)(*(double *)args[15]),
- (int)(long)userdata, (int)*(ffi_arg *)resp);
+ (int)(intptr_t)userdata, (int)*(ffi_arg *)resp);
}
@@ -50,19 +50,11 @@ typedef int (*closure_test_type0)(unsigned long long,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
ffi_type * cl_arg_types[17];
int res;
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cl_arg_types[0] = &ffi_type_uint64;
cl_arg_types[1] = &ffi_type_uint64;
cl_arg_types[2] = &ffi_type_uint64;
@@ -85,10 +77,10 @@ int main (void)
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
&ffi_type_sint, cl_arg_types) == FFI_OK);
- CHECK(ffi_prep_closure(pcl, &cif, closure_test_fn0,
- (void *) 3 /* userdata */) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn0,
+ (void *) 3 /* userdata */, code) == FFI_OK);
- res = (*((closure_test_type0)pcl))
+ res = (*((closure_test_type0)code))
(1, 2, 3, 4, 127, 429., 7., 8., 9.5, 10., 11, 12., 13,
19, 21., 1.);
/* { dg-output "1 2 3 4 127 429 7 8 9 10 11 12 13 19 21 1 3: 680" } */
diff --git a/libffi/testsuite/libffi.call/closure_loc_fn0.c b/libffi/testsuite/libffi.call/closure_loc_fn0.c
new file mode 100644
index 00000000000..b3afa0bbdfc
--- /dev/null
+++ b/libffi/testsuite/libffi.call/closure_loc_fn0.c
@@ -0,0 +1,95 @@
+/* Area: closure_call
+ Purpose: Check multiple values passing from different type.
+ Also, exceed the limit of gpr and fpr registers on PowerPC
+ Darwin.
+ Limitations: none.
+ PR: none.
+ Originator: <andreast@gcc.gnu.org> 20030828 */
+
+
+
+
+/* { dg-do run } */
+#include "ffitest.h"
+
+static void
+closure_loc_test_fn0(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata)
+{
+ *(ffi_arg*)resp =
+ (int)*(unsigned long long *)args[0] + (int)(*(int *)args[1]) +
+ (int)(*(unsigned long long *)args[2]) + (int)*(int *)args[3] +
+ (int)(*(signed short *)args[4]) +
+ (int)(*(unsigned long long *)args[5]) +
+ (int)*(int *)args[6] + (int)(*(int *)args[7]) +
+ (int)(*(double *)args[8]) + (int)*(int *)args[9] +
+ (int)(*(int *)args[10]) + (int)(*(float *)args[11]) +
+ (int)*(int *)args[12] + (int)(*(int *)args[13]) +
+ (int)(*(int *)args[14]) + *(int *)args[15] + (intptr_t)userdata;
+
+ printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
+ (int)*(unsigned long long *)args[0], (int)(*(int *)args[1]),
+ (int)(*(unsigned long long *)args[2]),
+ (int)*(int *)args[3], (int)(*(signed short *)args[4]),
+ (int)(*(unsigned long long *)args[5]),
+ (int)*(int *)args[6], (int)(*(int *)args[7]),
+ (int)(*(double *)args[8]), (int)*(int *)args[9],
+ (int)(*(int *)args[10]), (int)(*(float *)args[11]),
+ (int)*(int *)args[12], (int)(*(int *)args[13]),
+ (int)(*(int *)args[14]),*(int *)args[15],
+ (int)(intptr_t)userdata, (int)*(ffi_arg *)resp);
+
+}
+
+typedef int (*closure_loc_test_type0)(unsigned long long, int, unsigned long long,
+ int, signed short, unsigned long long, int,
+ int, double, int, int, float, int, int,
+ int, int);
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_closure *pcl;
+ ffi_type * cl_arg_types[17];
+ int res;
+ void *codeloc;
+
+ cl_arg_types[0] = &ffi_type_uint64;
+ cl_arg_types[1] = &ffi_type_sint;
+ cl_arg_types[2] = &ffi_type_uint64;
+ cl_arg_types[3] = &ffi_type_sint;
+ cl_arg_types[4] = &ffi_type_sshort;
+ cl_arg_types[5] = &ffi_type_uint64;
+ cl_arg_types[6] = &ffi_type_sint;
+ cl_arg_types[7] = &ffi_type_sint;
+ cl_arg_types[8] = &ffi_type_double;
+ cl_arg_types[9] = &ffi_type_sint;
+ cl_arg_types[10] = &ffi_type_sint;
+ cl_arg_types[11] = &ffi_type_float;
+ cl_arg_types[12] = &ffi_type_sint;
+ cl_arg_types[13] = &ffi_type_sint;
+ cl_arg_types[14] = &ffi_type_sint;
+ cl_arg_types[15] = &ffi_type_sint;
+ cl_arg_types[16] = NULL;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
+ &ffi_type_sint, cl_arg_types) == FFI_OK);
+
+ pcl = ffi_closure_alloc(sizeof(ffi_closure), &codeloc);
+ CHECK(pcl != NULL);
+ CHECK(codeloc != NULL);
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, closure_loc_test_fn0,
+ (void *) 3 /* userdata */, codeloc) == FFI_OK);
+
+ CHECK(memcmp(pcl, codeloc, sizeof(*pcl)) == 0);
+
+ res = (*((closure_loc_test_type0)codeloc))
+ (1LL, 2, 3LL, 4, 127, 429LL, 7, 8, 9.5, 10, 11, 12, 13,
+ 19, 21, 1);
+ /* { dg-output "1 2 3 4 127 429 7 8 9 10 11 12 13 19 21 1 3: 680" } */
+ printf("res: %d\n",res);
+ /* { dg-output "\nres: 680" } */
+ exit(0);
+}
diff --git a/libffi/testsuite/libffi.call/closure_stdcall.c b/libffi/testsuite/libffi.call/closure_stdcall.c
new file mode 100644
index 00000000000..6bfcc1fbb5b
--- /dev/null
+++ b/libffi/testsuite/libffi.call/closure_stdcall.c
@@ -0,0 +1,64 @@
+/* Area: closure_call (stdcall convention)
+ Purpose: Check handling when caller expects stdcall callee
+ Limitations: none.
+ PR: none.
+ Originator: <twalljava@dev.java.net> */
+
+/* { dg-do run { target i?86-*-cygwin* i?86-*-mingw* } } */
+#include "ffitest.h"
+
+static void
+closure_test_stdcall(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata)
+{
+ *(ffi_arg*)resp =
+ (int)*(int *)args[0] + (int)(*(int *)args[1])
+ + (int)(*(int *)args[2]) + (int)(*(int *)args[3])
+ + (int)(intptr_t)userdata;
+
+ printf("%d %d %d %d: %d\n",
+ (int)*(int *)args[0], (int)(*(int *)args[1]),
+ (int)(*(int *)args[2]), (int)(*(int *)args[3]),
+ (int)*(ffi_arg *)resp);
+
+}
+
+typedef int (__stdcall *closure_test_type0)(int, int, int, int);
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ ffi_type * cl_arg_types[17];
+ int res;
+ void* sp_pre;
+ void* sp_post;
+ char buf[1024];
+
+ cl_arg_types[0] = &ffi_type_uint;
+ cl_arg_types[1] = &ffi_type_uint;
+ cl_arg_types[2] = &ffi_type_uint;
+ cl_arg_types[3] = &ffi_type_uint;
+ cl_arg_types[4] = NULL;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_STDCALL, 4,
+ &ffi_type_sint, cl_arg_types) == FFI_OK);
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_stdcall,
+ (void *) 3 /* userdata */, code) == FFI_OK);
+
+ asm volatile (" movl %%esp,%0" : "=g" (sp_pre));
+ res = (*(closure_test_type0)code)(0, 1, 2, 3);
+ asm volatile (" movl %%esp,%0" : "=g" (sp_post));
+ /* { dg-output "0 1 2 3: 9" } */
+
+ printf("res: %d\n",res);
+ /* { dg-output "\nres: 9" } */
+
+ sprintf(buf, "mismatch: pre=%p vs post=%p", sp_pre, sp_post);
+ printf("stack pointer %s\n", (sp_pre == sp_post ? "match" : buf));
+ /* { dg-output "\nstack pointer match" } */
+ exit(0);
+}
diff --git a/libffi/testsuite/libffi.call/cls_12byte.c b/libffi/testsuite/libffi.call/cls_12byte.c
index 92530d5ff57..f0a334fa797 100644
--- a/libffi/testsuite/libffi.call/cls_12byte.c
+++ b/libffi/testsuite/libffi.call/cls_12byte.c
@@ -42,21 +42,13 @@ static void cls_struct_12byte_gn(ffi_cif* cif __UNUSED__, void* resp,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[4];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -87,13 +79,13 @@ int main (void)
printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 8 9 12" } */
- CHECK(ffi_prep_closure(pcl, &cif, cls_struct_12byte_gn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_12byte_gn, NULL, code) == FFI_OK);
res_dbl.a = 0;
res_dbl.b = 0;
res_dbl.c = 0;
- res_dbl = ((cls_struct_12byte(*)(cls_struct_12byte, cls_struct_12byte))(pcl))(h_dbl, j_dbl);
+ res_dbl = ((cls_struct_12byte(*)(cls_struct_12byte, cls_struct_12byte))(code))(h_dbl, j_dbl);
/* { dg-output "\n7 4 9 1 5 3: 8 9 12" } */
printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 8 9 12" } */
diff --git a/libffi/testsuite/libffi.call/cls_16byte.c b/libffi/testsuite/libffi.call/cls_16byte.c
index f3c314a8760..9b9292ab056 100644
--- a/libffi/testsuite/libffi.call/cls_16byte.c
+++ b/libffi/testsuite/libffi.call/cls_16byte.c
@@ -43,21 +43,13 @@ static void cls_struct_16byte_gn(ffi_cif* cif __UNUSED__, void* resp,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[4];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -92,9 +84,9 @@ int main (void)
res_dbl.b = 0.0;
res_dbl.c = 0;
- CHECK(ffi_prep_closure(pcl, &cif, cls_struct_16byte_gn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_16byte_gn, NULL, code) == FFI_OK);
- res_dbl = ((cls_struct_16byte(*)(cls_struct_16byte, cls_struct_16byte))(pcl))(h_dbl, j_dbl);
+ res_dbl = ((cls_struct_16byte(*)(cls_struct_16byte, cls_struct_16byte))(code))(h_dbl, j_dbl);
/* { dg-output "\n7 8 9 1 9 3: 8 17 12" } */
printf("res: %d %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 8 17 12" } */
diff --git a/libffi/testsuite/libffi.call/cls_18byte.c b/libffi/testsuite/libffi.call/cls_18byte.c
index 90165804695..40c8c6d96a1 100644
--- a/libffi/testsuite/libffi.call/cls_18byte.c
+++ b/libffi/testsuite/libffi.call/cls_18byte.c
@@ -47,21 +47,13 @@ cls_struct_18byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[3];
ffi_type* cls_struct_fields[5];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[3];
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -93,9 +85,9 @@ int main (void)
printf("res: %g %d %d %g\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
/* { dg-output "\nres: 5 252 250 8" } */
- CHECK(ffi_prep_closure(pcl, &cif, cls_struct_18byte_gn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_18byte_gn, NULL, code) == FFI_OK);
- res_dbl = ((cls_struct_18byte(*)(cls_struct_18byte, cls_struct_18byte))(pcl))(g_dbl, f_dbl);
+ res_dbl = ((cls_struct_18byte(*)(cls_struct_18byte, cls_struct_18byte))(code))(g_dbl, f_dbl);
/* { dg-output "\n1 127 126 3 4 125 124 5: 5 252 250 8" } */
printf("res: %g %d %d %g\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
/* { dg-output "\nres: 5 252 250 8" } */
diff --git a/libffi/testsuite/libffi.call/cls_19byte.c b/libffi/testsuite/libffi.call/cls_19byte.c
index 8af583467b1..aa6424818f7 100644
--- a/libffi/testsuite/libffi.call/cls_19byte.c
+++ b/libffi/testsuite/libffi.call/cls_19byte.c
@@ -50,21 +50,13 @@ cls_struct_19byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[3];
ffi_type* cls_struct_fields[6];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[3];
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -98,9 +90,9 @@ int main (void)
res_dbl.d, res_dbl.e);
/* { dg-output "\nres: 5 252 250 8 239" } */
- CHECK(ffi_prep_closure(pcl, &cif, cls_struct_19byte_gn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_19byte_gn, NULL, code) == FFI_OK);
- res_dbl = ((cls_struct_19byte(*)(cls_struct_19byte, cls_struct_19byte))(pcl))(g_dbl, f_dbl);
+ res_dbl = ((cls_struct_19byte(*)(cls_struct_19byte, cls_struct_19byte))(code))(g_dbl, f_dbl);
/* { dg-output "\n1 127 126 3 120 4 125 124 5 119: 5 252 250 8 239" } */
printf("res: %g %d %d %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c,
res_dbl.d, res_dbl.e);
diff --git a/libffi/testsuite/libffi.call/cls_1_1byte.c b/libffi/testsuite/libffi.call/cls_1_1byte.c
index 0fcc8c6d54c..b9402d678ad 100644
--- a/libffi/testsuite/libffi.call/cls_1_1byte.c
+++ b/libffi/testsuite/libffi.call/cls_1_1byte.c
@@ -43,21 +43,13 @@ cls_struct_1_1byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[2];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -86,9 +78,9 @@ int main (void)
printf("res: %d\n", res_dbl.a);
/* { dg-output "\nres: 190" } */
- CHECK(ffi_prep_closure(pcl, &cif, cls_struct_1_1byte_gn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_1_1byte_gn, NULL, code) == FFI_OK);
- res_dbl = ((cls_struct_1_1byte(*)(cls_struct_1_1byte, cls_struct_1_1byte))(pcl))(g_dbl, f_dbl);
+ res_dbl = ((cls_struct_1_1byte(*)(cls_struct_1_1byte, cls_struct_1_1byte))(code))(g_dbl, f_dbl);
/* { dg-output "\n12 178: 190" } */
printf("res: %d\n", res_dbl.a);
/* { dg-output "\nres: 190" } */
diff --git a/libffi/testsuite/libffi.call/cls_20byte.c b/libffi/testsuite/libffi.call/cls_20byte.c
index fa5f81a88c8..80dd7ac931b 100644
--- a/libffi/testsuite/libffi.call/cls_20byte.c
+++ b/libffi/testsuite/libffi.call/cls_20byte.c
@@ -43,21 +43,13 @@ cls_struct_20byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[4];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -88,9 +80,9 @@ int main (void)
printf("res: %g %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 5 7 10" } */
- CHECK(ffi_prep_closure(pcl, &cif, cls_struct_20byte_gn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_20byte_gn, NULL, code) == FFI_OK);
- res_dbl = ((cls_struct_20byte(*)(cls_struct_20byte, cls_struct_20byte))(pcl))(g_dbl, f_dbl);
+ res_dbl = ((cls_struct_20byte(*)(cls_struct_20byte, cls_struct_20byte))(code))(g_dbl, f_dbl);
/* { dg-output "\n1 2 3 4 5 7: 5 7 10" } */
printf("res: %g %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 5 7 10" } */
diff --git a/libffi/testsuite/libffi.call/cls_20byte1.c b/libffi/testsuite/libffi.call/cls_20byte1.c
index 072bafcafb5..50bcbbf831a 100644
--- a/libffi/testsuite/libffi.call/cls_20byte1.c
+++ b/libffi/testsuite/libffi.call/cls_20byte1.c
@@ -45,21 +45,13 @@ cls_struct_20byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[3];
ffi_type* cls_struct_fields[4];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[3];
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -90,9 +82,9 @@ int main (void)
printf("res: %d %g %g\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 5 7 10" } */
- CHECK(ffi_prep_closure(pcl, &cif, cls_struct_20byte_gn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_20byte_gn, NULL, code) == FFI_OK);
- res_dbl = ((cls_struct_20byte(*)(cls_struct_20byte, cls_struct_20byte))(pcl))(g_dbl, f_dbl);
+ res_dbl = ((cls_struct_20byte(*)(cls_struct_20byte, cls_struct_20byte))(code))(g_dbl, f_dbl);
/* { dg-output "\n1 2 3 4 5 7: 5 7 10" } */
printf("res: %d %g %g\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 5 7 10" } */
diff --git a/libffi/testsuite/libffi.call/cls_24byte.c b/libffi/testsuite/libffi.call/cls_24byte.c
index 22e169058c5..46a6eb4d31c 100644
--- a/libffi/testsuite/libffi.call/cls_24byte.c
+++ b/libffi/testsuite/libffi.call/cls_24byte.c
@@ -54,21 +54,13 @@ cls_struct_24byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[5];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -106,13 +98,13 @@ int main (void)
printf("res: %g %g %d %g\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
/* { dg-output "\nres: 22 15 17 25" } */
- CHECK(ffi_prep_closure(pcl, &cif, cls_struct_24byte_gn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_24byte_gn, NULL, code) == FFI_OK);
res_dbl = ((cls_struct_24byte(*)(cls_struct_24byte,
cls_struct_24byte,
cls_struct_24byte,
cls_struct_24byte))
- (pcl))(e_dbl, f_dbl, g_dbl, h_dbl);
+ (code))(e_dbl, f_dbl, g_dbl, h_dbl);
/* { dg-output "\n9 2 6 5 1 2 3 7 4 5 7 9 8 6 1 9: 22 15 17 25" } */
printf("res: %g %g %d %g\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
/* { dg-output "\nres: 22 15 17 25" } */
diff --git a/libffi/testsuite/libffi.call/cls_2byte.c b/libffi/testsuite/libffi.call/cls_2byte.c
index 5b91a09a2cc..101e130a1fc 100644
--- a/libffi/testsuite/libffi.call/cls_2byte.c
+++ b/libffi/testsuite/libffi.call/cls_2byte.c
@@ -43,21 +43,13 @@ cls_struct_2byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[4];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -87,9 +79,9 @@ int main (void)
printf("res: %d %d\n", res_dbl.a, res_dbl.b);
/* { dg-output "\nres: 13 140" } */
- CHECK(ffi_prep_closure(pcl, &cif, cls_struct_2byte_gn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_2byte_gn, NULL, code) == FFI_OK);
- res_dbl = ((cls_struct_2byte(*)(cls_struct_2byte, cls_struct_2byte))(pcl))(g_dbl, f_dbl);
+ res_dbl = ((cls_struct_2byte(*)(cls_struct_2byte, cls_struct_2byte))(code))(g_dbl, f_dbl);
/* { dg-output "\n12 127 1 13: 13 140" } */
printf("res: %d %d\n", res_dbl.a, res_dbl.b);
/* { dg-output "\nres: 13 140" } */
diff --git a/libffi/testsuite/libffi.call/cls_3_1byte.c b/libffi/testsuite/libffi.call/cls_3_1byte.c
index 93fe911d2da..fc780c30d6c 100644
--- a/libffi/testsuite/libffi.call/cls_3_1byte.c
+++ b/libffi/testsuite/libffi.call/cls_3_1byte.c
@@ -47,21 +47,13 @@ cls_struct_3_1byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[4];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -92,9 +84,9 @@ int main (void)
printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 190 192 194" } */
- CHECK(ffi_prep_closure(pcl, &cif, cls_struct_3_1byte_gn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_3_1byte_gn, NULL, code) == FFI_OK);
- res_dbl = ((cls_struct_3_1byte(*)(cls_struct_3_1byte, cls_struct_3_1byte))(pcl))(g_dbl, f_dbl);
+ res_dbl = ((cls_struct_3_1byte(*)(cls_struct_3_1byte, cls_struct_3_1byte))(code))(g_dbl, f_dbl);
/* { dg-output "\n12 13 14 178 179 180: 190 192 194" } */
printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 190 192 194" } */
diff --git a/libffi/testsuite/libffi.call/cls_3byte1.c b/libffi/testsuite/libffi.call/cls_3byte1.c
index b7726917094..5705ce38798 100644
--- a/libffi/testsuite/libffi.call/cls_3byte1.c
+++ b/libffi/testsuite/libffi.call/cls_3byte1.c
@@ -43,21 +43,13 @@ cls_struct_3byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[4];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -87,9 +79,9 @@ int main (void)
printf("res: %d %d\n", res_dbl.a, res_dbl.b);
/* { dg-output "\nres: 13 134" } */
- CHECK(ffi_prep_closure(pcl, &cif, cls_struct_3byte_gn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_3byte_gn, NULL, code) == FFI_OK);
- res_dbl = ((cls_struct_3byte(*)(cls_struct_3byte, cls_struct_3byte))(pcl))(g_dbl, f_dbl);
+ res_dbl = ((cls_struct_3byte(*)(cls_struct_3byte, cls_struct_3byte))(code))(g_dbl, f_dbl);
/* { dg-output "\n12 119 1 15: 13 134" } */
printf("res: %d %d\n", res_dbl.a, res_dbl.b);
/* { dg-output "\nres: 13 134" } */
diff --git a/libffi/testsuite/libffi.call/cls_3byte2.c b/libffi/testsuite/libffi.call/cls_3byte2.c
index 51128cc18ef..01770a0750b 100644
--- a/libffi/testsuite/libffi.call/cls_3byte2.c
+++ b/libffi/testsuite/libffi.call/cls_3byte2.c
@@ -43,21 +43,13 @@ cls_struct_3byte_gn1(ffi_cif* cif __UNUSED__, void* resp, void** args,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[4];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -87,9 +79,9 @@ int main (void)
printf("res: %d %d\n", res_dbl.a, res_dbl.b);
/* { dg-output "\nres: 24 144" } */
- CHECK(ffi_prep_closure(pcl, &cif, cls_struct_3byte_gn1, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_3byte_gn1, NULL, code) == FFI_OK);
- res_dbl = ((cls_struct_3byte_1(*)(cls_struct_3byte_1, cls_struct_3byte_1))(pcl))(g_dbl, f_dbl);
+ res_dbl = ((cls_struct_3byte_1(*)(cls_struct_3byte_1, cls_struct_3byte_1))(code))(g_dbl, f_dbl);
/* { dg-output "\n15 125 9 19: 24 144" } */
printf("res: %d %d\n", res_dbl.a, res_dbl.b);
/* { dg-output "\nres: 24 144" } */
diff --git a/libffi/testsuite/libffi.call/cls_4_1byte.c b/libffi/testsuite/libffi.call/cls_4_1byte.c
index a378d194f42..f3806d7ba1c 100644
--- a/libffi/testsuite/libffi.call/cls_4_1byte.c
+++ b/libffi/testsuite/libffi.call/cls_4_1byte.c
@@ -49,21 +49,13 @@ cls_struct_4_1byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[5];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -95,9 +87,9 @@ int main (void)
printf("res: %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
/* { dg-output "\nres: 190 192 194 196" } */
- CHECK(ffi_prep_closure(pcl, &cif, cls_struct_4_1byte_gn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_4_1byte_gn, NULL, code) == FFI_OK);
- res_dbl = ((cls_struct_4_1byte(*)(cls_struct_4_1byte, cls_struct_4_1byte))(pcl))(g_dbl, f_dbl);
+ res_dbl = ((cls_struct_4_1byte(*)(cls_struct_4_1byte, cls_struct_4_1byte))(code))(g_dbl, f_dbl);
/* { dg-output "\n12 13 14 15 178 179 180 181: 190 192 194 196" } */
printf("res: %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
/* { dg-output "\nres: 190 192 194 196" } */
diff --git a/libffi/testsuite/libffi.call/cls_4byte.c b/libffi/testsuite/libffi.call/cls_4byte.c
index b2c951dbeb5..a1aba3c09d5 100644
--- a/libffi/testsuite/libffi.call/cls_4byte.c
+++ b/libffi/testsuite/libffi.call/cls_4byte.c
@@ -43,21 +43,13 @@ cls_struct_4byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[4];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -87,9 +79,9 @@ int main (void)
printf("res: %d %d\n", res_dbl.a, res_dbl.b);
/* { dg-output "\nres: 139 248" } */
- CHECK(ffi_prep_closure(pcl, &cif, cls_struct_4byte_gn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_4byte_gn, NULL, code) == FFI_OK);
- res_dbl = ((cls_struct_4byte(*)(cls_struct_4byte, cls_struct_4byte))(pcl))(g_dbl, f_dbl);
+ res_dbl = ((cls_struct_4byte(*)(cls_struct_4byte, cls_struct_4byte))(code))(g_dbl, f_dbl);
/* { dg-output "\n127 120 12 128: 139 248" } */
printf("res: %d %d\n", res_dbl.a, res_dbl.b);
/* { dg-output "\nres: 139 248" } */
diff --git a/libffi/testsuite/libffi.call/cls_5_1_byte.c b/libffi/testsuite/libffi.call/cls_5_1_byte.c
index 40d2e64eec8..2ceba3ddb2d 100644
--- a/libffi/testsuite/libffi.call/cls_5_1_byte.c
+++ b/libffi/testsuite/libffi.call/cls_5_1_byte.c
@@ -51,21 +51,13 @@ cls_struct_5byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[6];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -105,9 +97,9 @@ int main (void)
res_dbl.d = 0;
res_dbl.e = 0;
- CHECK(ffi_prep_closure(pcl, &cif, cls_struct_5byte_gn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_5byte_gn, NULL, code) == FFI_OK);
- res_dbl = ((cls_struct_5byte(*)(cls_struct_5byte, cls_struct_5byte))(pcl))(g_dbl, f_dbl);
+ res_dbl = ((cls_struct_5byte(*)(cls_struct_5byte, cls_struct_5byte))(code))(g_dbl, f_dbl);
/* { dg-output "\n127 120 1 3 4 12 128 9 3 4: 139 248 10 6 8" } */
printf("res: %d %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c,
res_dbl.d, res_dbl.e);
diff --git a/libffi/testsuite/libffi.call/cls_5byte.c b/libffi/testsuite/libffi.call/cls_5byte.c
index 0307e51f6b9..61d595c2bf0 100644
--- a/libffi/testsuite/libffi.call/cls_5byte.c
+++ b/libffi/testsuite/libffi.call/cls_5byte.c
@@ -46,21 +46,13 @@ cls_struct_5byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[4];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -95,9 +87,9 @@ int main (void)
res_dbl.b = 0;
res_dbl.c = 0;
- CHECK(ffi_prep_closure(pcl, &cif, cls_struct_5byte_gn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_5byte_gn, NULL, code) == FFI_OK);
- res_dbl = ((cls_struct_5byte(*)(cls_struct_5byte, cls_struct_5byte))(pcl))(g_dbl, f_dbl);
+ res_dbl = ((cls_struct_5byte(*)(cls_struct_5byte, cls_struct_5byte))(code))(g_dbl, f_dbl);
/* { dg-output "\n127 120 1 12 128 9: 139 248 10" } */
printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 139 248 10" } */
diff --git a/libffi/testsuite/libffi.call/cls_64byte.c b/libffi/testsuite/libffi.call/cls_64byte.c
index 1329c6f26ab..576ebe0cc2a 100644
--- a/libffi/testsuite/libffi.call/cls_64byte.c
+++ b/libffi/testsuite/libffi.call/cls_64byte.c
@@ -59,21 +59,13 @@ cls_struct_64byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[9];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -116,13 +108,13 @@ int main (void)
res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h);
/* { dg-output "\nres: 22 15 17 25 6 13 19 18" } */
- CHECK(ffi_prep_closure(pcl, &cif, cls_struct_64byte_gn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_64byte_gn, NULL, code) == FFI_OK);
res_dbl = ((cls_struct_64byte(*)(cls_struct_64byte,
cls_struct_64byte,
cls_struct_64byte,
cls_struct_64byte))
- (pcl))(e_dbl, f_dbl, g_dbl, h_dbl);
+ (code))(e_dbl, f_dbl, g_dbl, h_dbl);
/* { dg-output "\n22 15 17 25 6 13 19 18" } */
printf("res: %g %g %g %g %g %g %g %g\n", res_dbl.a, res_dbl.b, res_dbl.c,
res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h);
diff --git a/libffi/testsuite/libffi.call/cls_6_1_byte.c b/libffi/testsuite/libffi.call/cls_6_1_byte.c
index 7ddb586ea1a..9f2eff68c1f 100644
--- a/libffi/testsuite/libffi.call/cls_6_1_byte.c
+++ b/libffi/testsuite/libffi.call/cls_6_1_byte.c
@@ -53,21 +53,13 @@ cls_struct_6byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[7];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -109,9 +101,9 @@ int main (void)
res_dbl.e = 0;
res_dbl.f = 0;
- CHECK(ffi_prep_closure(pcl, &cif, cls_struct_6byte_gn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_6byte_gn, NULL, code) == FFI_OK);
- res_dbl = ((cls_struct_6byte(*)(cls_struct_6byte, cls_struct_6byte))(pcl))(g_dbl, f_dbl);
+ res_dbl = ((cls_struct_6byte(*)(cls_struct_6byte, cls_struct_6byte))(code))(g_dbl, f_dbl);
/* { dg-output "\n127 120 1 3 4 5 12 128 9 3 4 5: 139 248 10 6 8 10" } */
printf("res: %d %d %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c,
res_dbl.d, res_dbl.e, res_dbl.f);
diff --git a/libffi/testsuite/libffi.call/cls_6byte.c b/libffi/testsuite/libffi.call/cls_6byte.c
index 24fd63baa37..73257b0989b 100644
--- a/libffi/testsuite/libffi.call/cls_6byte.c
+++ b/libffi/testsuite/libffi.call/cls_6byte.c
@@ -49,21 +49,13 @@ cls_struct_6byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[5];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -95,9 +87,9 @@ int main (void)
printf("res: %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
/* { dg-output "\nres: 139 248 10 255" } */
- CHECK(ffi_prep_closure(pcl, &cif, cls_struct_6byte_gn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_6byte_gn, NULL, code) == FFI_OK);
- res_dbl = ((cls_struct_6byte(*)(cls_struct_6byte, cls_struct_6byte))(pcl))(g_dbl, f_dbl);
+ res_dbl = ((cls_struct_6byte(*)(cls_struct_6byte, cls_struct_6byte))(code))(g_dbl, f_dbl);
/* { dg-output "\n127 120 1 128 12 128 9 127: 139 248 10 255" } */
printf("res: %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
/* { dg-output "\nres: 139 248 10 255" } */
diff --git a/libffi/testsuite/libffi.call/cls_7_1_byte.c b/libffi/testsuite/libffi.call/cls_7_1_byte.c
index 0cf1371a77a..50d09c9da72 100644
--- a/libffi/testsuite/libffi.call/cls_7_1_byte.c
+++ b/libffi/testsuite/libffi.call/cls_7_1_byte.c
@@ -55,21 +55,13 @@ cls_struct_7byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[8];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -113,9 +105,9 @@ int main (void)
res_dbl.f = 0;
res_dbl.g = 0;
- CHECK(ffi_prep_closure(pcl, &cif, cls_struct_7byte_gn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_7byte_gn, NULL, code) == FFI_OK);
- res_dbl = ((cls_struct_7byte(*)(cls_struct_7byte, cls_struct_7byte))(pcl))(g_dbl, f_dbl);
+ res_dbl = ((cls_struct_7byte(*)(cls_struct_7byte, cls_struct_7byte))(code))(g_dbl, f_dbl);
/* { dg-output "\n127 120 1 3 4 5 6 12 128 9 3 4 5 6: 139 248 10 6 8 10 12" } */
printf("res: %d %d %d %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c,
res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g);
diff --git a/libffi/testsuite/libffi.call/cls_7byte.c b/libffi/testsuite/libffi.call/cls_7byte.c
index 77858625fa9..f5c00003153 100644
--- a/libffi/testsuite/libffi.call/cls_7byte.c
+++ b/libffi/testsuite/libffi.call/cls_7byte.c
@@ -48,21 +48,13 @@ cls_struct_7byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[5];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -94,9 +86,9 @@ int main (void)
printf("res: %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
/* { dg-output "\nres: 139 248 10 509" } */
- CHECK(ffi_prep_closure(pcl, &cif, cls_struct_7byte_gn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_7byte_gn, NULL, code) == FFI_OK);
- res_dbl = ((cls_struct_7byte(*)(cls_struct_7byte, cls_struct_7byte))(pcl))(g_dbl, f_dbl);
+ res_dbl = ((cls_struct_7byte(*)(cls_struct_7byte, cls_struct_7byte))(code))(g_dbl, f_dbl);
/* { dg-output "\n127 120 1 254 12 128 9 255: 139 248 10 509" } */
printf("res: %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
/* { dg-output "\nres: 139 248 10 509" } */
diff --git a/libffi/testsuite/libffi.call/cls_8byte.c b/libffi/testsuite/libffi.call/cls_8byte.c
index 75326b8f70e..4aa99d12e41 100644
--- a/libffi/testsuite/libffi.call/cls_8byte.c
+++ b/libffi/testsuite/libffi.call/cls_8byte.c
@@ -42,21 +42,13 @@ cls_struct_8byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[4];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -85,9 +77,9 @@ int main (void)
/* { dg-output "1 2 4 5: 5 7" } */
printf("res: %d %g\n", res_dbl.a, res_dbl.b);
/* { dg-output "\nres: 5 7" } */
- CHECK(ffi_prep_closure(pcl, &cif, cls_struct_8byte_gn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_8byte_gn, NULL, code) == FFI_OK);
- res_dbl = ((cls_struct_8byte(*)(cls_struct_8byte, cls_struct_8byte))(pcl))(g_dbl, f_dbl);
+ res_dbl = ((cls_struct_8byte(*)(cls_struct_8byte, cls_struct_8byte))(code))(g_dbl, f_dbl);
/* { dg-output "\n1 2 4 5: 5 7" } */
printf("res: %d %g\n", res_dbl.a, res_dbl.b);
/* { dg-output "\nres: 5 7" } */
diff --git a/libffi/testsuite/libffi.call/cls_9byte1.c b/libffi/testsuite/libffi.call/cls_9byte1.c
index 0b3de9daa93..cc5e9d6c4e9 100644
--- a/libffi/testsuite/libffi.call/cls_9byte1.c
+++ b/libffi/testsuite/libffi.call/cls_9byte1.c
@@ -43,21 +43,13 @@ static void cls_struct_9byte_gn(ffi_cif* cif __UNUSED__, void* resp,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[3];
ffi_type* cls_struct_fields[3];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[3];
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -87,9 +79,9 @@ int main (void)
printf("res: %d %g\n", res_dbl.a, res_dbl.b);
/* { dg-output "\nres: 8 17" } */
- CHECK(ffi_prep_closure(pcl, &cif, cls_struct_9byte_gn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_9byte_gn, NULL, code) == FFI_OK);
- res_dbl = ((cls_struct_9byte(*)(cls_struct_9byte, cls_struct_9byte))(pcl))(h_dbl, j_dbl);
+ res_dbl = ((cls_struct_9byte(*)(cls_struct_9byte, cls_struct_9byte))(code))(h_dbl, j_dbl);
/* { dg-output "\n7 8 1 9: 8 17" } */
printf("res: %d %g\n", res_dbl.a, res_dbl.b);
/* { dg-output "\nres: 8 17" } */
diff --git a/libffi/testsuite/libffi.call/cls_9byte2.c b/libffi/testsuite/libffi.call/cls_9byte2.c
index 8cafc8af6c8..5c0ba0d4b8d 100644
--- a/libffi/testsuite/libffi.call/cls_9byte2.c
+++ b/libffi/testsuite/libffi.call/cls_9byte2.c
@@ -43,21 +43,13 @@ static void cls_struct_9byte_gn(ffi_cif* cif __UNUSED__, void* resp,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[3];
ffi_type* cls_struct_fields[3];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[3];
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -88,9 +80,9 @@ int main (void)
/* { dg-output "\nres: 8 17" } */
- CHECK(ffi_prep_closure(pcl, &cif, cls_struct_9byte_gn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_9byte_gn, NULL, code) == FFI_OK);
- res_dbl = ((cls_struct_9byte(*)(cls_struct_9byte, cls_struct_9byte))(pcl))(h_dbl, j_dbl);
+ res_dbl = ((cls_struct_9byte(*)(cls_struct_9byte, cls_struct_9byte))(code))(h_dbl, j_dbl);
/* { dg-output "\n7 8 1 9: 8 17" } */
printf("res: %g %d\n", res_dbl.a, res_dbl.b);
/* { dg-output "\nres: 8 17" } */
diff --git a/libffi/testsuite/libffi.call/cls_align_double.c b/libffi/testsuite/libffi.call/cls_align_double.c
index 5ba230154a4..22b94d5a09d 100644
--- a/libffi/testsuite/libffi.call/cls_align_double.c
+++ b/libffi/testsuite/libffi.call/cls_align_double.c
@@ -45,21 +45,13 @@ cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[4];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -90,9 +82,9 @@ int main (void)
printf("res: %d %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 13 14271 140" } */
- CHECK(ffi_prep_closure(pcl, &cif, cls_struct_align_gn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
- res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(pcl))(g_dbl, f_dbl);
+ res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
/* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
printf("res: %d %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 13 14271 140" } */
diff --git a/libffi/testsuite/libffi.call/cls_align_float.c b/libffi/testsuite/libffi.call/cls_align_float.c
index 996e1ab965b..62637f21d18 100644
--- a/libffi/testsuite/libffi.call/cls_align_float.c
+++ b/libffi/testsuite/libffi.call/cls_align_float.c
@@ -43,21 +43,13 @@ cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[4];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -88,9 +80,9 @@ int main (void)
printf("res: %d %g %d\n", res_dbl.a, (double)res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 13 14271 140" } */
- CHECK(ffi_prep_closure(pcl, &cif, cls_struct_align_gn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
- res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(pcl))(g_dbl, f_dbl);
+ res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
/* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
printf("res: %d %g %d\n", res_dbl.a, (double)res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 13 14271 140" } */
diff --git a/libffi/testsuite/libffi.call/cls_align_longdouble.c b/libffi/testsuite/libffi.call/cls_align_longdouble.c
index cb603950da8..af380603c99 100644
--- a/libffi/testsuite/libffi.call/cls_align_longdouble.c
+++ b/libffi/testsuite/libffi.call/cls_align_longdouble.c
@@ -44,21 +44,13 @@ cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[4];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -89,9 +81,9 @@ int main (void)
printf("res: %d %g %d\n", res_dbl.a, (double)res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 13 14271 140" } */
- CHECK(ffi_prep_closure(pcl, &cif, cls_struct_align_gn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
- res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(pcl))(g_dbl, f_dbl);
+ res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
/* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
printf("res: %d %g %d\n", res_dbl.a, (double)res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 13 14271 140" } */
diff --git a/libffi/testsuite/libffi.call/cls_align_longdouble_split.c b/libffi/testsuite/libffi.call/cls_align_longdouble_split.c
new file mode 100644
index 00000000000..40326778aee
--- /dev/null
+++ b/libffi/testsuite/libffi.call/cls_align_longdouble_split.c
@@ -0,0 +1,134 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure alignment of long double.
+ Limitations: none.
+ PR: none.
+ Originator: <hos@tamanegi.org> 20031203 */
+
+/* { dg-excess-errors "no long double format" { xfail x86_64-*-mingw* x86_64-*-cygwin* } } */
+/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */
+/* { dg-options -mlong-double-128 { target powerpc64*-*-* } } */
+/* { dg-output "" { xfail x86_64-*-mingw* x86_64-*-cygwin* } } */
+
+#include "ffitest.h"
+
+typedef struct cls_struct_align {
+ long double a;
+ long double b;
+ long double c;
+ long double d;
+ long double e;
+ long double f;
+ long double g;
+} cls_struct_align;
+
+cls_struct_align cls_struct_align_fn(
+ cls_struct_align a1,
+ cls_struct_align a2)
+{
+ struct cls_struct_align r;
+
+ r.a = a1.a + a2.a;
+ r.b = a1.b + a2.b;
+ r.c = a1.c + a2.c;
+ r.d = a1.d + a2.d;
+ r.e = a1.e + a2.e;
+ r.f = a1.f + a2.f;
+ r.g = a1.g + a2.g;
+
+ printf("%Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg: "
+ "%Lg %Lg %Lg %Lg %Lg %Lg %Lg\n",
+ a1.a, a1.b, a1.c, a1.d, a1.e, a1.f, a1.g,
+ a2.a, a2.b, a2.c, a2.d, a2.e, a2.f, a2.g,
+ r.a, r.b, r.c, r.d, r.e, r.f, r.g);
+
+ return r;
+}
+
+cls_struct_align cls_struct_align_fn2(
+ cls_struct_align a1)
+{
+ struct cls_struct_align r;
+
+ r.a = a1.a + 1;
+ r.b = a1.b + 1;
+ r.c = a1.c + 1;
+ r.d = a1.d + 1;
+ r.e = a1.e + 1;
+ r.f = a1.f + 1;
+ r.g = a1.g + 1;
+
+ printf("%Lg %Lg %Lg %Lg %Lg %Lg %Lg: "
+ "%Lg %Lg %Lg %Lg %Lg %Lg %Lg\n",
+ a1.a, a1.b, a1.c, a1.d, a1.e, a1.f, a1.g,
+ r.a, r.b, r.c, r.d, r.e, r.f, r.g);
+
+ return r;
+}
+
+static void
+cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+ struct cls_struct_align a1, a2;
+
+ a1 = *(struct cls_struct_align*)(args[0]);
+ a2 = *(struct cls_struct_align*)(args[1]);
+
+ *(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[3];
+ ffi_type* cls_struct_fields[8];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[3];
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ struct cls_struct_align g_dbl = { 1, 2, 3, 4, 5, 6, 7 };
+ struct cls_struct_align f_dbl = { 8, 9, 10, 11, 12, 13, 14 };
+ struct cls_struct_align res_dbl;
+
+ cls_struct_fields[0] = &ffi_type_longdouble;
+ cls_struct_fields[1] = &ffi_type_longdouble;
+ cls_struct_fields[2] = &ffi_type_longdouble;
+ cls_struct_fields[3] = &ffi_type_longdouble;
+ cls_struct_fields[4] = &ffi_type_longdouble;
+ cls_struct_fields[5] = &ffi_type_longdouble;
+ cls_struct_fields[6] = &ffi_type_longdouble;
+ cls_struct_fields[7] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
+ /* { dg-output "1 2 3 4 5 6 7 8 9 10 11 12 13 14: 9 11 13 15 17 19 21" } */
+ printf("res: %Lg %Lg %Lg %Lg %Lg %Lg %Lg\n", res_dbl.a, res_dbl.b,
+ res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g);
+ /* { dg-output "\nres: 9 11 13 15 17 19 21" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
+ /* { dg-output "\n1 2 3 4 5 6 7 8 9 10 11 12 13 14: 9 11 13 15 17 19 21" } */
+ printf("res: %Lg %Lg %Lg %Lg %Lg %Lg %Lg\n", res_dbl.a, res_dbl.b,
+ res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g);
+ /* { dg-output "\nres: 9 11 13 15 17 19 21" } */
+
+ exit(0);
+}
diff --git a/libffi/testsuite/libffi.call/cls_align_longdouble_split2.c b/libffi/testsuite/libffi.call/cls_align_longdouble_split2.c
new file mode 100644
index 00000000000..ced41c0b00c
--- /dev/null
+++ b/libffi/testsuite/libffi.call/cls_align_longdouble_split2.c
@@ -0,0 +1,117 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure alignment of long double.
+ Limitations: none.
+ PR: none.
+ Originator: Blake Chaffin 6/18/2007
+*/
+
+/* { dg-excess-errors "no long double format" { xfail x86_64-*-mingw* x86_64-*-cygwin* } } */
+/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* } } */
+/* { dg-options -mlong-double-128 { target powerpc64*-*-* } } */
+/* { dg-output "" { xfail x86_64-*-mingw* x86_64-*-cygwin* } } */
+
+#include "ffitest.h"
+
+typedef struct cls_struct_align {
+ long double a;
+ long double b;
+ long double c;
+ long double d;
+ long double e;
+ double f;
+ long double g;
+} cls_struct_align;
+
+cls_struct_align cls_struct_align_fn(
+ cls_struct_align a1,
+ cls_struct_align a2)
+{
+ struct cls_struct_align r;
+
+ r.a = a1.a + a2.a;
+ r.b = a1.b + a2.b;
+ r.c = a1.c + a2.c;
+ r.d = a1.d + a2.d;
+ r.e = a1.e + a2.e;
+ r.f = a1.f + a2.f;
+ r.g = a1.g + a2.g;
+
+ printf("%Lg %Lg %Lg %Lg %Lg %g %Lg %Lg %Lg %Lg %Lg %Lg %g %Lg: "
+ "%Lg %Lg %Lg %Lg %Lg %g %Lg\n",
+ a1.a, a1.b, a1.c, a1.d, a1.e, a1.f, a1.g,
+ a2.a, a2.b, a2.c, a2.d, a2.e, a2.f, a2.g,
+ r.a, r.b, r.c, r.d, r.e, r.f, r.g);
+
+ return r;
+}
+
+static void
+cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
+ void* userdata __UNUSED__)
+{
+ struct cls_struct_align a1, a2;
+
+ a1 = *(struct cls_struct_align*)(args[0]);
+ a2 = *(struct cls_struct_align*)(args[1]);
+
+ *(cls_struct_align*)resp = cls_struct_align_fn(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[3];
+ ffi_type* cls_struct_fields[8];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[3];
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ struct cls_struct_align g_dbl = { 1, 2, 3, 4, 5, 6, 7 };
+ struct cls_struct_align f_dbl = { 8, 9, 10, 11, 12, 13, 14 };
+ struct cls_struct_align res_dbl;
+
+ cls_struct_fields[0] = &ffi_type_longdouble;
+ cls_struct_fields[1] = &ffi_type_longdouble;
+ cls_struct_fields[2] = &ffi_type_longdouble;
+ cls_struct_fields[3] = &ffi_type_longdouble;
+ cls_struct_fields[4] = &ffi_type_longdouble;
+ cls_struct_fields[5] = &ffi_type_double;
+ cls_struct_fields[6] = &ffi_type_longdouble;
+ cls_struct_fields[7] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &g_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
+ /* { dg-output "1 2 3 4 5 6 7 8 9 10 11 12 13 14: 9 11 13 15 17 19 21" } */
+ printf("res: %Lg %Lg %Lg %Lg %Lg %g %Lg\n", res_dbl.a, res_dbl.b,
+ res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g);
+ /* { dg-output "\nres: 9 11 13 15 17 19 21" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
+ /* { dg-output "\n1 2 3 4 5 6 7 8 9 10 11 12 13 14: 9 11 13 15 17 19 21" } */
+ printf("res: %Lg %Lg %Lg %Lg %Lg %g %Lg\n", res_dbl.a, res_dbl.b,
+ res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g);
+ /* { dg-output "\nres: 9 11 13 15 17 19 21" } */
+
+ exit(0);
+}
+
+
+
diff --git a/libffi/testsuite/libffi.call/cls_align_pointer.c b/libffi/testsuite/libffi.call/cls_align_pointer.c
index 441edcb1027..cbc4f953ff6 100644
--- a/libffi/testsuite/libffi.call/cls_align_pointer.c
+++ b/libffi/testsuite/libffi.call/cls_align_pointer.c
@@ -19,11 +19,13 @@ cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
struct cls_struct_align result;
result.a = a1.a + a2.a;
- result.b = (void *)((unsigned long)a1.b + (unsigned long)a2.b);
+ result.b = (void *)((uintptr_t)a1.b + (uintptr_t)a2.b);
result.c = a1.c + a2.c;
- printf("%d %lu %d %d %lu %d: %d %lu %d\n", a1.a, (unsigned long)a1.b, a1.c,
- a2.a, (unsigned long)a2.b, a2.c, result.a, (unsigned long)result.b,
+ printf("%d %" PRIuPTR " %d %d %" PRIuPTR " %d: %d %" PRIuPTR " %d\n",
+ a1.a, (uintptr_t)a1.b, a1.c,
+ a2.a, (uintptr_t)a2.b, a2.c,
+ result.a, (uintptr_t)result.b,
result.c);
return result;
@@ -45,21 +47,13 @@ cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[4];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -87,14 +81,14 @@ int main (void)
ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
/* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
- printf("res: %d %lu %d\n", res_dbl.a, (unsigned long)res_dbl.b, res_dbl.c);
+ printf("res: %d %" PRIuPTR " %d\n", res_dbl.a, (uintptr_t)res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 13 14271 140" } */
- CHECK(ffi_prep_closure(pcl, &cif, cls_struct_align_gn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
- res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(pcl))(g_dbl, f_dbl);
+ res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
/* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
- printf("res: %d %lu %d\n", res_dbl.a, (unsigned long)res_dbl.b, res_dbl.c);
+ printf("res: %d %" PRIuPTR " %d\n", res_dbl.a, (uintptr_t)res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 13 14271 140" } */
exit(0);
diff --git a/libffi/testsuite/libffi.call/cls_align_sint16.c b/libffi/testsuite/libffi.call/cls_align_sint16.c
index fe4fe092215..383ea41d5a6 100644
--- a/libffi/testsuite/libffi.call/cls_align_sint16.c
+++ b/libffi/testsuite/libffi.call/cls_align_sint16.c
@@ -43,21 +43,13 @@ cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[4];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -88,9 +80,9 @@ int main (void)
printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 13 14271 140" } */
- CHECK(ffi_prep_closure(pcl, &cif, cls_struct_align_gn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
- res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(pcl))(g_dbl, f_dbl);
+ res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
/* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 13 14271 140" } */
diff --git a/libffi/testsuite/libffi.call/cls_align_sint32.c b/libffi/testsuite/libffi.call/cls_align_sint32.c
index c059da80975..705d78cfa84 100644
--- a/libffi/testsuite/libffi.call/cls_align_sint32.c
+++ b/libffi/testsuite/libffi.call/cls_align_sint32.c
@@ -43,21 +43,13 @@ cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[4];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -88,9 +80,9 @@ int main (void)
printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 13 14271 140" } */
- CHECK(ffi_prep_closure(pcl, &cif, cls_struct_align_gn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
- res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(pcl))(g_dbl, f_dbl);
+ res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
/* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 13 14271 140" } */
diff --git a/libffi/testsuite/libffi.call/cls_align_sint64.c b/libffi/testsuite/libffi.call/cls_align_sint64.c
index f5e9746cab0..2b15c983886 100644
--- a/libffi/testsuite/libffi.call/cls_align_sint64.c
+++ b/libffi/testsuite/libffi.call/cls_align_sint64.c
@@ -22,7 +22,7 @@ cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
result.b = a1.b + a2.b;
result.c = a1.c + a2.c;
- printf("%d %lld %d %d %lld %d: %d %lld %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c, result.a, result.b, result.c);
+ printf("%d %" PRIdLL " %d %d %" PRIdLL " %d: %d %" PRIdLL " %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c, result.a, result.b, result.c);
return result;
}
@@ -43,21 +43,13 @@ cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[4];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -85,14 +77,14 @@ int main (void)
ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
/* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
- printf("res: %d %lld %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ printf("res: %d %" PRIdLL " %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 13 14271 140" } */
- CHECK(ffi_prep_closure(pcl, &cif, cls_struct_align_gn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
- res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(pcl))(g_dbl, f_dbl);
+ res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
/* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
- printf("res: %d %lld %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ printf("res: %d %" PRIdLL " %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 13 14271 140" } */
exit(0);
diff --git a/libffi/testsuite/libffi.call/cls_align_uint16.c b/libffi/testsuite/libffi.call/cls_align_uint16.c
index c861bee344d..cb6b74821ea 100644
--- a/libffi/testsuite/libffi.call/cls_align_uint16.c
+++ b/libffi/testsuite/libffi.call/cls_align_uint16.c
@@ -43,21 +43,13 @@ cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[4];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -88,9 +80,9 @@ int main (void)
printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 13 14271 140" } */
- CHECK(ffi_prep_closure(pcl, &cif, cls_struct_align_gn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
- res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(pcl))(g_dbl, f_dbl);
+ res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
/* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 13 14271 140" } */
diff --git a/libffi/testsuite/libffi.call/cls_align_uint32.c b/libffi/testsuite/libffi.call/cls_align_uint32.c
index d680d8a9f8c..e453d3e5d9e 100644
--- a/libffi/testsuite/libffi.call/cls_align_uint32.c
+++ b/libffi/testsuite/libffi.call/cls_align_uint32.c
@@ -43,21 +43,13 @@ cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[4];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -88,9 +80,9 @@ int main (void)
printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 13 14271 140" } */
- CHECK(ffi_prep_closure(pcl, &cif, cls_struct_align_gn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
- res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(pcl))(g_dbl, f_dbl);
+ res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
/* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
printf("res: %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 13 14271 140" } */
diff --git a/libffi/testsuite/libffi.call/cls_align_uint64.c b/libffi/testsuite/libffi.call/cls_align_uint64.c
index 0737ba2305b..215584f60a4 100644
--- a/libffi/testsuite/libffi.call/cls_align_uint64.c
+++ b/libffi/testsuite/libffi.call/cls_align_uint64.c
@@ -23,7 +23,7 @@ cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
result.b = a1.b + a2.b;
result.c = a1.c + a2.c;
- printf("%d %lld %d %d %lld %d: %d %lld %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c, result.a, result.b, result.c);
+ printf("%d %" PRIdLL " %d %d %" PRIdLL " %d: %d %" PRIdLL " %d\n", a1.a, a1.b, a1.c, a2.a, a2.b, a2.c, result.a, result.b, result.c);
return result;
}
@@ -44,21 +44,13 @@ cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[4];
ffi_type cls_struct_type;
ffi_type* dbl_arg_types[5];
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -86,14 +78,14 @@ int main (void)
ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
/* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
- printf("res: %d %lld %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ printf("res: %d %" PRIdLL " %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 13 14271 140" } */
- CHECK(ffi_prep_closure(pcl, &cif, cls_struct_align_gn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_align_gn, NULL, code) == FFI_OK);
- res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(pcl))(g_dbl, f_dbl);
+ res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(code))(g_dbl, f_dbl);
/* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
- printf("res: %d %lld %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
+ printf("res: %d %" PRIdLL " %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 13 14271 140" } */
exit(0);
diff --git a/libffi/testsuite/libffi.call/cls_dbls_struct.c b/libffi/testsuite/libffi.call/cls_dbls_struct.c
new file mode 100644
index 00000000000..fcf48b79237
--- /dev/null
+++ b/libffi/testsuite/libffi.call/cls_dbls_struct.c
@@ -0,0 +1,66 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check double arguments in structs.
+ Limitations: none.
+ PR: none.
+ Originator: Blake Chaffin 6/23/2007 */
+
+/* { dg-do run } */
+
+#include "ffitest.h"
+
+typedef struct Dbls {
+ double x;
+ double y;
+} Dbls;
+
+void
+closure_test_fn(Dbls p)
+{
+ printf("%.1f %.1f\n", p.x, p.y);
+}
+
+void
+closure_test_gn(ffi_cif* cif __UNUSED__, void* resp __UNUSED__,
+ void** args, void* userdata __UNUSED__)
+{
+ closure_test_fn(*(Dbls*)args[0]);
+}
+
+int main(int argc __UNUSED__, char** argv __UNUSED__)
+{
+ ffi_cif cif;
+
+ void *code;
+ ffi_closure* pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ ffi_type* cl_arg_types[1];
+
+ ffi_type ts1_type;
+ ffi_type* ts1_type_elements[4];
+
+ ts1_type.size = 0;
+ ts1_type.alignment = 0;
+ ts1_type.type = FFI_TYPE_STRUCT;
+ ts1_type.elements = ts1_type_elements;
+
+ ts1_type_elements[0] = &ffi_type_double;
+ ts1_type_elements[1] = &ffi_type_double;
+ ts1_type_elements[2] = NULL;
+
+ cl_arg_types[0] = &ts1_type;
+
+ Dbls arg = { 1.0, 2.0 };
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ffi_type_void, cl_arg_types) == FFI_OK);
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_gn, NULL, code) == FFI_OK);
+
+ ((void*(*)(Dbls))(code))(arg);
+ /* { dg-output "1.0 2.0\n" { xfail x86_64-*-linux-* } } */
+
+ closure_test_fn(arg);
+ /* { dg-output "1.0 2.0\n" } */
+
+ return 0;
+}
diff --git a/libffi/testsuite/libffi.call/cls_double.c b/libffi/testsuite/libffi.call/cls_double.c
index ee77adde6a0..84ad4cb7d92 100644
--- a/libffi/testsuite/libffi.call/cls_double.c
+++ b/libffi/testsuite/libffi.call/cls_double.c
@@ -20,19 +20,11 @@ typedef double (*cls_ret_double)(double);
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
ffi_type * cl_arg_types[2];
double res;
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cl_arg_types[0] = &ffi_type_double;
cl_arg_types[1] = NULL;
@@ -40,9 +32,9 @@ int main (void)
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
&ffi_type_double, cl_arg_types) == FFI_OK);
- CHECK(ffi_prep_closure(pcl, &cif, cls_ret_double_fn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_double_fn, NULL, code) == FFI_OK);
- res = (*((cls_ret_double)pcl))(21474.789);
+ res = (*((cls_ret_double)code))(21474.789);
/* { dg-output "21474.789000: 21474.789000" } */
printf("res: %.6f\n", res);
/* { dg-output "\nres: 21474.789000" } */
diff --git a/libffi/testsuite/libffi.call/cls_double_va.c b/libffi/testsuite/libffi.call/cls_double_va.c
new file mode 100644
index 00000000000..45ce9bd7c38
--- /dev/null
+++ b/libffi/testsuite/libffi.call/cls_double_va.c
@@ -0,0 +1,56 @@
+/* Area: ffi_call, closure_call
+ Purpose: Test doubles passed in variable argument lists.
+ Limitations: none.
+ PR: none.
+ Originator: Blake Chaffin 6/6/2007 */
+
+/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */
+#include "ffitest.h"
+
+static void
+cls_double_va_fn(ffi_cif* cif __UNUSED__, void* resp,
+ void** args, void* userdata __UNUSED__)
+{
+ char* format = *(char**)args[0];
+ double doubleValue = *(double*)args[1];
+
+ *(ffi_arg*)resp = printf(format, doubleValue);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args[3];
+ ffi_type* arg_types[3];
+
+ char* format = "%.1f\n";
+ double doubleArg = 7;
+ ffi_arg res = 0;
+
+ arg_types[0] = &ffi_type_pointer;
+ arg_types[1] = &ffi_type_double;
+ arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ffi_type_sint,
+ arg_types) == FFI_OK);
+
+ args[0] = &format;
+ args[1] = &doubleArg;
+ args[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(printf), &res, args);
+ // { dg-output "7.0" }
+ printf("res: %d\n", (int) res);
+ // { dg-output "\nres: 4" }
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_double_va_fn, NULL, code) == FFI_OK);
+
+ res = ((int(*)(char*, double))(code))(format, doubleArg);
+ // { dg-output "\n7.0" }
+ printf("res: %d\n", (int) res);
+ // { dg-output "\nres: 4" }
+
+ exit(0);
+}
diff --git a/libffi/testsuite/libffi.call/cls_float.c b/libffi/testsuite/libffi.call/cls_float.c
index 8bed628f823..0090fed9063 100644
--- a/libffi/testsuite/libffi.call/cls_float.c
+++ b/libffi/testsuite/libffi.call/cls_float.c
@@ -21,20 +21,11 @@ typedef float (*cls_ret_float)(float);
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
ffi_type * cl_arg_types[2];
float res;
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
-
cl_arg_types[0] = &ffi_type_float;
cl_arg_types[1] = NULL;
@@ -42,8 +33,8 @@ int main (void)
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
&ffi_type_float, cl_arg_types) == FFI_OK);
- CHECK(ffi_prep_closure(pcl, &cif, cls_ret_float_fn, NULL) == FFI_OK);
- res = ((((cls_ret_float)pcl)(-2122.12)));
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_float_fn, NULL, code) == FFI_OK);
+ res = ((((cls_ret_float)code)(-2122.12)));
/* { dg-output "\\-2122.12: \\-2122.12" } */
printf("res: %.6f\n", res);
/* { dg-output "\nres: \-2122.120117" } */
diff --git a/libffi/testsuite/libffi.call/cls_longdouble.c b/libffi/testsuite/libffi.call/cls_longdouble.c
new file mode 100644
index 00000000000..2f50b368e7a
--- /dev/null
+++ b/libffi/testsuite/libffi.call/cls_longdouble.c
@@ -0,0 +1,105 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check long double arguments.
+ Limitations: none.
+ PR: none.
+ Originator: Blake Chaffin */
+
+/* { dg-excess-errors "no long double format" { xfail x86_64-*-mingw* x86_64-*-cygwin* } } */
+/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */
+/* { dg-options -mlong-double-128 { target powerpc64*-*-* } } */
+/* { dg-output "" { xfail x86_64-*-mingw* x86_64-*-cygwin* } } */
+
+#include "ffitest.h"
+
+long double cls_ldouble_fn(
+ long double a1,
+ long double a2,
+ long double a3,
+ long double a4,
+ long double a5,
+ long double a6,
+ long double a7,
+ long double a8)
+{
+ long double r = a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8;
+
+ printf("%Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg: %Lg\n",
+ a1, a2, a3, a4, a5, a6, a7, a8, r);
+
+ return r;
+}
+
+static void
+cls_ldouble_gn(ffi_cif* cif __UNUSED__, void* resp,
+ void** args, void* userdata __UNUSED__)
+{
+ long double a1 = *(long double*)args[0];
+ long double a2 = *(long double*)args[1];
+ long double a3 = *(long double*)args[2];
+ long double a4 = *(long double*)args[3];
+ long double a5 = *(long double*)args[4];
+ long double a6 = *(long double*)args[5];
+ long double a7 = *(long double*)args[6];
+ long double a8 = *(long double*)args[7];
+
+ *(long double*)resp = cls_ldouble_fn(
+ a1, a2, a3, a4, a5, a6, a7, a8);
+}
+
+int main(void)
+{
+ ffi_cif cif;
+ void* code;
+ ffi_closure* pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args[9];
+ ffi_type* arg_types[9];
+ long double res = 0;
+
+ long double arg1 = 1;
+ long double arg2 = 2;
+ long double arg3 = 3;
+ long double arg4 = 4;
+ long double arg5 = 5;
+ long double arg6 = 6;
+ long double arg7 = 7;
+ long double arg8 = 8;
+
+ arg_types[0] = &ffi_type_longdouble;
+ arg_types[1] = &ffi_type_longdouble;
+ arg_types[2] = &ffi_type_longdouble;
+ arg_types[3] = &ffi_type_longdouble;
+ arg_types[4] = &ffi_type_longdouble;
+ arg_types[5] = &ffi_type_longdouble;
+ arg_types[6] = &ffi_type_longdouble;
+ arg_types[7] = &ffi_type_longdouble;
+ arg_types[8] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 8, &ffi_type_longdouble,
+ arg_types) == FFI_OK);
+
+ args[0] = &arg1;
+ args[1] = &arg2;
+ args[2] = &arg3;
+ args[3] = &arg4;
+ args[4] = &arg5;
+ args[5] = &arg6;
+ args[6] = &arg7;
+ args[7] = &arg8;
+ args[8] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_ldouble_fn), &res, args);
+ /* { dg-output "1 2 3 4 5 6 7 8: 36" } */
+ printf("res: %Lg\n", res);
+ /* { dg-output "\nres: 36" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ldouble_gn, NULL, code) == FFI_OK);
+
+ res = ((long double(*)(long double, long double, long double, long double,
+ long double, long double, long double, long double))(code))(arg1, arg2,
+ arg3, arg4, arg5, arg6, arg7, arg8);
+ /* { dg-output "\n1 2 3 4 5 6 7 8: 36" } */
+ printf("res: %Lg\n", res);
+ /* { dg-output "\nres: 36" } */
+
+ return 0;
+}
diff --git a/libffi/testsuite/libffi.call/cls_longdouble_va.c b/libffi/testsuite/libffi.call/cls_longdouble_va.c
new file mode 100644
index 00000000000..3d725bd731a
--- /dev/null
+++ b/libffi/testsuite/libffi.call/cls_longdouble_va.c
@@ -0,0 +1,57 @@
+/* Area: ffi_call, closure_call
+ Purpose: Test long doubles passed in variable argument lists.
+ Limitations: none.
+ PR: none.
+ Originator: Blake Chaffin 6/6/2007 */
+
+/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */
+/* { dg-output "" { xfail x86_64-*-mingw* } } */
+#include "ffitest.h"
+
+static void
+cls_longdouble_va_fn(ffi_cif* cif __UNUSED__, void* resp,
+ void** args, void* userdata __UNUSED__)
+{
+ char* format = *(char**)args[0];
+ long double ldValue = *(long double*)args[1];
+
+ *(ffi_arg*)resp = printf(format, ldValue);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args[3];
+ ffi_type* arg_types[3];
+
+ char* format = "%L.1f\n";
+ long double ldArg = 7;
+ ffi_arg res = 0;
+
+ arg_types[0] = &ffi_type_pointer;
+ arg_types[1] = &ffi_type_longdouble;
+ arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ffi_type_sint,
+ arg_types) == FFI_OK);
+
+ args[0] = &format;
+ args[1] = &ldArg;
+ args[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(printf), &res, args);
+ // { dg-output "7.0" { xfail i*86-*-linux-* x86_64-*-linux-* } }
+ printf("res: %d\n", (int) res);
+ // { dg-output "\nres: 4" { xfail i*86-*-linux-* x86_64-*-linux-* } }
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_longdouble_va_fn, NULL, code) == FFI_OK);
+
+ res = ((int(*)(char*, long double))(code))(format, ldArg);
+ // { dg-output "\n7.0" }
+ printf("res: %d\n", (int) res);
+ // { dg-output "\nres: 4" }
+
+ exit(0);
+}
diff --git a/libffi/testsuite/libffi.call/cls_multi_schar.c b/libffi/testsuite/libffi.call/cls_multi_schar.c
index 713c3188d81..71df7b6516e 100644
--- a/libffi/testsuite/libffi.call/cls_multi_schar.c
+++ b/libffi/testsuite/libffi.call/cls_multi_schar.c
@@ -36,21 +36,13 @@ typedef signed char (*test_type)(signed char, signed char);
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void * args_dbl[3];
ffi_type * cl_arg_types[3];
ffi_arg res_call;
signed char a, b, res_closure;
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
a = 2;
b = 125;
@@ -71,9 +63,9 @@ int main (void)
printf("res: %d\n", (signed char)res_call);
/* { dg-output "\nres: 127" } */
- CHECK(ffi_prep_closure(pcl, &cif, test_func_gn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, test_func_gn, NULL, code) == FFI_OK);
- res_closure = (*((test_type)pcl))(2, 125);
+ res_closure = (*((test_type)code))(2, 125);
/* { dg-output "\n2 125: 127" } */
printf("res: %d\n", res_closure);
/* { dg-output "\nres: 127" } */
diff --git a/libffi/testsuite/libffi.call/cls_multi_sshort.c b/libffi/testsuite/libffi.call/cls_multi_sshort.c
index 852fdf73db7..4c391532667 100644
--- a/libffi/testsuite/libffi.call/cls_multi_sshort.c
+++ b/libffi/testsuite/libffi.call/cls_multi_sshort.c
@@ -36,21 +36,13 @@ typedef signed short (*test_type)(signed short, signed short);
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void * args_dbl[3];
ffi_type * cl_arg_types[3];
ffi_arg res_call;
unsigned short a, b, res_closure;
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
a = 2;
b = 32765;
@@ -71,9 +63,9 @@ int main (void)
printf("res: %d\n", (unsigned short)res_call);
/* { dg-output "\nres: 32767" } */
- CHECK(ffi_prep_closure(pcl, &cif, test_func_gn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, test_func_gn, NULL, code) == FFI_OK);
- res_closure = (*((test_type)pcl))(2, 32765);
+ res_closure = (*((test_type)code))(2, 32765);
/* { dg-output "\n2 32765: 32767" } */
printf("res: %d\n", res_closure);
/* { dg-output "\nres: 32767" } */
diff --git a/libffi/testsuite/libffi.call/cls_multi_sshortchar.c b/libffi/testsuite/libffi.call/cls_multi_sshortchar.c
index e4e92ef4480..1c3aeb5a66c 100644
--- a/libffi/testsuite/libffi.call/cls_multi_sshortchar.c
+++ b/libffi/testsuite/libffi.call/cls_multi_sshortchar.c
@@ -41,22 +41,14 @@ typedef signed short (*test_type)(signed char, signed short,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void * args_dbl[5];
ffi_type * cl_arg_types[5];
ffi_arg res_call;
signed char a, c;
signed short b, d, res_closure;
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
a = 1;
b = 32765;
c = 127;
@@ -83,9 +75,9 @@ int main (void)
printf("res: %d\n", (signed short)res_call);
/* { dg-output "\nres: 32765" } */
- CHECK(ffi_prep_closure(pcl, &cif, test_func_gn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, test_func_gn, NULL, code) == FFI_OK);
- res_closure = (*((test_type)pcl))(1, 32765, 127, -128);
+ res_closure = (*((test_type)code))(1, 32765, 127, -128);
/* { dg-output "\n1 32765 127 -128: 32765" } */
printf("res: %d\n", res_closure);
/* { dg-output "\nres: 32765" } */
diff --git a/libffi/testsuite/libffi.call/cls_multi_uchar.c b/libffi/testsuite/libffi.call/cls_multi_uchar.c
index 2c84aef6134..009c02c72ba 100644
--- a/libffi/testsuite/libffi.call/cls_multi_uchar.c
+++ b/libffi/testsuite/libffi.call/cls_multi_uchar.c
@@ -47,21 +47,13 @@ void test_func(ffi_cif *cif __UNUSED__, void *rval __UNUSED__, void **avals,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void * args_dbl[5];
ffi_type * cl_arg_types[5];
ffi_arg res_call;
unsigned char a, b, c, d, res_closure;
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
a = 1;
b = 2;
c = 127;
@@ -88,9 +80,9 @@ int main (void)
printf("res: %d\n", (unsigned char)res_call);
/* { dg-output "\nres: 255" } */
- CHECK(ffi_prep_closure(pcl, &cif, test_func_gn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, test_func_gn, NULL, code) == FFI_OK);
- res_closure = (*((test_type)pcl))(1, 2, 127, 125);
+ res_closure = (*((test_type)code))(1, 2, 127, 125);
/* { dg-output "\n1 2 127 125: 255" } */
printf("res: %d\n", res_closure);
/* { dg-output "\nres: 255" } */
diff --git a/libffi/testsuite/libffi.call/cls_multi_ushort.c b/libffi/testsuite/libffi.call/cls_multi_ushort.c
index 215fef832a8..dd10ca73468 100644
--- a/libffi/testsuite/libffi.call/cls_multi_ushort.c
+++ b/libffi/testsuite/libffi.call/cls_multi_ushort.c
@@ -36,21 +36,13 @@ typedef unsigned short (*test_type)(unsigned short, unsigned short);
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void * args_dbl[3];
ffi_type * cl_arg_types[3];
ffi_arg res_call;
unsigned short a, b, res_closure;
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
a = 2;
b = 32765;
@@ -71,9 +63,9 @@ int main (void)
printf("res: %d\n", (unsigned short)res_call);
/* { dg-output "\nres: 32767" } */
- CHECK(ffi_prep_closure(pcl, &cif, test_func_gn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, test_func_gn, NULL, code) == FFI_OK);
- res_closure = (*((test_type)pcl))(2, 32765);
+ res_closure = (*((test_type)code))(2, 32765);
/* { dg-output "\n2 32765: 32767" } */
printf("res: %d\n", res_closure);
/* { dg-output "\nres: 32767" } */
diff --git a/libffi/testsuite/libffi.call/cls_multi_ushortchar.c b/libffi/testsuite/libffi.call/cls_multi_ushortchar.c
index 1cde84abb5e..2588e97f987 100644
--- a/libffi/testsuite/libffi.call/cls_multi_ushortchar.c
+++ b/libffi/testsuite/libffi.call/cls_multi_ushortchar.c
@@ -41,22 +41,14 @@ typedef unsigned short (*test_type)(unsigned char, unsigned short,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void * args_dbl[5];
ffi_type * cl_arg_types[5];
ffi_arg res_call;
unsigned char a, c;
unsigned short b, d, res_closure;
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
a = 1;
b = 2;
c = 127;
@@ -83,9 +75,9 @@ int main (void)
printf("res: %d\n", (unsigned short)res_call);
/* { dg-output "\nres: 258" } */
- CHECK(ffi_prep_closure(pcl, &cif, test_func_gn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, test_func_gn, NULL, code) == FFI_OK);
- res_closure = (*((test_type)pcl))(1, 2, 127, 128);
+ res_closure = (*((test_type)code))(1, 2, 127, 128);
/* { dg-output "\n1 2 127 128: 258" } */
printf("res: %d\n", res_closure);
/* { dg-output "\nres: 258" } */
diff --git a/libffi/testsuite/libffi.call/cls_pointer.c b/libffi/testsuite/libffi.call/cls_pointer.c
new file mode 100644
index 00000000000..34e4209640b
--- /dev/null
+++ b/libffi/testsuite/libffi.call/cls_pointer.c
@@ -0,0 +1,74 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check pointer arguments.
+ Limitations: none.
+ PR: none.
+ Originator: Blake Chaffin 6/6/2007 */
+
+/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */
+#include "ffitest.h"
+
+void* cls_pointer_fn(void* a1, void* a2)
+{
+ void* result = (void*)((intptr_t)a1 + (intptr_t)a2);
+
+ printf("0x%08x 0x%08x: 0x%08x\n",
+ (unsigned int)(uintptr_t) a1,
+ (unsigned int)(uintptr_t) a2,
+ (unsigned int)(uintptr_t) result);
+
+ return result;
+}
+
+static void
+cls_pointer_gn(ffi_cif* cif __UNUSED__, void* resp,
+ void** args, void* userdata __UNUSED__)
+{
+ void* a1 = *(void**)(args[0]);
+ void* a2 = *(void**)(args[1]);
+
+ *(void**)resp = cls_pointer_fn(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure* pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args[3];
+// ffi_type cls_pointer_type;
+ ffi_type* arg_types[3];
+
+/* cls_pointer_type.size = sizeof(void*);
+ cls_pointer_type.alignment = 0;
+ cls_pointer_type.type = FFI_TYPE_POINTER;
+ cls_pointer_type.elements = NULL;*/
+
+ void* arg1 = (void*)0x12345678;
+ void* arg2 = (void*)0x89abcdef;
+ ffi_arg res = 0;
+
+ arg_types[0] = &ffi_type_pointer;
+ arg_types[1] = &ffi_type_pointer;
+ arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ffi_type_pointer,
+ arg_types) == FFI_OK);
+
+ args[0] = &arg1;
+ args[1] = &arg2;
+ args[2] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_pointer_fn), &res, args);
+ /* { dg-output "0x12345678 0x89abcdef: 0x9be02467" } */
+ printf("res: 0x%08x\n", (unsigned int) res);
+ /* { dg-output "\nres: 0x9be02467" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_pointer_gn, NULL, code) == FFI_OK);
+
+ res = (ffi_arg)((void*(*)(void*, void*))(code))(arg1, arg2);
+ /* { dg-output "\n0x12345678 0x89abcdef: 0x9be02467" } */
+ printf("res: 0x%08x\n", (unsigned int) res);
+ /* { dg-output "\nres: 0x9be02467" } */
+
+ exit(0);
+}
diff --git a/libffi/testsuite/libffi.call/cls_pointer_stack.c b/libffi/testsuite/libffi.call/cls_pointer_stack.c
new file mode 100644
index 00000000000..dd59c6b2c7a
--- /dev/null
+++ b/libffi/testsuite/libffi.call/cls_pointer_stack.c
@@ -0,0 +1,140 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check pointer arguments across multiple hideous stack frames.
+ Limitations: none.
+ PR: none.
+ Originator: Blake Chaffin 6/7/2007 */
+
+/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */
+#include "ffitest.h"
+
+static long dummyVar;
+
+long dummy_func(
+ long double a1, char b1,
+ long double a2, char b2,
+ long double a3, char b3,
+ long double a4, char b4)
+{
+ return a1 + b1 + a2 + b2 + a3 + b3 + a4 + b4;
+}
+
+void* cls_pointer_fn2(void* a1, void* a2)
+{
+ long double trample1 = (intptr_t)a1 + (intptr_t)a2;
+ char trample2 = ((char*)&a1)[0] + ((char*)&a2)[0];
+ long double trample3 = (intptr_t)trample1 + (intptr_t)a1;
+ char trample4 = trample2 + ((char*)&a1)[1];
+ long double trample5 = (intptr_t)trample3 + (intptr_t)a2;
+ char trample6 = trample4 + ((char*)&a2)[1];
+ long double trample7 = (intptr_t)trample5 + (intptr_t)trample1;
+ char trample8 = trample6 + trample2;
+
+ dummyVar = dummy_func(trample1, trample2, trample3, trample4,
+ trample5, trample6, trample7, trample8);
+
+ void* result = (void*)((intptr_t)a1 + (intptr_t)a2);
+
+ printf("0x%08x 0x%08x: 0x%08x\n",
+ (unsigned int)(uintptr_t) a1,
+ (unsigned int)(uintptr_t) a2,
+ (unsigned int)(uintptr_t) result);
+
+ return result;
+}
+
+void* cls_pointer_fn1(void* a1, void* a2)
+{
+ long double trample1 = (intptr_t)a1 + (intptr_t)a2;
+ char trample2 = ((char*)&a1)[0] + ((char*)&a2)[0];
+ long double trample3 = (intptr_t)trample1 + (intptr_t)a1;
+ char trample4 = trample2 + ((char*)&a1)[1];
+ long double trample5 = (intptr_t)trample3 + (intptr_t)a2;
+ char trample6 = trample4 + ((char*)&a2)[1];
+ long double trample7 = (intptr_t)trample5 + (intptr_t)trample1;
+ char trample8 = trample6 + trample2;
+
+ dummyVar = dummy_func(trample1, trample2, trample3, trample4,
+ trample5, trample6, trample7, trample8);
+
+ void* result = (void*)((intptr_t)a1 + (intptr_t)a2);
+
+ printf("0x%08x 0x%08x: 0x%08x\n",
+ (unsigned int)(intptr_t) a1,
+ (unsigned int)(intptr_t) a2,
+ (unsigned int)(intptr_t) result);
+
+ result = cls_pointer_fn2(result, a1);
+
+ return result;
+}
+
+static void
+cls_pointer_gn(ffi_cif* cif __UNUSED__, void* resp,
+ void** args, void* userdata __UNUSED__)
+{
+ void* a1 = *(void**)(args[0]);
+ void* a2 = *(void**)(args[1]);
+
+ long double trample1 = (intptr_t)a1 + (intptr_t)a2;
+ char trample2 = ((char*)&a1)[0] + ((char*)&a2)[0];
+ long double trample3 = (intptr_t)trample1 + (intptr_t)a1;
+ char trample4 = trample2 + ((char*)&a1)[1];
+ long double trample5 = (intptr_t)trample3 + (intptr_t)a2;
+ char trample6 = trample4 + ((char*)&a2)[1];
+ long double trample7 = (intptr_t)trample5 + (intptr_t)trample1;
+ char trample8 = trample6 + trample2;
+
+ dummyVar = dummy_func(trample1, trample2, trample3, trample4,
+ trample5, trample6, trample7, trample8);
+
+ *(void**)resp = cls_pointer_fn1(a1, a2);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure* pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args[3];
+// ffi_type cls_pointer_type;
+ ffi_type* arg_types[3];
+
+/* cls_pointer_type.size = sizeof(void*);
+ cls_pointer_type.alignment = 0;
+ cls_pointer_type.type = FFI_TYPE_POINTER;
+ cls_pointer_type.elements = NULL;*/
+
+ void* arg1 = (void*)0x01234567;
+ void* arg2 = (void*)0x89abcdef;
+ ffi_arg res = 0;
+
+ arg_types[0] = &ffi_type_pointer;
+ arg_types[1] = &ffi_type_pointer;
+ arg_types[2] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ffi_type_pointer,
+ arg_types) == FFI_OK);
+
+ args[0] = &arg1;
+ args[1] = &arg2;
+ args[2] = NULL;
+
+ printf("\n");
+ ffi_call(&cif, FFI_FN(cls_pointer_fn1), &res, args);
+
+ printf("res: 0x%08x\n", (unsigned int) res);
+ // { dg-output "\n0x01234567 0x89abcdef: 0x8acf1356" }
+ // { dg-output "\n0x8acf1356 0x01234567: 0x8bf258bd" }
+ // { dg-output "\nres: 0x8bf258bd" }
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_pointer_gn, NULL, code) == FFI_OK);
+
+ res = (ffi_arg)((void*(*)(void*, void*))(code))(arg1, arg2);
+
+ printf("res: 0x%08x\n", (unsigned int) res);
+ // { dg-output "\n0x01234567 0x89abcdef: 0x8acf1356" }
+ // { dg-output "\n0x8acf1356 0x01234567: 0x8bf258bd" }
+ // { dg-output "\nres: 0x8bf258bd" }
+
+ exit(0);
+}
diff --git a/libffi/testsuite/libffi.call/cls_schar.c b/libffi/testsuite/libffi.call/cls_schar.c
index bb1f2c64f35..82986b172c3 100644
--- a/libffi/testsuite/libffi.call/cls_schar.c
+++ b/libffi/testsuite/libffi.call/cls_schar.c
@@ -21,19 +21,11 @@ typedef signed char (*cls_ret_schar)(signed char);
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
ffi_type * cl_arg_types[2];
signed char res;
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cl_arg_types[0] = &ffi_type_schar;
cl_arg_types[1] = NULL;
@@ -41,9 +33,9 @@ int main (void)
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
&ffi_type_schar, cl_arg_types) == FFI_OK);
- CHECK(ffi_prep_closure(pcl, &cif, cls_ret_schar_fn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_schar_fn, NULL, code) == FFI_OK);
- res = (*((cls_ret_schar)pcl))(127);
+ res = (*((cls_ret_schar)code))(127);
/* { dg-output "127: 127" } */
printf("res: %d\n", res);
/* { dg-output "\nres: 127" } */
diff --git a/libffi/testsuite/libffi.call/cls_sint.c b/libffi/testsuite/libffi.call/cls_sint.c
index cf21bf84417..c7e13b73a3b 100644
--- a/libffi/testsuite/libffi.call/cls_sint.c
+++ b/libffi/testsuite/libffi.call/cls_sint.c
@@ -19,19 +19,11 @@ typedef signed int (*cls_ret_sint)(signed int);
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
ffi_type * cl_arg_types[2];
signed int res;
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cl_arg_types[0] = &ffi_type_sint;
cl_arg_types[1] = NULL;
@@ -39,9 +31,9 @@ int main (void)
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
&ffi_type_sint, cl_arg_types) == FFI_OK);
- CHECK(ffi_prep_closure(pcl, &cif, cls_ret_sint_fn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_sint_fn, NULL, code) == FFI_OK);
- res = (*((cls_ret_sint)pcl))(65534);
+ res = (*((cls_ret_sint)code))(65534);
/* { dg-output "65534: 65534" } */
printf("res: %d\n",res);
/* { dg-output "\nres: 65534" } */
diff --git a/libffi/testsuite/libffi.call/cls_sshort.c b/libffi/testsuite/libffi.call/cls_sshort.c
index 8d63413318d..846d57ed1ba 100644
--- a/libffi/testsuite/libffi.call/cls_sshort.c
+++ b/libffi/testsuite/libffi.call/cls_sshort.c
@@ -19,19 +19,11 @@ typedef signed short (*cls_ret_sshort)(signed short);
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
ffi_type * cl_arg_types[2];
signed short res;
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cl_arg_types[0] = &ffi_type_sshort;
cl_arg_types[1] = NULL;
@@ -39,9 +31,9 @@ int main (void)
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
&ffi_type_sshort, cl_arg_types) == FFI_OK);
- CHECK(ffi_prep_closure(pcl, &cif, cls_ret_sshort_fn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_sshort_fn, NULL, code) == FFI_OK);
- res = (*((cls_ret_sshort)pcl))(255);
+ res = (*((cls_ret_sshort)code))(255);
/* { dg-output "255: 255" } */
printf("res: %d\n",res);
/* { dg-output "\nres: 255" } */
diff --git a/libffi/testsuite/libffi.call/cls_uchar.c b/libffi/testsuite/libffi.call/cls_uchar.c
index ea78ce5840a..c1317e795fd 100644
--- a/libffi/testsuite/libffi.call/cls_uchar.c
+++ b/libffi/testsuite/libffi.call/cls_uchar.c
@@ -19,19 +19,11 @@ typedef unsigned char (*cls_ret_uchar)(unsigned char);
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
ffi_type * cl_arg_types[2];
unsigned char res;
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cl_arg_types[0] = &ffi_type_uchar;
cl_arg_types[1] = NULL;
@@ -39,9 +31,9 @@ int main (void)
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
&ffi_type_uchar, cl_arg_types) == FFI_OK);
- CHECK(ffi_prep_closure(pcl, &cif, cls_ret_uchar_fn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_uchar_fn, NULL, code) == FFI_OK);
- res = (*((cls_ret_uchar)pcl))(127);
+ res = (*((cls_ret_uchar)code))(127);
/* { dg-output "127: 127" } */
printf("res: %d\n",res);
/* { dg-output "\nres: 127" } */
diff --git a/libffi/testsuite/libffi.call/cls_uint.c b/libffi/testsuite/libffi.call/cls_uint.c
index e31e41aacf2..885cff5c314 100644
--- a/libffi/testsuite/libffi.call/cls_uint.c
+++ b/libffi/testsuite/libffi.call/cls_uint.c
@@ -20,19 +20,11 @@ typedef unsigned int (*cls_ret_uint)(unsigned int);
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
ffi_type * cl_arg_types[2];
unsigned int res;
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cl_arg_types[0] = &ffi_type_uint;
cl_arg_types[1] = NULL;
@@ -40,9 +32,9 @@ int main (void)
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
&ffi_type_uint, cl_arg_types) == FFI_OK);
- CHECK(ffi_prep_closure(pcl, &cif, cls_ret_uint_fn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_uint_fn, NULL, code) == FFI_OK);
- res = (*((cls_ret_uint)pcl))(2147483647);
+ res = (*((cls_ret_uint)code))(2147483647);
/* { dg-output "2147483647: 2147483647" } */
printf("res: %d\n",res);
/* { dg-output "\nres: 2147483647" } */
diff --git a/libffi/testsuite/libffi.call/cls_ulonglong.c b/libffi/testsuite/libffi.call/cls_ulonglong.c
index 1cc0a389332..c3cf0d6ec01 100644
--- a/libffi/testsuite/libffi.call/cls_ulonglong.c
+++ b/libffi/testsuite/libffi.call/cls_ulonglong.c
@@ -12,7 +12,7 @@ static void cls_ret_ulonglong_fn(ffi_cif* cif __UNUSED__, void* resp,
{
*(unsigned long long *)resp= *(unsigned long long *)args[0];
- printf("%llu: %llu\n",*(unsigned long long *)args[0],
+ printf("%" PRIuLL ": %" PRIuLL "\n",*(unsigned long long *)args[0],
*(unsigned long long *)(resp));
}
typedef unsigned long long (*cls_ret_ulonglong)(unsigned long long);
@@ -20,34 +20,26 @@ typedef unsigned long long (*cls_ret_ulonglong)(unsigned long long);
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
ffi_type * cl_arg_types[2];
unsigned long long res;
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cl_arg_types[0] = &ffi_type_uint64;
cl_arg_types[1] = NULL;
/* Initialize the cif */
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
&ffi_type_uint64, cl_arg_types) == FFI_OK);
- CHECK(ffi_prep_closure(pcl, &cif, cls_ret_ulonglong_fn, NULL) == FFI_OK);
- res = (*((cls_ret_ulonglong)pcl))(214LL);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_ulonglong_fn, NULL, code) == FFI_OK);
+ res = (*((cls_ret_ulonglong)code))(214LL);
/* { dg-output "214: 214" } */
- printf("res: %lld\n", res);
+ printf("res: %" PRIdLL "\n", res);
/* { dg-output "\nres: 214" } */
- res = (*((cls_ret_ulonglong)pcl))(9223372035854775808LL);
+ res = (*((cls_ret_ulonglong)code))(9223372035854775808LL);
/* { dg-output "\n9223372035854775808: 9223372035854775808" } */
- printf("res: %lld\n", res);
+ printf("res: %" PRIdLL "\n", res);
/* { dg-output "\nres: 9223372035854775808" } */
exit(0);
diff --git a/libffi/testsuite/libffi.call/cls_ushort.c b/libffi/testsuite/libffi.call/cls_ushort.c
index 81f984862a3..a00100e07f8 100644
--- a/libffi/testsuite/libffi.call/cls_ushort.c
+++ b/libffi/testsuite/libffi.call/cls_ushort.c
@@ -20,19 +20,11 @@ typedef unsigned short (*cls_ret_ushort)(unsigned short);
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
ffi_type * cl_arg_types[2];
unsigned short res;
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cl_arg_types[0] = &ffi_type_ushort;
cl_arg_types[1] = NULL;
@@ -40,9 +32,9 @@ int main (void)
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
&ffi_type_ushort, cl_arg_types) == FFI_OK);
- CHECK(ffi_prep_closure(pcl, &cif, cls_ret_ushort_fn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_ushort_fn, NULL, code) == FFI_OK);
- res = (*((cls_ret_ushort)pcl))(65535);
+ res = (*((cls_ret_ushort)code))(65535);
/* { dg-output "65535: 65535" } */
printf("res: %d\n",res);
/* { dg-output "\nres: 65535" } */
diff --git a/libffi/testsuite/libffi.call/err_bad_abi.c b/libffi/testsuite/libffi.call/err_bad_abi.c
new file mode 100644
index 00000000000..a21a3fddd04
--- /dev/null
+++ b/libffi/testsuite/libffi.call/err_bad_abi.c
@@ -0,0 +1,37 @@
+/* Area: ffi_prep_cif, ffi_prep_closure
+ Purpose: Test error return for bad ABIs.
+ Limitations: none.
+ PR: none.
+ Originator: Blake Chaffin 6/6/2007 */
+
+/* { dg-do run { xfail *-*-* } } */
+#include "ffitest.h"
+
+static void
+dummy_fn(ffi_cif* cif __UNUSED__, void* resp __UNUSED__,
+ void** args __UNUSED__, void* userdata __UNUSED__)
+{}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args[1];
+ ffi_type* arg_types[1];
+
+ arg_types[0] = NULL;
+ args[0] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, 255, 0, &ffi_type_void,
+ arg_types) == FFI_BAD_ABI);
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 0, &ffi_type_void,
+ arg_types) == FFI_OK);
+
+ cif.abi= 255;
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, dummy_fn, NULL, code) == FFI_BAD_ABI);
+
+ exit(0);
+}
diff --git a/libffi/testsuite/libffi.call/err_bad_typedef.c b/libffi/testsuite/libffi.call/err_bad_typedef.c
new file mode 100644
index 00000000000..bd2fc54a0e8
--- /dev/null
+++ b/libffi/testsuite/libffi.call/err_bad_typedef.c
@@ -0,0 +1,25 @@
+/* Area: ffi_prep_cif
+ Purpose: Test error return for bad typedefs.
+ Limitations: none.
+ PR: none.
+ Originator: Blake Chaffin 6/6/2007 */
+
+/* { dg-do run { xfail *-*-* } } */
+#include "ffitest.h"
+
+int main (void)
+{
+ ffi_cif cif;
+ ffi_type* arg_types[1];
+
+ arg_types[0] = NULL;
+
+ ffi_type badType = ffi_type_void;
+
+ badType.size = 0;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 0, &badType,
+ arg_types) == FFI_BAD_TYPEDEF);
+
+ exit(0);
+}
diff --git a/libffi/testsuite/libffi.call/ffitest.h b/libffi/testsuite/libffi.call/ffitest.h
index e73f758f586..c7cb76cb3b5 100644
--- a/libffi/testsuite/libffi.call/ffitest.h
+++ b/libffi/testsuite/libffi.call/ffitest.h
@@ -2,6 +2,8 @@
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
+#include <stdint.h>
+#include <inttypes.h>
#include <ffi.h>
#include "fficonfig.h"
@@ -43,6 +45,15 @@
#endif
+/* MinGW kludge. */
+#ifdef WIN64
+#define PRIdLL "PRId64"
+#define PRIuLL "PRIu64"
+#else
+#define PRIdLL "lld"
+#define PRIuLL "llu"
+#endif
+
#ifdef USING_MMAP
static inline void *
allocate_mmap (size_t size)
diff --git a/libffi/testsuite/libffi.call/float2.c b/libffi/testsuite/libffi.call/float2.c
index fa9dd311d69..a0b296cf4b9 100644
--- a/libffi/testsuite/libffi.call/float2.c
+++ b/libffi/testsuite/libffi.call/float2.c
@@ -4,7 +4,8 @@
PR: none.
Originator: From the original ffitest.c */
-/* { dg-do run } */
+/* { dg-excess-errors "fails" { target x86_64-*-mingw* x86_64-*-cygwin* } } */
+/* { dg-do run { xfail x86_64-*-mingw* x86_64-*-cygwin* } } */
#include "ffitest.h"
#include "float.h"
diff --git a/libffi/testsuite/libffi.call/nested_struct.c b/libffi/testsuite/libffi.call/nested_struct.c
index adce7ba434f..8aa527ede4e 100644
--- a/libffi/testsuite/libffi.call/nested_struct.c
+++ b/libffi/testsuite/libffi.call/nested_struct.c
@@ -68,10 +68,8 @@ cls_struct_combined_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[5];
ffi_type* cls_struct_fields1[5];
@@ -79,12 +77,6 @@ int main (void)
ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2;
ffi_type* dbl_arg_types[5];
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -143,12 +135,12 @@ int main (void)
CHECK( res_dbl.e.dd == (e_dbl.a + f_dbl.dd + g_dbl.e.dd));
CHECK( res_dbl.e.ff == (e_dbl.b + f_dbl.ff + g_dbl.e.ff));
- CHECK(ffi_prep_closure(pcl, &cif, cls_struct_combined_gn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_combined_gn, NULL, code) == FFI_OK);
res_dbl = ((cls_struct_combined(*)(cls_struct_16byte1,
cls_struct_16byte2,
cls_struct_combined))
- (pcl))(e_dbl, f_dbl, g_dbl);
+ (code))(e_dbl, f_dbl, g_dbl);
/* { dg-output "\n9 2 6 1 2 3 4 5 6 3 1 8: 15 10 13 10 12 13" } */
CHECK( res_dbl.d.a == (e_dbl.a + f_dbl.dd + g_dbl.d.a));
CHECK( res_dbl.d.b == (e_dbl.b + f_dbl.ff + g_dbl.d.b));
diff --git a/libffi/testsuite/libffi.call/nested_struct1.c b/libffi/testsuite/libffi.call/nested_struct1.c
index f7fe72e5902..2a9f515cded 100644
--- a/libffi/testsuite/libffi.call/nested_struct1.c
+++ b/libffi/testsuite/libffi.call/nested_struct1.c
@@ -72,10 +72,8 @@ cls_struct_combined_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[5];
ffi_type* cls_struct_fields[5];
ffi_type* cls_struct_fields1[5];
@@ -83,12 +81,6 @@ int main (void)
ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2;
ffi_type* dbl_arg_types[5];
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -150,13 +142,13 @@ int main (void)
CHECK( res_dbl.e.dd == (e_dbl.a + f_dbl.dd + g_dbl.e.dd));
CHECK( res_dbl.e.ff == (e_dbl.b + f_dbl.ff + g_dbl.e.ff));
- CHECK(ffi_prep_closure(pcl, &cif, cls_struct_combined_gn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_combined_gn, NULL, code) == FFI_OK);
res_dbl = ((cls_struct_combined(*)(cls_struct_16byte1,
cls_struct_16byte2,
cls_struct_combined,
cls_struct_16byte1))
- (pcl))(e_dbl, f_dbl, g_dbl, h_dbl);
+ (code))(e_dbl, f_dbl, g_dbl, h_dbl);
/* { dg-output "\n9 2 6 1 2 3 4 5 6 3 1 8 3 2 4: 15 10 13 10 12 13" } */
CHECK( res_dbl.d.a == (e_dbl.a + f_dbl.dd + g_dbl.d.a));
CHECK( res_dbl.d.b == (e_dbl.b + f_dbl.ff + g_dbl.d.b));
diff --git a/libffi/testsuite/libffi.call/nested_struct10.c b/libffi/testsuite/libffi.call/nested_struct10.c
index 8d9aba2acdc..d6a718bdd01 100644
--- a/libffi/testsuite/libffi.call/nested_struct10.c
+++ b/libffi/testsuite/libffi.call/nested_struct10.c
@@ -58,10 +58,8 @@ B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[4];
ffi_type* cls_struct_fields[3];
ffi_type* cls_struct_fields1[4];
@@ -69,12 +67,6 @@ int main (void)
ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2;
ffi_type* dbl_arg_types[4];
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -129,9 +121,9 @@ int main (void)
CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e));
CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e));
- CHECK(ffi_prep_closure(pcl, &cif, B_gn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK);
- res_dbl = ((B(*)(A, B, C))(pcl))(e_dbl, f_dbl, g_dbl);
+ res_dbl = ((B(*)(A, B, C))(code))(e_dbl, f_dbl, g_dbl);
/* { dg-output "\n1 7 12 127 99 255 2 9: 270 242 143" } */
CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + f_dbl.z + g_dbl.d));
CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e));
diff --git a/libffi/testsuite/libffi.call/nested_struct2.c b/libffi/testsuite/libffi.call/nested_struct2.c
index 821fcc40f6b..de1584c18a1 100644
--- a/libffi/testsuite/libffi.call/nested_struct2.c
+++ b/libffi/testsuite/libffi.call/nested_struct2.c
@@ -49,22 +49,14 @@ B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[3];
ffi_type* cls_struct_fields[3];
ffi_type* cls_struct_fields1[3];
ffi_type cls_struct_type, cls_struct_type1;
ffi_type* dbl_arg_types[3];
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -106,9 +98,9 @@ int main (void)
CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b));
- CHECK(ffi_prep_closure(pcl, &cif, B_gn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK);
- res_dbl = ((B(*)(A, B))(pcl))(e_dbl, f_dbl);
+ res_dbl = ((B(*)(A, B))(code))(e_dbl, f_dbl);
/* { dg-output "\n1 7 12 127 99: 13 233 134" } */
CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a));
CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
diff --git a/libffi/testsuite/libffi.call/nested_struct3.c b/libffi/testsuite/libffi.call/nested_struct3.c
index f11aff49b94..58aa85362e8 100644
--- a/libffi/testsuite/libffi.call/nested_struct3.c
+++ b/libffi/testsuite/libffi.call/nested_struct3.c
@@ -50,22 +50,14 @@ B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[3];
ffi_type* cls_struct_fields[3];
ffi_type* cls_struct_fields1[3];
ffi_type cls_struct_type, cls_struct_type1;
ffi_type* dbl_arg_types[3];
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -108,9 +100,9 @@ int main (void)
CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b));
- CHECK(ffi_prep_closure(pcl, &cif, B_gn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK);
- res_dbl = ((B(*)(A, B))(pcl))(e_dbl, f_dbl);
+ res_dbl = ((B(*)(A, B))(code))(e_dbl, f_dbl);
/* { dg-output "\n1 7 12 127 99: 13 233 134" } */
CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a));
CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
diff --git a/libffi/testsuite/libffi.call/nested_struct4.c b/libffi/testsuite/libffi.call/nested_struct4.c
index 0553ce88166..98e491e65cf 100644
--- a/libffi/testsuite/libffi.call/nested_struct4.c
+++ b/libffi/testsuite/libffi.call/nested_struct4.c
@@ -50,22 +50,14 @@ B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[3];
ffi_type* cls_struct_fields[3];
ffi_type* cls_struct_fields1[3];
ffi_type cls_struct_type, cls_struct_type1;
ffi_type* dbl_arg_types[3];
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -107,9 +99,9 @@ int main (void)
CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b));
- CHECK(ffi_prep_closure(pcl, &cif, B_gn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK);
- res_dbl = ((B(*)(A, B))(pcl))(e_dbl, f_dbl);
+ res_dbl = ((B(*)(A, B))(code))(e_dbl, f_dbl);
/* { dg-output "\n1 7 12 127 99: 13 233 134" } */
CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a));
CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
diff --git a/libffi/testsuite/libffi.call/nested_struct5.c b/libffi/testsuite/libffi.call/nested_struct5.c
index a77931b59b8..d8e3537d5a0 100644
--- a/libffi/testsuite/libffi.call/nested_struct5.c
+++ b/libffi/testsuite/libffi.call/nested_struct5.c
@@ -50,22 +50,14 @@ B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[3];
ffi_type* cls_struct_fields[3];
ffi_type* cls_struct_fields1[3];
ffi_type cls_struct_type, cls_struct_type1;
ffi_type* dbl_arg_types[3];
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -108,9 +100,9 @@ int main (void)
CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b));
- CHECK(ffi_prep_closure(pcl, &cif, B_gn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK);
- res_dbl = ((B(*)(A, B))(pcl))(e_dbl, f_dbl);
+ res_dbl = ((B(*)(A, B))(code))(e_dbl, f_dbl);
/* { dg-output "\n1 7 12 127 99: 13 233 134" } */
CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a));
CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
diff --git a/libffi/testsuite/libffi.call/nested_struct6.c b/libffi/testsuite/libffi.call/nested_struct6.c
index af2821c769f..2f2b25a15db 100644
--- a/libffi/testsuite/libffi.call/nested_struct6.c
+++ b/libffi/testsuite/libffi.call/nested_struct6.c
@@ -57,10 +57,8 @@ B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[4];
ffi_type* cls_struct_fields[3];
ffi_type* cls_struct_fields1[3];
@@ -68,12 +66,6 @@ int main (void)
ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2;
ffi_type* dbl_arg_types[4];
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -127,9 +119,9 @@ int main (void)
CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e));
CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e));
- CHECK(ffi_prep_closure(pcl, &cif, B_gn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK);
- res_dbl = ((B(*)(A, B, C))(pcl))(e_dbl, f_dbl, g_dbl);
+ res_dbl = ((B(*)(A, B, C))(code))(e_dbl, f_dbl, g_dbl);
/* { dg-output "\n1 7 12 127 99 2 9: 15 242 143" } */
CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + g_dbl.d));
CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e));
diff --git a/libffi/testsuite/libffi.call/nested_struct7.c b/libffi/testsuite/libffi.call/nested_struct7.c
index c7dd4f7347e..14c70239eb2 100644
--- a/libffi/testsuite/libffi.call/nested_struct7.c
+++ b/libffi/testsuite/libffi.call/nested_struct7.c
@@ -50,22 +50,14 @@ B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[3];
ffi_type* cls_struct_fields[3];
ffi_type* cls_struct_fields1[3];
ffi_type cls_struct_type, cls_struct_type1;
ffi_type* dbl_arg_types[3];
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -107,9 +99,9 @@ int main (void)
CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b));
- CHECK(ffi_prep_closure(pcl, &cif, B_gn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK);
- res_dbl = ((B(*)(A, B))(pcl))(e_dbl, f_dbl);
+ res_dbl = ((B(*)(A, B))(code))(e_dbl, f_dbl);
/* { dg-output "\n1 7 12 127 99: 13 233 134" } */
CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a));
CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y));
diff --git a/libffi/testsuite/libffi.call/nested_struct8.c b/libffi/testsuite/libffi.call/nested_struct8.c
index 775ff70fdaf..bb77ead8d32 100644
--- a/libffi/testsuite/libffi.call/nested_struct8.c
+++ b/libffi/testsuite/libffi.call/nested_struct8.c
@@ -57,10 +57,8 @@ B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[4];
ffi_type* cls_struct_fields[3];
ffi_type* cls_struct_fields1[3];
@@ -68,12 +66,6 @@ int main (void)
ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2;
ffi_type* dbl_arg_types[4];
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -127,9 +119,9 @@ int main (void)
CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e));
CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e));
- CHECK(ffi_prep_closure(pcl, &cif, B_gn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK);
- res_dbl = ((B(*)(A, B, C))(pcl))(e_dbl, f_dbl, g_dbl);
+ res_dbl = ((B(*)(A, B, C))(code))(e_dbl, f_dbl, g_dbl);
/* { dg-output "\n1 7 12 127 99 2 9: 15 242 143" } */
CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + g_dbl.d));
CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e));
diff --git a/libffi/testsuite/libffi.call/nested_struct9.c b/libffi/testsuite/libffi.call/nested_struct9.c
index 70332de890b..e9f541c83a8 100644
--- a/libffi/testsuite/libffi.call/nested_struct9.c
+++ b/libffi/testsuite/libffi.call/nested_struct9.c
@@ -57,10 +57,8 @@ B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args_dbl[4];
ffi_type* cls_struct_fields[3];
ffi_type* cls_struct_fields1[3];
@@ -68,12 +66,6 @@ int main (void)
ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2;
ffi_type* dbl_arg_types[4];
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
cls_struct_type.size = 0;
cls_struct_type.alignment = 0;
cls_struct_type.type = FFI_TYPE_STRUCT;
@@ -127,9 +119,9 @@ int main (void)
CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e));
CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e));
- CHECK(ffi_prep_closure(pcl, &cif, B_gn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, B_gn, NULL, code) == FFI_OK);
- res_dbl = ((B(*)(A, B, C))(pcl))(e_dbl, f_dbl, g_dbl);
+ res_dbl = ((B(*)(A, B, C))(code))(e_dbl, f_dbl, g_dbl);
/* { dg-output "\n1 7 12 127 99 2 9: 15 242 143" } */
CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + g_dbl.d));
CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e));
diff --git a/libffi/testsuite/libffi.call/problem1.c b/libffi/testsuite/libffi.call/problem1.c
index ca70cc8d773..6a91555a1fa 100644
--- a/libffi/testsuite/libffi.call/problem1.c
+++ b/libffi/testsuite/libffi.call/problem1.c
@@ -45,19 +45,11 @@ int main(void)
ffi_type* my_ffi_struct_fields[4];
ffi_type my_ffi_struct_type;
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
void* args[4];
ffi_type* arg_types[3];
-#ifdef USING_MMAP
- pcl = allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
-
struct my_ffi_struct g = { 1.0, 2.0, 3.0 };
struct my_ffi_struct f = { 1.0, 2.0, 3.0 };
struct my_ffi_struct res;
@@ -87,9 +79,9 @@ int main(void)
printf("res: %g %g %g\n", res.a, res.b, res.c);
/* { dg-output "\nres: 2 4 6" } */
- CHECK(ffi_prep_closure(pcl, &cif, stub, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, stub, NULL, code) == FFI_OK);
- res = ((my_ffi_struct(*)(struct my_ffi_struct, struct my_ffi_struct))(pcl))(g, f);
+ res = ((my_ffi_struct(*)(struct my_ffi_struct, struct my_ffi_struct))(code))(g, f);
/* { dg-output "\n1 2 3 1 2 3: 2 4 6" } */
printf("res: %g %g %g\n", res.a, res.b, res.c);
/* { dg-output "\nres: 2 4 6" } */
diff --git a/libffi/testsuite/libffi.call/return_ldl.c b/libffi/testsuite/libffi.call/return_ldl.c
index 413bf94a67d..5c2fe65aece 100644
--- a/libffi/testsuite/libffi.call/return_ldl.c
+++ b/libffi/testsuite/libffi.call/return_ldl.c
@@ -4,7 +4,7 @@
PR: none.
Originator: <andreast@gcc.gnu.org> 20071113 */
-/* { dg-do run } */
+/* { dg-do run { xfail x86_64-*-mingw* x86_64-*-cygwin* } } */
#include "ffitest.h"
static long double return_ldl(long double ldl)
diff --git a/libffi/testsuite/libffi.call/return_ll1.c b/libffi/testsuite/libffi.call/return_ll1.c
index 5681d84b407..dad90c17ff3 100644
--- a/libffi/testsuite/libffi.call/return_ll1.c
+++ b/libffi/testsuite/libffi.call/return_ll1.c
@@ -36,7 +36,7 @@ int main (void)
ll2 = 11111111;
ffi_call(&cif, FFI_FN(return_ll), &rlonglong, values);
- printf("res: %lld, %lld\n", rlonglong, ll0 + ll1 + ll2);
+ printf("res: %" PRIdLL ", %" PRIdLL "\n", rlonglong, ll0 + ll1 + ll2);
/* { dg-output "res: 11111133333222, 11111133333222" } */
exit(0);
}
diff --git a/libffi/testsuite/libffi.call/stret_large.c b/libffi/testsuite/libffi.call/stret_large.c
new file mode 100644
index 00000000000..12819cf467d
--- /dev/null
+++ b/libffi/testsuite/libffi.call/stret_large.c
@@ -0,0 +1,145 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure returning with different structure size.
+ Depending on the ABI. Check bigger struct which overlaps
+ the gp and fp register count on Darwin/AIX/ppc64.
+ Limitations: none.
+ PR: none.
+ Originator: Blake Chaffin 6/21/2007 */
+
+/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */
+#include "ffitest.h"
+
+// 13 FPRs: 104 bytes
+// 14 FPRs: 112 bytes
+
+typedef struct struct_108byte {
+ double a;
+ double b;
+ double c;
+ double d;
+ double e;
+ double f;
+ double g;
+ double h;
+ double i;
+ double j;
+ double k;
+ double l;
+ double m;
+ int n;
+} struct_108byte;
+
+struct_108byte cls_struct_108byte_fn(
+ struct_108byte b0,
+ struct_108byte b1,
+ struct_108byte b2,
+ struct_108byte b3)
+{
+ struct_108byte result;
+
+ result.a = b0.a + b1.a + b2.a + b3.a;
+ result.b = b0.b + b1.b + b2.b + b3.b;
+ result.c = b0.c + b1.c + b2.c + b3.c;
+ result.d = b0.d + b1.d + b2.d + b3.d;
+ result.e = b0.e + b1.e + b2.e + b3.e;
+ result.f = b0.f + b1.f + b2.f + b3.f;
+ result.g = b0.g + b1.g + b2.g + b3.g;
+ result.h = b0.h + b1.h + b2.h + b3.h;
+ result.i = b0.i + b1.i + b2.i + b3.i;
+ result.j = b0.j + b1.j + b2.j + b3.j;
+ result.k = b0.k + b1.k + b2.k + b3.k;
+ result.l = b0.l + b1.l + b2.l + b3.l;
+ result.m = b0.m + b1.m + b2.m + b3.m;
+ result.n = b0.n + b1.n + b2.n + b3.n;
+
+ printf("%g %g %g %g %g %g %g %g %g %g %g %g %g %d\n", result.a, result.b, result.c,
+ result.d, result.e, result.f, result.g, result.h, result.i,
+ result.j, result.k, result.l, result.m, result.n);
+
+ return result;
+}
+
+static void
+cls_struct_108byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata __UNUSED__)
+{
+ struct_108byte b0, b1, b2, b3;
+
+ b0 = *(struct_108byte*)(args[0]);
+ b1 = *(struct_108byte*)(args[1]);
+ b2 = *(struct_108byte*)(args[2]);
+ b3 = *(struct_108byte*)(args[3]);
+
+ *(struct_108byte*)resp = cls_struct_108byte_fn(b0, b1, b2, b3);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[15];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ struct_108byte e_dbl = { 9.0, 2.0, 6.0, 5.0, 3.0, 4.0, 8.0, 1.0, 1.0, 2.0, 3.0, 7.0, 2.0, 7 };
+ struct_108byte f_dbl = { 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 6.0, 7.0, 4.0, 5.0, 7.0, 9.0, 1.0, 4 };
+ struct_108byte g_dbl = { 4.0, 5.0, 7.0, 9.0, 1.0, 1.0, 2.0, 9.0, 8.0, 6.0, 1.0, 4.0, 0.0, 3 };
+ struct_108byte h_dbl = { 8.0, 6.0, 1.0, 4.0, 0.0, 3.0, 3.0, 1.0, 9.0, 2.0, 6.0, 5.0, 3.0, 2 };
+ struct_108byte res_dbl;
+
+ cls_struct_fields[0] = &ffi_type_double;
+ cls_struct_fields[1] = &ffi_type_double;
+ cls_struct_fields[2] = &ffi_type_double;
+ cls_struct_fields[3] = &ffi_type_double;
+ cls_struct_fields[4] = &ffi_type_double;
+ cls_struct_fields[5] = &ffi_type_double;
+ cls_struct_fields[6] = &ffi_type_double;
+ cls_struct_fields[7] = &ffi_type_double;
+ cls_struct_fields[8] = &ffi_type_double;
+ cls_struct_fields[9] = &ffi_type_double;
+ cls_struct_fields[10] = &ffi_type_double;
+ cls_struct_fields[11] = &ffi_type_double;
+ cls_struct_fields[12] = &ffi_type_double;
+ cls_struct_fields[13] = &ffi_type_sint32;
+ cls_struct_fields[14] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = &cls_struct_type;
+ dbl_arg_types[3] = &cls_struct_type;
+ dbl_arg_types[4] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &e_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = &g_dbl;
+ args_dbl[3] = &h_dbl;
+ args_dbl[4] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_108byte_fn), &res_dbl, args_dbl);
+ /* { dg-output "22 15 17 25 6 13 19 18 22 15 17 25 6 16" } */
+ printf("res: %g %g %g %g %g %g %g %g %g %g %g %g %g %d\n", res_dbl.a, res_dbl.b,
+ res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i,
+ res_dbl.j, res_dbl.k, res_dbl.l, res_dbl.m, res_dbl.n);
+ /* { dg-output "\nres: 22 15 17 25 6 13 19 18 22 15 17 25 6 16" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_108byte_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((struct_108byte(*)(struct_108byte, struct_108byte,
+ struct_108byte, struct_108byte))(code))(e_dbl, f_dbl, g_dbl, h_dbl);
+ /* { dg-output "\n22 15 17 25 6 13 19 18 22 15 17 25 6 16" } */
+ printf("res: %g %g %g %g %g %g %g %g %g %g %g %g %g %d\n", res_dbl.a, res_dbl.b,
+ res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i,
+ res_dbl.j, res_dbl.k, res_dbl.l, res_dbl.m, res_dbl.n);
+ /* { dg-output "\nres: 22 15 17 25 6 13 19 18 22 15 17 25 6 16" } */
+
+ exit(0);
+}
diff --git a/libffi/testsuite/libffi.call/stret_large2.c b/libffi/testsuite/libffi.call/stret_large2.c
new file mode 100644
index 00000000000..e63bb67923a
--- /dev/null
+++ b/libffi/testsuite/libffi.call/stret_large2.c
@@ -0,0 +1,148 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure returning with different structure size.
+ Depending on the ABI. Check bigger struct which overlaps
+ the gp and fp register count on Darwin/AIX/ppc64.
+ Limitations: none.
+ PR: none.
+ Originator: Blake Chaffin 6/21/2007 */
+
+/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */
+#include "ffitest.h"
+
+// 13 FPRs: 104 bytes
+// 14 FPRs: 112 bytes
+
+typedef struct struct_116byte {
+ double a;
+ double b;
+ double c;
+ double d;
+ double e;
+ double f;
+ double g;
+ double h;
+ double i;
+ double j;
+ double k;
+ double l;
+ double m;
+ double n;
+ int o;
+} struct_116byte;
+
+struct_116byte cls_struct_116byte_fn(
+ struct_116byte b0,
+ struct_116byte b1,
+ struct_116byte b2,
+ struct_116byte b3)
+{
+ struct_116byte result;
+
+ result.a = b0.a + b1.a + b2.a + b3.a;
+ result.b = b0.b + b1.b + b2.b + b3.b;
+ result.c = b0.c + b1.c + b2.c + b3.c;
+ result.d = b0.d + b1.d + b2.d + b3.d;
+ result.e = b0.e + b1.e + b2.e + b3.e;
+ result.f = b0.f + b1.f + b2.f + b3.f;
+ result.g = b0.g + b1.g + b2.g + b3.g;
+ result.h = b0.h + b1.h + b2.h + b3.h;
+ result.i = b0.i + b1.i + b2.i + b3.i;
+ result.j = b0.j + b1.j + b2.j + b3.j;
+ result.k = b0.k + b1.k + b2.k + b3.k;
+ result.l = b0.l + b1.l + b2.l + b3.l;
+ result.m = b0.m + b1.m + b2.m + b3.m;
+ result.n = b0.n + b1.n + b2.n + b3.n;
+ result.o = b0.o + b1.o + b2.o + b3.o;
+
+ printf("%g %g %g %g %g %g %g %g %g %g %g %g %g %g %d\n", result.a, result.b, result.c,
+ result.d, result.e, result.f, result.g, result.h, result.i,
+ result.j, result.k, result.l, result.m, result.n, result.o);
+
+ return result;
+}
+
+static void
+cls_struct_116byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata __UNUSED__)
+{
+ struct_116byte b0, b1, b2, b3;
+
+ b0 = *(struct_116byte*)(args[0]);
+ b1 = *(struct_116byte*)(args[1]);
+ b2 = *(struct_116byte*)(args[2]);
+ b3 = *(struct_116byte*)(args[3]);
+
+ *(struct_116byte*)resp = cls_struct_116byte_fn(b0, b1, b2, b3);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[16];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ struct_116byte e_dbl = { 9.0, 2.0, 6.0, 5.0, 3.0, 4.0, 8.0, 1.0, 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 7 };
+ struct_116byte f_dbl = { 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 6.0, 7.0, 4.0, 5.0, 7.0, 9.0, 1.0, 6.0, 4 };
+ struct_116byte g_dbl = { 4.0, 5.0, 7.0, 9.0, 1.0, 1.0, 2.0, 9.0, 8.0, 6.0, 1.0, 4.0, 0.0, 7.0, 3 };
+ struct_116byte h_dbl = { 8.0, 6.0, 1.0, 4.0, 0.0, 3.0, 3.0, 1.0, 9.0, 2.0, 6.0, 5.0, 3.0, 8.0, 2 };
+ struct_116byte res_dbl;
+
+ cls_struct_fields[0] = &ffi_type_double;
+ cls_struct_fields[1] = &ffi_type_double;
+ cls_struct_fields[2] = &ffi_type_double;
+ cls_struct_fields[3] = &ffi_type_double;
+ cls_struct_fields[4] = &ffi_type_double;
+ cls_struct_fields[5] = &ffi_type_double;
+ cls_struct_fields[6] = &ffi_type_double;
+ cls_struct_fields[7] = &ffi_type_double;
+ cls_struct_fields[8] = &ffi_type_double;
+ cls_struct_fields[9] = &ffi_type_double;
+ cls_struct_fields[10] = &ffi_type_double;
+ cls_struct_fields[11] = &ffi_type_double;
+ cls_struct_fields[12] = &ffi_type_double;
+ cls_struct_fields[13] = &ffi_type_double;
+ cls_struct_fields[14] = &ffi_type_sint32;
+ cls_struct_fields[15] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = &cls_struct_type;
+ dbl_arg_types[3] = &cls_struct_type;
+ dbl_arg_types[4] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &e_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = &g_dbl;
+ args_dbl[3] = &h_dbl;
+ args_dbl[4] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_116byte_fn), &res_dbl, args_dbl);
+ /* { dg-output "22 15 17 25 6 13 19 18 22 15 17 25 6 26 16" } */
+ printf("res: %g %g %g %g %g %g %g %g %g %g %g %g %g %g %d\n", res_dbl.a, res_dbl.b,
+ res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i,
+ res_dbl.j, res_dbl.k, res_dbl.l, res_dbl.m, res_dbl.n, res_dbl.o);
+ /* { dg-output "\nres: 22 15 17 25 6 13 19 18 22 15 17 25 6 26 16" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_116byte_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((struct_116byte(*)(struct_116byte, struct_116byte,
+ struct_116byte, struct_116byte))(code))(e_dbl, f_dbl, g_dbl, h_dbl);
+ /* { dg-output "\n22 15 17 25 6 13 19 18 22 15 17 25 6 26 16" } */
+ printf("res: %g %g %g %g %g %g %g %g %g %g %g %g %g %g %d\n", res_dbl.a, res_dbl.b,
+ res_dbl.c, res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i,
+ res_dbl.j, res_dbl.k, res_dbl.l, res_dbl.m, res_dbl.n, res_dbl.o);
+ /* { dg-output "\nres: 22 15 17 25 6 13 19 18 22 15 17 25 6 26 16" } */
+
+ exit(0);
+}
diff --git a/libffi/testsuite/libffi.call/stret_medium.c b/libffi/testsuite/libffi.call/stret_medium.c
new file mode 100644
index 00000000000..13c4464ffac
--- /dev/null
+++ b/libffi/testsuite/libffi.call/stret_medium.c
@@ -0,0 +1,124 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure returning with different structure size.
+ Depending on the ABI. Check bigger struct which overlaps
+ the gp and fp register count on Darwin/AIX/ppc64.
+ Limitations: none.
+ PR: none.
+ Originator: Blake Chaffin 6/21/2007 */
+
+/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */
+#include "ffitest.h"
+
+typedef struct struct_72byte {
+ double a;
+ double b;
+ double c;
+ double d;
+ double e;
+ double f;
+ double g;
+ double h;
+ double i;
+} struct_72byte;
+
+struct_72byte cls_struct_72byte_fn(
+ struct_72byte b0,
+ struct_72byte b1,
+ struct_72byte b2,
+ struct_72byte b3)
+{
+ struct_72byte result;
+
+ result.a = b0.a + b1.a + b2.a + b3.a;
+ result.b = b0.b + b1.b + b2.b + b3.b;
+ result.c = b0.c + b1.c + b2.c + b3.c;
+ result.d = b0.d + b1.d + b2.d + b3.d;
+ result.e = b0.e + b1.e + b2.e + b3.e;
+ result.f = b0.f + b1.f + b2.f + b3.f;
+ result.g = b0.g + b1.g + b2.g + b3.g;
+ result.h = b0.h + b1.h + b2.h + b3.h;
+ result.i = b0.i + b1.i + b2.i + b3.i;
+
+ printf("%g %g %g %g %g %g %g %g %g\n", result.a, result.b, result.c,
+ result.d, result.e, result.f, result.g, result.h, result.i);
+
+ return result;
+}
+
+static void
+cls_struct_72byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata __UNUSED__)
+{
+ struct_72byte b0, b1, b2, b3;
+
+ b0 = *(struct_72byte*)(args[0]);
+ b1 = *(struct_72byte*)(args[1]);
+ b2 = *(struct_72byte*)(args[2]);
+ b3 = *(struct_72byte*)(args[3]);
+
+ *(struct_72byte*)resp = cls_struct_72byte_fn(b0, b1, b2, b3);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[10];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ struct_72byte e_dbl = { 9.0, 2.0, 6.0, 5.0, 3.0, 4.0, 8.0, 1.0, 7.0 };
+ struct_72byte f_dbl = { 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 6.0, 7.0, 4.0 };
+ struct_72byte g_dbl = { 4.0, 5.0, 7.0, 9.0, 1.0, 1.0, 2.0, 9.0, 3.0 };
+ struct_72byte h_dbl = { 8.0, 6.0, 1.0, 4.0, 0.0, 3.0, 3.0, 1.0, 2.0 };
+ struct_72byte res_dbl;
+
+ cls_struct_fields[0] = &ffi_type_double;
+ cls_struct_fields[1] = &ffi_type_double;
+ cls_struct_fields[2] = &ffi_type_double;
+ cls_struct_fields[3] = &ffi_type_double;
+ cls_struct_fields[4] = &ffi_type_double;
+ cls_struct_fields[5] = &ffi_type_double;
+ cls_struct_fields[6] = &ffi_type_double;
+ cls_struct_fields[7] = &ffi_type_double;
+ cls_struct_fields[8] = &ffi_type_double;
+ cls_struct_fields[9] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = &cls_struct_type;
+ dbl_arg_types[3] = &cls_struct_type;
+ dbl_arg_types[4] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &e_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = &g_dbl;
+ args_dbl[3] = &h_dbl;
+ args_dbl[4] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_72byte_fn), &res_dbl, args_dbl);
+ /* { dg-output "22 15 17 25 6 13 19 18 16" } */
+ printf("res: %g %g %g %g %g %g %g %g %g\n", res_dbl.a, res_dbl.b, res_dbl.c,
+ res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i);
+ /* { dg-output "\nres: 22 15 17 25 6 13 19 18 16" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_72byte_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((struct_72byte(*)(struct_72byte, struct_72byte,
+ struct_72byte, struct_72byte))(code))(e_dbl, f_dbl, g_dbl, h_dbl);
+ /* { dg-output "\n22 15 17 25 6 13 19 18 16" } */
+ printf("res: %g %g %g %g %g %g %g %g %g\n", res_dbl.a, res_dbl.b, res_dbl.c,
+ res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i);
+ /* { dg-output "\nres: 22 15 17 25 6 13 19 18 16" } */
+
+ exit(0);
+}
diff --git a/libffi/testsuite/libffi.call/stret_medium2.c b/libffi/testsuite/libffi.call/stret_medium2.c
new file mode 100644
index 00000000000..a012f9e6813
--- /dev/null
+++ b/libffi/testsuite/libffi.call/stret_medium2.c
@@ -0,0 +1,124 @@
+/* Area: ffi_call, closure_call
+ Purpose: Check structure returning with different structure size.
+ Depending on the ABI. Check bigger struct which overlaps
+ the gp and fp register count on Darwin/AIX/ppc64.
+ Limitations: none.
+ PR: none.
+ Originator: Blake Chaffin 6/21/2007 */
+
+/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */
+#include "ffitest.h"
+
+typedef struct struct_72byte {
+ double a;
+ double b;
+ double c;
+ double d;
+ double e;
+ double f;
+ double g;
+ double h;
+ long long i;
+} struct_72byte;
+
+struct_72byte cls_struct_72byte_fn(
+ struct_72byte b0,
+ struct_72byte b1,
+ struct_72byte b2,
+ struct_72byte b3)
+{
+ struct_72byte result;
+
+ result.a = b0.a + b1.a + b2.a + b3.a;
+ result.b = b0.b + b1.b + b2.b + b3.b;
+ result.c = b0.c + b1.c + b2.c + b3.c;
+ result.d = b0.d + b1.d + b2.d + b3.d;
+ result.e = b0.e + b1.e + b2.e + b3.e;
+ result.f = b0.f + b1.f + b2.f + b3.f;
+ result.g = b0.g + b1.g + b2.g + b3.g;
+ result.h = b0.h + b1.h + b2.h + b3.h;
+ result.i = b0.i + b1.i + b2.i + b3.i;
+
+ printf("%g %g %g %g %g %g %g %g %" PRIdLL "\n", result.a, result.b, result.c,
+ result.d, result.e, result.f, result.g, result.h, result.i);
+
+ return result;
+}
+
+static void
+cls_struct_72byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, void* userdata __UNUSED__)
+{
+ struct_72byte b0, b1, b2, b3;
+
+ b0 = *(struct_72byte*)(args[0]);
+ b1 = *(struct_72byte*)(args[1]);
+ b2 = *(struct_72byte*)(args[2]);
+ b3 = *(struct_72byte*)(args[3]);
+
+ *(struct_72byte*)resp = cls_struct_72byte_fn(b0, b1, b2, b3);
+}
+
+int main (void)
+{
+ ffi_cif cif;
+ void *code;
+ ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
+ void* args_dbl[5];
+ ffi_type* cls_struct_fields[10];
+ ffi_type cls_struct_type;
+ ffi_type* dbl_arg_types[5];
+
+ cls_struct_type.size = 0;
+ cls_struct_type.alignment = 0;
+ cls_struct_type.type = FFI_TYPE_STRUCT;
+ cls_struct_type.elements = cls_struct_fields;
+
+ struct_72byte e_dbl = { 9.0, 2.0, 6.0, 5.0, 3.0, 4.0, 8.0, 1.0, 7 };
+ struct_72byte f_dbl = { 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 6.0, 7.0, 4 };
+ struct_72byte g_dbl = { 4.0, 5.0, 7.0, 9.0, 1.0, 1.0, 2.0, 9.0, 3 };
+ struct_72byte h_dbl = { 8.0, 6.0, 1.0, 4.0, 0.0, 3.0, 3.0, 1.0, 2 };
+ struct_72byte res_dbl;
+
+ cls_struct_fields[0] = &ffi_type_double;
+ cls_struct_fields[1] = &ffi_type_double;
+ cls_struct_fields[2] = &ffi_type_double;
+ cls_struct_fields[3] = &ffi_type_double;
+ cls_struct_fields[4] = &ffi_type_double;
+ cls_struct_fields[5] = &ffi_type_double;
+ cls_struct_fields[6] = &ffi_type_double;
+ cls_struct_fields[7] = &ffi_type_double;
+ cls_struct_fields[8] = &ffi_type_sint64;
+ cls_struct_fields[9] = NULL;
+
+ dbl_arg_types[0] = &cls_struct_type;
+ dbl_arg_types[1] = &cls_struct_type;
+ dbl_arg_types[2] = &cls_struct_type;
+ dbl_arg_types[3] = &cls_struct_type;
+ dbl_arg_types[4] = NULL;
+
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &cls_struct_type,
+ dbl_arg_types) == FFI_OK);
+
+ args_dbl[0] = &e_dbl;
+ args_dbl[1] = &f_dbl;
+ args_dbl[2] = &g_dbl;
+ args_dbl[3] = &h_dbl;
+ args_dbl[4] = NULL;
+
+ ffi_call(&cif, FFI_FN(cls_struct_72byte_fn), &res_dbl, args_dbl);
+ /* { dg-output "22 15 17 25 6 13 19 18 16" } */
+ printf("res: %g %g %g %g %g %g %g %g %" PRIdLL "\n", res_dbl.a, res_dbl.b, res_dbl.c,
+ res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i);
+ /* { dg-output "\nres: 22 15 17 25 6 13 19 18 16" } */
+
+ CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_72byte_gn, NULL, code) == FFI_OK);
+
+ res_dbl = ((struct_72byte(*)(struct_72byte, struct_72byte,
+ struct_72byte, struct_72byte))(code))(e_dbl, f_dbl, g_dbl, h_dbl);
+ /* { dg-output "\n22 15 17 25 6 13 19 18 16" } */
+ printf("res: %g %g %g %g %g %g %g %g %" PRIdLL "\n", res_dbl.a, res_dbl.b, res_dbl.c,
+ res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i);
+ /* { dg-output "\nres: 22 15 17 25 6 13 19 18 16" } */
+
+ exit(0);
+}
diff --git a/libffi/testsuite/libffi.special/ffitestcxx.h b/libffi/testsuite/libffi.special/ffitestcxx.h
index b9f0d48761f..92fb6568017 100644
--- a/libffi/testsuite/libffi.special/ffitestcxx.h
+++ b/libffi/testsuite/libffi.special/ffitestcxx.h
@@ -43,6 +43,16 @@
#endif
+
+/* MinGW kludge. */
+#ifdef WIN64
+#define PRIdLL "PRId64"
+#define PRIuLL "PRIu64"
+#else
+#define PRIdLL "lld"
+#define PRIuLL "llu"
+#endif
+
#ifdef USING_MMAP
static inline void *
allocate_mmap (size_t size)
diff --git a/libffi/testsuite/libffi.special/unwindtest.cc b/libffi/testsuite/libffi.special/unwindtest.cc
index a3d803780ab..723871626d1 100644
--- a/libffi/testsuite/libffi.special/unwindtest.cc
+++ b/libffi/testsuite/libffi.special/unwindtest.cc
@@ -6,6 +6,7 @@
/* { dg-do run } */
#include "ffitestcxx.h"
+#include <stdint.h>
void
closure_test_fn(ffi_cif* cif __UNUSED__, void* resp __UNUSED__,
@@ -27,7 +28,7 @@ void closure_test_fn1(ffi_cif* cif __UNUSED__, void* resp,
(int)(*(double*)args[8]) + (int)*(int *)args[9] +
(int)(*(int *)args[10]) + (int)(*(float *)args[11]) +
(int)*(int *)args[12] + (int)(*(int *)args[13]) +
- (int)(*(int *)args[14]) + *(int *)args[15] + (int)(long)userdata;
+ (int)(*(int *)args[14]) + *(int *)args[15] + (int)(intptr_t)userdata;
printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
(int)*(float *)args[0], (int)(*(float *)args[1]),
@@ -38,7 +39,7 @@ void closure_test_fn1(ffi_cif* cif __UNUSED__, void* resp,
(int)(*(int *)args[10]), (int)(*(float *)args[11]),
(int)*(int *)args[12], (int)(*(int *)args[13]),
(int)(*(int *)args[14]), *(int *)args[15],
- (int)(long)userdata, (int)*(ffi_arg*)resp);
+ (int)(intptr_t)userdata, (int)*(ffi_arg*)resp);
throw (int)*(ffi_arg*)resp;
}
@@ -50,27 +51,20 @@ typedef int (*closure_test_type1)(float, float, float, float, signed short,
int main (void)
{
ffi_cif cif;
-#ifndef USING_MMAP
- static ffi_closure cl;
-#endif
- ffi_closure *pcl;
+ void *code;
+ ffi_closure *pcl = (ffi_closure *)ffi_closure_alloc(sizeof(ffi_closure), &code);
ffi_type * cl_arg_types[17];
-#ifdef USING_MMAP
- pcl = (ffi_closure *) allocate_mmap (sizeof(ffi_closure));
-#else
- pcl = &cl;
-#endif
{
cl_arg_types[1] = NULL;
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 0,
&ffi_type_void, cl_arg_types) == FFI_OK);
- CHECK(ffi_prep_closure(pcl, &cif, closure_test_fn, NULL) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn, NULL, code) == FFI_OK);
try
{
- (*((closure_test_type)(pcl)))();
+ (*((closure_test_type)(code)))();
} catch (int exception_code)
{
CHECK(exception_code == 9);
@@ -104,11 +98,11 @@ int main (void)
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
&ffi_type_sint, cl_arg_types) == FFI_OK);
- CHECK(ffi_prep_closure(pcl, &cif, closure_test_fn1,
- (void *) 3 /* userdata */) == FFI_OK);
+ CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn1,
+ (void *) 3 /* userdata */, code) == FFI_OK);
try
{
- (*((closure_test_type1)pcl))
+ (*((closure_test_type1)code))
(1.1, 2.2, 3.3, 4.4, 127, 5.5, 6.6, 8, 9, 10, 11, 12.0, 13,
19, 21, 1);
/* { dg-output "\n1 2 3 4 127 5 6 8 9 10 11 12 13 19 21 1 3: 255" } */
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
index e76b383939e..8ce2a104cce 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -1,3 +1,17 @@
+2009-06-10 Maciej W. Rozycki <macro@linux-mips.org>
+
+ * config.host (vax-*-linux*): New.
+
+2009-05-31 Anthony Green <green@moxielogic.com>
+
+ * config.host: Add moxie support.
+ * config/moxie/t-moxie: New file.
+
+2009-05-29 David Billinghurst <billingd@gcc.gnu.org>
+
+ * config.host: Add i386/${host_address}/t-fprules-softfp and
+ t-softfp to tmake_file for i[34567]86-*-cygwin*.
+
2009-04-17 Aurelien Jarno <aurelien@aurel32.net>
* config.host: Add i386/${host_address}/t-fprules-softfp to
diff --git a/libgcc/config.host b/libgcc/config.host
index 4a1cfb2a295..25879b1bc68 100644
--- a/libgcc/config.host
+++ b/libgcc/config.host
@@ -84,6 +84,8 @@ fido-*-*)
;;
frv*) cpu_type=frv
;;
+moxie*) cpu_type=moxie
+ ;;
i[34567]86-*-*)
cpu_type=i386
;;
@@ -415,6 +417,10 @@ mmix-knuth-mmixware)
;;
mn10300-*-*)
;;
+moxie-*-*)
+ tmake_file=${cpu_type}/t-moxie
+ extra_parts="crtbegin.o crtend.o crti.o crtn.o"
+ ;;
pdp11-*-*)
;;
picochip-*-*)
@@ -528,6 +534,8 @@ v850e-*-*)
;;
v850-*-*)
;;
+vax-*-linux*)
+ ;;
vax-*-netbsdelf*)
;;
vax-*-netbsd*)
@@ -562,7 +570,8 @@ esac
case ${host} in
i[34567]86-*-darwin* | x86_64-*-darwin* | \
i[34567]86-*-kfreebsd*-gnu | x86_64-*-kfreebsd*-gnu | \
- i[34567]86-*-linux* | x86_64-*-linux*)
+ i[34567]86-*-linux* | x86_64-*-linux* | \
+ i[34567]86-*-cygwin*)
if test "${host_address}" = 32; then
tmake_file="${tmake_file} t-softfp i386/${host_address}/t-fprules-softfp"
fi
diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog
index 383527990dd..51065aee4bb 100644
--- a/libgfortran/ChangeLog
+++ b/libgfortran/ChangeLog
@@ -1,3 +1,85 @@
+2009-06-14 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+
+ * fmain.c (main): Don't PREFIX set_args.
+ * libgfortran.h (set_args): Use iexport_proto.
+ * runtime/main.c (set_args): Use iexport.
+
+2009-06-07 Jerry DeLisle <jvdelisle@gcc.gnu.org>
+
+ PR libfortran/40008
+ * libgfortran.h: Define IOPARM_OPEN_HAS_NEWUNIT.
+ * io/open.c (st_open): Don't error on negative unit number if NEWUNIT
+ was specified. If NEWUNIT is specified, call new function to get the
+ unique unit number and assign it.
+ * io/io.h (st_parameter_open): Add pointer to newunit. Add prototype for
+ next_available_newunit. Add prototype for new function,
+ get_unique_unit_number.
+ * io/unit.c: Declare next_available_newunit. Define the first newunit
+ number. (init_units): Initialize next_available_unit.
+ (get_unique_unit_number): New function. Fix whitespace and comments.
+ * io/transfer.c (data_transfer_init): Update error message to not be
+ specific to OPEN statements.
+
+2009-06-07 Jerry DeLisle <jvdelisle@gcc.gnu.org>
+
+ PR libfortran/40334
+ * io/list_read.c (list_formatted_read_scalar): Set the end file
+ conditions after a return from EOF error.
+
+2009-06-04 Janne Blomqvist <jb@gcc.gnu.org>
+
+ PR libfortran/40330
+ * io/format.c (free_format_hash_table): Also free and nullify hash key.
+ (save_parsed_format): Copy string rather than pointer copy.
+
+2009-05-29 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
+
+ PR fortran/40019
+ * intrinsics/bit_intrinsics.c: New file.
+ * gfortran.map (GFORTRAN_1.2): New list.
+ * Makefile.am: Add intrinsics/bit_intrinsics.c.
+ * Makefile.in: Regenerate.
+
+2009-05-29 Janne Blomqvist <jb@gcc.gnu.org>
+
+ PR libfortran/40190
+ * configure.ac: Check for localtime_r and gmtime_r.
+ * intrinsics/date_and_time.c: Add fallback implementations for
+ localtime_r and gmtime_r.
+ (date_and_time): Change to use localtime_r and gmtime_r instead of
+ localtime and gmtime, respectively.
+ (itime0): Use localtime_r instead of localtime.
+ (ltime_0): Likewise.
+ (gmtime_0): Use gmtime_r instead of gmtime.
+ * config.h.in: Regenerated
+ * configure: Regenerated.
+
+2009-05-27 Janne Blomqvist <jb@gcc.gnu.org>
+
+ PR fortran/39178
+ * runtime/main.c (store_exe_path): Remove static attribute.
+ * libgfortran.h: Add back store_exe_path prototype.
+
+2009-05-27 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR libfortran/40187
+ * intrinsics/iso_c_binding.c (c_f_pointer_u0): Take care
+ of stride in "shape" argument.
+
+2009-05-26 Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/39178
+ * runtime/main.c (store_exe_path): Make static
+ and multiple-times callable.
+ (set_args): Call store_exe_path.
+ * libgfortran.h: Remove store_exe_path prototype.
+ * fmain.c (main): Remove store_exe_path call.
+
+2009-05-19 Jerry DeLisle <jvdelisle@gcc.gnu.org>
+
+ PR libfortran/37754
+ * io/write_float.def: Simplify format calculation.
+
2009-05-07 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
PR fortran/22423
diff --git a/libgfortran/Makefile.am b/libgfortran/Makefile.am
index ce73ff22e51..f5f92dfb432 100644
--- a/libgfortran/Makefile.am
+++ b/libgfortran/Makefile.am
@@ -62,6 +62,7 @@ intrinsics/associated.c \
intrinsics/abort.c \
intrinsics/access.c \
intrinsics/args.c \
+intrinsics/bit_intrinsics.c \
intrinsics/c99_functions.c \
intrinsics/chdir.c \
intrinsics/chmod.c \
diff --git a/libgfortran/Makefile.in b/libgfortran/Makefile.in
index 8d356d5f3b8..ce2b5a21cb1 100644
--- a/libgfortran/Makefile.in
+++ b/libgfortran/Makefile.in
@@ -416,9 +416,9 @@ am__libgfortran_la_SOURCES_DIST = runtime/backtrace.c \
io/size_from_kind.c io/transfer.c io/unit.c io/unix.c \
io/write.c io/fbuf.c intrinsics/associated.c \
intrinsics/abort.c intrinsics/access.c intrinsics/args.c \
- intrinsics/c99_functions.c intrinsics/chdir.c \
- intrinsics/chmod.c intrinsics/clock.c intrinsics/cpu_time.c \
- intrinsics/cshift0.c intrinsics/ctime.c \
+ intrinsics/bit_intrinsics.c intrinsics/c99_functions.c \
+ intrinsics/chdir.c intrinsics/chmod.c intrinsics/clock.c \
+ intrinsics/cpu_time.c intrinsics/cshift0.c intrinsics/ctime.c \
intrinsics/date_and_time.c intrinsics/dtime.c intrinsics/env.c \
intrinsics/eoshift0.c intrinsics/eoshift2.c \
intrinsics/erfc_scaled.c intrinsics/etime.c intrinsics/exit.c \
@@ -711,9 +711,9 @@ am__objects_35 = close.lo file_pos.lo format.lo inquire.lo \
intrinsics.lo list_read.lo lock.lo open.lo read.lo \
size_from_kind.lo transfer.lo unit.lo unix.lo write.lo fbuf.lo
am__objects_36 = associated.lo abort.lo access.lo args.lo \
- c99_functions.lo chdir.lo chmod.lo clock.lo cpu_time.lo \
- cshift0.lo ctime.lo date_and_time.lo dtime.lo env.lo \
- eoshift0.lo eoshift2.lo erfc_scaled.lo etime.lo exit.lo \
+ bit_intrinsics.lo c99_functions.lo chdir.lo chmod.lo clock.lo \
+ cpu_time.lo cshift0.lo ctime.lo date_and_time.lo dtime.lo \
+ env.lo eoshift0.lo eoshift2.lo erfc_scaled.lo etime.lo exit.lo \
fnum.lo gerror.lo getcwd.lo getlog.lo getXid.lo hostnm.lo \
ierrno.lo ishftc.lo iso_c_generated_procs.lo iso_c_binding.lo \
kill.lo link.lo malloc.lo mvbits.lo move_alloc.lo \
@@ -990,6 +990,7 @@ intrinsics/associated.c \
intrinsics/abort.c \
intrinsics/access.c \
intrinsics/args.c \
+intrinsics/bit_intrinsics.c \
intrinsics/c99_functions.c \
intrinsics/chdir.c \
intrinsics/chmod.c \
@@ -1804,6 +1805,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/args.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/associated.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backtrace.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bit_intrinsics.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/c99_functions.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chdir.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chmod.Plo@am__quote@
@@ -5322,6 +5324,13 @@ args.lo: intrinsics/args.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o args.lo `test -f 'intrinsics/args.c' || echo '$(srcdir)/'`intrinsics/args.c
+bit_intrinsics.lo: intrinsics/bit_intrinsics.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT bit_intrinsics.lo -MD -MP -MF "$(DEPDIR)/bit_intrinsics.Tpo" -c -o bit_intrinsics.lo `test -f 'intrinsics/bit_intrinsics.c' || echo '$(srcdir)/'`intrinsics/bit_intrinsics.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/bit_intrinsics.Tpo" "$(DEPDIR)/bit_intrinsics.Plo"; else rm -f "$(DEPDIR)/bit_intrinsics.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intrinsics/bit_intrinsics.c' object='bit_intrinsics.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o bit_intrinsics.lo `test -f 'intrinsics/bit_intrinsics.c' || echo '$(srcdir)/'`intrinsics/bit_intrinsics.c
+
c99_functions.lo: intrinsics/c99_functions.c
@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT c99_functions.lo -MD -MP -MF "$(DEPDIR)/c99_functions.Tpo" -c -o c99_functions.lo `test -f 'intrinsics/c99_functions.c' || echo '$(srcdir)/'`intrinsics/c99_functions.c; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/c99_functions.Tpo" "$(DEPDIR)/c99_functions.Plo"; else rm -f "$(DEPDIR)/c99_functions.Tpo"; exit 1; fi
diff --git a/libgfortran/config.h.in b/libgfortran/config.h.in
index 3542638b0cd..3bab479635a 100644
--- a/libgfortran/config.h.in
+++ b/libgfortran/config.h.in
@@ -426,6 +426,9 @@
/* libc includes getuid */
#undef HAVE_GETUID
+/* Define to 1 if you have the `gmtime_r' function. */
+#undef HAVE_GMTIME_R
+
/* Define if the compiler has a thread header that is non single. */
#undef HAVE_GTHR_DEFAULT
@@ -507,6 +510,9 @@
/* libm includes llroundl */
#undef HAVE_LLROUNDL
+/* Define to 1 if you have the `localtime_r' function. */
+#undef HAVE_LOCALTIME_R
+
/* libm includes log */
#undef HAVE_LOG
diff --git a/libgfortran/configure b/libgfortran/configure
index 0ebca7d67da..043884bad5a 100755
--- a/libgfortran/configure
+++ b/libgfortran/configure
@@ -19503,6 +19503,114 @@ fi
done
+
+for ac_func in localtime_r gmtime_r
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
# Check for glibc backtrace functions
@@ -34881,6 +34989,9 @@ ac_configure_args="${multilib_arg} ${ac_configure_args}"
multi_basedir="$multi_basedir"
CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
CC="$CC"
+CXX="$CXX"
+GFORTRAN="$GFORTRAN"
+GCJ="$GCJ"
AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
diff --git a/libgfortran/configure.ac b/libgfortran/configure.ac
index c0709bbbe51..b1e5d1e2c35 100644
--- a/libgfortran/configure.ac
+++ b/libgfortran/configure.ac
@@ -226,6 +226,7 @@ AC_CHECK_FUNCS(chdir strerror getlogin gethostname kill link symlink perror)
AC_CHECK_FUNCS(sleep time ttyname signal alarm ctime clock access fork execl)
AC_CHECK_FUNCS(wait setmode execvp pipe dup2 close fdopen strcasestr getrlimit)
AC_CHECK_FUNCS(gettimeofday stat fstat lstat getpwuid vsnprintf dup getcwd)
+AC_CHECK_FUNCS(localtime_r gmtime_r)
# Check for glibc backtrace functions
AC_CHECK_FUNCS(backtrace backtrace_symbols)
diff --git a/libgfortran/fmain.c b/libgfortran/fmain.c
index 1d6b45e111d..c59f319f7d8 100644
--- a/libgfortran/fmain.c
+++ b/libgfortran/fmain.c
@@ -9,13 +9,9 @@ void MAIN__ (void);
int
main (int argc, char *argv[])
{
- /* Store the path of the executable file. */
- store_exe_path (argv[0]);
-
/* Set up the runtime environment. */
set_args (argc, argv);
-
/* Call the Fortran main program. Internally this is a function
called MAIN__ */
MAIN__ ();
diff --git a/libgfortran/gfortran.map b/libgfortran/gfortran.map
index 93973d5b338..c8de09cf055 100644
--- a/libgfortran/gfortran.map
+++ b/libgfortran/gfortran.map
@@ -1090,6 +1090,13 @@ GFORTRAN_1.1 {
_gfortran_unpack1_char4;
} GFORTRAN_1.0;
+
+GFORTRAN_1.2 {
+ global:
+ _gfortran_clz128;
+ _gfortran_ctz128;
+} GFORTRAN_1.1;
+
F2C_1.0 {
global:
_gfortran_f2c_specific__abs_c4;
diff --git a/libgfortran/intrinsics/bit_intrinsics.c b/libgfortran/intrinsics/bit_intrinsics.c
new file mode 100644
index 00000000000..92f5f039be6
--- /dev/null
+++ b/libgfortran/intrinsics/bit_intrinsics.c
@@ -0,0 +1,138 @@
+/* Implementation of the bit intrinsics not implemented as GCC builtins.
+ Copyright (C) 2009 Free Software Foundation, Inc.
+
+This file is part of the GNU Fortran runtime library (libgfortran).
+
+Libgfortran 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.
+
+Libgfortran 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 "libgfortran.h"
+
+
+#ifdef HAVE_GFC_INTEGER_16
+extern int clz128 (GFC_INTEGER_16);
+export_proto(clz128);
+
+int
+clz128 (GFC_INTEGER_16 x)
+{
+ int res = 127;
+
+ // We can't write 0xFFFFFFFFFFFFFFFF0000000000000000, so we work around it
+ if (x & ((__uint128_t) 0xFFFFFFFFFFFFFFFF << 64))
+ {
+ res -= 64;
+ x >>= 64;
+ }
+
+ if (x & 0xFFFFFFFF00000000)
+ {
+ res -= 32;
+ x >>= 32;
+ }
+
+ if (x & 0xFFFF0000)
+ {
+ res -= 16;
+ x >>= 16;
+ }
+
+ if (x & 0xFF00)
+ {
+ res -= 8;
+ x >>= 8;
+ }
+
+ if (x & 0xF0)
+ {
+ res -= 4;
+ x >>= 4;
+ }
+
+ if (x & 0xC)
+ {
+ res -= 2;
+ x >>= 2;
+ }
+
+ if (x & 0x2)
+ {
+ res -= 1;
+ x >>= 1;
+ }
+
+ return res;
+}
+#endif
+
+
+#ifdef HAVE_GFC_INTEGER_16
+extern int ctz128 (GFC_INTEGER_16);
+export_proto(ctz128);
+
+int
+ctz128 (GFC_INTEGER_16 x)
+{
+ int res = 0;
+
+ if ((x & 0xFFFFFFFFFFFFFFFF) == 0)
+ {
+ res += 64;
+ x >>= 64;
+ }
+
+ if ((x & 0xFFFFFFFF) == 0)
+ {
+ res += 32;
+ x >>= 32;
+ }
+
+ if ((x & 0xFFFF) == 0)
+ {
+ res += 16;
+ x >>= 16;
+ }
+
+ if ((x & 0xFF) == 0)
+ {
+ res += 8;
+ x >>= 8;
+ }
+
+ if ((x & 0xF) == 0)
+ {
+ res += 4;
+ x >>= 4;
+ }
+
+ if ((x & 0x3) == 0)
+ {
+ res += 2;
+ x >>= 2;
+ }
+
+ if ((x & 0x1) == 0)
+ {
+ res += 1;
+ x >>= 1;
+ }
+
+ return res;
+}
+#endif
diff --git a/libgfortran/intrinsics/date_and_time.c b/libgfortran/intrinsics/date_and_time.c
index 9cfa9e822c5..be64626637c 100644
--- a/libgfortran/intrinsics/date_and_time.c
+++ b/libgfortran/intrinsics/date_and_time.c
@@ -48,6 +48,31 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#define abs(x) ((x)>=0 ? (x) : -(x))
#endif
+
+/* If the re-entrant versions of localtime and gmtime are not
+ available, provide fallback implementations. On some targets where
+ the _r versions are not available, localtime and gmtime use
+ thread-local storage so they are threadsafe. */
+
+#ifndef HAVE_LOCALTIME_R
+static struct tm *
+localtime_r (const time_t * timep, struct tm * result)
+{
+ *result = *localtime (timep);
+ return result;
+}
+#endif
+
+#ifndef HAVE_GMTIME_R
+static struct tm *
+gmtime_r (const time_t * timep, struct tm * result)
+{
+ *result = *gmtime (timep);
+ return result;
+}
+#endif
+
+
/* DATE_AND_TIME ([DATE, TIME, ZONE, VALUES])
Description: Returns data on the real-time clock and date in a form
@@ -166,8 +191,8 @@ date_and_time (char *__date, char *__time, char *__zone,
if (lt != (time_t) -1)
{
- local_time = *localtime (&lt);
- UTC_time = *gmtime (&lt);
+ localtime_r (&lt, &local_time);
+ gmtime_r (&lt, &UTC_time);
/* All arguments can be derived from VALUES. */
values[0] = 1900 + local_time.tm_year;
@@ -361,7 +386,7 @@ itime0 (int x[3])
if (lt != (time_t) -1)
{
- local_time = *localtime (&lt);
+ localtime_r (&lt, &local_time);
x[0] = local_time.tm_hour;
x[1] = local_time.tm_min;
@@ -443,7 +468,7 @@ idate0 (int x[3])
if (lt != (time_t) -1)
{
- local_time = *localtime (&lt);
+ localtime_r (&lt, &local_time);
x[0] = local_time.tm_mday;
x[1] = 1 + local_time.tm_mon;
@@ -510,7 +535,7 @@ idate_i8 (gfc_array_i8 *__values)
/* GMTIME(STIME, TARRAY) - Non-standard
Description: Given a system time value STime, fills TArray with values
- extracted from it appropriate to the GMT time zone using gmtime(3).
+ extracted from it appropriate to the GMT time zone using gmtime_r(3).
The array elements are as follows:
@@ -530,7 +555,7 @@ gmtime_0 (const time_t * t, int x[9])
{
struct tm lt;
- lt = *gmtime (t);
+ gmtime_r (t, &lt);
x[0] = lt.tm_sec;
x[1] = lt.tm_min;
x[2] = lt.tm_hour;
@@ -602,7 +627,7 @@ gmtime_i8 (GFC_INTEGER_8 * t, gfc_array_i8 * tarray)
/* LTIME(STIME, TARRAY) - Non-standard
Description: Given a system time value STime, fills TArray with values
- extracted from it appropriate to the local time zone using localtime(3).
+ extracted from it appropriate to the local time zone using localtime_r(3).
The array elements are as follows:
@@ -622,7 +647,7 @@ ltime_0 (const time_t * t, int x[9])
{
struct tm lt;
- lt = *localtime (t);
+ localtime_r (t, &lt);
x[0] = lt.tm_sec;
x[1] = lt.tm_min;
x[2] = lt.tm_hour;
diff --git a/libgfortran/intrinsics/iso_c_binding.c b/libgfortran/intrinsics/iso_c_binding.c
index a8d876832cb..38f07753c72 100644
--- a/libgfortran/intrinsics/iso_c_binding.c
+++ b/libgfortran/intrinsics/iso_c_binding.c
@@ -95,9 +95,17 @@ ISO_C_BINDING_PREFIX (c_f_pointer_u0) (void *c_ptr_in,
if (shape != NULL)
{
+ index_type source_stride;
+ index_type size;
+ char *p;
+
f_ptr_out->offset = 0;
shapeSize = 0;
-
+ p = shape->data;
+ size = GFC_DESCRIPTOR_SIZE(shape);
+
+ source_stride = shape->dim[0].stride * size;
+
/* shape's length (rank of the output array) */
shapeSize = shape->dim[0].ubound + 1 - shape->dim[0].lbound;
for (i = 0; i < shapeSize; i++)
@@ -107,40 +115,40 @@ ISO_C_BINDING_PREFIX (c_f_pointer_u0) (void *c_ptr_in,
/* Have to allow for the SHAPE array to be any valid kind for
an INTEGER type. */
#ifdef HAVE_GFC_INTEGER_1
- if (GFC_DESCRIPTOR_SIZE (shape) == 1)
- f_ptr_out->dim[i].ubound = ((GFC_INTEGER_1 *) (shape->data))[i];
+ if (size == 1)
+ f_ptr_out->dim[i].ubound = *((GFC_INTEGER_1 *) p);
#endif
#ifdef HAVE_GFC_INTEGER_2
- if (GFC_DESCRIPTOR_SIZE (shape) == 2)
- f_ptr_out->dim[i].ubound = ((GFC_INTEGER_2 *) (shape->data))[i];
+ if (size == 2)
+ f_ptr_out->dim[i].ubound = *((GFC_INTEGER_2 *) p);
#endif
#ifdef HAVE_GFC_INTEGER_4
- if (GFC_DESCRIPTOR_SIZE (shape) == 4)
- f_ptr_out->dim[i].ubound = ((GFC_INTEGER_4 *) (shape->data))[i];
+ if (size == 4)
+ f_ptr_out->dim[i].ubound = *((GFC_INTEGER_4 *) p);
#endif
#ifdef HAVE_GFC_INTEGER_8
- if (GFC_DESCRIPTOR_SIZE (shape) == 8)
- f_ptr_out->dim[i].ubound = ((GFC_INTEGER_8 *) (shape->data))[i];
+ if (size == 8)
+ f_ptr_out->dim[i].ubound = *((GFC_INTEGER_8 *) p);
#endif
#ifdef HAVE_GFC_INTEGER_16
- if (GFC_DESCRIPTOR_SIZE (shape) == 16)
- f_ptr_out->dim[i].ubound = ((GFC_INTEGER_16 *) (shape->data))[i];
-#endif
- }
-
- /* Set the offset and strides.
- offset is (sum of (dim[i].lbound * dim[i].stride) for all
- dims) the -1 means we'll back the data pointer up that much
- perhaps we could just realign the data pointer and not change
- the offset? */
- f_ptr_out->dim[0].stride = 1;
- f_ptr_out->offset = f_ptr_out->dim[0].lbound * f_ptr_out->dim[0].stride;
- for (i = 1; i < shapeSize; i++)
- {
- f_ptr_out->dim[i].stride = (f_ptr_out->dim[i-1].ubound + 1)
- - f_ptr_out->dim[i-1].lbound;
- f_ptr_out->offset += f_ptr_out->dim[i].lbound
- * f_ptr_out->dim[i].stride;
+ if (size == 16)
+ f_ptr_out->dim[i].ubound = *((GFC_INTEGER_16 *) p);
+#endif
+ p += source_stride;
+
+ if (i == 0)
+ {
+ f_ptr_out->dim[0].stride = 1;
+ f_ptr_out->offset = f_ptr_out->dim[0].lbound
+ * f_ptr_out->dim[0].stride;
+ }
+ else
+ {
+ f_ptr_out->dim[i].stride = (f_ptr_out->dim[i-1].ubound + 1)
+ - f_ptr_out->dim[i-1].lbound;
+ f_ptr_out->offset += f_ptr_out->dim[i].lbound
+ * f_ptr_out->dim[i].stride;
+ }
}
f_ptr_out->offset *= -1;
diff --git a/libgfortran/io/format.c b/libgfortran/io/format.c
index a1ec43cfbb3..2c116d6fed4 100644
--- a/libgfortran/io/format.c
+++ b/libgfortran/io/format.c
@@ -87,7 +87,12 @@ free_format_hash_table (gfc_unit *u)
for (i = 0; i < FORMAT_HASH_SIZE; i++)
{
if (u->format_hash_table[i].hashed_fmt != NULL)
- free_format_data (u->format_hash_table[i].hashed_fmt);
+ {
+ free_format_data (u->format_hash_table[i].hashed_fmt);
+ free_mem (u->format_hash_table[i].key);
+ }
+ u->format_hash_table[i].key = NULL;
+ u->format_hash_table[i].key_len = 0;
u->format_hash_table[i].hashed_fmt = NULL;
}
}
@@ -164,7 +169,11 @@ save_parsed_format (st_parameter_dt *dtp)
free_format_data (u->format_hash_table[hash].hashed_fmt);
u->format_hash_table[hash].hashed_fmt = NULL;
- u->format_hash_table[hash].key = dtp->format;
+ if (u->format_hash_table[hash].key != NULL)
+ free_mem (u->format_hash_table[hash].key);
+ u->format_hash_table[hash].key = get_mem (dtp->format_len);
+ memcpy (u->format_hash_table[hash].key, dtp->format, dtp->format_len);
+
u->format_hash_table[hash].key_len = dtp->format_len;
u->format_hash_table[hash].hashed_fmt = dtp->u.p.fmt;
}
diff --git a/libgfortran/io/io.h b/libgfortran/io/io.h
index 22e097ae22d..9e1e45e252b 100644
--- a/libgfortran/io/io.h
+++ b/libgfortran/io/io.h
@@ -297,6 +297,7 @@ typedef struct
CHARACTER2 (round);
CHARACTER1 (sign);
CHARACTER2 (asynchronous);
+ GFC_INTEGER_4 *newunit;
}
st_parameter_open;
@@ -794,6 +795,10 @@ internal_proto(unpack_filename);
extern gfc_offset max_offset;
internal_proto(max_offset);
+/* Unit number to be assigned when NEWUNIT is used in an OPEN statement. */
+extern GFC_INTEGER_4 next_available_newunit;
+internal_proto(next_available_newunit);
+
/* Unit tree root. */
extern gfc_unit *unit_root;
internal_proto(unit_root);
@@ -831,6 +836,9 @@ internal_proto (finish_last_advance_record);
extern int unit_truncate (gfc_unit *, gfc_offset, st_parameter_common *);
internal_proto (unit_truncate);
+extern GFC_INTEGER_4 get_unique_unit_number (st_parameter_open *);
+internal_proto(get_unique_unit_number);
+
/* open.c */
extern gfc_unit *new_unit (st_parameter_open *, gfc_unit *, unit_flags *);
diff --git a/libgfortran/io/list_read.c b/libgfortran/io/list_read.c
index 7cd1f6089de..f6d5687ba8e 100644
--- a/libgfortran/io/list_read.c
+++ b/libgfortran/io/list_read.c
@@ -1687,6 +1687,11 @@ list_formatted_read_scalar (st_parameter_dt *dtp, volatile bt type, void *p,
if (setjmp (eof_jump))
{
generate_error (&dtp->common, LIBERROR_END, NULL);
+ if (!is_internal_unit (dtp))
+ {
+ dtp->u.p.current_unit->endfile = AFTER_ENDFILE;
+ dtp->u.p.current_unit->current_record = 0;
+ }
goto cleanup;
}
diff --git a/libgfortran/io/open.c b/libgfortran/io/open.c
index ba6e9d8804a..d5b4007ea23 100644
--- a/libgfortran/io/open.c
+++ b/libgfortran/io/open.c
@@ -814,7 +814,7 @@ st_open (st_parameter_open *opp)
flags.convert = conv;
- if (opp->common.unit < 0)
+ if (!(opp->common.flags & IOPARM_OPEN_HAS_NEWUNIT) && opp->common.unit < 0)
generate_error (&opp->common, LIBERROR_BAD_OPTION,
"Bad unit number in OPEN statement");
@@ -842,8 +842,13 @@ st_open (st_parameter_open *opp)
if ((opp->common.flags & IOPARM_LIBRETURN_MASK) == IOPARM_LIBRETURN_OK)
{
- u = find_or_create_unit (opp->common.unit);
+ if ((opp->common.flags & IOPARM_OPEN_HAS_NEWUNIT))
+ {
+ *opp->newunit = get_unique_unit_number(opp);
+ opp->common.unit = *opp->newunit;
+ }
+ u = find_or_create_unit (opp->common.unit);
if (u->s == NULL)
{
u = new_unit (opp, u, &flags);
diff --git a/libgfortran/io/transfer.c b/libgfortran/io/transfer.c
index ea1ef7a44bf..08ba7f56f59 100644
--- a/libgfortran/io/transfer.c
+++ b/libgfortran/io/transfer.c
@@ -2020,7 +2020,7 @@ data_transfer_init (st_parameter_dt *dtp, int read_flag)
close_unit (dtp->u.p.current_unit);
dtp->u.p.current_unit = NULL;
generate_error (&dtp->common, LIBERROR_BAD_OPTION,
- "Bad unit number in OPEN statement");
+ "Bad unit number in statement");
return;
}
memset (&u_flags, '\0', sizeof (u_flags));
diff --git a/libgfortran/io/unit.c b/libgfortran/io/unit.c
index 77afd9b2bb6..d8d0c29a8f5 100644
--- a/libgfortran/io/unit.c
+++ b/libgfortran/io/unit.c
@@ -67,6 +67,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
/* Subroutines related to units */
+GFC_INTEGER_4 next_available_newunit;
+#define GFC_FIRST_NEWUNIT -10
#define CACHE_SIZE 3
static gfc_unit *unit_cache[CACHE_SIZE];
@@ -131,7 +133,6 @@ rotate_right (gfc_unit * t)
}
-
static int
compare (int a, int b)
{
@@ -480,7 +481,7 @@ free_internal_unit (st_parameter_dt *dtp)
/* get_unit()-- Returns the unit structure associated with the integer
- * unit or the internal file. */
+ unit or the internal file. */
gfc_unit *
get_unit (st_parameter_dt *dtp, int do_create)
@@ -489,7 +490,7 @@ get_unit (st_parameter_dt *dtp, int do_create)
if ((dtp->common.flags & IOPARM_DT_HAS_INTERNAL_UNIT) != 0)
return get_internal_unit(dtp);
- /* Has to be an external unit */
+ /* Has to be an external unit. */
dtp->u.p.unit_is_internal = 0;
dtp->internal_unit_desc = NULL;
@@ -499,7 +500,7 @@ get_unit (st_parameter_dt *dtp, int do_create)
/*************************/
-/* Initialize everything */
+/* Initialize everything. */
void
init_units (void)
@@ -511,6 +512,8 @@ init_units (void)
__GTHREAD_MUTEX_INIT_FUNCTION (&unit_lock);
#endif
+ next_available_newunit = GFC_FIRST_NEWUNIT;
+
if (options.stdin_unit >= 0)
{ /* STDIN */
u = insert_unit (options.stdin_unit);
@@ -601,10 +604,8 @@ init_units (void)
}
/* Calculate the maximum file offset in a portable manner.
- * max will be the largest signed number for the type gfc_offset.
- *
- * set a 1 in the LSB and keep a running sum, stopping at MSB-1 bit. */
-
+ max will be the largest signed number for the type gfc_offset.
+ set a 1 in the LSB and keep a running sum, stopping at MSB-1 bit. */
max_offset = 0;
for (i = 0; i < sizeof (max_offset) * 8 - 1; i++)
max_offset = max_offset + ((gfc_offset) 1 << i);
@@ -663,8 +664,8 @@ unlock_unit (gfc_unit *u)
}
/* close_unit()-- Close a unit. The stream is closed, and any memory
- * associated with the stream is freed. Returns nonzero on I/O error.
- * Should be called with the u->lock locked. */
+ associated with the stream is freed. Returns nonzero on I/O error.
+ Should be called with the u->lock locked. */
int
close_unit (gfc_unit *u)
@@ -674,11 +675,11 @@ close_unit (gfc_unit *u)
/* close_units()-- Delete units on completion. We just keep deleting
- * the root of the treap until there is nothing left.
- * Not sure what to do with locking here. Some other thread might be
- * holding some unit's lock and perhaps hold it indefinitely
- * (e.g. waiting for input from some pipe) and close_units shouldn't
- * delay the program too much. */
+ the root of the treap until there is nothing left.
+ Not sure what to do with locking here. Some other thread might be
+ holding some unit's lock and perhaps hold it indefinitely
+ (e.g. waiting for input from some pipe) and close_units shouldn't
+ delay the program too much. */
void
close_units (void)
@@ -813,3 +814,22 @@ finish_last_advance_record (gfc_unit *u)
fbuf_flush (u, u->mode);
}
+/* Assign a negative number for NEWUNIT in OPEN statements. */
+GFC_INTEGER_4
+get_unique_unit_number (st_parameter_open *opp)
+{
+ GFC_INTEGER_4 num;
+
+ __gthread_mutex_lock (&unit_lock);
+ num = next_available_newunit--;
+
+ /* Do not allow NEWUNIT numbers to wrap. */
+ if (next_available_newunit >= GFC_FIRST_NEWUNIT )
+ {
+ __gthread_mutex_unlock (&unit_lock);
+ generate_error (&opp->common, LIBERROR_INTERNAL, "NEWUNIT exhausted");
+ return 0;
+ }
+ __gthread_mutex_unlock (&unit_lock);
+ return num;
+}
diff --git a/libgfortran/io/write_float.def b/libgfortran/io/write_float.def
index acf47fbe17e..9804d7b9ab1 100644
--- a/libgfortran/io/write_float.def
+++ b/libgfortran/io/write_float.def
@@ -603,7 +603,7 @@ output_float_FMT_G_ ## x (st_parameter_dt *dtp, const fnode *f, \
int d = f->u.real.d;\
int w = f->u.real.w;\
fnode *newf;\
- GFC_REAL_ ## x exp_d;\
+ GFC_REAL_ ## x rexp_d;\
int low, high, mid;\
int ubound, lbound;\
char *p;\
@@ -612,8 +612,8 @@ output_float_FMT_G_ ## x (st_parameter_dt *dtp, const fnode *f, \
save_scale_factor = dtp->u.p.scale_factor;\
newf = (fnode *) get_mem (sizeof (fnode));\
\
- exp_d = calculate_exp_ ## x (d);\
- if ((m > 0.0 && m < 0.1 - 0.05 / exp_d) || (m >= exp_d - 0.5 ) ||\
+ rexp_d = calculate_exp_ ## x (-d);\
+ if ((m > 0.0 && m < 0.1 - 0.05 * rexp_d) || (rexp_d * (m + 0.5) >= 1.0) ||\
((m == 0.0) && !(compile_options.allow_std & GFC_STD_F2003)))\
{ \
newf->format = FMT_E;\
@@ -635,8 +635,7 @@ output_float_FMT_G_ ## x (st_parameter_dt *dtp, const fnode *f, \
GFC_REAL_ ## x temp;\
mid = (low + high) / 2;\
\
- temp = (calculate_exp_ ## x (mid) - \
- 5 * calculate_exp_ ## x (mid - d - 1)) / 10;\
+ temp = (calculate_exp_ ## x (mid - 1) * (1 - 0.5 * rexp_d));\
\
if (m < temp)\
{ \
diff --git a/libgfortran/libgfortran.h b/libgfortran/libgfortran.h
index 3591fa9c279..fcf736a3f1d 100644
--- a/libgfortran/libgfortran.h
+++ b/libgfortran/libgfortran.h
@@ -590,6 +590,7 @@ st_parameter_common;
#define IOPARM_OPEN_HAS_ROUND (1 << 20)
#define IOPARM_OPEN_HAS_SIGN (1 << 21)
#define IOPARM_OPEN_HAS_ASYNCHRONOUS (1 << 22)
+#define IOPARM_OPEN_HAS_NEWUNIT (1 << 23)
/* library start function and end macro. These can be expanded if needed
in the future. cmp is st_parameter_common *cmp */
@@ -605,7 +606,7 @@ extern void stupid_function_name_for_static_linking (void);
internal_proto(stupid_function_name_for_static_linking);
extern void set_args (int, char **);
-export_proto(set_args);
+iexport_proto(set_args);
extern void get_args (int *, char ***);
internal_proto(get_args);
diff --git a/libgfortran/runtime/main.c b/libgfortran/runtime/main.c
index 3cccc3d0304..28247ca878f 100644
--- a/libgfortran/runtime/main.c
+++ b/libgfortran/runtime/main.c
@@ -69,25 +69,6 @@ determine_endianness (void)
static int argc_save;
static char **argv_save;
-/* Set the saved values of the command line arguments. */
-
-void
-set_args (int argc, char **argv)
-{
- argc_save = argc;
- argv_save = argv;
-}
-
-/* Retrieve the saved values of the command line arguments. */
-
-void
-get_args (int *argc, char ***argv)
-{
- *argc = argc_save;
- *argv = argv_save;
-}
-
-
static const char *exe_path;
static int please_free_exe_path_when_done;
@@ -106,6 +87,10 @@ store_exe_path (const char * argv0)
char buf[PATH_MAX], *cwd, *path;
+ /* This can only happen if store_exe_path is called multiple times. */
+ if (please_free_exe_path_when_done)
+ free ((char *) exe_path);
+
/* On the simulator argv is not set. */
if (argv0 == NULL || argv0[0] == '/')
{
@@ -128,6 +113,7 @@ store_exe_path (const char * argv0)
please_free_exe_path_when_done = 1;
}
+
/* Return the full path of the executable. */
char *
full_exe_path (void)
@@ -135,6 +121,29 @@ full_exe_path (void)
return (char *) exe_path;
}
+
+/* Set the saved values of the command line arguments. */
+
+void
+set_args (int argc, char **argv)
+{
+ argc_save = argc;
+ argv_save = argv;
+ store_exe_path (argv[0]);
+}
+iexport(set_args);
+
+
+/* Retrieve the saved values of the command line arguments. */
+
+void
+get_args (int *argc, char ***argv)
+{
+ *argc = argc_save;
+ *argv = argv_save;
+}
+
+
/* Initialize the runtime library. */
static void __attribute__((constructor))
diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog
index e7183d589b6..63295bf4b09 100644
--- a/libgomp/ChangeLog
+++ b/libgomp/ChangeLog
@@ -1,3 +1,22 @@
+2009-06-09 Nathan Froyd <froydnj@codesourcery.com>
+
+ * Makefile.am (LTLDFLAGS): Define.
+ (LINK): Define.
+ * Makefile.in: Regenerate.
+
+2009-05-27 Janne Blomqvist <jb@gcc.gnu.org>
+
+ PR fortran/39718
+ * testsuite/libgomp.fortran/fortran.exp: Don't link with
+ libgfortranbegin, check existence of libgfortran.a instead of
+ libgfortranbegin.a.
+
+2009-05-20 Jakub Jelinek <jakub@redhat.com>
+
+ PR libgomp/40174
+ * team.c (gomp_thread_start): Destroy thr->release semaphore.
+ (gomp_free_pool_helper): Likewise.
+
2009-04-20 Vasilis Liaskovitis <vliaskov@gmail.com>
Jakub Jelinek <jakub@redhat.com>
diff --git a/libgomp/Makefile.am b/libgomp/Makefile.am
index d1967a0280b..ebb4b6ab8f7 100644
--- a/libgomp/Makefile.am
+++ b/libgomp/Makefile.am
@@ -41,6 +41,11 @@ if USE_FORTRAN
nodist_finclude_HEADERS = omp_lib.h omp_lib.f90 omp_lib.mod omp_lib_kinds.mod
endif
+LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS))
+
+LINK = $(LIBTOOL) --tag CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LTLDFLAGS) -o $@
+
omp_lib_kinds.mod: omp_lib.mod
:
omp_lib.mod: omp_lib.f90
diff --git a/libgomp/Makefile.in b/libgomp/Makefile.in
index fe709e82734..a1e3afc484b 100644
--- a/libgomp/Makefile.in
+++ b/libgomp/Makefile.in
@@ -97,8 +97,6 @@ LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
-LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
- $(AM_LDFLAGS) $(LDFLAGS) -o $@
SOURCES = $(libgomp_la_SOURCES)
DIST_SOURCES = $(libgomp_la_SOURCES)
MULTISRCTOP =
@@ -317,6 +315,9 @@ libgomp_la_SOURCES = alloc.c barrier.c critical.c env.c error.c iter.c \
nodist_noinst_HEADERS = libgomp_f.h
nodist_libsubinclude_HEADERS = omp.h
@USE_FORTRAN_TRUE@nodist_finclude_HEADERS = omp_lib.h omp_lib.f90 omp_lib.mod omp_lib_kinds.mod
+LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS))
+LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LTLDFLAGS) -o $@
# Automake Documentation:
# If your package has Texinfo files in many directories, you can use the
diff --git a/libgomp/team.c b/libgomp/team.c
index 4110e3f22b2..44ffd56095f 100644
--- a/libgomp/team.c
+++ b/libgomp/team.c
@@ -125,6 +125,7 @@ gomp_thread_start (void *xdata)
while (local_fn);
}
+ gomp_sem_destroy (&thr->release);
return NULL;
}
@@ -201,6 +202,7 @@ gomp_free_pool_helper (void *thread_pool)
struct gomp_thread_pool *pool
= (struct gomp_thread_pool *) thread_pool;
gomp_barrier_wait_last (&pool->threads_dock);
+ gomp_sem_destroy (&gomp_thread ()->release);
pthread_exit (NULL);
}
diff --git a/libgomp/testsuite/libgomp.fortran/fortran.exp b/libgomp/testsuite/libgomp.fortran/fortran.exp
index 0f7ad6e5a91..3d6615ffee7 100644
--- a/libgomp/testsuite/libgomp.fortran/fortran.exp
+++ b/libgomp/testsuite/libgomp.fortran/fortran.exp
@@ -1,5 +1,5 @@
set lang_library_path "../libgfortran/.libs"
-set lang_link_flags "-lgfortranbegin -lgfortran"
+set lang_link_flags "-lgfortran"
set lang_test_file_found 0
load_lib libgomp-dg.exp
@@ -8,11 +8,11 @@ load_lib libgomp-dg.exp
dg-init
if { $blddir != "" } {
- if [file exists "${blddir}/${lang_library_path}/libgfortranbegin.a"] {
- set lang_test_file "${lang_library_path}/libgfortranbegin.a"
+ if [file exists "${blddir}/${lang_library_path}/libgfortran.a"] {
+ set lang_test_file "${lang_library_path}/libgfortran.a"
set lang_test_file_found 1
} else {
- puts "No libgfortranbegin library found, will not execute fortran tests"
+ puts "No libgfortran library found, will not execute fortran tests"
}
} elseif [info exists GFORTRAN_UNDER_TEST] {
set lang_test_file_found 1
diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog
index 13c7fd5dd1f..f5ac7832942 100644
--- a/libiberty/ChangeLog
+++ b/libiberty/ChangeLog
@@ -1,3 +1,46 @@
+2009-06-16 Nick Clifton <nickc@redhat.com>
+
+ PR 10197
+ * testsuite/test-demangle.c: Rename getline to get_line to avoid
+ conflicts with system function of the same name.
+
+2009-05-30 Eli Zaretskii <eliz@gnu.org>
+
+ * snprintf.c: Doc fix.
+
+ * vsnprintf.c: Doc fix.
+
+2009-05-29 Kai Tietz <kai.tietz@onevision.com>
+
+ * pex-win32.c (pex_win32_fdopenr): Set INHERIT to false.
+
+2009-05-29 Michael Matz <matz@suse.de>
+
+ * fibheap.c (fibheap_replace_key_data): Make sure we don't early
+ out when forcing the minimum.
+ (fibheap_delete_node): Assert that we managed to force the minimum.
+
+2009-05-25 Tristan Gingold <gingold@adacore.com>
+
+ * config.h-vms: Rewritten. Define configure macros.
+ Use DEC-C builtin alloca.
+
+ * makefile.vms (OBJS): Update list.
+ (OPT): New variable.
+ (CFLAGS): Update compilation flags.
+ (libiberty.olb): Do not depend on alloca-conf.h anymore.
+
+2009-05-19 Ian Lance Taylor <iant@google.com>
+ Ben Elliston <bje@au.ibm.com>
+
+ * cp-demangle.c (cplus_demangle_fill_ctor): Fix logic bug.
+ (cplus_demangle_fill_dtor): Likewise.
+
+2009-05-17 Julian Brown <julian@codesourcery.com>
+
+ * pex-win32.c (pex_win32_exec_child): Fix logic to avoid closing
+ standard handles (stdin, stdout, stderr) in parent.
+
2009-04-29 Julian Brown <julian@codesourcery.com>
* pex-win32.c (pex_win32_pipe): Add _O_NOINHERIT.
diff --git a/libiberty/config.h-vms b/libiberty/config.h-vms
index ccac6a2bcc7..d84453101e8 100644
--- a/libiberty/config.h-vms
+++ b/libiberty/config.h-vms
@@ -1,13 +1,11 @@
-#ifndef NEED_strerror
-#define NEED_strerror
-#endif
-#ifndef NEED_basename
-#define NEED_basename
-#endif
-#ifndef NEED_psignal
-#define NEED_psignal
-#endif
-#ifndef NEED_on_exit
-#define NEED_on_exit
-#endif
+/* This is -*- C -*- */
+#define HAVE_STDLIB_H 1
+#define HAVE_UNISTD_H 1
+#define HAVE_STRING_H 1
+#define HAVE_SYS_STAT_H 1
+#define HAVE_SYS_TIME_H 1
+/* Cheat: use vms builtin alloca. */
+#ifdef __DECC
+#define C_alloca(x) __ALLOCA(x)
+#endif
diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c
index b02f9bbf97e..4f309ef992b 100644
--- a/libiberty/cp-demangle.c
+++ b/libiberty/cp-demangle.c
@@ -719,8 +719,8 @@ cplus_demangle_fill_ctor (struct demangle_component *p,
{
if (p == NULL
|| name == NULL
- || (kind < gnu_v3_complete_object_ctor
- && kind > gnu_v3_complete_object_allocating_ctor))
+ || (int) kind < gnu_v3_complete_object_ctor
+ || (int) kind > gnu_v3_complete_object_allocating_ctor)
return 0;
p->type = DEMANGLE_COMPONENT_CTOR;
p->u.s_ctor.kind = kind;
@@ -738,8 +738,8 @@ cplus_demangle_fill_dtor (struct demangle_component *p,
{
if (p == NULL
|| name == NULL
- || (kind < gnu_v3_deleting_dtor
- && kind > gnu_v3_base_object_dtor))
+ || (int) kind < gnu_v3_deleting_dtor
+ || (int) kind > gnu_v3_base_object_dtor)
return 0;
p->type = DEMANGLE_COMPONENT_DTOR;
p->u.s_dtor.kind = kind;
diff --git a/libiberty/fibheap.c b/libiberty/fibheap.c
index c032149c0c2..a37ee4ef270 100644
--- a/libiberty/fibheap.c
+++ b/libiberty/fibheap.c
@@ -214,7 +214,10 @@ fibheap_replace_key_data (fibheap_t heap, fibnode_t node,
node->key = key;
y = node->parent;
- if (okey == key)
+ /* Short-circuit if the key is the same, as we then don't have to
+ do anything. Except if we're trying to force the new node to
+ be the new minimum for delete. */
+ if (okey == key && okey != FIBHEAPKEY_MIN)
return odata;
/* These two compares are specifically <= 0 to make sure that in the case
@@ -256,6 +259,11 @@ fibheap_delete_node (fibheap_t heap, fibnode_t node)
/* To perform delete, we just make it the min key, and extract. */
fibheap_replace_key (heap, node, FIBHEAPKEY_MIN);
+ if (node != heap->min)
+ {
+ fprintf (stderr, "Can't force minimum on fibheap.\n");
+ abort ();
+ }
fibheap_extract_min (heap);
return ret;
diff --git a/libiberty/makefile.vms b/libiberty/makefile.vms
index 6a7dd45718e..2f45f69a2ae 100644
--- a/libiberty/makefile.vms
+++ b/libiberty/makefile.vms
@@ -7,19 +7,25 @@
#
#
-OBJS=bcopy.obj,bcmp.obj,getopt.obj,obstack.obj,xexit.obj,xmalloc.obj,hex.obj,\
- getopt1.obj,cplus-dem.obj,strncasecmp.obj,strcasecmp.obj,strdup.obj,\
- concat.obj,getruntime.obj,getpagesize.obj,alloca.obj,xstrerror.obj,\
- xmemdup.obj,xstrdup.obj,xatexit.obj,choose-temp.obj,fnmatch.obj,objalloc.obj
+OBJS=getopt.obj,obstack.obj,xexit.obj,xmalloc.obj,hex.obj,\
+ getopt1.obj,cplus-dem.obj,cp-demangle.obj,cp-demint.obj,\
+ asprintf.obj vasprintf.obj,mkstemps.obj,\
+ concat.obj,getruntime.obj,getpagesize.obj,getpwd.obj,xstrerror.obj,\
+ xmemdup.obj,xstrdup.obj,xatexit.obj,choose-temp.obj,fnmatch.obj,\
+ objalloc.obj,safe-ctype.obj,hashtab.obj,lbasename.obj,argv.obj,\
+ lrealpath.obj,make-temp-file.obj,unlink-if-ordinary.obj
ifeq ($(CC),gcc)
CFLAGS=/include=([],[-.include])
else
# assume dec c
-CFLAGS=/noopt/debug/include=([],[-.include])/define=("const=")/warnings=disable=(missingreturn,implicitfunc)
+OPT=/noopt/debug/warnings=disable=(missingreturn)
+CFLAGS=$(OPT)/include=([],[-.include])/name=(as_is,shortened)\
+ /define=(HAVE_CONFIG_H=1)\
+ /prefix=(all,except=("getopt","optarg","optopt","optind","opterr"))
endif
-libiberty.olb: config.h alloca-conf.h $(OBJS)
+libiberty.olb: config.h $(OBJS)
purge
lib/create libiberty *.obj
diff --git a/libiberty/pex-win32.c b/libiberty/pex-win32.c
index 30ef4359200..44274067482 100644
--- a/libiberty/pex-win32.c
+++ b/libiberty/pex-win32.c
@@ -753,17 +753,20 @@ pex_win32_exec_child (struct pex_obj *obj ATTRIBUTE_UNUSED, int flags,
original descriptors. */
orig_in = in;
in = _dup (orig_in);
- _close (orig_in);
+ if (orig_in != STDIN_FILENO)
+ _close (orig_in);
orig_out = out;
out = _dup (orig_out);
- _close (orig_out);
+ if (orig_out != STDOUT_FILENO)
+ _close (orig_out);
if (separate_stderr)
{
orig_err = errdes;
errdes = _dup (orig_err);
- _close (orig_err);
+ if (orig_err != STDERR_FILENO)
+ _close (orig_err);
}
stdin_handle = INVALID_HANDLE_VALUE;
@@ -844,11 +847,9 @@ pex_win32_exec_child (struct pex_obj *obj ATTRIBUTE_UNUSED, int flags,
/* Close the standard input, standard output and standard error handles
in the parent. */
- if (in != STDIN_FILENO)
- _close (in);
- if (out != STDOUT_FILENO)
- _close (out);
- if (errdes != STDERR_FILENO)
+ _close (in);
+ _close (out);
+ if (separate_stderr)
_close (errdes);
return pid;
@@ -914,6 +915,11 @@ static FILE *
pex_win32_fdopenr (struct pex_obj *obj ATTRIBUTE_UNUSED, int fd,
int binary)
{
+ HANDLE h = (HANDLE) _get_osfhandle (fd);
+ if (h == INVALID_HANDLE_VALUE)
+ return NULL;
+ if (! SetHandleInformation (h, HANDLE_FLAG_INHERIT, 0))
+ return NULL;
return fdopen (fd, binary ? "rb" : "r");
}
diff --git a/libiberty/snprintf.c b/libiberty/snprintf.c
index f1ba49f980f..36c8e9b3430 100644
--- a/libiberty/snprintf.c
+++ b/libiberty/snprintf.c
@@ -27,13 +27,15 @@ the executable file might be covered by the GNU General Public License. */
@deftypefn Supplemental int snprintf (char *@var{buf}, size_t @var{n}, const char *@var{format}, ...)
-This function is similar to sprintf, but it will print at most @var{n}
-characters. On error the return value is -1, otherwise it returns the
-number of characters that would have been printed had @var{n} been
-sufficiently large, regardless of the actual value of @var{n}. Note
-some pre-C99 system libraries do not implement this correctly so users
-cannot generally rely on the return value if the system version of
-this function is used.
+This function is similar to @code{sprintf}, but it will write to
+@var{buf} at most @code{@var{n}-1} bytes of text, followed by a
+terminating null byte, for a total of @var{n} bytes.
+On error the return value is -1, otherwise it returns the number of
+bytes, not including the terminating null byte, that would have been
+written had @var{n} been sufficiently large, regardless of the actual
+value of @var{n}. Note some pre-C99 system libraries do not implement
+this correctly so users cannot generally rely on the return value if
+the system version of this function is used.
@end deftypefn
diff --git a/libiberty/testsuite/test-demangle.c b/libiberty/testsuite/test-demangle.c
index 12b07dd6476..1c982d6ef20 100644
--- a/libiberty/testsuite/test-demangle.c
+++ b/libiberty/testsuite/test-demangle.c
@@ -46,7 +46,7 @@ static unsigned int lineno;
#define LINELEN 80
static void
-getline(buf)
+get_line(buf)
struct line *buf;
{
char *data = buf->data;
@@ -196,12 +196,12 @@ main(argc, argv)
{
const char *inp;
- getline (&format);
+ get_line (&format);
if (feof (stdin))
break;
- getline (&input);
- getline (&expect);
+ get_line (&input);
+ get_line (&expect);
inp = protect_end (input.data);
@@ -322,7 +322,7 @@ main(argc, argv)
if (no_params)
{
- getline (&expect);
+ get_line (&expect);
result = cplus_demangle (inp, DMGL_ANSI|DMGL_TYPES);
if (result
diff --git a/libiberty/vsnprintf.c b/libiberty/vsnprintf.c
index 7df5bd88e52..5470df2223b 100644
--- a/libiberty/vsnprintf.c
+++ b/libiberty/vsnprintf.c
@@ -27,13 +27,15 @@ the executable file might be covered by the GNU General Public License. */
@deftypefn Supplemental int vsnprintf (char *@var{buf}, size_t @var{n}, const char *@var{format}, va_list @var{ap})
-This function is similar to vsprintf, but it will print at most
-@var{n} characters. On error the return value is -1, otherwise it
-returns the number of characters that would have been printed had
-@var{n} been sufficiently large, regardless of the actual value of
-@var{n}. Note some pre-C99 system libraries do not implement this
-correctly so users cannot generally rely on the return value if the
-system version of this function is used.
+This function is similar to @code{vsprintf}, but it will write to
+@var{buf} at most @code{@var{n}-1} bytes of text, followed by a
+terminating null byte, for a total of @var{n} bytes. On error the
+return value is -1, otherwise it returns the number of characters that
+would have been printed had @var{n} been sufficiently large,
+regardless of the actual value of @var{n}. Note some pre-C99 system
+libraries do not implement this correctly so users cannot generally
+rely on the return value if the system version of this function is
+used.
@end deftypefn
diff --git a/libjava/classpath/ChangeLog.gcj b/libjava/classpath/ChangeLog.gcj
index e4d7c2fae3c..6398644ad7d 100644
--- a/libjava/classpath/ChangeLog.gcj
+++ b/libjava/classpath/ChangeLog.gcj
@@ -1,3 +1,13 @@
+2009-06-16 Matthias Klose <doko@ubuntu.com>
+
+ * tools/gnu/classpath/tools/gjdoc/Main.java (getGjdocVersion): Use
+ gnu.classpath.Configuration.CLASSPATH_VERSION as version number.
+ * tools/gnu/classpath/tools/doclets/htmldoclet/HtmlDoclet.java
+ (getDocletVersion): Likewise.
+ * tools/classes/gnu/classpath/tools/gjdoc/Main*.class: Regenerate.
+ * tools/classes/gnu/classpath/tools/doclets/htmldoclet/HtmlDoclet*.class:
+ Regenerate.
+
2009-03-16 Matthias Klose <doko@ubuntu.com>
* configure.ac: Detect xulrunner-1.9.
diff --git a/libjava/classpath/tools/classes/gnu/classpath/tools/doclets/htmldoclet/HtmlDoclet.class b/libjava/classpath/tools/classes/gnu/classpath/tools/doclets/htmldoclet/HtmlDoclet.class
index 6e9981b5ee7..e76e4ad0885 100644
--- a/libjava/classpath/tools/classes/gnu/classpath/tools/doclets/htmldoclet/HtmlDoclet.class
+++ b/libjava/classpath/tools/classes/gnu/classpath/tools/doclets/htmldoclet/HtmlDoclet.class
Binary files differ
diff --git a/libjava/classpath/tools/classes/gnu/classpath/tools/gjdoc/Main.class b/libjava/classpath/tools/classes/gnu/classpath/tools/gjdoc/Main.class
index 1ce24d1d49c..e53a62553b3 100644
--- a/libjava/classpath/tools/classes/gnu/classpath/tools/gjdoc/Main.class
+++ b/libjava/classpath/tools/classes/gnu/classpath/tools/gjdoc/Main.class
Binary files differ
diff --git a/libjava/classpath/tools/gnu/classpath/tools/doclets/htmldoclet/HtmlDoclet.java b/libjava/classpath/tools/gnu/classpath/tools/doclets/htmldoclet/HtmlDoclet.java
index 837333ddf0f..e49e1c57341 100644
--- a/libjava/classpath/tools/gnu/classpath/tools/doclets/htmldoclet/HtmlDoclet.java
+++ b/libjava/classpath/tools/gnu/classpath/tools/doclets/htmldoclet/HtmlDoclet.java
@@ -3736,20 +3736,7 @@ public class HtmlDoclet
protected String getDocletVersion()
{
if (null == docletVersion) {
- try {
- Properties versionProperties = new Properties();
- InputStream in = getClass().getResourceAsStream("/version.properties");
- if (in == null) {
- in = new FileInputStream("src/resources/version.properties");
- }
- versionProperties.load(in);
- docletVersion = versionProperties.getProperty("gjdoc.version");
- }
- catch (IOException ignore) {
- }
- if (null == docletVersion) {
- docletVersion = "unknown";
- }
+ docletVersion = gnu.classpath.Configuration.CLASSPATH_VERSION;
}
return docletVersion;
}
diff --git a/libjava/classpath/tools/gnu/classpath/tools/gjdoc/Main.java b/libjava/classpath/tools/gnu/classpath/tools/gjdoc/Main.java
index d1316b34183..cbbc8f4f7dd 100644
--- a/libjava/classpath/tools/gnu/classpath/tools/gjdoc/Main.java
+++ b/libjava/classpath/tools/gnu/classpath/tools/gjdoc/Main.java
@@ -1825,16 +1825,7 @@ public final class Main
public String getGjdocVersion()
{
if (null == gjdocVersion) {
- try {
- Properties versionProperties = new Properties();
- versionProperties.load(getClass().getResourceAsStream("version.properties"));
- gjdocVersion = versionProperties.getProperty("gjdoc.version");
- }
- catch (IOException ignore) {
- }
- if (null == gjdocVersion) {
- gjdocVersion = "unknown";
- }
+ gjdocVersion = gnu.classpath.Configuration.CLASSPATH_VERSION;
}
return gjdocVersion;
}
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 45e0f2b6b39..03c011072c1 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,6 +1,480 @@
+2009-06-16 Jonathan Wakely <jwakely.gcc@gmail.com>
+
+ * libsupc++/exception_ptr.h (exception_ptr::swap(exception_ptr&&)):
+ Remove.
+ (exception_ptr::operator=(exception_ptr&&)): Cast source to
+ rvalue-reference so that move constructor is called.
+ * testsuite/18_support/exception_ptr/move.cc: New.
+
+2009-06-16 Jonathan Wakely <jwakely.gcc@gmail.com>
+
+ * include/std/thread (~thread(), operator=(thread&&)): Call terminate
+ if joinable.
+
+2009-06-15 Tom Tromey <tromey@redhat.com>
+
+ * python/libstdcxx/v6/printers.py (StdMapPrinter.__init__): Don't
+ set self.iter.
+ (StdMapPrinter.to_string): Make a new iterator.
+ (StdMapPrinter.children): Likewise.
+ (StdSetPrinter.__init__): Don't set self.iter.
+ (StdSetPrinter.to_string): Make a new iterator.
+ (StdSetPrinter.children): Likewise.
+
+2009-06-11 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * include/bits/random.tcc
+ (negative_binomial_distribution<>::operator()
+ (_UniformRandomNumberGenerator&, const param_type&): Tweak to use a
+ class member gamma_distribution.
+ (negative_binomial_distribution<>::operator()
+ (_UniformRandomNumberGenerator&)): Implement out of line here.
+ (operator<<(basic_ostream<>&, negative_binomial_distribution<>),
+ operator>>(basic_ostream<>&, negative_binomial_distribution<>): Adjust.
+ (student_t_distribution<>::operator()
+ (_UniformRandomNumberGenerator&, const param_type&): Move inline,
+ simplify.
+ (operator<<(basic_ostream<>&, student_t_distribution<>),
+ operator>>(basic_ostream<>&, student_t_distribution<>): Adjust.
+ (chi_squared_distribution<>::operator()
+ (_UniformRandomNumberGenerator&, const param_type&): Move inline,
+ tweak to use a class member gamma_distribution.
+ (operator<<(basic_ostream<>&, chi_squared_distribution<>),
+ operator>>(basic_ostream<>&, chi_squared_distribution<>): Adjust.
+ (fisher_f_distribution<>::operator() (_UniformRandomNumberGenerator&,
+ const param_type&): Move inline, tweak to use class member
+ gamma_distributions.
+ (operator<<(basic_ostream<>&, fisher_f_distribution<>),
+ operator>>(basic_ostream<>&, fisher_f_distribution<>): Adjust.
+ * include/bits/random.h: Adjust, minor tweaks.
+
+2009-06-10 Tom Tromey <tromey@redhat.com>
+
+ * python/libstdcxx/v6/printers.py (lookup_function): Remove extra ';'.
+ (build_libstdcxx_dictionary): Accept shortened form of
+ basic_string names.
+ (StdStringPrinter.to_string): Remove reference to WideEncoding.
+
+2009-06-10 Tom Tromey <tromey@redhat.com>
+
+ PR libstdc++/40289:
+ * python/Makefile.in: Rebuild.
+ * python/hook.in: Compute module path relative to objfile.
+ * python/Makefile.am (pythondir): Redefine.
+ (gdb.py): Subst toolexeclibdir.
+ (install-data-local): Rewrite.
+
+2009-06-09 Benjamin Kosnik <bkoz@redhat.com>
+
+ * include/bits/move.h: Doxygen group fixes.
+
+2009-06-08 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * include/bits/random.tcc (gamma_distribution<>::operator()
+ (_UniformRandomNumberGenerator&, const param_type&): Redo, using
+ the Marsaglia/Tsang algorithm.
+ (gamma_distribution<>::param_type::_M_initialize): Adjust.
+ (operator<<(basic_ostream<>&, gamma_distribution<>),
+ operator>>(basic_ostream<>&, gamma_distribution<>): Likewise.
+
+ * include/bits/random.tcc(student_t_distribution<>::_M_gaussian):
+ Remove, just use normal_distribution.
+ (operator<<(basic_ostream<>&, student_t_distribution<>),
+ operator>>(basic_ostream<>&, student_t_distribution<>): Adjust.
+ (linear_congruential_engine<>::operator()()): Move inline.
+ (lognormal_distribution<>::operator()(_UniformRandomNumberGenerator&,
+ const param_type&)): Move inline, just use normal_distribution.
+ (operator<<(basic_ostream<>&, lognormal_distribution<>),
+ operator>>(basic_ostream<>&, lognormal_distribution<>): Adjust.
+ (weibull_distribution<>::operator()(_UniformRandomNumberGenerator&,
+ const param_type&)): Move here, out of line.
+ (piecewise_constant_distribution<>::param_type::param_type()): Move
+ inline.
+ * include/bits/random.h: Adjust, minor tweaks.
+
+2009-06-05 Benjamin Kosnik <bkoz@redhat.com>
+
+ * testsuite/29_atomics/atomic_address/cons/aggregate.cc: Remove xfail.
+
+2009-06-04 Benjamin Kosnik <bkoz@redhat.com>
+
+ * include/ext/throw_allocator.h: Rework.
+ * include/ext/pb_ds/detail/debug_map_base.hpp: Adjust usage.
+ * include/ext/pb_ds/detail/gp_hash_table_map_/resize_fn_imps.hpp: Same.
+ * include/ext/pb_ds/detail/ov_tree_map_/erase_fn_imps.hpp: Same.
+ * include/ext/pb_ds/detail/ov_tree_map_/ov_tree_map_.hpp: Same.
+ * testsuite/23_containers/list/modifiers/insert/25288.cc: Same.
+ * testsuite/util/regression/rand/priority_queue/
+ container_rand_regression_test.tcc: Inline functions.
+ * testsuite/util/regression/rand/assoc/
+ container_rand_regression_test.tcc: Same.
+
+2009-06-03 Benjamin Kosnik <bkoz@redhat.com>
+
+ * testsuite/23_containers/list/cons/6.cc: Adjust test name.
+
+2009-06-02 Richard Sandiford <r.sandiford@uk.ibm.com>
+
+ * crossconfig.m4 (GLIBCXX_CROSSCONFIG): Handle AIX targets.
+ * configure: Regenerate.
+
+2009-06-03 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR libstdc++/40299
+ * include/ext/memory: Fully qualify calls with __gnu_cxx.
+ * testsuite/ext/rope/40299.cc: New.
+
+2009-05-28 Tom Tromey <tromey@redhat.com>
+ Phil Muldoon <pmuldoon@redhat.com>
+ Jonathan Wakely <jwakely.gcc@gmail.com>
+
+ * python/Makefile.in, , python/libstdcxx/__init__.py,
+ python/libstdcxx/v6/__init__.py, python/libstdcxx/v6/printers.py,
+ python/hook.in, python/Makefile.am: New files.
+ * configure, Makefile.in: Rebuild.
+ * acinclude.m4 (glibcxx_SUBDIRS): Add python.
+ * Makefile.am (SUBDIRS): Add python.
+
+2009-05-28 Benjamin Kosnik <bkoz@redhat.com>
+
+ * testsuite/util/testsuite_allocator.h (check_new, check_delete): Move
+ to ...
+ * testsuite/util/replacement_memory_operators.h: ...here. New.
+ * testsuite/util/testsuite_hooks.h (counter): To object_counter.
+ * testsuite/util/testsuite_hooks.cc: Same.
+
+ * testsuite/ext/mt_allocator/deallocate_local_thread-1.cc: Use
+ replacement_memory_operators.h.
+ * testsuite/ext/mt_allocator/deallocate_local_thread-3.cc: Same.
+ * testsuite/ext/mt_allocator/check_delete.cc: Same.
+ * testsuite/ext/mt_allocator/deallocate_local_thread-5.cc: Same.
+ * testsuite/ext/mt_allocator/deallocate_local_thread-7.cc: Same.
+ * testsuite/ext/mt_allocator/deallocate_global_thread-1.cc: Same.
+ * testsuite/ext/mt_allocator/deallocate_global_thread-3.cc: Same.
+ * testsuite/ext/mt_allocator/deallocate_local-2.cc: Same.
+ * testsuite/ext/mt_allocator/deallocate_local-4.cc: Same.
+ * testsuite/ext/mt_allocator/deallocate_local-6.cc: Same.
+ * testsuite/ext/mt_allocator/deallocate_local-8.cc: Same.
+ * testsuite/ext/mt_allocator/deallocate_global-2.cc: Same.
+ * testsuite/ext/mt_allocator/deallocate_global-4.cc: Same.
+ * testsuite/ext/mt_allocator/check_new.cc: Same.
+ * testsuite/ext/debug_allocator/check_delete.cc: Same.
+ * testsuite/ext/debug_allocator/check_new.cc: Same.
+ * testsuite/ext/new_allocator/deallocate_global.cc: Same.
+ * testsuite/ext/new_allocator/check_delete.cc: Same.
+ * testsuite/ext/new_allocator/check_new.cc: Same.
+ * testsuite/ext/new_allocator/deallocate_local.cc: Same.
+ * testsuite/ext/throw_allocator/deallocate_global.cc: Same.
+ * testsuite/ext/throw_allocator/check_delete.cc: Same.
+ * testsuite/ext/throw_allocator/check_new.cc: Same.
+ * testsuite/ext/throw_allocator/deallocate_local.cc: Same.
+ * testsuite/ext/malloc_allocator/deallocate_global.cc: Same.
+ * testsuite/ext/malloc_allocator/check_delete.cc: Same.
+ * testsuite/ext/malloc_allocator/check_new.cc: Same.
+ * testsuite/ext/malloc_allocator/deallocate_local.cc: Same.
+ * testsuite/ext/pool_allocator/check_delete.cc: Same.
+ * testsuite/ext/pool_allocator/check_new.cc: Same.
+ * testsuite/ext/bitmap_allocator/check_delete.cc: Same.
+ * testsuite/ext/bitmap_allocator/check_new.cc: Same.
+ * testsuite/ext/array_allocator/check_delete.cc: Same.
+ * testsuite/ext/array_allocator/check_new.cc: Same.
+ * testsuite/23_containers/deque/cons/1.cc: Same.
+ * testsuite/23_containers/deque/cons/2.cc: Same.
+
+2009-05-27 Benjamin Kosnik <bkoz@redhat.com>
+
+ * libsupc++/initializer_list: Format.
+ * testsuite/18_support/initializer_list/requirements/typedefs.cc: New.
+ * testsuite/18_support/initializer_list/requirements/
+ explicit_instantiation.cc: New.
+
+2009-05-27 Benjamin Kosnik <bkoz@redhat.com>
+
+ PR libstdc++/40273
+ * include/tr1_impl/functional: Add explicit casts.
+ * testsuite/20_util/function/requirements/
+ explicit_instantiation.cc: New.
+ * testsuite/20_util/function/null_pointer_comparisons.cc: New.
+
+2009-05-24 Eelis van der Weegen <eelis@eelis.net>
+
+ * libsupc++/initializer_list (initializer_list): Add missing typedefs.
+
+2009-05-21 Benjamin Kosnik <bkoz@redhat.com>
+
+ PR libstdc++/40221
+ * include/tr1_impl/functional: Add explicit cast.
+
+2009-05-21 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR libstdc++/40094
+ Revert:
+ 2009-05-07 Paolo Carlini <paolo.carlini@oracle.com>
+ * include/ext/throw_allocator.h (throw_allocator_base): Avoid
+ out of line member functions definitions.
+ (throw_allocator_base::_S_g, _S_map, _S_throw_prob, _S_label):
+ Remove, use static locals instead.
+ (throw_allocator_base::do_check_allocated, print_to_string): Declare.
+ * src/throw_allocator.cc: New.
+ * src/Makefile.am: Add.
+ * config/abi/pre/gnu.ver: Add exports.
+ * src/Makefile.in: Regenerate.
+
+2009-05-20 Benjamin Kosnik <bkoz@redhat.com>
+
+ * include/tr1_impl/functional (function): Use explicit operator bool.
+ * include/bits/shared_ptr.h (__shared_ptr): Same.
+ * include/bits/unique_ptr.h (unique_ptr): Same.
+ * include/std/mutex (unique_lock): Same.
+ * include/std/system_error (error_code): Same.
+ (error_condition): Same.
+ * include/std/ostream (sentry): Same.
+ * include/std/istream (sentry): Same.
+ * testsuite/19_diagnostics/error_condition/operators/bool.cc: Adjust.
+ * testsuite/19_diagnostics/error_condition/operators/bool_neg.cc: Same.
+ * testsuite/19_diagnostics/error_code/operators/bool.cc: Same.
+ * testsuite/19_diagnostics/error_code/operators/bool_neg.cc: Same.
+ * testsuite/20_util/unique_ptr/modifiers/reset_neg.cc: Same.
+ * testsuite/20_util/unique_ptr/assign/assign_neg.cc: Same.
+ * testsuite/20_util/shared_ptr/observers/bool_conv.cc: Same.
+
+2009-05-19 Benjamin Kosnik <bkoz@redhat.com>
+
+ * testsuite/23_containers/list/14340.cc: Abstract list type.
+ * testsuite/23_containers/list/init-list.cc: Same.
+ * testsuite/23_containers/list/pthread5.cc: Same.
+ * testsuite/23_containers/list/invalidation/1.cc: Same.
+ * testsuite/23_containers/list/invalidation/2.cc: Same.
+ * testsuite/23_containers/list/invalidation/3.cc: Same.
+ * testsuite/23_containers/list/invalidation/4.cc: Same.
+ * testsuite/23_containers/list/modifiers/insert/25288.cc: Same.
+ * testsuite/23_containers/list/modifiers/1.cc: Same.
+ * testsuite/23_containers/list/modifiers/2.cc: Same.
+ * testsuite/23_containers/list/modifiers/3.cc: Same.
+ * testsuite/23_containers/list/modifiers/swap/1.cc: Same.
+ * testsuite/23_containers/list/modifiers/swap/2.cc: Same.
+ * testsuite/23_containers/list/modifiers/swap/3.cc: Same.
+ * testsuite/23_containers/list/cons/1.cc: Same.
+ * testsuite/23_containers/list/cons/2.cc: Same.
+ * testsuite/23_containers/list/cons/3.cc: Same.
+ * testsuite/23_containers/list/cons/4.cc: Same.
+ * testsuite/23_containers/list/cons/5.cc: Same.
+ * testsuite/23_containers/list/cons/6.cc: Same.
+ * testsuite/23_containers/list/cons/7.cc: Same.
+ * testsuite/23_containers/list/cons/clear_allocator.cc: Same.
+ * testsuite/23_containers/list/cons/8.cc: Same.
+ * testsuite/23_containers/list/cons/9.cc: Same.
+ * testsuite/23_containers/list/operations/1.cc: Same.
+ * testsuite/23_containers/list/operations/2.cc: Same.
+ * testsuite/23_containers/list/operations/3.cc: Same.
+ * testsuite/23_containers/list/operations/4.cc: Same.
+ * testsuite/23_containers/list/operations/5.cc: Same.
+ * testsuite/23_containers/list/requirements/citerators.cc: Same.
+ * testsuite/23_containers/list/requirements/dr438/assign_neg.cc: Same.
+ * testsuite/23_containers/list/requirements/dr438/insert_neg.cc: Same.
+ * testsuite/23_containers/list/requirements/dr438/
+ constructor_1_neg.cc: Same.
+ * testsuite/23_containers/list/requirements/dr438/
+ constructor_2_neg.cc: Same.
+ * testsuite/23_containers/list/requirements/dr438/constructor.cc: Same.
+ * testsuite/23_containers/list/requirements/
+ partial_specialization/1.cc: Same.
+ * testsuite/23_containers/list/23781.cc: Same.
+ * testsuite/23_containers/list/pthread1.cc: Same.
+ * testsuite/23_containers/list/capacity/1.cc: Same.
+ * testsuite/23_containers/list/capacity/29134.cc: Same.
+ * testsuite/23_containers/list/check_construct_destroy.cc: Same.
+ * testsuite/23_containers/list/moveable.cc: Same.
+
+ * testsuite/util/common_type/assoc/common_type.hpp: Re-break lines.
+
+2009-05-19 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR libstdc++/40184
+ * include/bits/locale_classes.h (locale::facet::_S_lc_ctype_c_locale):
+ Declare...
+ * config/locale/gnu/c_locale.cc: ... and define.
+ * config/locale/generic/c_locale.cc: Define.
+ * src/localename.cc (locale::_Impl::_Impl(const char*, size_t)):
+ Use it.
+ * testsuite/22_locale/locale/cons/40184.cc: New.
+
+2009-05-18 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR libstdc++/40192
+ * include/bits/stl_construct.h (struct _Destroy_aux): Add.
+ (_Destroy(_ForwardIterator, _ForwardIterator)): Use the latter.
+ * testsuite/23_containers/vector/40192.cc: New.
+
+2009-05-18 Jonathan Wakely <jwakely.gcc@gmail.com>
+
+ * include/bits/stl_pair.h (swap): Do not swap rvalues.
+ * include/bits/stl_deque.h (swap): Likewise.
+ * include/bits/stl_list.h (swap): Likewise.
+ * include/bits/stl_vector.h (swap): Likewise.
+ * include/bits/stl_bvector.h (swap): Likewise.
+ * include/bits/stl_queue.h (swap): Likewise.
+ * include/bits/stl_stack.h (swap): Likewise.
+ * include/bits/stl_tree.h (swap): Likewise.
+ * include/bits/stl_map.h (swap): Likewise.
+ * include/bits/stl_multimap.h (swap): Likewise.
+ * include/bits/stl_set.h (swap): Likewise.
+ * include/bits/stl_multiset.h (swap): Likewise.
+ * include/bits/forward_list.h (swap): Likewise.
+ * include/bits/unique_ptr.h (swap): Likewise.
+ * include/debug/deque (swap): Likewise.
+ * include/debug/list (swap): Likewise.
+ * include/debug/vector (swap): Likewise.
+ * include/debug/map.h (swap): Likewise.
+ * include/debug/multimap.h (swap): Likewise.
+ * include/debug/set.h (swap): Likewise.
+ * include/debug/multiset.h (swap): Likewise.
+ * include/debug/unordered_map (swap): Likewise.
+ * include/debug/unordered_set (swap): Likewise.
+ * include/ext/vstring.h (swap): Likewise.
+ * include/tr1_impl/unordered_map (swap): Likewise.
+ * include/tr1_impl/hashtable (swap): Likewise.
+ * include/tr1_impl/unordered_set (swap): Likewise.
+ * include/std/tuple (swap): Likewise.
+ * include/std/mutex (swap): Likewise.
+ * include/std/thread (swap): Likewise.
+ (operator<<): Only output to lvalue streams.
+ * testsuite/20_util/shared_ptr/modifiers/swap_rvalue.cc: Remove.
+ * testsuite/23_containers/headers/forward_list/synopsis.cc: Adjust.
+ * testsuite/23_containers/deque/requirements/dr438/
+ assign_neg.cc: Adjust line numbers.
+ * testsuite/23_containers/deque/requirements/dr438/
+ constructor_1_neg.cc: Likewise.
+ * testsuite/23_containers/deque/requirements/dr438/
+ constructor_2_neg.cc: Likewise.
+ * testsuite/23_containers/deque/requirements/dr438/
+ insert_neg.cc: Likewise.
+ * testsuite/23_containers/list/requirements/dr438/
+ assign_neg.cc: Likewise.
+ * testsuite/23_containers/list/requirements/dr438/
+ constructor_1_neg.cc: Likewise.
+ * testsuite/23_containers/list/requirements/dr438/
+ constructor_2_neg.cc: Likewise.
+ * testsuite/23_containers/list/requirements/dr438/
+ insert_neg.cc: Likewise.
+ * testsuite/23_containers/vector/requirements/dr438/
+ assign_neg.cc: Likewise.
+ * 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.
+ * testsuite/30_threads/thread/swap/1.cc: Swap with lvalue and also
+ test non-member swap.
+ * testsuite/30_threads/thread/swap/2.cc: Remove.
+
+2009-05-16 Jonathan Wakely <jwakely.gcc@gmail.com>
+
+ * include/std/mutex: Move std::lock_error to ...
+ * src/compatibility.cc: Here.
+ * src/mutex.cc: Likewise.
+ * testsuite/30_threads/headers/mutex/types_std_c++0x.cc: Add checks
+ for lock types and remove std::lock_error check.
+
+2009-05-15 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * testsuite/21_strings/basic_string/40160.cc: Remove spurious
+ double include.
+
+2009-05-15 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR libstdc++/40160
+ * include/debug/formatter.h (_Parameter::_Parameter): Don't use
+ typeid when __GXX_RTTI is undefined.
+ * src/debug.cc (_Error_formatter::_Parameter::_M_print_field): Adjust
+ for null _M_variant._M_iterator._M_type,
+ _M_variant._M_iterator._M_seq_type, _M_variant._M_sequence._M_type.
+ * testsuite/21_strings/basic_string/40160.cc: New.
+
+2009-05-15 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * testsuite/26_numerics/random/discrete_distribution/cons/
+ num_xbound_fun.cc: Minor tweaks.
+ * testsuite/26_numerics/random/piecewise_constant_distribution/
+ cons/initlist_fun.cc: Likewise
+ * testsuite/26_numerics/random/piecewise_constant_distribution/
+ cons/num_xbound_fun.cc: Likewise
+ * testsuite/26_numerics/random/piecewise_linear_distribution/
+ cons/initlist_fun.cc: Likewise
+ * testsuite/26_numerics/random/piecewise_linear_distribution/
+ cons/num_xbound_fun.cc: Likewise
+
+2009-05-15 David Billinghurst <billingd@gcc.gnu.org>
+
+ PR libstdc++/36211
+ * testsuite/lib/libstdc++.exp(v3_target_compile): Add
+ cxxldflags to additional_flags rather than cxx_final.
+
+2009-05-15 David Billinghurst <billingd@gcc.gnu.org>
+
+ * testsuite/26_numerics/random/discrete_distribution/cons/
+ num_xbound_fun.cc: Replace non-standard macro M_PI with constant pi.
+ * testsuite/26_numerics/random/piecewise_constant_distribution/cons/
+ initlist_fun.cc: Likewise
+ * testsuite/26_numerics/random/piecewise_constant_distribution/cons/
+ num_xbound_fun.cc: Likewise
+ * testsuite/26_numerics/random/piecewise_linear_distribution/cons/
+ initlist_fun.cc: Likewise
+ * testsuite/26_numerics/random/piecewise_linear_distribution/cons/
+ num_xbound_fun.cc: Likewise
+
+2009-05-14 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR libstdc++/40123
+ * random.tcc (independent_bits_engine<>::operator()()): Use
+ result_type(1), not 1UL.
+
+ * random.tcc (independent_bits_engine<>::operator()()): Use _M_b.max()
+ and _M_b.min(), instead of this->max() and this->min().
+
+ * random.h (_ShiftMin1): Remove, adjust everywhere.
+
+ * random.tcc: Minor cosmetic changes.
+
+2009-05-14 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * include/bits/random.tcc (cauchy_distribution<>::
+ operator()(_UniformRandomNumberGenerator&, const param_type&)):
+ Avoid M_PI, a glibc extension.
+
+2009-05-13 Ben Elliston <bje@au.ibm.com>
+
+ * include/Makefile.am (PCHFLAGS): Remove -Winvalid-pch.
+ * include/Makefile.in: Likewise.
+
+2009-05-13 Ben Elliston <bje@au.ibm.com>
+
+ * src/compatibility.cc (_ZTIe, _ZTIPe, _ZTIPKe): Change type to
+ const void * const.
+
+2009-05-12 Edward Smith-Rowland <3dw4rd@verizon.net>
+
+ * doc/xml/manual/status_cxx200x.xml: Note missing constexpr for
+ random number engines, complex, bitset, array, time utilities, and
+ char_traits.
+
+2009-05-12 Jonathan Wakely <jwakely.gcc@gmail.com>
+
+ * libsupc++/exception: Include nested_exception.h in C++0x mode.
+ * libsupc++/nested_exception.h: New.
+ * libsupc++/Makefile.am: Add new header.
+ * libsupc++/Makefile.in: Regenerate.
+ * testsuite/18_support/nested_exception/rethrow_nested.cc: New.
+ * testsuite/18_support/nested_exception/throw_with_nested.cc: New.
+ * testsuite/18_support/nested_exception/cons.cc: New.
+ * testsuite/18_support/nested_exception/nested_ptr.cc: New.
+ * testsuite/18_support/nested_exception/rethrow_if_nested.cc: New.
+ * doc/xml/manual/status_cxx200x.xml: Adjust.
+
2009-05-07 Paolo Carlini <paolo.carlini@oracle.com>
- * include/ext/throw_allocator.h: Remove redundante include.
+ * include/ext/throw_allocator.h: Remove redundant include.
2009-05-07 Paolo Carlini <paolo.carlini@oracle.com>
@@ -26,10 +500,10 @@
2009-05-06 Johannes Singler <singler@ira.uka.de>
- PR libstdc++/39546
- * include/parallel/algo.h (find_switch):
- Parametrize binder2nd with const T& instead of T.
- * testsuite/25_algorithms/find/39546.cc: new test case
+ PR libstdc++/39546
+ * include/parallel/algo.h (find_switch):
+ Parametrize binder2nd with const T& instead of T.
+ * testsuite/25_algorithms/find/39546.cc: new test case
2009-05-06 Paolo Carlini <paolo.carlini@oracle.com>
diff --git a/libstdc++-v3/Makefile.am b/libstdc++-v3/Makefile.am
index 7c8f9c2df1d..1f8d3159bc7 100644
--- a/libstdc++-v3/Makefile.am
+++ b/libstdc++-v3/Makefile.am
@@ -27,7 +27,8 @@ if GLIBCXX_HOSTED
hosted_source = doc src po testsuite
endif
## Keep this list sync'd with acinclude.m4:GLIBCXX_CONFIGURE.
-SUBDIRS = include libsupc++ $(hosted_source)
+## Note that python must come after src.
+SUBDIRS = include libsupc++ $(hosted_source) python
ACLOCAL_AMFLAGS = -I . -I .. -I ../config
diff --git a/libstdc++-v3/Makefile.in b/libstdc++-v3/Makefile.in
index 7d5afd96f05..c51a637bc1d 100644
--- a/libstdc++-v3/Makefile.in
+++ b/libstdc++-v3/Makefile.in
@@ -87,7 +87,7 @@ RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
uninstall-recursive
ETAGS = etags
CTAGS = ctags
-DIST_SUBDIRS = include libsupc++ doc src po testsuite
+DIST_SUBDIRS = include libsupc++ doc src po testsuite python
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
distdir = $(PACKAGE)-$(VERSION)
top_distdir = $(distdir)
@@ -321,7 +321,7 @@ WARN_CXXFLAGS = \
# -I/-D flags to pass when compiling.
AM_CPPFLAGS = $(GLIBCXX_INCLUDES)
@GLIBCXX_HOSTED_TRUE@hosted_source = doc src po testsuite
-SUBDIRS = include libsupc++ $(hosted_source)
+SUBDIRS = include libsupc++ $(hosted_source) python
ACLOCAL_AMFLAGS = -I . -I .. -I ../config
# Multilib support.
diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
index 186916c2e47..d7895f5ec7f 100644
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -49,7 +49,7 @@ AC_DEFUN([GLIBCXX_CONFIGURE], [
# Keep these sync'd with the list in Makefile.am. The first provides an
# expandable list at autoconf time; the second provides an expandable list
# (i.e., shell variable) at configure time.
- m4_define([glibcxx_SUBDIRS],[include libsupc++ src doc po testsuite])
+ m4_define([glibcxx_SUBDIRS],[include libsupc++ python src doc po testsuite])
SUBDIRS='glibcxx_SUBDIRS'
# These need to be absolute paths, yet at the same time need to
diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver
index f40fd97ef38..240e7bcf09b 100644
--- a/libstdc++-v3/config/abi/pre/gnu.ver
+++ b/libstdc++-v3/config/abi/pre/gnu.ver
@@ -964,10 +964,6 @@ GLIBCXX_3.4.12 {
_ZSt27__set_once_functor_lock_ptrPSt11unique_lockISt5mutexE;
_ZSt16__get_once_mutexv;
- # throw_allocator
- _ZN9__gnu_cxx20throw_allocator_base18do_check_allocated*;
- _ZN9__gnu_cxx20throw_allocator_base15print_to_string*;
-
} GLIBCXX_3.4.11;
# Symbols in the support library (libsupc++) have their own tag.
diff --git a/libstdc++-v3/config/locale/generic/c_locale.cc b/libstdc++-v3/config/locale/generic/c_locale.cc
index 3b9f1bd42a5..a79a970f231 100644
--- a/libstdc++-v3/config/locale/generic/c_locale.cc
+++ b/libstdc++-v3/config/locale/generic/c_locale.cc
@@ -226,6 +226,10 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
locale::facet::_S_clone_c_locale(__c_locale&)
{ return __c_locale(); }
+ __c_locale
+ locale::facet::_S_lc_ctype_c_locale(__c_locale, const char*)
+ { return __c_locale(); }
+
_GLIBCXX_END_NAMESPACE
_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
diff --git a/libstdc++-v3/config/locale/gnu/c_locale.cc b/libstdc++-v3/config/locale/gnu/c_locale.cc
index cd32dc03130..4864d25cd34 100644
--- a/libstdc++-v3/config/locale/gnu/c_locale.cc
+++ b/libstdc++-v3/config/locale/gnu/c_locale.cc
@@ -133,10 +133,10 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
{
// This named locale is not supported by the underlying OS.
__throw_runtime_error(__N("locale::facet::_S_create_c_locale "
- "name not valid"));
+ "name not valid"));
}
}
-
+
void
locale::facet::_S_destroy_c_locale(__c_locale& __cloc)
{
@@ -148,6 +148,23 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
locale::facet::_S_clone_c_locale(__c_locale& __cloc)
{ return __duplocale(__cloc); }
+ __c_locale
+ locale::facet::_S_lc_ctype_c_locale(__c_locale __cloc, const char* __s)
+ {
+ __c_locale __dup = __duplocale(__cloc);
+ if (__dup == __c_locale(0))
+ __throw_runtime_error(__N("locale::facet::_S_lc_ctype_c_locale "
+ "duplocale error"));
+ __c_locale __changed = __newlocale(LC_CTYPE_MASK, __s, __dup);
+ if (__changed == __c_locale(0))
+ {
+ __freelocale(__dup);
+ __throw_runtime_error(__N("locale::facet::_S_lc_ctype_c_locale "
+ "newlocale error"));
+ }
+ return __changed;
+ }
+
_GLIBCXX_END_NAMESPACE
_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
index a80bbaecb43..0f19ba59f5c 100755
--- a/libstdc++-v3/configure
+++ b/libstdc++-v3/configure
@@ -2453,7 +2453,7 @@ echo "${ECHO_T}$ac_cv_prog_egrep" >&6
# expandable list at autoconf time; the second provides an expandable list
# (i.e., shell variable) at configure time.
- SUBDIRS='include libsupc++ src doc po testsuite'
+ SUBDIRS='include libsupc++ python src doc po testsuite'
# These need to be absolute paths, yet at the same time need to
# canonicalize only relative paths, because then amd will not unmount
@@ -59243,6 +59243,17458 @@ _ACEOF
;;
+ *-aix*)
+
+ # If we're not using GNU ld, then there's no point in even trying these
+ # tests. Check for that first. We should have already tested for gld
+ # by now (in libtool), but require it now just to be safe...
+ test -z "$SECTION_LDFLAGS" && SECTION_LDFLAGS=''
+ test -z "$OPT_LDFLAGS" && OPT_LDFLAGS=''
+
+
+
+ # The name set by libtool depends on the version of libtool. Shame on us
+ # for depending on an impl detail, but c'est la vie. Older versions used
+ # ac_cv_prog_gnu_ld, but now it's lt_cv_prog_gnu_ld, and is copied back on
+ # top of with_gnu_ld (which is also set by --with-gnu-ld, so that actually
+ # makes sense). We'll test with_gnu_ld everywhere else, so if that isn't
+ # set (hence we're using an older libtool), then set it.
+ if test x${with_gnu_ld+set} != xset; then
+ if test x${ac_cv_prog_gnu_ld+set} != xset; then
+ # We got through "ac_require(ac_prog_ld)" and still not set? Huh?
+ with_gnu_ld=no
+ else
+ with_gnu_ld=$ac_cv_prog_gnu_ld
+ fi
+ fi
+
+ # Start by getting the version number. I think the libtool test already
+ # does some of this, but throws away the result.
+ glibcxx_ld_is_gold=no
+ if test x"$with_gnu_ld" = x"yes"; then
+ echo "$as_me:$LINENO: checking for ld version" >&5
+echo $ECHO_N "checking for ld version... $ECHO_C" >&6
+
+ if $LD --version 2>/dev/null | grep 'GNU gold' >/dev/null 2>&1; then
+ glibcxx_ld_is_gold=yes
+ fi
+ ldver=`$LD --version 2>/dev/null | head -1 | \
+ sed -e 's/GNU \(go\)\{0,1\}ld \(version \)\{0,1\}\(([^)]*) \)\{0,1\}\([0-9.][0-9.]*\).*/\4/'`
+
+ glibcxx_gnu_ld_version=`echo $ldver | \
+ $AWK -F. '{ if (NF<3) $3=0; print ($1*100+$2)*100+$3 }'`
+ echo "$as_me:$LINENO: result: $glibcxx_gnu_ld_version" >&5
+echo "${ECHO_T}$glibcxx_gnu_ld_version" >&6
+ fi
+
+ # Set --gc-sections.
+ glibcxx_have_gc_sections=no
+ if test "$glibcxx_ld_is_gold" = "yes"; then
+ if $LD --help 2>/dev/null | grep gc-sections >/dev/null 2>&1; then
+ glibcxx_have_gc_sections=yes
+ fi
+ else
+ glibcxx_gcsections_min_ld=21602
+ if test x"$with_gnu_ld" = x"yes" &&
+ test $glibcxx_gnu_ld_version -gt $glibcxx_gcsections_min_ld ; then
+ glibcxx_have_gc_sections=yes
+ fi
+ fi
+ if test "$glibcxx_have_gc_sections" = "yes"; then
+ # Sufficiently young GNU ld it is! Joy and bunny rabbits!
+ # NB: This flag only works reliably after 2.16.1. Configure tests
+ # for this are difficult, so hard wire a value that should work.
+
+ ac_test_CFLAGS="${CFLAGS+set}"
+ ac_save_CFLAGS="$CFLAGS"
+ CFLAGS='-Wl,--gc-sections'
+
+ # Check for -Wl,--gc-sections
+ echo "$as_me:$LINENO: checking for ld that supports -Wl,--gc-sections" >&5
+echo $ECHO_N "checking for ld that supports -Wl,--gc-sections... $ECHO_C" >&6
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+ int one(void) { return 1; }
+ int two(void) { return 2; }
+
+int
+main ()
+{
+ two();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_gcsections=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_gcsections=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ if test "$ac_gcsections" = "yes"; then
+ rm -f conftest.c
+ touch conftest.c
+ if $CC -c conftest.c; then
+ if $LD --gc-sections -o conftest conftest.o 2>&1 | \
+ grep "Warning: gc-sections option ignored" > /dev/null; then
+ ac_gcsections=no
+ fi
+ fi
+ rm -f conftest.c conftest.o conftest
+ fi
+ if test "$ac_gcsections" = "yes"; then
+ SECTION_LDFLAGS="-Wl,--gc-sections $SECTION_LDFLAGS"
+ fi
+ echo "$as_me:$LINENO: result: $ac_gcsections" >&5
+echo "${ECHO_T}$ac_gcsections" >&6
+
+ if test "$ac_test_CFLAGS" = set; then
+ CFLAGS="$ac_save_CFLAGS"
+ else
+ # this is the suspicious part
+ CFLAGS=''
+ fi
+ fi
+
+ # Set -z,relro.
+ # Note this is only for shared objects.
+ ac_ld_relro=no
+ if test x"$with_gnu_ld" = x"yes"; then
+ echo "$as_me:$LINENO: checking for ld that supports -Wl,-z,relro" >&5
+echo $ECHO_N "checking for ld that supports -Wl,-z,relro... $ECHO_C" >&6
+ cxx_z_relo=`$LD -v --help 2>/dev/null | grep "z relro"`
+ if test -n "$cxx_z_relo"; then
+ OPT_LDFLAGS="-Wl,-z,relro"
+ ac_ld_relro=yes
+ fi
+ echo "$as_me:$LINENO: result: $ac_ld_relro" >&5
+echo "${ECHO_T}$ac_ld_relro" >&6
+ fi
+
+ # Set linker optimization flags.
+ if test x"$with_gnu_ld" = x"yes"; then
+ OPT_LDFLAGS="-Wl,-O1 $OPT_LDFLAGS"
+ fi
+
+
+
+
+
+ ac_test_CXXFLAGS="${CXXFLAGS+set}"
+ ac_save_CXXFLAGS="$CXXFLAGS"
+ CXXFLAGS='-fno-builtin -D_GNU_SOURCE'
+
+ echo "$as_me:$LINENO: checking for sin in -lm" >&5
+echo $ECHO_N "checking for sin in -lm... $ECHO_C" >&6
+if test "${ac_cv_lib_m_sin+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm $LIBS"
+if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char sin ();
+int
+main ()
+{
+sin ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_lib_m_sin=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_m_sin=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_m_sin" >&5
+echo "${ECHO_T}$ac_cv_lib_m_sin" >&6
+if test $ac_cv_lib_m_sin = yes; then
+ libm="-lm"
+fi
+
+ ac_save_LIBS="$LIBS"
+ LIBS="$LIBS $libm"
+
+
+
+ echo "$as_me:$LINENO: checking for isinf declaration" >&5
+echo $ECHO_N "checking for isinf declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func_isinf_use+set} != xset; then
+ if test "${glibcxx_cv_func_isinf_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ isinf(0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func_isinf_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func_isinf_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func_isinf_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func_isinf_use" >&6
+
+ if test x$glibcxx_cv_func_isinf_use = x"yes"; then
+
+for ac_func in isinf
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ echo "$as_me:$LINENO: checking for _isinf declaration" >&5
+echo $ECHO_N "checking for _isinf declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func__isinf_use+set} != xset; then
+ if test "${glibcxx_cv_func__isinf_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ _isinf(0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func__isinf_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func__isinf_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func__isinf_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func__isinf_use" >&6
+
+ if test x$glibcxx_cv_func__isinf_use = x"yes"; then
+
+for ac_func in _isinf
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+
+ echo "$as_me:$LINENO: checking for isnan declaration" >&5
+echo $ECHO_N "checking for isnan declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func_isnan_use+set} != xset; then
+ if test "${glibcxx_cv_func_isnan_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ isnan(0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func_isnan_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func_isnan_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func_isnan_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func_isnan_use" >&6
+
+ if test x$glibcxx_cv_func_isnan_use = x"yes"; then
+
+for ac_func in isnan
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ echo "$as_me:$LINENO: checking for _isnan declaration" >&5
+echo $ECHO_N "checking for _isnan declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func__isnan_use+set} != xset; then
+ if test "${glibcxx_cv_func__isnan_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ _isnan(0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func__isnan_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func__isnan_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func__isnan_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func__isnan_use" >&6
+
+ if test x$glibcxx_cv_func__isnan_use = x"yes"; then
+
+for ac_func in _isnan
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+
+ echo "$as_me:$LINENO: checking for finite declaration" >&5
+echo $ECHO_N "checking for finite declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func_finite_use+set} != xset; then
+ if test "${glibcxx_cv_func_finite_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ finite(0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func_finite_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func_finite_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func_finite_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func_finite_use" >&6
+
+ if test x$glibcxx_cv_func_finite_use = x"yes"; then
+
+for ac_func in finite
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ echo "$as_me:$LINENO: checking for _finite declaration" >&5
+echo $ECHO_N "checking for _finite declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func__finite_use+set} != xset; then
+ if test "${glibcxx_cv_func__finite_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ _finite(0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func__finite_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func__finite_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func__finite_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func__finite_use" >&6
+
+ if test x$glibcxx_cv_func__finite_use = x"yes"; then
+
+for ac_func in _finite
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+
+ echo "$as_me:$LINENO: checking for sincos declaration" >&5
+echo $ECHO_N "checking for sincos declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func_sincos_use+set} != xset; then
+ if test "${glibcxx_cv_func_sincos_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ sincos(0, 0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func_sincos_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func_sincos_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func_sincos_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func_sincos_use" >&6
+
+ if test x$glibcxx_cv_func_sincos_use = x"yes"; then
+
+for ac_func in sincos
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ echo "$as_me:$LINENO: checking for _sincos declaration" >&5
+echo $ECHO_N "checking for _sincos declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func__sincos_use+set} != xset; then
+ if test "${glibcxx_cv_func__sincos_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ _sincos(0, 0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func__sincos_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func__sincos_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func__sincos_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func__sincos_use" >&6
+
+ if test x$glibcxx_cv_func__sincos_use = x"yes"; then
+
+for ac_func in _sincos
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+
+ echo "$as_me:$LINENO: checking for fpclass declaration" >&5
+echo $ECHO_N "checking for fpclass declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func_fpclass_use+set} != xset; then
+ if test "${glibcxx_cv_func_fpclass_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ fpclass(0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func_fpclass_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func_fpclass_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func_fpclass_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func_fpclass_use" >&6
+
+ if test x$glibcxx_cv_func_fpclass_use = x"yes"; then
+
+for ac_func in fpclass
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ echo "$as_me:$LINENO: checking for _fpclass declaration" >&5
+echo $ECHO_N "checking for _fpclass declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func__fpclass_use+set} != xset; then
+ if test "${glibcxx_cv_func__fpclass_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ _fpclass(0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func__fpclass_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func__fpclass_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func__fpclass_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func__fpclass_use" >&6
+
+ if test x$glibcxx_cv_func__fpclass_use = x"yes"; then
+
+for ac_func in _fpclass
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+
+ echo "$as_me:$LINENO: checking for qfpclass declaration" >&5
+echo $ECHO_N "checking for qfpclass declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func_qfpclass_use+set} != xset; then
+ if test "${glibcxx_cv_func_qfpclass_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ qfpclass(0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func_qfpclass_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func_qfpclass_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func_qfpclass_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func_qfpclass_use" >&6
+
+ if test x$glibcxx_cv_func_qfpclass_use = x"yes"; then
+
+for ac_func in qfpclass
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ echo "$as_me:$LINENO: checking for _qfpclass declaration" >&5
+echo $ECHO_N "checking for _qfpclass declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func__qfpclass_use+set} != xset; then
+ if test "${glibcxx_cv_func__qfpclass_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ _qfpclass(0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func__qfpclass_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func__qfpclass_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func__qfpclass_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func__qfpclass_use" >&6
+
+ if test x$glibcxx_cv_func__qfpclass_use = x"yes"; then
+
+for ac_func in _qfpclass
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+
+ echo "$as_me:$LINENO: checking for hypot declaration" >&5
+echo $ECHO_N "checking for hypot declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func_hypot_use+set} != xset; then
+ if test "${glibcxx_cv_func_hypot_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ hypot(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func_hypot_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func_hypot_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func_hypot_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func_hypot_use" >&6
+
+ if test x$glibcxx_cv_func_hypot_use = x"yes"; then
+
+for ac_func in hypot
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ echo "$as_me:$LINENO: checking for _hypot declaration" >&5
+echo $ECHO_N "checking for _hypot declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func__hypot_use+set} != xset; then
+ if test "${glibcxx_cv_func__hypot_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ _hypot(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func__hypot_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func__hypot_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func__hypot_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func__hypot_use" >&6
+
+ if test x$glibcxx_cv_func__hypot_use = x"yes"; then
+
+for ac_func in _hypot
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+
+ echo "$as_me:$LINENO: checking for float trig functions" >&5
+echo $ECHO_N "checking for float trig functions... $ECHO_C" >&6
+ if test "${glibcxx_cv_func_float_trig_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+acosf (0); asinf (0); atanf (0); cosf (0); sinf (0); tanf (0); coshf (0); sinhf (0); tanhf (0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func_float_trig_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func_float_trig_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func_float_trig_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func_float_trig_use" >&6
+ if test x$glibcxx_cv_func_float_trig_use = x"yes"; then
+
+
+
+
+
+
+
+
+
+for ac_func in acosf asinf atanf cosf sinf tanf coshf sinhf tanhf
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ else
+ echo "$as_me:$LINENO: checking for _float trig functions" >&5
+echo $ECHO_N "checking for _float trig functions... $ECHO_C" >&6
+ if test "${glibcxx_cv_func__float_trig_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+_acosf (0); _asinf (0); _atanf (0); _cosf (0); _sinf (0); _tanf (0); _coshf (0); _sinhf (0); _tanhf (0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func__float_trig_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func__float_trig_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func__float_trig_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func__float_trig_use" >&6
+ if test x$glibcxx_cv_func__float_trig_use = x"yes"; then
+
+
+
+
+
+
+
+
+
+for ac_func in _acosf _asinf _atanf _cosf _sinf _tanf _coshf _sinhf _tanhf
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ echo "$as_me:$LINENO: checking for float round functions" >&5
+echo $ECHO_N "checking for float round functions... $ECHO_C" >&6
+ if test "${glibcxx_cv_func_float_round_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ceilf (0); floorf (0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func_float_round_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func_float_round_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func_float_round_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func_float_round_use" >&6
+ if test x$glibcxx_cv_func_float_round_use = x"yes"; then
+
+
+for ac_func in ceilf floorf
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ else
+ echo "$as_me:$LINENO: checking for _float round functions" >&5
+echo $ECHO_N "checking for _float round functions... $ECHO_C" >&6
+ if test "${glibcxx_cv_func__float_round_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+_ceilf (0); _floorf (0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func__float_round_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func__float_round_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func__float_round_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func__float_round_use" >&6
+ if test x$glibcxx_cv_func__float_round_use = x"yes"; then
+
+
+for ac_func in _ceilf _floorf
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+
+
+
+ echo "$as_me:$LINENO: checking for expf declaration" >&5
+echo $ECHO_N "checking for expf declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func_expf_use+set} != xset; then
+ if test "${glibcxx_cv_func_expf_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ expf(0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func_expf_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func_expf_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func_expf_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func_expf_use" >&6
+
+ if test x$glibcxx_cv_func_expf_use = x"yes"; then
+
+for ac_func in expf
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ echo "$as_me:$LINENO: checking for _expf declaration" >&5
+echo $ECHO_N "checking for _expf declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func__expf_use+set} != xset; then
+ if test "${glibcxx_cv_func__expf_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ _expf(0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func__expf_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func__expf_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func__expf_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func__expf_use" >&6
+
+ if test x$glibcxx_cv_func__expf_use = x"yes"; then
+
+for ac_func in _expf
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+
+ echo "$as_me:$LINENO: checking for isnanf declaration" >&5
+echo $ECHO_N "checking for isnanf declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func_isnanf_use+set} != xset; then
+ if test "${glibcxx_cv_func_isnanf_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ isnanf(0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func_isnanf_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func_isnanf_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func_isnanf_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func_isnanf_use" >&6
+
+ if test x$glibcxx_cv_func_isnanf_use = x"yes"; then
+
+for ac_func in isnanf
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ echo "$as_me:$LINENO: checking for _isnanf declaration" >&5
+echo $ECHO_N "checking for _isnanf declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func__isnanf_use+set} != xset; then
+ if test "${glibcxx_cv_func__isnanf_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ _isnanf(0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func__isnanf_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func__isnanf_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func__isnanf_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func__isnanf_use" >&6
+
+ if test x$glibcxx_cv_func__isnanf_use = x"yes"; then
+
+for ac_func in _isnanf
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+
+ echo "$as_me:$LINENO: checking for isinff declaration" >&5
+echo $ECHO_N "checking for isinff declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func_isinff_use+set} != xset; then
+ if test "${glibcxx_cv_func_isinff_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ isinff(0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func_isinff_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func_isinff_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func_isinff_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func_isinff_use" >&6
+
+ if test x$glibcxx_cv_func_isinff_use = x"yes"; then
+
+for ac_func in isinff
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ echo "$as_me:$LINENO: checking for _isinff declaration" >&5
+echo $ECHO_N "checking for _isinff declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func__isinff_use+set} != xset; then
+ if test "${glibcxx_cv_func__isinff_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ _isinff(0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func__isinff_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func__isinff_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func__isinff_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func__isinff_use" >&6
+
+ if test x$glibcxx_cv_func__isinff_use = x"yes"; then
+
+for ac_func in _isinff
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+
+ echo "$as_me:$LINENO: checking for atan2f declaration" >&5
+echo $ECHO_N "checking for atan2f declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func_atan2f_use+set} != xset; then
+ if test "${glibcxx_cv_func_atan2f_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ atan2f(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func_atan2f_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func_atan2f_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func_atan2f_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func_atan2f_use" >&6
+
+ if test x$glibcxx_cv_func_atan2f_use = x"yes"; then
+
+for ac_func in atan2f
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ echo "$as_me:$LINENO: checking for _atan2f declaration" >&5
+echo $ECHO_N "checking for _atan2f declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func__atan2f_use+set} != xset; then
+ if test "${glibcxx_cv_func__atan2f_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ _atan2f(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func__atan2f_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func__atan2f_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func__atan2f_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func__atan2f_use" >&6
+
+ if test x$glibcxx_cv_func__atan2f_use = x"yes"; then
+
+for ac_func in _atan2f
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+
+ echo "$as_me:$LINENO: checking for fabsf declaration" >&5
+echo $ECHO_N "checking for fabsf declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func_fabsf_use+set} != xset; then
+ if test "${glibcxx_cv_func_fabsf_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ fabsf(0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func_fabsf_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func_fabsf_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func_fabsf_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func_fabsf_use" >&6
+
+ if test x$glibcxx_cv_func_fabsf_use = x"yes"; then
+
+for ac_func in fabsf
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ echo "$as_me:$LINENO: checking for _fabsf declaration" >&5
+echo $ECHO_N "checking for _fabsf declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func__fabsf_use+set} != xset; then
+ if test "${glibcxx_cv_func__fabsf_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ _fabsf(0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func__fabsf_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func__fabsf_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func__fabsf_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func__fabsf_use" >&6
+
+ if test x$glibcxx_cv_func__fabsf_use = x"yes"; then
+
+for ac_func in _fabsf
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+
+ echo "$as_me:$LINENO: checking for fmodf declaration" >&5
+echo $ECHO_N "checking for fmodf declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func_fmodf_use+set} != xset; then
+ if test "${glibcxx_cv_func_fmodf_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ fmodf(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func_fmodf_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func_fmodf_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func_fmodf_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func_fmodf_use" >&6
+
+ if test x$glibcxx_cv_func_fmodf_use = x"yes"; then
+
+for ac_func in fmodf
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ echo "$as_me:$LINENO: checking for _fmodf declaration" >&5
+echo $ECHO_N "checking for _fmodf declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func__fmodf_use+set} != xset; then
+ if test "${glibcxx_cv_func__fmodf_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ _fmodf(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func__fmodf_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func__fmodf_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func__fmodf_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func__fmodf_use" >&6
+
+ if test x$glibcxx_cv_func__fmodf_use = x"yes"; then
+
+for ac_func in _fmodf
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+
+ echo "$as_me:$LINENO: checking for frexpf declaration" >&5
+echo $ECHO_N "checking for frexpf declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func_frexpf_use+set} != xset; then
+ if test "${glibcxx_cv_func_frexpf_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ frexpf(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func_frexpf_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func_frexpf_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func_frexpf_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func_frexpf_use" >&6
+
+ if test x$glibcxx_cv_func_frexpf_use = x"yes"; then
+
+for ac_func in frexpf
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ echo "$as_me:$LINENO: checking for _frexpf declaration" >&5
+echo $ECHO_N "checking for _frexpf declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func__frexpf_use+set} != xset; then
+ if test "${glibcxx_cv_func__frexpf_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ _frexpf(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func__frexpf_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func__frexpf_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func__frexpf_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func__frexpf_use" >&6
+
+ if test x$glibcxx_cv_func__frexpf_use = x"yes"; then
+
+for ac_func in _frexpf
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+
+ echo "$as_me:$LINENO: checking for hypotf declaration" >&5
+echo $ECHO_N "checking for hypotf declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func_hypotf_use+set} != xset; then
+ if test "${glibcxx_cv_func_hypotf_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ hypotf(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func_hypotf_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func_hypotf_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func_hypotf_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func_hypotf_use" >&6
+
+ if test x$glibcxx_cv_func_hypotf_use = x"yes"; then
+
+for ac_func in hypotf
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ echo "$as_me:$LINENO: checking for _hypotf declaration" >&5
+echo $ECHO_N "checking for _hypotf declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func__hypotf_use+set} != xset; then
+ if test "${glibcxx_cv_func__hypotf_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ _hypotf(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func__hypotf_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func__hypotf_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func__hypotf_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func__hypotf_use" >&6
+
+ if test x$glibcxx_cv_func__hypotf_use = x"yes"; then
+
+for ac_func in _hypotf
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+
+ echo "$as_me:$LINENO: checking for ldexpf declaration" >&5
+echo $ECHO_N "checking for ldexpf declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func_ldexpf_use+set} != xset; then
+ if test "${glibcxx_cv_func_ldexpf_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ ldexpf(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func_ldexpf_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func_ldexpf_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func_ldexpf_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func_ldexpf_use" >&6
+
+ if test x$glibcxx_cv_func_ldexpf_use = x"yes"; then
+
+for ac_func in ldexpf
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ echo "$as_me:$LINENO: checking for _ldexpf declaration" >&5
+echo $ECHO_N "checking for _ldexpf declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func__ldexpf_use+set} != xset; then
+ if test "${glibcxx_cv_func__ldexpf_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ _ldexpf(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func__ldexpf_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func__ldexpf_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func__ldexpf_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func__ldexpf_use" >&6
+
+ if test x$glibcxx_cv_func__ldexpf_use = x"yes"; then
+
+for ac_func in _ldexpf
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+
+ echo "$as_me:$LINENO: checking for logf declaration" >&5
+echo $ECHO_N "checking for logf declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func_logf_use+set} != xset; then
+ if test "${glibcxx_cv_func_logf_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ logf(0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func_logf_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func_logf_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func_logf_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func_logf_use" >&6
+
+ if test x$glibcxx_cv_func_logf_use = x"yes"; then
+
+for ac_func in logf
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ echo "$as_me:$LINENO: checking for _logf declaration" >&5
+echo $ECHO_N "checking for _logf declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func__logf_use+set} != xset; then
+ if test "${glibcxx_cv_func__logf_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ _logf(0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func__logf_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func__logf_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func__logf_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func__logf_use" >&6
+
+ if test x$glibcxx_cv_func__logf_use = x"yes"; then
+
+for ac_func in _logf
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+
+ echo "$as_me:$LINENO: checking for log10f declaration" >&5
+echo $ECHO_N "checking for log10f declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func_log10f_use+set} != xset; then
+ if test "${glibcxx_cv_func_log10f_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ log10f(0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func_log10f_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func_log10f_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func_log10f_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func_log10f_use" >&6
+
+ if test x$glibcxx_cv_func_log10f_use = x"yes"; then
+
+for ac_func in log10f
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ echo "$as_me:$LINENO: checking for _log10f declaration" >&5
+echo $ECHO_N "checking for _log10f declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func__log10f_use+set} != xset; then
+ if test "${glibcxx_cv_func__log10f_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ _log10f(0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func__log10f_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func__log10f_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func__log10f_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func__log10f_use" >&6
+
+ if test x$glibcxx_cv_func__log10f_use = x"yes"; then
+
+for ac_func in _log10f
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+
+ echo "$as_me:$LINENO: checking for modff declaration" >&5
+echo $ECHO_N "checking for modff declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func_modff_use+set} != xset; then
+ if test "${glibcxx_cv_func_modff_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ modff(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func_modff_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func_modff_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func_modff_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func_modff_use" >&6
+
+ if test x$glibcxx_cv_func_modff_use = x"yes"; then
+
+for ac_func in modff
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ echo "$as_me:$LINENO: checking for _modff declaration" >&5
+echo $ECHO_N "checking for _modff declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func__modff_use+set} != xset; then
+ if test "${glibcxx_cv_func__modff_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ _modff(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func__modff_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func__modff_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func__modff_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func__modff_use" >&6
+
+ if test x$glibcxx_cv_func__modff_use = x"yes"; then
+
+for ac_func in _modff
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+
+ echo "$as_me:$LINENO: checking for modf declaration" >&5
+echo $ECHO_N "checking for modf declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func_modf_use+set} != xset; then
+ if test "${glibcxx_cv_func_modf_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ modf(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func_modf_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func_modf_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func_modf_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func_modf_use" >&6
+
+ if test x$glibcxx_cv_func_modf_use = x"yes"; then
+
+for ac_func in modf
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ echo "$as_me:$LINENO: checking for _modf declaration" >&5
+echo $ECHO_N "checking for _modf declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func__modf_use+set} != xset; then
+ if test "${glibcxx_cv_func__modf_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ _modf(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func__modf_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func__modf_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func__modf_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func__modf_use" >&6
+
+ if test x$glibcxx_cv_func__modf_use = x"yes"; then
+
+for ac_func in _modf
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+
+ echo "$as_me:$LINENO: checking for powf declaration" >&5
+echo $ECHO_N "checking for powf declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func_powf_use+set} != xset; then
+ if test "${glibcxx_cv_func_powf_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ powf(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func_powf_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func_powf_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func_powf_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func_powf_use" >&6
+
+ if test x$glibcxx_cv_func_powf_use = x"yes"; then
+
+for ac_func in powf
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ echo "$as_me:$LINENO: checking for _powf declaration" >&5
+echo $ECHO_N "checking for _powf declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func__powf_use+set} != xset; then
+ if test "${glibcxx_cv_func__powf_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ _powf(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func__powf_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func__powf_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func__powf_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func__powf_use" >&6
+
+ if test x$glibcxx_cv_func__powf_use = x"yes"; then
+
+for ac_func in _powf
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+
+ echo "$as_me:$LINENO: checking for sqrtf declaration" >&5
+echo $ECHO_N "checking for sqrtf declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func_sqrtf_use+set} != xset; then
+ if test "${glibcxx_cv_func_sqrtf_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ sqrtf(0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func_sqrtf_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func_sqrtf_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func_sqrtf_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func_sqrtf_use" >&6
+
+ if test x$glibcxx_cv_func_sqrtf_use = x"yes"; then
+
+for ac_func in sqrtf
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ echo "$as_me:$LINENO: checking for _sqrtf declaration" >&5
+echo $ECHO_N "checking for _sqrtf declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func__sqrtf_use+set} != xset; then
+ if test "${glibcxx_cv_func__sqrtf_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ _sqrtf(0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func__sqrtf_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func__sqrtf_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func__sqrtf_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func__sqrtf_use" >&6
+
+ if test x$glibcxx_cv_func__sqrtf_use = x"yes"; then
+
+for ac_func in _sqrtf
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+
+ echo "$as_me:$LINENO: checking for sincosf declaration" >&5
+echo $ECHO_N "checking for sincosf declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func_sincosf_use+set} != xset; then
+ if test "${glibcxx_cv_func_sincosf_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ sincosf(0, 0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func_sincosf_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func_sincosf_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func_sincosf_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func_sincosf_use" >&6
+
+ if test x$glibcxx_cv_func_sincosf_use = x"yes"; then
+
+for ac_func in sincosf
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ echo "$as_me:$LINENO: checking for _sincosf declaration" >&5
+echo $ECHO_N "checking for _sincosf declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func__sincosf_use+set} != xset; then
+ if test "${glibcxx_cv_func__sincosf_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ _sincosf(0, 0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func__sincosf_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func__sincosf_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func__sincosf_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func__sincosf_use" >&6
+
+ if test x$glibcxx_cv_func__sincosf_use = x"yes"; then
+
+for ac_func in _sincosf
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+
+ echo "$as_me:$LINENO: checking for finitef declaration" >&5
+echo $ECHO_N "checking for finitef declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func_finitef_use+set} != xset; then
+ if test "${glibcxx_cv_func_finitef_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ finitef(0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func_finitef_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func_finitef_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func_finitef_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func_finitef_use" >&6
+
+ if test x$glibcxx_cv_func_finitef_use = x"yes"; then
+
+for ac_func in finitef
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ echo "$as_me:$LINENO: checking for _finitef declaration" >&5
+echo $ECHO_N "checking for _finitef declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func__finitef_use+set} != xset; then
+ if test "${glibcxx_cv_func__finitef_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ _finitef(0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func__finitef_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func__finitef_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func__finitef_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func__finitef_use" >&6
+
+ if test x$glibcxx_cv_func__finitef_use = x"yes"; then
+
+for ac_func in _finitef
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+
+ echo "$as_me:$LINENO: checking for long double trig functions" >&5
+echo $ECHO_N "checking for long double trig functions... $ECHO_C" >&6
+ if test "${glibcxx_cv_func_long_double_trig_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+acosl (0); asinl (0); atanl (0); cosl (0); sinl (0); tanl (0); coshl (0); sinhl (0); tanhl (0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func_long_double_trig_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func_long_double_trig_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func_long_double_trig_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func_long_double_trig_use" >&6
+ if test x$glibcxx_cv_func_long_double_trig_use = x"yes"; then
+
+
+
+
+
+
+
+
+
+for ac_func in acosl asinl atanl cosl sinl tanl coshl sinhl tanhl
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ else
+ echo "$as_me:$LINENO: checking for _long double trig functions" >&5
+echo $ECHO_N "checking for _long double trig functions... $ECHO_C" >&6
+ if test "${glibcxx_cv_func__long_double_trig_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+_acosl (0); _asinl (0); _atanl (0); _cosl (0); _sinl (0); _tanl (0); _coshl (0); _sinhl (0); _tanhl (0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func__long_double_trig_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func__long_double_trig_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func__long_double_trig_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func__long_double_trig_use" >&6
+ if test x$glibcxx_cv_func__long_double_trig_use = x"yes"; then
+
+
+
+
+
+
+
+
+
+for ac_func in _acosl _asinl _atanl _cosl _sinl _tanl _coshl _sinhl _tanhl
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ echo "$as_me:$LINENO: checking for long double round functions" >&5
+echo $ECHO_N "checking for long double round functions... $ECHO_C" >&6
+ if test "${glibcxx_cv_func_long_double_round_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ceill (0); floorl (0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func_long_double_round_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func_long_double_round_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func_long_double_round_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func_long_double_round_use" >&6
+ if test x$glibcxx_cv_func_long_double_round_use = x"yes"; then
+
+
+for ac_func in ceill floorl
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ else
+ echo "$as_me:$LINENO: checking for _long double round functions" >&5
+echo $ECHO_N "checking for _long double round functions... $ECHO_C" >&6
+ if test "${glibcxx_cv_func__long_double_round_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+_ceill (0); _floorl (0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func__long_double_round_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func__long_double_round_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func__long_double_round_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func__long_double_round_use" >&6
+ if test x$glibcxx_cv_func__long_double_round_use = x"yes"; then
+
+
+for ac_func in _ceill _floorl
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+
+
+
+ echo "$as_me:$LINENO: checking for isnanl declaration" >&5
+echo $ECHO_N "checking for isnanl declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func_isnanl_use+set} != xset; then
+ if test "${glibcxx_cv_func_isnanl_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ isnanl(0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func_isnanl_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func_isnanl_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func_isnanl_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func_isnanl_use" >&6
+
+ if test x$glibcxx_cv_func_isnanl_use = x"yes"; then
+
+for ac_func in isnanl
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ echo "$as_me:$LINENO: checking for _isnanl declaration" >&5
+echo $ECHO_N "checking for _isnanl declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func__isnanl_use+set} != xset; then
+ if test "${glibcxx_cv_func__isnanl_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ _isnanl(0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func__isnanl_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func__isnanl_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func__isnanl_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func__isnanl_use" >&6
+
+ if test x$glibcxx_cv_func__isnanl_use = x"yes"; then
+
+for ac_func in _isnanl
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+
+ echo "$as_me:$LINENO: checking for isinfl declaration" >&5
+echo $ECHO_N "checking for isinfl declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func_isinfl_use+set} != xset; then
+ if test "${glibcxx_cv_func_isinfl_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ isinfl(0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func_isinfl_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func_isinfl_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func_isinfl_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func_isinfl_use" >&6
+
+ if test x$glibcxx_cv_func_isinfl_use = x"yes"; then
+
+for ac_func in isinfl
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ echo "$as_me:$LINENO: checking for _isinfl declaration" >&5
+echo $ECHO_N "checking for _isinfl declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func__isinfl_use+set} != xset; then
+ if test "${glibcxx_cv_func__isinfl_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ _isinfl(0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func__isinfl_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func__isinfl_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func__isinfl_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func__isinfl_use" >&6
+
+ if test x$glibcxx_cv_func__isinfl_use = x"yes"; then
+
+for ac_func in _isinfl
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+
+ echo "$as_me:$LINENO: checking for atan2l declaration" >&5
+echo $ECHO_N "checking for atan2l declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func_atan2l_use+set} != xset; then
+ if test "${glibcxx_cv_func_atan2l_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ atan2l(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func_atan2l_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func_atan2l_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func_atan2l_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func_atan2l_use" >&6
+
+ if test x$glibcxx_cv_func_atan2l_use = x"yes"; then
+
+for ac_func in atan2l
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ echo "$as_me:$LINENO: checking for _atan2l declaration" >&5
+echo $ECHO_N "checking for _atan2l declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func__atan2l_use+set} != xset; then
+ if test "${glibcxx_cv_func__atan2l_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ _atan2l(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func__atan2l_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func__atan2l_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func__atan2l_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func__atan2l_use" >&6
+
+ if test x$glibcxx_cv_func__atan2l_use = x"yes"; then
+
+for ac_func in _atan2l
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+
+ echo "$as_me:$LINENO: checking for expl declaration" >&5
+echo $ECHO_N "checking for expl declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func_expl_use+set} != xset; then
+ if test "${glibcxx_cv_func_expl_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ expl(0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func_expl_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func_expl_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func_expl_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func_expl_use" >&6
+
+ if test x$glibcxx_cv_func_expl_use = x"yes"; then
+
+for ac_func in expl
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ echo "$as_me:$LINENO: checking for _expl declaration" >&5
+echo $ECHO_N "checking for _expl declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func__expl_use+set} != xset; then
+ if test "${glibcxx_cv_func__expl_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ _expl(0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func__expl_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func__expl_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func__expl_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func__expl_use" >&6
+
+ if test x$glibcxx_cv_func__expl_use = x"yes"; then
+
+for ac_func in _expl
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+
+ echo "$as_me:$LINENO: checking for fabsl declaration" >&5
+echo $ECHO_N "checking for fabsl declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func_fabsl_use+set} != xset; then
+ if test "${glibcxx_cv_func_fabsl_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ fabsl(0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func_fabsl_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func_fabsl_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func_fabsl_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func_fabsl_use" >&6
+
+ if test x$glibcxx_cv_func_fabsl_use = x"yes"; then
+
+for ac_func in fabsl
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ echo "$as_me:$LINENO: checking for _fabsl declaration" >&5
+echo $ECHO_N "checking for _fabsl declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func__fabsl_use+set} != xset; then
+ if test "${glibcxx_cv_func__fabsl_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ _fabsl(0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func__fabsl_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func__fabsl_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func__fabsl_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func__fabsl_use" >&6
+
+ if test x$glibcxx_cv_func__fabsl_use = x"yes"; then
+
+for ac_func in _fabsl
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+
+ echo "$as_me:$LINENO: checking for fmodl declaration" >&5
+echo $ECHO_N "checking for fmodl declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func_fmodl_use+set} != xset; then
+ if test "${glibcxx_cv_func_fmodl_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ fmodl(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func_fmodl_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func_fmodl_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func_fmodl_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func_fmodl_use" >&6
+
+ if test x$glibcxx_cv_func_fmodl_use = x"yes"; then
+
+for ac_func in fmodl
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ echo "$as_me:$LINENO: checking for _fmodl declaration" >&5
+echo $ECHO_N "checking for _fmodl declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func__fmodl_use+set} != xset; then
+ if test "${glibcxx_cv_func__fmodl_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ _fmodl(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func__fmodl_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func__fmodl_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func__fmodl_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func__fmodl_use" >&6
+
+ if test x$glibcxx_cv_func__fmodl_use = x"yes"; then
+
+for ac_func in _fmodl
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+
+ echo "$as_me:$LINENO: checking for frexpl declaration" >&5
+echo $ECHO_N "checking for frexpl declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func_frexpl_use+set} != xset; then
+ if test "${glibcxx_cv_func_frexpl_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ frexpl(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func_frexpl_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func_frexpl_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func_frexpl_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func_frexpl_use" >&6
+
+ if test x$glibcxx_cv_func_frexpl_use = x"yes"; then
+
+for ac_func in frexpl
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ echo "$as_me:$LINENO: checking for _frexpl declaration" >&5
+echo $ECHO_N "checking for _frexpl declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func__frexpl_use+set} != xset; then
+ if test "${glibcxx_cv_func__frexpl_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ _frexpl(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func__frexpl_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func__frexpl_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func__frexpl_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func__frexpl_use" >&6
+
+ if test x$glibcxx_cv_func__frexpl_use = x"yes"; then
+
+for ac_func in _frexpl
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+
+ echo "$as_me:$LINENO: checking for hypotl declaration" >&5
+echo $ECHO_N "checking for hypotl declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func_hypotl_use+set} != xset; then
+ if test "${glibcxx_cv_func_hypotl_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ hypotl(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func_hypotl_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func_hypotl_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func_hypotl_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func_hypotl_use" >&6
+
+ if test x$glibcxx_cv_func_hypotl_use = x"yes"; then
+
+for ac_func in hypotl
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ echo "$as_me:$LINENO: checking for _hypotl declaration" >&5
+echo $ECHO_N "checking for _hypotl declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func__hypotl_use+set} != xset; then
+ if test "${glibcxx_cv_func__hypotl_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ _hypotl(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func__hypotl_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func__hypotl_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func__hypotl_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func__hypotl_use" >&6
+
+ if test x$glibcxx_cv_func__hypotl_use = x"yes"; then
+
+for ac_func in _hypotl
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+
+ echo "$as_me:$LINENO: checking for ldexpl declaration" >&5
+echo $ECHO_N "checking for ldexpl declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func_ldexpl_use+set} != xset; then
+ if test "${glibcxx_cv_func_ldexpl_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ ldexpl(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func_ldexpl_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func_ldexpl_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func_ldexpl_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func_ldexpl_use" >&6
+
+ if test x$glibcxx_cv_func_ldexpl_use = x"yes"; then
+
+for ac_func in ldexpl
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ echo "$as_me:$LINENO: checking for _ldexpl declaration" >&5
+echo $ECHO_N "checking for _ldexpl declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func__ldexpl_use+set} != xset; then
+ if test "${glibcxx_cv_func__ldexpl_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ _ldexpl(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func__ldexpl_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func__ldexpl_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func__ldexpl_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func__ldexpl_use" >&6
+
+ if test x$glibcxx_cv_func__ldexpl_use = x"yes"; then
+
+for ac_func in _ldexpl
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+
+ echo "$as_me:$LINENO: checking for logl declaration" >&5
+echo $ECHO_N "checking for logl declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func_logl_use+set} != xset; then
+ if test "${glibcxx_cv_func_logl_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ logl(0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func_logl_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func_logl_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func_logl_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func_logl_use" >&6
+
+ if test x$glibcxx_cv_func_logl_use = x"yes"; then
+
+for ac_func in logl
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ echo "$as_me:$LINENO: checking for _logl declaration" >&5
+echo $ECHO_N "checking for _logl declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func__logl_use+set} != xset; then
+ if test "${glibcxx_cv_func__logl_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ _logl(0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func__logl_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func__logl_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func__logl_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func__logl_use" >&6
+
+ if test x$glibcxx_cv_func__logl_use = x"yes"; then
+
+for ac_func in _logl
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+
+ echo "$as_me:$LINENO: checking for log10l declaration" >&5
+echo $ECHO_N "checking for log10l declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func_log10l_use+set} != xset; then
+ if test "${glibcxx_cv_func_log10l_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ log10l(0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func_log10l_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func_log10l_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func_log10l_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func_log10l_use" >&6
+
+ if test x$glibcxx_cv_func_log10l_use = x"yes"; then
+
+for ac_func in log10l
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ echo "$as_me:$LINENO: checking for _log10l declaration" >&5
+echo $ECHO_N "checking for _log10l declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func__log10l_use+set} != xset; then
+ if test "${glibcxx_cv_func__log10l_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ _log10l(0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func__log10l_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func__log10l_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func__log10l_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func__log10l_use" >&6
+
+ if test x$glibcxx_cv_func__log10l_use = x"yes"; then
+
+for ac_func in _log10l
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+
+ echo "$as_me:$LINENO: checking for modfl declaration" >&5
+echo $ECHO_N "checking for modfl declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func_modfl_use+set} != xset; then
+ if test "${glibcxx_cv_func_modfl_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ modfl(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func_modfl_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func_modfl_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func_modfl_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func_modfl_use" >&6
+
+ if test x$glibcxx_cv_func_modfl_use = x"yes"; then
+
+for ac_func in modfl
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ echo "$as_me:$LINENO: checking for _modfl declaration" >&5
+echo $ECHO_N "checking for _modfl declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func__modfl_use+set} != xset; then
+ if test "${glibcxx_cv_func__modfl_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ _modfl(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func__modfl_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func__modfl_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func__modfl_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func__modfl_use" >&6
+
+ if test x$glibcxx_cv_func__modfl_use = x"yes"; then
+
+for ac_func in _modfl
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+
+ echo "$as_me:$LINENO: checking for powl declaration" >&5
+echo $ECHO_N "checking for powl declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func_powl_use+set} != xset; then
+ if test "${glibcxx_cv_func_powl_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ powl(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func_powl_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func_powl_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func_powl_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func_powl_use" >&6
+
+ if test x$glibcxx_cv_func_powl_use = x"yes"; then
+
+for ac_func in powl
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ echo "$as_me:$LINENO: checking for _powl declaration" >&5
+echo $ECHO_N "checking for _powl declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func__powl_use+set} != xset; then
+ if test "${glibcxx_cv_func__powl_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ _powl(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func__powl_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func__powl_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func__powl_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func__powl_use" >&6
+
+ if test x$glibcxx_cv_func__powl_use = x"yes"; then
+
+for ac_func in _powl
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+
+ echo "$as_me:$LINENO: checking for sqrtl declaration" >&5
+echo $ECHO_N "checking for sqrtl declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func_sqrtl_use+set} != xset; then
+ if test "${glibcxx_cv_func_sqrtl_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ sqrtl(0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func_sqrtl_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func_sqrtl_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func_sqrtl_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func_sqrtl_use" >&6
+
+ if test x$glibcxx_cv_func_sqrtl_use = x"yes"; then
+
+for ac_func in sqrtl
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ echo "$as_me:$LINENO: checking for _sqrtl declaration" >&5
+echo $ECHO_N "checking for _sqrtl declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func__sqrtl_use+set} != xset; then
+ if test "${glibcxx_cv_func__sqrtl_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ _sqrtl(0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func__sqrtl_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func__sqrtl_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func__sqrtl_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func__sqrtl_use" >&6
+
+ if test x$glibcxx_cv_func__sqrtl_use = x"yes"; then
+
+for ac_func in _sqrtl
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+
+ echo "$as_me:$LINENO: checking for sincosl declaration" >&5
+echo $ECHO_N "checking for sincosl declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func_sincosl_use+set} != xset; then
+ if test "${glibcxx_cv_func_sincosl_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ sincosl(0, 0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func_sincosl_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func_sincosl_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func_sincosl_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func_sincosl_use" >&6
+
+ if test x$glibcxx_cv_func_sincosl_use = x"yes"; then
+
+for ac_func in sincosl
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ echo "$as_me:$LINENO: checking for _sincosl declaration" >&5
+echo $ECHO_N "checking for _sincosl declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func__sincosl_use+set} != xset; then
+ if test "${glibcxx_cv_func__sincosl_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+int
+main ()
+{
+ _sincosl(0, 0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func__sincosl_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func__sincosl_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func__sincosl_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func__sincosl_use" >&6
+
+ if test x$glibcxx_cv_func__sincosl_use = x"yes"; then
+
+for ac_func in _sincosl
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+
+ echo "$as_me:$LINENO: checking for finitel declaration" >&5
+echo $ECHO_N "checking for finitel declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func_finitel_use+set} != xset; then
+ if test "${glibcxx_cv_func_finitel_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ finitel(0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func_finitel_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func_finitel_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func_finitel_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func_finitel_use" >&6
+
+ if test x$glibcxx_cv_func_finitel_use = x"yes"; then
+
+for ac_func in finitel
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ else
+
+ echo "$as_me:$LINENO: checking for _finitel declaration" >&5
+echo $ECHO_N "checking for _finitel declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func__finitel_use+set} != xset; then
+ if test "${glibcxx_cv_func__finitel_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <math.h>
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #endif
+
+int
+main ()
+{
+ _finitel(0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func__finitel_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func__finitel_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func__finitel_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func__finitel_use" >&6
+
+ if test x$glibcxx_cv_func__finitel_use = x"yes"; then
+
+for ac_func in _finitel
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ fi
+ fi
+
+
+
+
+
+ LIBS="$ac_save_LIBS"
+ CXXFLAGS="$ac_save_CXXFLAGS"
+
+
+ ac_test_CXXFLAGS="${CXXFLAGS+set}"
+ ac_save_CXXFLAGS="$CXXFLAGS"
+ CXXFLAGS='-fno-builtin -D_GNU_SOURCE'
+
+
+ echo "$as_me:$LINENO: checking for strtold declaration" >&5
+echo $ECHO_N "checking for strtold declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func_strtold_use+set} != xset; then
+ if test "${glibcxx_cv_func_strtold_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+int
+main ()
+{
+ strtold(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func_strtold_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func_strtold_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func_strtold_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func_strtold_use" >&6
+ if test x$glibcxx_cv_func_strtold_use = x"yes"; then
+
+for ac_func in strtold
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ fi
+
+
+
+
+
+ echo "$as_me:$LINENO: checking for strtof declaration" >&5
+echo $ECHO_N "checking for strtof declaration... $ECHO_C" >&6
+ if test x${glibcxx_cv_func_strtof_use+set} != xset; then
+ if test "${glibcxx_cv_func_strtof_use+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+
+
+ ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+int
+main ()
+{
+ strtof(0, 0);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_cxx_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ glibcxx_cv_func_strtof_use=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+glibcxx_cv_func_strtof_use=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+
+ fi
+ echo "$as_me:$LINENO: result: $glibcxx_cv_func_strtof_use" >&5
+echo "${ECHO_T}$glibcxx_cv_func_strtof_use" >&6
+ if test x$glibcxx_cv_func_strtof_use = x"yes"; then
+
+for ac_func in strtof
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_var=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ fi
+
+
+
+
+
+ CXXFLAGS="$ac_save_CXXFLAGS"
+
+ cat >>confdefs.h <<\_ACEOF
+#define _GLIBCXX_USE_RANDOM_TR1 1
+_ACEOF
+
+ # We don't yet support AIX's TLS ABI.
+ #GCC_CHECK_TLS
+
+
+
+
+
+ am_save_CPPFLAGS="$CPPFLAGS"
+
+ for element in $INCICONV; do
+ haveit=
+ for x in $CPPFLAGS; do
+
+ acl_save_prefix="$prefix"
+ prefix="$acl_final_prefix"
+ acl_save_exec_prefix="$exec_prefix"
+ exec_prefix="$acl_final_exec_prefix"
+ eval x=\"$x\"
+ exec_prefix="$acl_save_exec_prefix"
+ prefix="$acl_save_prefix"
+
+ if test "X$x" = "X$element"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element"
+ fi
+ done
+
+
+ echo "$as_me:$LINENO: checking for iconv" >&5
+echo $ECHO_N "checking for iconv... $ECHO_C" >&6
+if test "${am_cv_func_iconv+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ am_cv_func_iconv="no, consider installing GNU libiconv"
+ am_cv_lib_iconv=no
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <iconv.h>
+int
+main ()
+{
+iconv_t cd = iconv_open("","");
+ iconv(cd,NULL,NULL,NULL,NULL);
+ iconv_close(cd);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ am_cv_func_iconv=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ if test "$am_cv_func_iconv" != yes; then
+ am_save_LIBS="$LIBS"
+ LIBS="$LIBS $LIBICONV"
+ if test x$gcc_no_link = xyes; then
+ { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <iconv.h>
+int
+main ()
+{
+iconv_t cd = iconv_open("","");
+ iconv(cd,NULL,NULL,NULL,NULL);
+ iconv_close(cd);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ am_cv_lib_iconv=yes
+ am_cv_func_iconv=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LIBS="$am_save_LIBS"
+ fi
+
+fi
+echo "$as_me:$LINENO: result: $am_cv_func_iconv" >&5
+echo "${ECHO_T}$am_cv_func_iconv" >&6
+ if test "$am_cv_func_iconv" = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_ICONV 1
+_ACEOF
+
+ fi
+ if test "$am_cv_lib_iconv" = yes; then
+ echo "$as_me:$LINENO: checking how to link with libiconv" >&5
+echo $ECHO_N "checking how to link with libiconv... $ECHO_C" >&6
+ echo "$as_me:$LINENO: result: $LIBICONV" >&5
+echo "${ECHO_T}$LIBICONV" >&6
+ else
+ CPPFLAGS="$am_save_CPPFLAGS"
+ LIBICONV=
+ LTLIBICONV=
+ fi
+
+
+
+ if test "$am_cv_func_iconv" = yes; then
+ echo "$as_me:$LINENO: checking for iconv declaration" >&5
+echo $ECHO_N "checking for iconv declaration... $ECHO_C" >&6
+ if test "${am_cv_proto_iconv+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+#include <stdlib.h>
+#include <iconv.h>
+extern
+#ifdef __cplusplus
+"C"
+#endif
+#if defined(__STDC__) || defined(__cplusplus)
+size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);
+#else
+size_t iconv();
+#endif
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ am_cv_proto_iconv_arg1=""
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+am_cv_proto_iconv_arg1="const"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"
+fi
+
+ am_cv_proto_iconv=`echo "$am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'`
+ echo "$as_me:$LINENO: result: ${ac_t:-
+ }$am_cv_proto_iconv" >&5
+echo "${ECHO_T}${ac_t:-
+ }$am_cv_proto_iconv" >&6
+
+cat >>confdefs.h <<_ACEOF
+#define ICONV_CONST $am_cv_proto_iconv_arg1
+_ACEOF
+
+ fi
+
+ ;;
+
*-darwin*)
# Darwin versions vary, but the linker should work in a cross environment,
# so we just check for all the features here.
@@ -118371,7 +135823,7 @@ else
fi
- ac_config_files="$ac_config_files Makefile include/Makefile libsupc++/Makefile src/Makefile doc/Makefile po/Makefile testsuite/Makefile"
+ ac_config_files="$ac_config_files Makefile include/Makefile libsupc++/Makefile python/Makefile src/Makefile doc/Makefile po/Makefile testsuite/Makefile"
ac_config_files="$ac_config_files scripts/testsuite_flags"
@@ -119026,6 +136478,9 @@ ac_configure_args="${multilib_arg} ${ac_configure_args}"
multi_basedir="$multi_basedir"
CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
CC="$CC"
+CXX="$CXX"
+GFORTRAN="$GFORTRAN"
+GCJ="$GCJ"
# The HP-UX ksh and POSIX shell print the target directory to stdout
@@ -119413,6 +136868,7 @@ do
"Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
"include/Makefile" ) CONFIG_FILES="$CONFIG_FILES include/Makefile" ;;
"libsupc++/Makefile" ) CONFIG_FILES="$CONFIG_FILES libsupc++/Makefile" ;;
+ "python/Makefile" ) CONFIG_FILES="$CONFIG_FILES python/Makefile" ;;
"src/Makefile" ) CONFIG_FILES="$CONFIG_FILES src/Makefile" ;;
"doc/Makefile" ) CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;;
"po/Makefile" ) CONFIG_FILES="$CONFIG_FILES po/Makefile" ;;
diff --git a/libstdc++-v3/crossconfig.m4 b/libstdc++-v3/crossconfig.m4
index 16a19dc4689..fdaa9d6d0dd 100644
--- a/libstdc++-v3/crossconfig.m4
+++ b/libstdc++-v3/crossconfig.m4
@@ -28,6 +28,16 @@ case "${host}" in
AC_DEFINE(HAVE_SQRTF)
;;
+ *-aix*)
+ GLIBCXX_CHECK_LINKER_FEATURES
+ GLIBCXX_CHECK_MATH_SUPPORT
+ GLIBCXX_CHECK_STDLIB_SUPPORT
+ AC_DEFINE(_GLIBCXX_USE_RANDOM_TR1)
+ # We don't yet support AIX's TLS ABI.
+ #GCC_CHECK_TLS
+ AM_ICONV
+ ;;
+
*-darwin*)
# Darwin versions vary, but the linker should work in a cross environment,
# so we just check for all the features here.
diff --git a/libstdc++-v3/doc/xml/manual/status_cxx200x.xml b/libstdc++-v3/doc/xml/manual/status_cxx200x.xml
index 159bc9fec39..61b2ec2c2ab 100644
--- a/libstdc++-v3/doc/xml/manual/status_cxx200x.xml
+++ b/libstdc++-v3/doc/xml/manual/status_cxx200x.xml
@@ -235,10 +235,9 @@ particular release.
<entry></entry>
</row>
<row>
- <?dbhtml bgcolor="#C8B0B0" ?>
<entry>18.8.6</entry>
<entry>Class <code>nested_exception</code></entry>
- <entry>N</entry>
+ <entry>Y</entry>
<entry></entry>
</row>
<row>
@@ -404,8 +403,8 @@ particular release.
<row>
<entry>20.3.6</entry>
<entry>Class template <code>bitset</code></entry>
- <entry>Y</entry>
- <entry></entry>
+ <entry>Partial</entry>
+ <entry>Missing constexpr</entry>
</row>
<row>
<entry>20.4</entry>
@@ -942,8 +941,8 @@ particular release.
<row>
<entry>20.9.2.2</entry>
<entry><code>duration_values</code></entry>
- <entry>Y</entry>
- <entry></entry>
+ <entry>Partial</entry>
+ <entry>Missing constexpr</entry>
</row>
<row>
<entry>20.9.2.3</entry>
@@ -954,14 +953,14 @@ particular release.
<row>
<entry>20.9.3</entry>
<entry>Class template <code>duration</code></entry>
- <entry>Y</entry>
- <entry></entry>
+ <entry>Partial</entry>
+ <entry>Missing constexpr</entry>
</row>
<row>
<entry>20.9.4</entry>
<entry>Class template <code>time_point</code></entry>
- <entry>Y</entry>
- <entry></entry>
+ <entry>Partial</entry>
+ <entry>Missing constexpr</entry>
</row>
<row>
<entry>20.9.5</entry>
@@ -1034,26 +1033,26 @@ particular release.
<row>
<entry>21.2.3.1</entry>
<entry>struct <code>char_traits&lt;char&gt;</code></entry>
- <entry>Y</entry>
- <entry></entry>
+ <entry>Partial</entry>
+ <entry>Missing constexpr</entry>
</row>
<row>
<entry>21.2.3.2</entry>
<entry>struct <code>char_traits&lt;char16_t&gt;</code></entry>
- <entry>Y</entry>
- <entry></entry>
+ <entry>Partial</entry>
+ <entry>Missing constexpr</entry>
</row>
<row>
<entry>21.2.3.3</entry>
<entry>struct <code>char_traits&lt;char32_t&gt;</code></entry>
- <entry>Y</entry>
- <entry></entry>
+ <entry>Partial</entry>
+ <entry>Missing constexpr</entry>
</row>
<row>
<entry>21.2.3.4</entry>
<entry>struct <code>char_traits&lt;wchar_t&gt;</code></entry>
- <entry>Y</entry>
- <entry></entry>
+ <entry>Partial</entry>
+ <entry>Missing constexpr</entry>
</row>
<row>
<entry>21.3</entry>
@@ -1325,8 +1324,8 @@ particular release.
<row>
<entry>23.3.1</entry>
<entry>Class template <code>array</code></entry>
- <entry>Y</entry>
- <entry></entry>
+ <entry>Partial</entry>
+ <entry>Missing constexpr</entry>
</row>
<row>
<entry>23.3.2</entry>
@@ -1629,8 +1628,8 @@ particular release.
<row>
<entry>26.4</entry>
<entry>Complex numbers</entry>
- <entry>Y</entry>
- <entry></entry>
+ <entry>Partial</entry>
+ <entry>Missing constexpr</entry>
</row>
<row>
<entry>26.5</entry>
@@ -1662,19 +1661,19 @@ particular release.
<entry>26.5.3.1</entry>
<entry>Class template <code>linear_congruential_engine</code></entry>
<entry>Y</entry>
- <entry></entry>
+ <entry>Missing constexpr</entry>
</row>
<row>
<entry>26.5.3.2</entry>
<entry>Class template <code>mersenne_twister_engine</code></entry>
<entry>Y</entry>
- <entry></entry>
+ <entry>Missing constexpr</entry>
</row>
<row>
<entry>26.5.3.3</entry>
<entry>Class template <code>subtract_with_carry_engine</code></entry>
<entry>Y</entry>
- <entry></entry>
+ <entry>Missing constexpr</entry>
</row>
<row>
<entry>26.5.4</entry>
@@ -1686,19 +1685,19 @@ particular release.
<entry>26.5.4.1</entry>
<entry>Class template <code>discard_block_engine</code></entry>
<entry>Y</entry>
- <entry></entry>
+ <entry>Missing constexpr</entry>
</row>
<row>
<entry>26.5.4.2</entry>
<entry>Class template <code>independent_bits_engine</code></entry>
<entry>Y</entry>
- <entry></entry>
+ <entry>Missing constexpr</entry>
</row>
<row>
<entry>26.5.4.3</entry>
<entry>Class template <code>shuffle_order_engine</code></entry>
<entry>Y</entry>
- <entry></entry>
+ <entry>Missing constexpr</entry>
</row>
<row>
<entry>26.5.5</entry>
@@ -1710,7 +1709,7 @@ particular release.
<entry>26.5.6</entry>
<entry>Class <code>random_device</code></entry>
<entry>Y</entry>
- <entry></entry>
+ <entry>Missing constexpr</entry>
</row>
<row>
<entry>26.5.7</entry>
@@ -2375,8 +2374,8 @@ particular release.
<row>
<entry>30.4.5.1</entry>
<entry><code>once_flag</code></entry>
- <entry>Y</entry>
- <entry></entry>
+ <entry>Partial</entry>
+ <entry>Missing constexpr</entry>
</row>
<row>
<entry>30.4.5.2</entry>
diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index 6e7b28303e1..6a9c4f09ed4 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -852,7 +852,7 @@ pch_output_dirs = \
${pch1_output_builddir} ${pch2_output_builddir} ${pch3_output_builddir}
pch_output_anchors = \
${pch1_output_anchor} ${pch2_output_anchor} ${pch3_output_anchor}
-PCHFLAGS=-Winvalid-pch -x c++-header $(CXXFLAGS)
+PCHFLAGS=-x c++-header $(CXXFLAGS)
if GLIBCXX_BUILD_PCH
pch_build = ${pch_output}
else
diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in
index 9f8782c5ea8..4ac2739cb43 100644
--- a/libstdc++-v3/include/Makefile.in
+++ b/libstdc++-v3/include/Makefile.in
@@ -1098,7 +1098,7 @@ pch_output_dirs = \
pch_output_anchors = \
${pch1_output_anchor} ${pch2_output_anchor} ${pch3_output_anchor}
-PCHFLAGS = -Winvalid-pch -x c++-header $(CXXFLAGS)
+PCHFLAGS = -x c++-header $(CXXFLAGS)
@GLIBCXX_BUILD_PCH_FALSE@pch_build =
@GLIBCXX_BUILD_PCH_TRUE@pch_build = ${pch_output}
diff --git a/libstdc++-v3/include/bits/forward_list.h b/libstdc++-v3/include/bits/forward_list.h
index d49eb4a0678..724d87b01b1 100644
--- a/libstdc++-v3/include/bits/forward_list.h
+++ b/libstdc++-v3/include/bits/forward_list.h
@@ -983,7 +983,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
* function.
*/
void
- swap(forward_list&& __list)
+ swap(forward_list& __list)
{ _Node_base::swap(this->_M_impl._M_head, __list._M_impl._M_head); }
/**
@@ -1285,20 +1285,6 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
forward_list<_Tp, _Alloc>& __ly)
{ __lx.swap(__ly); }
- /// See std::forward_list::swap().
- template<typename _Tp, typename _Alloc>
- inline void
- swap(forward_list<_Tp, _Alloc>&& __lx,
- forward_list<_Tp, _Alloc>& __ly)
- { __lx.swap(__ly); }
-
- /// See std::forward_list::swap().
- template<typename _Tp, typename _Alloc>
- inline void
- swap(forward_list<_Tp, _Alloc>& __lx,
- forward_list<_Tp, _Alloc>&& __ly)
- { __lx.swap(__ly); }
-
_GLIBCXX_END_NAMESPACE // namespace std
#endif // __GXX_EXPERIMENTAL_CXX0X__
diff --git a/libstdc++-v3/include/bits/locale_classes.h b/libstdc++-v3/include/bits/locale_classes.h
index 1a7f2c20912..7ae9c53bc6a 100644
--- a/libstdc++-v3/include/bits/locale_classes.h
+++ b/libstdc++-v3/include/bits/locale_classes.h
@@ -381,6 +381,9 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
static void
_S_destroy_c_locale(__c_locale& __cloc);
+ static __c_locale
+ _S_lc_ctype_c_locale(__c_locale __cloc, const char* __s);
+
// Returns data from the underlying "C" library data for the
// classic locale.
static __c_locale
diff --git a/libstdc++-v3/include/bits/move.h b/libstdc++-v3/include/bits/move.h
index ef86c4d1206..25773e13c48 100644
--- a/libstdc++-v3/include/bits/move.h
+++ b/libstdc++-v3/include/bits/move.h
@@ -39,18 +39,25 @@
_GLIBCXX_BEGIN_NAMESPACE(std)
- // 20.2.2, forward/move
+ /// identity
template<typename _Tp>
struct identity
{
typedef _Tp type;
};
+ /// forward
template<typename _Tp>
inline _Tp&&
forward(typename std::identity<_Tp>::type&& __t)
{ return __t; }
+ /**
+ * @brief Move a value.
+ * @ingroup mutating_algorithms
+ * @param __t A thing of arbitrary type.
+ * @return Same, moved.
+ */
template<typename _Tp>
inline typename std::remove_reference<_Tp>::type&&
move(_Tp&& __t)
@@ -67,8 +74,9 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
/**
* @brief Swaps two values.
- * @param a A thing of arbitrary type.
- * @param b Another thing of arbitrary type.
+ * @ingroup mutating_algorithms
+ * @param __a A thing of arbitrary type.
+ * @param __b Another thing of arbitrary type.
* @return Nothing.
*/
template<typename _Tp>
diff --git a/libstdc++-v3/include/bits/random.h b/libstdc++-v3/include/bits/random.h
index 425420607ce..e8edbf05dd4 100644
--- a/libstdc++-v3/include/bits/random.h
+++ b/libstdc++-v3/include/bits/random.h
@@ -68,23 +68,6 @@ namespace std
struct _Shift<_UIntType, __w, true>
{ static const _UIntType __value = _UIntType(1) << __w; };
- // XXX need constexpr
- template<typename _UIntType, size_t __w,
- bool = __w < static_cast<size_t>
- (std::numeric_limits<_UIntType>::digits)>
- struct _ShiftMin1
- {
- static const _UIntType __value =
- __gnu_cxx::__numeric_traits<_UIntType>::__max;
- };
-
- template<typename _UIntType, size_t __w>
- struct _ShiftMin1<_UIntType, __w, true>
- {
- static const _UIntType __value =
- (_UIntType(1) << __w) - _UIntType(1);
- };
-
template<typename _Tp, _Tp __a, _Tp __c, _Tp __m, bool>
struct _Mod;
@@ -285,7 +268,11 @@ namespace std
* @brief Gets the next random number in the sequence.
*/
result_type
- operator()();
+ operator()()
+ {
+ _M_x = __detail::__mod<_UIntType, __a, __c, __m>(_M_x);
+ return _M_x;
+ }
/**
* @brief Compares two linear congruential random number generator
@@ -395,11 +382,11 @@ namespace std
static_assert(__w <=
static_cast<size_t>(numeric_limits<_UIntType>::digits),
"mersenne_twister_engine template arguments out of bounds");
- static_assert(__a <= __detail::_ShiftMin1<_UIntType, __w>::__value,
+ static_assert(__a <= (__detail::_Shift<_UIntType, __w>::__value - 1),
"mersenne_twister_engine template arguments out of bounds");
- static_assert(__b <= __detail::_ShiftMin1<_UIntType, __w>::__value,
+ static_assert(__b <= (__detail::_Shift<_UIntType, __w>::__value - 1),
"mersenne_twister_engine template arguments out of bounds");
- static_assert(__c <= __detail::_ShiftMin1<_UIntType, __w>::__value,
+ static_assert(__c <= (__detail::_Shift<_UIntType, __w>::__value - 1),
"mersenne_twister_engine template arguments out of bounds");
public:
@@ -459,7 +446,7 @@ namespace std
*/
result_type
max() const
- { return __detail::_ShiftMin1<_UIntType, __w>::__value; }
+ { return __detail::_Shift<_UIntType, __w>::__value - 1; }
/**
* @brief Discard a sequence of random numbers.
@@ -644,7 +631,7 @@ namespace std
*/
result_type
max() const
- { return __detail::_ShiftMin1<_UIntType, __w>::__value; }
+ { return __detail::_Shift<_UIntType, __w>::__value - 1; }
/**
* @brief Discard a sequence of random numbers.
@@ -1040,7 +1027,7 @@ namespace std
*/
result_type
max() const
- { return __detail::_ShiftMin1<_UIntType, __w>::__value; }
+ { return __detail::_Shift<_UIntType, __w>::__value - 1; }
/**
* @brief Discard a sequence of random numbers.
@@ -1605,12 +1592,7 @@ namespace std
template<typename _UniformRandomNumberGenerator>
result_type
operator()(_UniformRandomNumberGenerator& __urng)
- {
- typedef typename _UniformRandomNumberGenerator::result_type
- _UResult_type;
- return _M_call(__urng, this->a(), this->b(),
- typename is_integral<_UResult_type>::type());
- }
+ { return this->operator()(__urng, this->param()); }
/**
* Gets a uniform random number in the range @f$[0, n)@f$.
@@ -1782,11 +1764,7 @@ namespace std
template<typename _UniformRandomNumberGenerator>
result_type
operator()(_UniformRandomNumberGenerator& __urng)
- {
- __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
- __aurng(__urng);
- return (__aurng() * (this->b() - this->a())) + this->a();
- }
+ { return this->operator()(__urng, this->param()); }
template<typename _UniformRandomNumberGenerator>
result_type
@@ -2031,12 +2009,12 @@ namespace std
explicit
lognormal_distribution(_RealType __m = _RealType(0),
_RealType __s = _RealType(1))
- : _M_param(__m, __s)
+ : _M_param(__m, __s), _M_nd()
{ }
explicit
lognormal_distribution(const param_type& __p)
- : _M_param(__p)
+ : _M_param(__p), _M_nd()
{ }
/**
@@ -2044,7 +2022,7 @@ namespace std
*/
void
reset()
- { }
+ { _M_nd.reset(); }
/**
*
@@ -2094,10 +2072,13 @@ namespace std
template<typename _UniformRandomNumberGenerator>
result_type
operator()(_UniformRandomNumberGenerator& __urng,
- const param_type& __p);
+ const param_type& __p)
+ { return std::exp(__p.s() * _M_nd(__urng) + __p.m()); }
private:
param_type _M_param;
+
+ std::normal_distribution<result_type> _M_nd;
};
/**
@@ -2130,6 +2111,164 @@ namespace std
operator>>(std::basic_istream<_CharT, _Traits>&,
std::lognormal_distribution<_RealType>&);
+
+ /**
+ * @brief A gamma continuous distribution for random numbers.
+ *
+ * The formula for the gamma probability density function is
+ * @f$ p(x|\alpha,\beta) = \frac{1}{\beta\Gamma(\alpha)}
+ * (x/\beta)^{\alpha - 1} e^{-x/\beta} @f$.
+ */
+ template<typename _RealType = double>
+ class gamma_distribution
+ {
+ public:
+ /** The type of the range of the distribution. */
+ typedef _RealType result_type;
+ /** Parameter type. */
+ struct param_type
+ {
+ typedef gamma_distribution<_RealType> distribution_type;
+ friend class gamma_distribution<_RealType>;
+
+ explicit
+ param_type(_RealType __alpha_val = _RealType(1),
+ _RealType __beta_val = _RealType(1))
+ : _M_alpha(__alpha_val), _M_beta(__beta_val)
+ {
+ _GLIBCXX_DEBUG_ASSERT(_M_alpha > _RealType(0));
+ _M_initialize();
+ }
+
+ _RealType
+ alpha() const
+ { return _M_alpha; }
+
+ _RealType
+ beta() const
+ { return _M_beta; }
+
+ private:
+ void
+ _M_initialize();
+
+ _RealType _M_alpha;
+ _RealType _M_beta;
+
+ _RealType _M_malpha, _M_a2;
+ };
+
+ public:
+ /**
+ * @brief Constructs a gamma distribution with parameters
+ * @f$ \alpha @f$ and @f$ \beta @f$.
+ */
+ explicit
+ gamma_distribution(_RealType __alpha_val = _RealType(1),
+ _RealType __beta_val = _RealType(1))
+ : _M_param(__alpha_val, __beta_val), _M_nd()
+ { }
+
+ explicit
+ gamma_distribution(const param_type& __p)
+ : _M_param(__p), _M_nd()
+ { }
+
+ /**
+ * @brief Resets the distribution state.
+ */
+ void
+ reset()
+ { _M_nd.reset(); }
+
+ /**
+ * @brief Returns the @f$ \alpha @f$ of the distribution.
+ */
+ _RealType
+ alpha() const
+ { return _M_param.alpha(); }
+
+ /**
+ * @brief Returns the @f$ \beta @f$ of the distribution.
+ */
+ _RealType
+ beta() const
+ { return _M_param.beta(); }
+
+ /**
+ * @brief Returns the parameter set of the distribution.
+ */
+ param_type
+ param() const
+ { return _M_param; }
+
+ /**
+ * @brief Sets the parameter set of the distribution.
+ * @param __param The new parameter set of the distribution.
+ */
+ void
+ param(const param_type& __param)
+ { _M_param = __param; }
+
+ /**
+ * @brief Returns the greatest lower bound value of the distribution.
+ */
+ result_type
+ min() const
+ { return result_type(0); }
+
+ /**
+ * @brief Returns the least upper bound value of the distribution.
+ */
+ result_type
+ max() const
+ { return std::numeric_limits<result_type>::max(); }
+
+ template<typename _UniformRandomNumberGenerator>
+ result_type
+ operator()(_UniformRandomNumberGenerator& __urng)
+ { return this->operator()(__urng, this->param()); }
+
+ template<typename _UniformRandomNumberGenerator>
+ result_type
+ operator()(_UniformRandomNumberGenerator& __urng,
+ const param_type& __p);
+
+ private:
+ param_type _M_param;
+
+ std::normal_distribution<result_type> _M_nd;
+ };
+
+ /**
+ * @brief Inserts a %gamma_distribution random number distribution
+ * @p __x into the output stream @p __os.
+ *
+ * @param __os An output stream.
+ * @param __x A %gamma_distribution random number distribution.
+ *
+ * @returns The output stream with the state of @p __x inserted or in
+ * an error state.
+ */
+ template<typename _RealType, typename _CharT, typename _Traits>
+ std::basic_ostream<_CharT, _Traits>&
+ operator<<(std::basic_ostream<_CharT, _Traits>&,
+ const std::gamma_distribution<_RealType>&);
+
+ /**
+ * @brief Extracts a %gamma_distribution random number distribution
+ * @p __x from the input stream @p __is.
+ *
+ * @param __is An input stream.
+ * @param __x A %gamma_distribution random number generator engine.
+ *
+ * @returns The input stream with @p __x extracted or in an error state.
+ */
+ template<typename _RealType, typename _CharT, typename _Traits>
+ std::basic_istream<_CharT, _Traits>&
+ operator>>(std::basic_istream<_CharT, _Traits>&,
+ std::gamma_distribution<_RealType>&);
+
/**
* @brief A chi_squared_distribution random number distribution.
@@ -2163,12 +2302,12 @@ namespace std
explicit
chi_squared_distribution(_RealType __n = _RealType(1))
- : _M_param(__n)
+ : _M_param(__n), _M_gd(__n / 2)
{ }
explicit
chi_squared_distribution(const param_type& __p)
- : _M_param(__p)
+ : _M_param(__p), _M_gd(__p.n() / 2)
{ }
/**
@@ -2176,7 +2315,7 @@ namespace std
*/
void
reset()
- { }
+ { _M_gd.reset(); }
/**
*
@@ -2217,15 +2356,22 @@ namespace std
template<typename _UniformRandomNumberGenerator>
result_type
operator()(_UniformRandomNumberGenerator& __urng)
- { return this->operator()(__urng, this->param()); }
+ { return 2 * _M_gd(__urng); }
template<typename _UniformRandomNumberGenerator>
result_type
operator()(_UniformRandomNumberGenerator& __urng,
- const param_type& __p);
+ const param_type& __p)
+ {
+ typedef typename std::gamma_distribution<result_type>::param_type
+ param_type;
+ return 2 * _M_gd(__urng, param_type(__p.n() / 2));
+ }
private:
param_type _M_param;
+
+ std::gamma_distribution<result_type> _M_gd;
};
/**
@@ -2439,12 +2585,12 @@ namespace std
explicit
fisher_f_distribution(_RealType __m = _RealType(1),
_RealType __n = _RealType(1))
- : _M_param(__m, __n)
+ : _M_param(__m, __n), _M_gd_x(__m / 2), _M_gd_y(__n / 2)
{ }
explicit
fisher_f_distribution(const param_type& __p)
- : _M_param(__p)
+ : _M_param(__p), _M_gd_x(__p.m() / 2), _M_gd_y(__p.n() / 2)
{ }
/**
@@ -2452,7 +2598,10 @@ namespace std
*/
void
reset()
- { }
+ {
+ _M_gd_x.reset();
+ _M_gd_y.reset();
+ }
/**
*
@@ -2497,15 +2646,23 @@ namespace std
template<typename _UniformRandomNumberGenerator>
result_type
operator()(_UniformRandomNumberGenerator& __urng)
- { return this->operator()(__urng, this->param()); }
+ { return (_M_gd_x(__urng) * n()) / (_M_gd_y(__urng) * m()); }
template<typename _UniformRandomNumberGenerator>
result_type
operator()(_UniformRandomNumberGenerator& __urng,
- const param_type& __p);
+ const param_type& __p)
+ {
+ typedef typename std::gamma_distribution<result_type>::param_type
+ param_type;
+ return ((_M_gd_x(__urng, param_type(__p.m() / 2)) * n())
+ / (_M_gd_y(__urng, param_type(__p.n() / 2)) * m()));
+ }
private:
param_type _M_param;
+
+ std::gamma_distribution<result_type> _M_gd_x, _M_gd_y;
};
/**
@@ -2572,12 +2729,12 @@ namespace std
explicit
student_t_distribution(_RealType __n = _RealType(1))
- : _M_param(__n)
+ : _M_param(__n), _M_nd(), _M_gd(__n / 2, 2)
{ }
explicit
student_t_distribution(const param_type& __p)
- : _M_param(__p)
+ : _M_param(__p), _M_nd(), _M_gd(__p.n() / 2, 2)
{ }
/**
@@ -2585,7 +2742,10 @@ namespace std
*/
void
reset()
- { }
+ {
+ _M_nd.reset();
+ _M_gd.reset();
+ }
/**
*
@@ -2625,21 +2785,26 @@ namespace std
template<typename _UniformRandomNumberGenerator>
result_type
- operator()(_UniformRandomNumberGenerator& __urng)
- { return this->operator()(__urng, this->param()); }
+ operator()(_UniformRandomNumberGenerator& __urng)
+ { return _M_nd(__urng) * std::sqrt(n() / _M_gd(__urng)); }
template<typename _UniformRandomNumberGenerator>
result_type
operator()(_UniformRandomNumberGenerator& __urng,
- const param_type& __p);
+ const param_type& __p)
+ {
+ typedef typename std::gamma_distribution<result_type>::param_type
+ param_type;
+
+ const result_type __g = _M_gd(__urng, param_type(__p.n() / 2, 2));
+ return _M_nd(__urng) * std::sqrt(__p.n() / __g);
+ }
private:
- template<typename _UniformRandomNumberGenerator>
- result_type
- _M_gaussian(_UniformRandomNumberGenerator& __urng,
- const result_type __sigma);
-
param_type _M_param;
+
+ std::normal_distribution<result_type> _M_nd;
+ std::gamma_distribution<result_type> _M_gd;
};
/**
@@ -2778,14 +2943,7 @@ namespace std
template<typename _UniformRandomNumberGenerator>
result_type
operator()(_UniformRandomNumberGenerator& __urng)
- {
- __detail::_Adaptor<_UniformRandomNumberGenerator, double>
- __aurng(__urng);
- if ((__aurng() - __aurng.min())
- < this->p() * (__aurng.max() - __aurng.min()))
- return true;
- return false;
- }
+ { return this->operator()(__urng, this->param()); }
template<typename _UniformRandomNumberGenerator>
result_type
@@ -3006,7 +3164,7 @@ namespace std
param_type _M_param;
// NB: Unused when _GLIBCXX_USE_C99_MATH_TR1 is undefined.
- normal_distribution<double> _M_nd;
+ std::normal_distribution<double> _M_nd;
};
@@ -3195,12 +3353,12 @@ namespace std
explicit
negative_binomial_distribution(_IntType __k = 1, double __p = 0.5)
- : _M_param(__k, __p)
+ : _M_param(__k, __p), _M_gd(__k, __p / (1.0 - __p))
{ }
explicit
negative_binomial_distribution(const param_type& __p)
- : _M_param(__p)
+ : _M_param(__p), _M_gd(__p.k(), __p.p() / (1.0 - __p.p()))
{ }
/**
@@ -3208,7 +3366,7 @@ namespace std
*/
void
reset()
- { }
+ { _M_gd.reset(); }
/**
* @brief Return the @f$ k @f$ parameter of the distribution.
@@ -3255,8 +3413,7 @@ namespace std
template<typename _UniformRandomNumberGenerator>
result_type
- operator()(_UniformRandomNumberGenerator& __urng)
- { return this->operator()(__urng, this->param()); }
+ operator()(_UniformRandomNumberGenerator& __urng);
template<typename _UniformRandomNumberGenerator>
result_type
@@ -3265,6 +3422,8 @@ namespace std
private:
param_type _M_param;
+
+ std::gamma_distribution<double> _M_gd;
};
/**
@@ -3450,7 +3609,7 @@ namespace std
param_type _M_param;
// NB: Unused when _GLIBCXX_USE_C99_MATH_TR1 is undefined.
- normal_distribution<double> _M_nd;
+ std::normal_distribution<double> _M_nd;
};
/**
@@ -3556,11 +3715,7 @@ namespace std
template<typename _UniformRandomNumberGenerator>
result_type
operator()(_UniformRandomNumberGenerator& __urng)
- {
- __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
- __aurng(__urng);
- return -std::log(__aurng()) / this->lambda();
- }
+ { return this->operator()(__urng, this->param()); }
template<typename _UniformRandomNumberGenerator>
result_type
@@ -3608,164 +3763,6 @@ namespace std
/**
- * @brief A gamma continuous distribution for random numbers.
- *
- * The formula for the gamma probability density function is
- * @f$ p(x|\alpha,\beta) = \frac{1}{\beta\Gamma(\alpha)}
- * (x/\beta)^{\alpha - 1} e^{-x/\beta} @f$.
- */
- template<typename _RealType = double>
- class gamma_distribution
- {
- public:
- /** The type of the range of the distribution. */
- typedef _RealType result_type;
- /** Parameter type. */
- struct param_type
- {
- typedef gamma_distribution<_RealType> distribution_type;
- friend class gamma_distribution<_RealType>;
-
- explicit
- param_type(_RealType __alpha_val = _RealType(1),
- _RealType __beta_val = _RealType(1))
- : _M_alpha(__alpha_val), _M_beta(__beta_val)
- {
- _GLIBCXX_DEBUG_ASSERT(_M_alpha > _RealType(0));
- _M_initialize();
- }
-
- _RealType
- alpha() const
- { return _M_alpha; }
-
- _RealType
- beta() const
- { return _M_beta; }
-
- private:
- void
- _M_initialize();
-
- _RealType _M_alpha;
- _RealType _M_beta;
-
- // Hosts either lambda of GB or d of modified Vaduva's.
- _RealType _M_l_d;
- };
-
- public:
- /**
- * @brief Constructs a gamma distribution with parameters
- * @f$ \alpha @f$ and @f$ \beta @f$.
- */
- explicit
- gamma_distribution(_RealType __alpha_val = _RealType(1),
- _RealType __beta_val = _RealType(1))
- : _M_param(__alpha_val, __beta_val)
- { }
-
- explicit
- gamma_distribution(const param_type& __p)
- : _M_param(__p)
- { }
-
- /**
- * @brief Resets the distribution state.
- *
- * Does nothing for the gamma distribution.
- */
- void
- reset() { }
-
- /**
- * @brief Returns the @f$ \alpha @f$ of the distribution.
- */
- _RealType
- alpha() const
- { return _M_param.alpha(); }
-
- /**
- * @brief Returns the @f$ \beta @f$ of the distribution.
- */
- _RealType
- beta() const
- { return _M_param.beta(); }
-
- /**
- * @brief Returns the parameter set of the distribution.
- */
- param_type
- param() const
- { return _M_param; }
-
- /**
- * @brief Sets the parameter set of the distribution.
- * @param __param The new parameter set of the distribution.
- */
- void
- param(const param_type& __param)
- { _M_param = __param; }
-
- /**
- * @brief Returns the greatest lower bound value of the distribution.
- */
- result_type
- min() const
- { return result_type(0); }
-
- /**
- * @brief Returns the least upper bound value of the distribution.
- */
- result_type
- max() const
- { return std::numeric_limits<result_type>::max(); }
-
- template<typename _UniformRandomNumberGenerator>
- result_type
- operator()(_UniformRandomNumberGenerator& __urng)
- { return this->operator()(__urng, this->param()); }
-
- template<typename _UniformRandomNumberGenerator>
- result_type
- operator()(_UniformRandomNumberGenerator& __urng,
- const param_type& __p);
-
- private:
- param_type _M_param;
- };
-
- /**
- * @brief Inserts a %gamma_distribution random number distribution
- * @p __x into the output stream @p __os.
- *
- * @param __os An output stream.
- * @param __x A %gamma_distribution random number distribution.
- *
- * @returns The output stream with the state of @p __x inserted or in
- * an error state.
- */
- template<typename _RealType, typename _CharT, typename _Traits>
- std::basic_ostream<_CharT, _Traits>&
- operator<<(std::basic_ostream<_CharT, _Traits>&,
- const std::gamma_distribution<_RealType>&);
-
- /**
- * @brief Extracts a %gamma_distribution random number distribution
- * @p __x from the input stream @p __is.
- *
- * @param __is An input stream.
- * @param __x A %gamma_distribution random number generator engine.
- *
- * @returns The input stream with @p __x extracted or in an error state.
- */
- template<typename _RealType, typename _CharT, typename _Traits>
- std::basic_istream<_CharT, _Traits>&
- operator>>(std::basic_istream<_CharT, _Traits>&,
- std::gamma_distribution<_RealType>&);
-
-
- /**
* @brief A weibull_distribution random number distribution.
*
* The formula for the normal probability density function is
@@ -3871,13 +3868,7 @@ namespace std
template<typename _UniformRandomNumberGenerator>
result_type
operator()(_UniformRandomNumberGenerator& __urng,
- const param_type& __p)
- {
- __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
- __aurng(__urng);
- return __p.b() * std::pow(-std::log(__aurng()),
- result_type(1) / __p.a());
- }
+ const param_type& __p);
private:
param_type _M_param;
@@ -4239,7 +4230,9 @@ namespace std
typedef piecewise_constant_distribution<_RealType> distribution_type;
friend class piecewise_constant_distribution<_RealType>;
- param_type();
+ param_type()
+ : _M_int(), _M_den(), _M_cp()
+ { _M_initialize(); }
template<typename _InputIteratorB, typename _InputIteratorW>
param_type(_InputIteratorB __bfirst,
diff --git a/libstdc++-v3/include/bits/random.tcc b/libstdc++-v3/include/bits/random.tcc
index 8944c116b7e..eb2ce4a4500 100644
--- a/libstdc++-v3/include/bits/random.tcc
+++ b/libstdc++-v3/include/bits/random.tcc
@@ -128,19 +128,6 @@ namespace std
seed(__sum);
}
- /**
- * Gets the next generated value in sequence.
- */
- template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
- typename linear_congruential_engine<_UIntType, __a, __c, __m>::
- result_type
- linear_congruential_engine<_UIntType, __a, __c, __m>::
- operator()()
- {
- _M_x = __detail::__mod<_UIntType, __a, __c, __m>(_M_x);
- return _M_x;
- }
-
template<typename _UIntType, _UIntType __a, _UIntType __c, _UIntType __m,
typename _CharT, typename _Traits>
std::basic_ostream<_CharT, _Traits>&
@@ -554,9 +541,9 @@ namespace std
independent_bits_engine<_RandomNumberEngine, __w, _UIntType>::
operator()()
{
- const long double __r = static_cast<long double>(this->max())
- - static_cast<long double>(this->min()) + 1.0L;
- const result_type __m = std::log10(__r) / std::log10(2.0L);
+ const long double __r = static_cast<long double>(_M_b.max())
+ - static_cast<long double>(_M_b.min()) + 1.0L;
+ const result_type __m = std::log(__r) / std::log(2.0L);
result_type __n, __n0, __y0, __y1, __s0, __s1;
for (size_t __i = 0; __i < 2; ++__i)
{
@@ -564,8 +551,8 @@ namespace std
__n0 = __n - __w % __n;
const result_type __w0 = __w / __n;
const result_type __w1 = __w0 + 1;
- __s0 = 1UL << __w0;
- __s1 = 1UL << __w1;
+ __s0 = result_type(1) << __w0;
+ __s1 = result_type(1) << __w1;
__y0 = __s0 * (__r / __s0);
__y1 = __s1 * (__r / __s1);
if (__r - __y0 <= __y0 / __n)
@@ -577,19 +564,17 @@ namespace std
{
result_type __u;
do
- __u = _M_b() - this->min();
+ __u = _M_b() - _M_b.min();
while (__u >= __y0);
- __sum = __s0 * __sum
- + __u % __s0;
+ __sum = __s0 * __sum + __u % __s0;
}
for (size_t __k = __n0; __k < __n; ++__k)
{
result_type __u;
do
- __u = _M_b() - this->min();
+ __u = _M_b() - _M_b.min();
while (__u >= __y1);
- __sum = __s1 * __sum
- + __u % __s1;
+ __sum = __s1 * __sum + __u % __s1;
}
return __sum;
}
@@ -869,24 +854,35 @@ namespace std
return __is;
}
+
template<typename _IntType>
template<typename _UniformRandomNumberGenerator>
typename negative_binomial_distribution<_IntType>::result_type
negative_binomial_distribution<_IntType>::
- operator()(_UniformRandomNumberGenerator& __urng,
- const param_type& __p)
+ operator()(_UniformRandomNumberGenerator& __urng)
{
- typename gamma_distribution<>::param_type
- __gamma_param(__p.k(), 1.0);
- gamma_distribution<> __gamma(__gamma_param);
- double __x = __gamma(__urng);
+ const double __y = _M_gd(__urng);
- typename poisson_distribution<result_type>::param_type
- __poisson_param(__x * __p.p() / (1.0 - __p.p()));
- poisson_distribution<result_type> __poisson(__poisson_param);
- result_type __m = __poisson(__urng);
+ // XXX Is the constructor too slow?
+ std::poisson_distribution<result_type> __poisson(__y);
+ return __poisson(__urng);
+ }
- return __m;
+ template<typename _IntType>
+ template<typename _UniformRandomNumberGenerator>
+ typename negative_binomial_distribution<_IntType>::result_type
+ negative_binomial_distribution<_IntType>::
+ operator()(_UniformRandomNumberGenerator& __urng,
+ const param_type& __p)
+ {
+ typedef typename std::gamma_distribution<result_type>::param_type
+ param_type;
+
+ const double __y =
+ _M_gd(__urng, param_type(__p.k(), __p.p() / (1.0 - __p.p())));
+
+ std::poisson_distribution<result_type> __poisson(__y);
+ return __poisson(__urng);
}
template<typename _IntType, typename _CharT, typename _Traits>
@@ -905,7 +901,8 @@ namespace std
__os.fill(__os.widen(' '));
__os.precision(std::numeric_limits<double>::digits10 + 1);
- __os << __x.k() << __space << __x.p();
+ __os << __x.k() << __space << __x.p()
+ << __space << __x._M_gd;
__os.flags(__flags);
__os.fill(__fill);
@@ -926,7 +923,7 @@ namespace std
_IntType __k;
double __p;
- __is >> __k >> __p;
+ __is >> __k >> __p >> __x._M_gd;
__x.param(typename negative_binomial_distribution<_IntType>::
param_type(__k, __p));
@@ -1512,33 +1509,6 @@ namespace std
}
- template<typename _RealType>
- template<typename _UniformRandomNumberGenerator>
- typename lognormal_distribution<_RealType>::result_type
- lognormal_distribution<_RealType>::
- operator()(_UniformRandomNumberGenerator& __urng,
- const param_type& __p)
- {
- _RealType __u, __v, __r2, __normal;
- __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
- __aurng(__urng);
-
- do
- {
- // Choose x,y in uniform square (-1,-1) to (+1,+1).
- __u = 2 * __aurng() - 1;
- __v = 2 * __aurng() - 1;
-
- // See if it is in the unit circle.
- __r2 = __u * __u + __v * __v;
- }
- while (__r2 > 1 || __r2 == 0);
-
- __normal = __u * std::sqrt(-2 * std::log(__r2) / __r2);
-
- return std::exp(__p.s() * __normal + __p.m());
- }
-
template<typename _RealType, typename _CharT, typename _Traits>
std::basic_ostream<_CharT, _Traits>&
operator<<(std::basic_ostream<_CharT, _Traits>& __os,
@@ -1555,7 +1525,8 @@ namespace std
__os.fill(__space);
__os.precision(std::numeric_limits<_RealType>::digits10 + 1);
- __os << __x.m() << __space << __x.s();
+ __os << __x.m() << __space << __x.s()
+ << __space << __x._M_nd;
__os.flags(__flags);
__os.fill(__fill);
@@ -1575,7 +1546,7 @@ namespace std
__is.flags(__ios_base::dec | __ios_base::skipws);
_RealType __m, __s;
- __is >> __m >> __s;
+ __is >> __m >> __s >> __x._M_nd;
__x.param(typename lognormal_distribution<_RealType>::
param_type(__m, __s));
@@ -1584,19 +1555,6 @@ namespace std
}
- template<typename _RealType>
- template<typename _UniformRandomNumberGenerator>
- typename chi_squared_distribution<_RealType>::result_type
- chi_squared_distribution<_RealType>::
- operator()(_UniformRandomNumberGenerator& __urng,
- const param_type& __p)
- {
- typename gamma_distribution<_RealType>::param_type
- __gamma_param(__p.n() / 2, 1.0);
- gamma_distribution<_RealType> __gamma(__gamma_param);
- return 2 * __gamma(__urng);
- }
-
template<typename _RealType, typename _CharT, typename _Traits>
std::basic_ostream<_CharT, _Traits>&
operator<<(std::basic_ostream<_CharT, _Traits>& __os,
@@ -1613,7 +1571,7 @@ namespace std
__os.fill(__space);
__os.precision(std::numeric_limits<_RealType>::digits10 + 1);
- __os << __x.n();
+ __os << __x.n() << __space << __x._M_gd;
__os.flags(__flags);
__os.fill(__fill);
@@ -1633,7 +1591,7 @@ namespace std
__is.flags(__ios_base::dec | __ios_base::skipws);
_RealType __n;
- __is >> __n;
+ __is >> __n >> __x._M_gd;
__x.param(typename chi_squared_distribution<_RealType>::
param_type(__n));
@@ -1653,12 +1611,11 @@ namespace std
__aurng(__urng);
_RealType __u;
do
- {
- __u = __aurng();
- }
+ __u = __aurng();
while (__u == 0.5);
- return __p.a() + __p.b() * std::tan(M_PI * __u);
+ const _RealType __pi = 3.1415926535897932384626433832795029L;
+ return __p.a() + __p.b() * std::tan(__pi * __u);
}
template<typename _RealType, typename _CharT, typename _Traits>
@@ -1706,23 +1663,6 @@ namespace std
}
- template<typename _RealType>
- template<typename _UniformRandomNumberGenerator>
- typename fisher_f_distribution<_RealType>::result_type
- fisher_f_distribution<_RealType>::
- operator()(_UniformRandomNumberGenerator& __urng,
- const param_type& __p)
- {
- gamma_distribution<_RealType> __gamma;
- _RealType __ym = __gamma(__urng,
- typename gamma_distribution<_RealType>::param_type(__p.m() / 2, 2));
-
- _RealType __yn = __gamma(__urng,
- typename gamma_distribution<_RealType>::param_type(__p.n() / 2, 2));
-
- return (__ym * __p.n()) / (__yn * __p.m());
- }
-
template<typename _RealType, typename _CharT, typename _Traits>
std::basic_ostream<_CharT, _Traits>&
operator<<(std::basic_ostream<_CharT, _Traits>& __os,
@@ -1739,7 +1679,8 @@ namespace std
__os.fill(__space);
__os.precision(std::numeric_limits<_RealType>::digits10 + 1);
- __os << __x.m() << __space << __x.n();
+ __os << __x.m() << __space << __x.n()
+ << __space << __x._M_gd_x << __space << __x._M_gd_y;
__os.flags(__flags);
__os.fill(__fill);
@@ -1759,7 +1700,7 @@ namespace std
__is.flags(__ios_base::dec | __ios_base::skipws);
_RealType __m, __n;
- __is >> __m >> __n;
+ __is >> __m >> __n >> __x._M_gd_x >> __x._M_gd_y;
__x.param(typename fisher_f_distribution<_RealType>::
param_type(__m, __n));
@@ -1768,75 +1709,6 @@ namespace std
}
- //
- // This could be operator() for a Gaussian distribution.
- //
- template<typename _RealType>
- template<typename _UniformRandomNumberGenerator>
- typename student_t_distribution<_RealType>::result_type
- student_t_distribution<_RealType>::
- _M_gaussian(_UniformRandomNumberGenerator& __urng,
- const result_type __sigma)
- {
- _RealType __x, __y, __r2;
- __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
- __aurng(__urng);
-
- do
- {
- // Choose x,y in uniform square (-1,-1) to (+1,+1).
- __x = 2 * __aurng() - 1;
- __y = 2 * __aurng() - 1;
-
- // See if it is in the unit circle.
- __r2 = __x * __x + __y * __y;
- }
- while (__r2 > 1 || __r2 == 0);
-
- // Box-Muller transform.
- return __sigma * __y * std::sqrt(-2 * std::log(__r2) / __r2);
- }
-
- template<typename _RealType>
- template<typename _UniformRandomNumberGenerator>
- typename student_t_distribution<_RealType>::result_type
- student_t_distribution<_RealType>::
- operator()(_UniformRandomNumberGenerator& __urng,
- const param_type& __param)
- {
- if (__param.n() <= 2.0)
- {
- _RealType __y1 = _M_gaussian(__urng, 1.0);
- typename chi_squared_distribution<_RealType>::param_type
- __chisq_param(__param.n());
- chi_squared_distribution<_RealType> __chisq(__chisq_param);
- _RealType __y2 = __chisq(__urng);
-
- return __y1 / std::sqrt(__y2 / __param.n());
- }
- else
- {
- _RealType __y1, __y2, __z;
- do
- {
- __y1 = _M_gaussian(__urng, 1.0);
- typename exponential_distribution<_RealType>::param_type
- __exp_param(1.0 / (__param.n() / 2.0 - 1.0));
- exponential_distribution<_RealType>
- __exponential(__exp_param);
- __y2 = __exponential(__urng);
-
- __z = __y1 * __y1 / (__param.n() - 2.0);
- }
- while (1.0 - __z < 0.0 || std::exp(-__y2 - __z) > (1.0 - __z));
-
- // Note that there is a typo in Knuth's formula, the line below
- // is taken from the original paper of Marsaglia, Mathematics of
- // Computation, 34 (1980), p 234-256
- return __y1 / std::sqrt((1.0 - 2.0 / __param.n()) * (1.0 - __z));
- }
- }
-
template<typename _RealType, typename _CharT, typename _Traits>
std::basic_ostream<_CharT, _Traits>&
operator<<(std::basic_ostream<_CharT, _Traits>& __os,
@@ -1853,7 +1725,7 @@ namespace std
__os.fill(__space);
__os.precision(std::numeric_limits<_RealType>::digits10 + 1);
- __os << __x.n();
+ __os << __x.n() << __space << __x._M_nd << __space << __x._M_gd;
__os.flags(__flags);
__os.fill(__fill);
@@ -1873,7 +1745,7 @@ namespace std
__is.flags(__ios_base::dec | __ios_base::skipws);
_RealType __n;
- __is >> __n;
+ __is >> __n >> __x._M_nd >> __x._M_gd;
__x.param(typename student_t_distribution<_RealType>::param_type(__n));
__is.flags(__flags);
@@ -1886,28 +1758,16 @@ namespace std
gamma_distribution<_RealType>::param_type::
_M_initialize()
{
- if (_M_alpha >= 1)
- _M_l_d = std::sqrt(2 * _M_alpha - 1);
- else
- _M_l_d = (std::pow(_M_alpha, _M_alpha / (1 - _M_alpha))
- * (1 - _M_alpha));
+ _M_malpha = _M_alpha < 1.0 ? _M_alpha + _RealType(1.0) : _M_alpha;
+
+ const _RealType __a1 = _M_malpha - _RealType(1.0) / _RealType(3.0);
+ _M_a2 = _RealType(1.0) / std::sqrt(_RealType(9.0) * __a1);
}
/**
- * Cheng's rejection algorithm GB for alpha >= 1 and a modification
- * of Vaduva's rejection from Weibull algorithm due to Devroye for
- * alpha < 1.
- *
- * References:
- * Cheng, R. C. "The Generation of Gamma Random Variables with Non-integral
- * Shape Parameter." Applied Statistics, 26, 71-75, 1977.
- *
- * Vaduva, I. "Computer Generation of Gamma Gandom Variables by Rejection
- * and Composition Procedures." Math. Operationsforschung and Statistik,
- * Series in Statistics, 8, 545-576, 1977.
- *
- * Devroye, L. "Non-Uniform Random Variates Generation." Springer-Verlag,
- * New York, 1986, Ch. IX, Sect. 3.4 (+ Errata!).
+ * Marsaglia, G. and Tsang, W. W.
+ * "A Simple Method for Generating Gamma Variables"
+ * ACM Transactions on Mathematical Software, 26, 3, 363-372, 2000.
*/
template<typename _RealType>
template<typename _UniformRandomNumberGenerator>
@@ -1916,58 +1776,40 @@ namespace std
operator()(_UniformRandomNumberGenerator& __urng,
const param_type& __param)
{
- result_type __x;
__detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
__aurng(__urng);
- bool __reject;
- const _RealType __alpha_val = __param.alpha();
- const _RealType __beta_val = __param.beta();
- if (__alpha_val >= 1)
- {
- // alpha - log(4)
- const result_type __b = __alpha_val
- - result_type(1.3862943611198906188344642429163531L);
- const result_type __c = __alpha_val + __param._M_l_d;
- const result_type __1l = 1 / __param._M_l_d;
-
- // 1 + log(9 / 2)
- const result_type __k = 2.5040773967762740733732583523868748L;
+ result_type __u, __v, __n;
+ const result_type __a1 = (__param._M_malpha
+ - _RealType(1.0) / _RealType(3.0));
+ do
+ {
do
{
- const result_type __u = __aurng() / __beta_val;
- const result_type __v = __aurng() / __beta_val;
-
- const result_type __y = __1l * std::log(__v / (1 - __v));
- __x = __alpha_val * std::exp(__y);
-
- const result_type __z = __u * __v * __v;
- const result_type __r = __b + __c * __y - __x;
-
- __reject = __r < result_type(4.5) * __z - __k;
- if (__reject)
- __reject = __r < std::log(__z);
+ __n = _M_nd(__urng);
+ __v = result_type(1.0) + __param._M_a2 * __n;
}
- while (__reject);
+ while (__v <= 0.0);
+
+ __v = __v * __v * __v;
+ __u = __aurng();
}
+ while (__u > result_type(1.0) - 0.331 * __n * __n * __n * __n
+ && (std::log(__u) > (0.5 * __n * __n + __a1
+ * (1.0 - __v + std::log(__v)))));
+
+ if (__param.alpha() == __param._M_malpha)
+ return __a1 * __v * __param.beta();
else
{
- const result_type __c = 1 / __alpha_val;
-
do
- {
- const result_type __z = -std::log(__aurng() / __beta_val);
- const result_type __e = -std::log(__aurng() / __beta_val);
-
- __x = std::pow(__z, __c);
-
- __reject = __z + __e < __param._M_l_d + __x;
- }
- while (__reject);
+ __u = __aurng();
+ while (__u == 0.0);
+
+ return (std::pow(__u, result_type(1.0) / __param.alpha())
+ * __a1 * __v * __param.beta());
}
-
- return __beta_val * __x;
}
template<typename _RealType, typename _CharT, typename _Traits>
@@ -1986,7 +1828,8 @@ namespace std
__os.fill(__space);
__os.precision(std::numeric_limits<_RealType>::digits10 + 1);
- __os << __x.alpha() << __space << __x.beta();
+ __os << __x.alpha() << __space << __x.beta()
+ << __space << __x._M_nd;
__os.flags(__flags);
__os.fill(__fill);
@@ -2006,7 +1849,7 @@ namespace std
__is.flags(__ios_base::dec | __ios_base::skipws);
_RealType __alpha_val, __beta_val;
- __is >> __alpha_val >> __beta_val;
+ __is >> __alpha_val >> __beta_val >> __x._M_nd;
__x.param(typename gamma_distribution<_RealType>::
param_type(__alpha_val, __beta_val));
@@ -2015,6 +1858,19 @@ namespace std
}
+ template<typename _RealType>
+ template<typename _UniformRandomNumberGenerator>
+ typename weibull_distribution<_RealType>::result_type
+ weibull_distribution<_RealType>::
+ operator()(_UniformRandomNumberGenerator& __urng,
+ const param_type& __p)
+ {
+ __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
+ __aurng(__urng);
+ return __p.b() * std::pow(-std::log(__aurng()),
+ result_type(1) / __p.a());
+ }
+
template<typename _RealType, typename _CharT, typename _Traits>
std::basic_ostream<_CharT, _Traits>&
operator<<(std::basic_ostream<_CharT, _Traits>& __os,
@@ -2269,12 +2125,6 @@ namespace std
}
template<typename _RealType>
- piecewise_constant_distribution<_RealType>::param_type::
- param_type()
- : _M_int(), _M_den(), _M_cp()
- { _M_initialize(); }
-
- template<typename _RealType>
template<typename _InputIteratorB, typename _InputIteratorW>
piecewise_constant_distribution<_RealType>::param_type::
param_type(_InputIteratorB __bbegin,
@@ -2318,8 +2168,7 @@ namespace std
template<typename _RealType>
template<typename _Func>
piecewise_constant_distribution<_RealType>::param_type::
- param_type(size_t __nw, _RealType __xmin, _RealType __xmax,
- _Func __fw)
+ param_type(size_t __nw, _RealType __xmin, _RealType __xmax, _Func __fw)
: _M_int(), _M_den(), _M_cp()
{
for (size_t __i = 0; __i <= __nw; ++__i)
@@ -2649,12 +2498,12 @@ namespace std
_RandomAccessIterator __end)
{
typedef typename iterator_traits<_RandomAccessIterator>::value_type
- __Type;
+ _Type;
if (__begin == __end)
return;
- std::fill(__begin, __end, __Type(0x8b8b8b8bU));
+ std::fill(__begin, __end, _Type(0x8b8b8b8bU));
const size_t __n = __end - __begin;
const size_t __s = _M_v.size();
@@ -2669,21 +2518,21 @@ namespace std
for (size_t __k = 0; __k < __m; ++__k)
{
- __Type __arg = __begin[__k % __n]
- ^ __begin[(__k + __p) % __n]
- ^ __begin[(__k - 1) % __n];
- __Type __r1 = __arg ^ (__arg << 27);
- __r1 = __detail::__mod<__Type, 1664525U, 0U,
- __detail::_Shift<__Type, 32>::__value>(__r1);
- __Type __r2 = __r1;
+ _Type __arg = (__begin[__k % __n]
+ ^ __begin[(__k + __p) % __n]
+ ^ __begin[(__k - 1) % __n]);
+ _Type __r1 = __arg ^ (__arg << 27);
+ __r1 = __detail::__mod<_Type, 1664525U, 0U,
+ __detail::_Shift<_Type, 32>::__value>(__r1);
+ _Type __r2 = __r1;
if (__k == 0)
__r2 += __s;
else if (__k <= __s)
__r2 += __k % __n + _M_v[__k - 1];
else
__r2 += __k % __n;
- __r2 = __detail::__mod<__Type, 1U, 0U,
- __detail::_Shift<__Type, 32>::__value>(__r2);
+ __r2 = __detail::__mod<_Type, 1U, 0U,
+ __detail::_Shift<_Type, 32>::__value>(__r2);
__begin[(__k + __p) % __n] += __r1;
__begin[(__k + __q) % __n] += __r2;
__begin[__k % __n] = __r2;
@@ -2691,15 +2540,15 @@ namespace std
for (size_t __k = __m; __k < __m + __n; ++__k)
{
- __Type __arg = __begin[__k % __n]
- + __begin[(__k + __p) % __n]
- + __begin[(__k - 1) % __n];
- __Type __r3 = __arg ^ (__arg << 27);
- __r3 = __detail::__mod<__Type, 1566083941U, 0U,
- __detail::_Shift<__Type, 32>::__value>(__r3);
- __Type __r4 = __r3 - __k % __n;
- __r4 = __detail::__mod<__Type, 1U, 0U,
- __detail::_Shift<__Type, 32>::__value>(__r4);
+ _Type __arg = (__begin[__k % __n]
+ + __begin[(__k + __p) % __n]
+ + __begin[(__k - 1) % __n]);
+ _Type __r3 = __arg ^ (__arg << 27);
+ __r3 = __detail::__mod<_Type, 1566083941U, 0U,
+ __detail::_Shift<_Type, 32>::__value>(__r3);
+ _Type __r4 = __r3 - __k % __n;
+ __r4 = __detail::__mod<_Type, 1U, 0U,
+ __detail::_Shift<_Type, 32>::__value>(__r4);
__begin[(__k + __p) % __n] ^= __r4;
__begin[(__k + __q) % __n] ^= __r3;
__begin[__k % __n] = __r4;
@@ -2716,7 +2565,7 @@ namespace std
__bits);
const long double __r = static_cast<long double>(__urng.max())
- static_cast<long double>(__urng.min()) + 1.0L;
- const size_t __log2r = std::log10(__r) / std::log10(2.0L);
+ const size_t __log2r = std::log(__r) / std::log(2.0L);
size_t __k = std::max<size_t>(1UL, (__b + __log2r - 1UL) / __log2r);
_RealType __sum = _RealType(0);
_RealType __tmp = _RealType(1);
diff --git a/libstdc++-v3/include/bits/shared_ptr.h b/libstdc++-v3/include/bits/shared_ptr.h
index a378ae01d34..c7a45f39bc1 100644
--- a/libstdc++-v3/include/bits/shared_ptr.h
+++ b/libstdc++-v3/include/bits/shared_ptr.h
@@ -816,13 +816,8 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
get() const // never throws
{ return _M_ptr; }
- // Implicit conversion to "bool"
- private:
- typedef _Tp* __shared_ptr::*__unspecified_bool_type;
-
- public:
- operator __unspecified_bool_type() const // never throws
- { return _M_ptr == 0 ? 0 : &__shared_ptr::_M_ptr; }
+ explicit operator bool() const // never throws
+ { return _M_ptr == 0 ? false : true; }
bool
unique() const // never throws
diff --git a/libstdc++-v3/include/bits/stl_bvector.h b/libstdc++-v3/include/bits/stl_bvector.h
index 0e60b7f1b92..87dbb0b3f87 100644
--- a/libstdc++-v3/include/bits/stl_bvector.h
+++ b/libstdc++-v3/include/bits/stl_bvector.h
@@ -743,11 +743,7 @@ template<typename _Alloc>
}
void
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- swap(vector&& __x)
-#else
swap(vector& __x)
-#endif
{
std::swap(this->_M_impl._M_start, __x._M_impl._M_start);
std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish);
diff --git a/libstdc++-v3/include/bits/stl_construct.h b/libstdc++-v3/include/bits/stl_construct.h
index 265c3ab1902..9df37fe1950 100644
--- a/libstdc++-v3/include/bits/stl_construct.h
+++ b/libstdc++-v3/include/bits/stl_construct.h
@@ -82,6 +82,26 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
_Destroy(_Tp* __pointer)
{ __pointer->~_Tp(); }
+ template<bool>
+ struct _Destroy_aux
+ {
+ template<typename _ForwardIterator>
+ static void
+ __destroy(_ForwardIterator __first, _ForwardIterator __last)
+ {
+ for (; __first != __last; ++__first)
+ std::_Destroy(&*__first);
+ }
+ };
+
+ template<>
+ struct _Destroy_aux<true>
+ {
+ template<typename _ForwardIterator>
+ static void
+ __destroy(_ForwardIterator, _ForwardIterator) { }
+ };
+
/**
* Destroy a range of objects. If the value_type of the object has
* a trivial destructor, the compiler should optimize all of this
@@ -93,9 +113,8 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
{
typedef typename iterator_traits<_ForwardIterator>::value_type
_Value_type;
- if (!__has_trivial_destructor(_Value_type))
- for (; __first != __last; ++__first)
- std::_Destroy(&*__first);
+ std::_Destroy_aux<__has_trivial_destructor(_Value_type)>::
+ __destroy(__first, __last);
}
/**
diff --git a/libstdc++-v3/include/bits/stl_deque.h b/libstdc++-v3/include/bits/stl_deque.h
index 1c20e275f75..7f601cbf0fb 100644
--- a/libstdc++-v3/include/bits/stl_deque.h
+++ b/libstdc++-v3/include/bits/stl_deque.h
@@ -1395,11 +1395,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
* std::swap(d1,d2) will feed to this function.
*/
void
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- swap(deque&& __x)
-#else
swap(deque& __x)
-#endif
{
std::swap(this->_M_impl._M_start, __x._M_impl._M_start);
std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish);
@@ -1802,18 +1798,6 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
swap(deque<_Tp,_Alloc>& __x, deque<_Tp,_Alloc>& __y)
{ __x.swap(__y); }
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- template<typename _Tp, typename _Alloc>
- inline void
- swap(deque<_Tp,_Alloc>&& __x, deque<_Tp,_Alloc>& __y)
- { __x.swap(__y); }
-
- template<typename _Tp, typename _Alloc>
- inline void
- swap(deque<_Tp,_Alloc>& __x, deque<_Tp,_Alloc>&& __y)
- { __x.swap(__y); }
-#endif
-
_GLIBCXX_END_NESTED_NAMESPACE
#endif /* _STL_DEQUE_H */
diff --git a/libstdc++-v3/include/bits/stl_list.h b/libstdc++-v3/include/bits/stl_list.h
index bba1f53044e..f758baed5c9 100644
--- a/libstdc++-v3/include/bits/stl_list.h
+++ b/libstdc++-v3/include/bits/stl_list.h
@@ -1106,11 +1106,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
* function.
*/
void
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- swap(list&& __x)
-#else
swap(list& __x)
-#endif
{
_List_node_base::swap(this->_M_impl._M_node, __x._M_impl._M_node);
@@ -1516,18 +1512,6 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y)
{ __x.swap(__y); }
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- template<typename _Tp, typename _Alloc>
- inline void
- swap(list<_Tp, _Alloc>&& __x, list<_Tp, _Alloc>& __y)
- { __x.swap(__y); }
-
- template<typename _Tp, typename _Alloc>
- inline void
- swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>&& __y)
- { __x.swap(__y); }
-#endif
-
_GLIBCXX_END_NESTED_NAMESPACE
#endif /* _STL_LIST_H */
diff --git a/libstdc++-v3/include/bits/stl_map.h b/libstdc++-v3/include/bits/stl_map.h
index 90e5239ddab..5416d827567 100644
--- a/libstdc++-v3/include/bits/stl_map.h
+++ b/libstdc++-v3/include/bits/stl_map.h
@@ -608,11 +608,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
* that std::swap(m1,m2) will feed to this function.
*/
void
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- swap(map&& __x)
-#else
swap(map& __x)
-#endif
{ _M_t.swap(__x._M_t); }
/**
@@ -852,20 +848,6 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
map<_Key, _Tp, _Compare, _Alloc>& __y)
{ __x.swap(__y); }
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
- inline void
- swap(map<_Key, _Tp, _Compare, _Alloc>&& __x,
- map<_Key, _Tp, _Compare, _Alloc>& __y)
- { __x.swap(__y); }
-
- template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
- inline void
- swap(map<_Key, _Tp, _Compare, _Alloc>& __x,
- map<_Key, _Tp, _Compare, _Alloc>&& __y)
- { __x.swap(__y); }
-#endif
-
_GLIBCXX_END_NESTED_NAMESPACE
#endif /* _STL_MAP_H */
diff --git a/libstdc++-v3/include/bits/stl_multimap.h b/libstdc++-v3/include/bits/stl_multimap.h
index 484537cf2fe..91dcfa675f4 100644
--- a/libstdc++-v3/include/bits/stl_multimap.h
+++ b/libstdc++-v3/include/bits/stl_multimap.h
@@ -544,11 +544,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
* std::swap(m1,m2) will feed to this function.
*/
void
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- swap(multimap&& __x)
-#else
swap(multimap& __x)
-#endif
{ _M_t.swap(__x._M_t); }
/**
@@ -781,20 +777,6 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
multimap<_Key, _Tp, _Compare, _Alloc>& __y)
{ __x.swap(__y); }
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
- inline void
- swap(multimap<_Key, _Tp, _Compare, _Alloc>&& __x,
- multimap<_Key, _Tp, _Compare, _Alloc>& __y)
- { __x.swap(__y); }
-
- template<typename _Key, typename _Tp, typename _Compare, typename _Alloc>
- inline void
- swap(multimap<_Key, _Tp, _Compare, _Alloc>& __x,
- multimap<_Key, _Tp, _Compare, _Alloc>&& __y)
- { __x.swap(__y); }
-#endif
-
_GLIBCXX_END_NESTED_NAMESPACE
#endif /* _STL_MULTIMAP_H */
diff --git a/libstdc++-v3/include/bits/stl_multiset.h b/libstdc++-v3/include/bits/stl_multiset.h
index b5c710f31d2..be9e2489ce9 100644
--- a/libstdc++-v3/include/bits/stl_multiset.h
+++ b/libstdc++-v3/include/bits/stl_multiset.h
@@ -376,11 +376,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
* std::swap(s1,s2) will feed to this function.
*/
void
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- swap(multiset&& __x)
-#else
swap(multiset& __x)
-#endif
{ _M_t.swap(__x._M_t); }
// insert/erase
@@ -678,20 +674,6 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
multiset<_Key, _Compare, _Alloc>& __y)
{ __x.swap(__y); }
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- template<typename _Key, typename _Compare, typename _Alloc>
- inline void
- swap(multiset<_Key, _Compare, _Alloc>&& __x,
- multiset<_Key, _Compare, _Alloc>& __y)
- { __x.swap(__y); }
-
- template<typename _Key, typename _Compare, typename _Alloc>
- inline void
- swap(multiset<_Key, _Compare, _Alloc>& __x,
- multiset<_Key, _Compare, _Alloc>&& __y)
- { __x.swap(__y); }
-#endif
-
_GLIBCXX_END_NESTED_NAMESPACE
#endif /* _STL_MULTISET_H */
diff --git a/libstdc++-v3/include/bits/stl_pair.h b/libstdc++-v3/include/bits/stl_pair.h
index fd395adbd0b..d6c590186d6 100644
--- a/libstdc++-v3/include/bits/stl_pair.h
+++ b/libstdc++-v3/include/bits/stl_pair.h
@@ -131,7 +131,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
}
void
- swap(pair&& __p)
+ swap(pair& __p)
{
using std::swap;
swap(first, __p.first);
@@ -185,16 +185,6 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
inline void
swap(pair<_T1, _T2>& __x, pair<_T1, _T2>& __y)
{ __x.swap(__y); }
-
- template<class _T1, class _T2>
- inline void
- swap(pair<_T1, _T2>&& __x, pair<_T1, _T2>& __y)
- { __x.swap(__y); }
-
- template<class _T1, class _T2>
- inline void
- swap(pair<_T1, _T2>& __x, pair<_T1, _T2>&& __y)
- { __x.swap(__y); }
#endif
/**
diff --git a/libstdc++-v3/include/bits/stl_queue.h b/libstdc++-v3/include/bits/stl_queue.h
index 7479469d15a..61149c45708 100644
--- a/libstdc++-v3/include/bits/stl_queue.h
+++ b/libstdc++-v3/include/bits/stl_queue.h
@@ -249,7 +249,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
#ifdef __GXX_EXPERIMENTAL_CXX0X__
void
- swap(queue&& __q)
+ swap(queue& __q)
{ c.swap(__q.c); }
#endif
};
@@ -317,16 +317,6 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
inline void
swap(queue<_Tp, _Seq>& __x, queue<_Tp, _Seq>& __y)
{ __x.swap(__y); }
-
- template<typename _Tp, typename _Seq>
- inline void
- swap(queue<_Tp, _Seq>&& __x, queue<_Tp, _Seq>& __y)
- { __x.swap(__y); }
-
- template<typename _Tp, typename _Seq>
- inline void
- swap(queue<_Tp, _Seq>& __x, queue<_Tp, _Seq>&& __y)
- { __x.swap(__y); }
#endif
/**
@@ -550,7 +540,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
#ifdef __GXX_EXPERIMENTAL_CXX0X__
void
- swap(priority_queue&& __pq)
+ swap(priority_queue& __pq)
{
using std::swap;
c.swap(__pq.c);
@@ -567,18 +557,6 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
swap(priority_queue<_Tp, _Sequence, _Compare>& __x,
priority_queue<_Tp, _Sequence, _Compare>& __y)
{ __x.swap(__y); }
-
- template<typename _Tp, typename _Sequence, typename _Compare>
- inline void
- swap(priority_queue<_Tp, _Sequence, _Compare>&& __x,
- priority_queue<_Tp, _Sequence, _Compare>& __y)
- { __x.swap(__y); }
-
- template<typename _Tp, typename _Sequence, typename _Compare>
- inline void
- swap(priority_queue<_Tp, _Sequence, _Compare>& __x,
- priority_queue<_Tp, _Sequence, _Compare>&& __y)
- { __x.swap(__y); }
#endif
_GLIBCXX_END_NAMESPACE
diff --git a/libstdc++-v3/include/bits/stl_set.h b/libstdc++-v3/include/bits/stl_set.h
index f06fe033642..ccd0bc7b2ff 100644
--- a/libstdc++-v3/include/bits/stl_set.h
+++ b/libstdc++-v3/include/bits/stl_set.h
@@ -383,11 +383,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
* std::swap(s1,s2) will feed to this function.
*/
void
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- swap(set&& __x)
-#else
swap(set& __x)
-#endif
{ _M_t.swap(__x._M_t); }
// insert/erase
@@ -691,18 +687,6 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
swap(set<_Key, _Compare, _Alloc>& __x, set<_Key, _Compare, _Alloc>& __y)
{ __x.swap(__y); }
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- template<typename _Key, typename _Compare, typename _Alloc>
- inline void
- swap(set<_Key, _Compare, _Alloc>&& __x, set<_Key, _Compare, _Alloc>& __y)
- { __x.swap(__y); }
-
- template<typename _Key, typename _Compare, typename _Alloc>
- inline void
- swap(set<_Key, _Compare, _Alloc>& __x, set<_Key, _Compare, _Alloc>&& __y)
- { __x.swap(__y); }
-#endif
-
_GLIBCXX_END_NESTED_NAMESPACE
#endif /* _STL_SET_H */
diff --git a/libstdc++-v3/include/bits/stl_stack.h b/libstdc++-v3/include/bits/stl_stack.h
index da301d474a8..41784087210 100644
--- a/libstdc++-v3/include/bits/stl_stack.h
+++ b/libstdc++-v3/include/bits/stl_stack.h
@@ -213,7 +213,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
#ifdef __GXX_EXPERIMENTAL_CXX0X__
void
- swap(stack&& __s)
+ swap(stack& __s)
{ c.swap(__s.c); }
#endif
};
@@ -282,16 +282,6 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
inline void
swap(stack<_Tp, _Seq>& __x, stack<_Tp, _Seq>& __y)
{ __x.swap(__y); }
-
- template<typename _Tp, typename _Seq>
- inline void
- swap(stack<_Tp, _Seq>&& __x, stack<_Tp, _Seq>& __y)
- { __x.swap(__y); }
-
- template<typename _Tp, typename _Seq>
- inline void
- swap(stack<_Tp, _Seq>& __x, stack<_Tp, _Seq>&& __y)
- { __x.swap(__y); }
#endif
_GLIBCXX_END_NAMESPACE
diff --git a/libstdc++-v3/include/bits/stl_tree.h b/libstdc++-v3/include/bits/stl_tree.h
index ecf3b5c3fe4..1a67b563f62 100644
--- a/libstdc++-v3/include/bits/stl_tree.h
+++ b/libstdc++-v3/include/bits/stl_tree.h
@@ -675,11 +675,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
{ return _M_get_Node_allocator().max_size(); }
void
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- swap(_Rb_tree&& __t);
-#else
swap(_Rb_tree& __t);
-#endif
// Insert/erase.
pair<iterator, bool>
@@ -1104,11 +1100,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
typename _Compare, typename _Alloc>
void
_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- swap(_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&& __t)
-#else
swap(_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __t)
-#endif
{
if (_M_root() == 0)
{
diff --git a/libstdc++-v3/include/bits/stl_vector.h b/libstdc++-v3/include/bits/stl_vector.h
index 9af983d4346..a68e9560816 100644
--- a/libstdc++-v3/include/bits/stl_vector.h
+++ b/libstdc++-v3/include/bits/stl_vector.h
@@ -923,11 +923,7 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
* std::swap(v1,v2) will feed to this function.
*/
void
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- swap(vector&& __x)
-#else
swap(vector& __x)
-#endif
{
std::swap(this->_M_impl._M_start, __x._M_impl._M_start);
std::swap(this->_M_impl._M_finish, __x._M_impl._M_finish);
@@ -1216,18 +1212,6 @@ _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
swap(vector<_Tp, _Alloc>& __x, vector<_Tp, _Alloc>& __y)
{ __x.swap(__y); }
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- template<typename _Tp, typename _Alloc>
- inline void
- swap(vector<_Tp, _Alloc>&& __x, vector<_Tp, _Alloc>& __y)
- { __x.swap(__y); }
-
- template<typename _Tp, typename _Alloc>
- inline void
- swap(vector<_Tp, _Alloc>& __x, vector<_Tp, _Alloc>&& __y)
- { __x.swap(__y); }
-#endif
-
_GLIBCXX_END_NESTED_NAMESPACE
#endif /* _STL_VECTOR_H */
diff --git a/libstdc++-v3/include/bits/unique_ptr.h b/libstdc++-v3/include/bits/unique_ptr.h
index b686d11fd80..7c08c81eac7 100644
--- a/libstdc++-v3/include/bits/unique_ptr.h
+++ b/libstdc++-v3/include/bits/unique_ptr.h
@@ -85,7 +85,6 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
class unique_ptr
{
typedef std::tuple<_Tp*, _Tp_Deleter> __tuple_type;
- typedef __tuple_type unique_ptr::* __unspecified_bool_type;
typedef _Tp* unique_ptr::* __unspecified_pointer_type;
public:
@@ -181,8 +180,8 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
get_deleter() const
{ return std::get<1>(_M_t); }
- operator __unspecified_bool_type () const
- { return get() == 0 ? 0 : &unique_ptr::_M_t; }
+ explicit operator bool() const
+ { return get() == 0 ? false : true; }
// Modifiers.
pointer
@@ -204,7 +203,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
}
void
- swap(unique_ptr&& __u)
+ swap(unique_ptr& __u)
{
using std::swap;
swap(_M_t, __u._M_t);
@@ -233,7 +232,6 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
class unique_ptr<_Tp[], _Tp_Deleter>
{
typedef std::tuple<_Tp*, _Tp_Deleter> __tuple_type;
- typedef __tuple_type unique_ptr::* __unspecified_bool_type;
typedef _Tp* unique_ptr::* __unspecified_pointer_type;
public:
@@ -323,8 +321,8 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
get_deleter() const
{ return std::get<1>(_M_t); }
- operator __unspecified_bool_type () const
- { return get() == 0 ? 0 : &unique_ptr::_M_t; }
+ explicit operator bool() const
+ { return get() == 0 ? false : true; }
// Modifiers.
pointer
@@ -350,7 +348,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
void reset(_Up) = delete;
void
- swap(unique_ptr&& __u)
+ swap(unique_ptr& __u)
{
using std::swap;
swap(_M_t, __u._M_t);
@@ -389,18 +387,6 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
unique_ptr<_Tp, _Tp_Deleter>& __y)
{ __x.swap(__y); }
- template<typename _Tp, typename _Tp_Deleter>
- inline void
- swap(unique_ptr<_Tp, _Tp_Deleter>&& __x,
- unique_ptr<_Tp, _Tp_Deleter>& __y)
- { __x.swap(__y); }
-
- template<typename _Tp, typename _Tp_Deleter>
- inline void
- swap(unique_ptr<_Tp, _Tp_Deleter>& __x,
- unique_ptr<_Tp, _Tp_Deleter>&& __y)
- { __x.swap(__y); }
-
template<typename _Tp, typename _Tp_Deleter,
typename _Up, typename _Up_Deleter>
inline bool
diff --git a/libstdc++-v3/include/debug/deque b/libstdc++-v3/include/debug/deque
index b481fd14bb4..3a39dc46004 100644
--- a/libstdc++-v3/include/debug/deque
+++ b/libstdc++-v3/include/debug/deque
@@ -432,11 +432,7 @@ namespace __debug
}
void
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- swap(deque&& __x)
-#else
swap(deque& __x)
-#endif
{
_Base::swap(__x);
this->_M_swap(__x);
@@ -497,18 +493,6 @@ namespace __debug
swap(deque<_Tp, _Alloc>& __lhs, deque<_Tp, _Alloc>& __rhs)
{ __lhs.swap(__rhs); }
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- template<typename _Tp, typename _Alloc>
- inline void
- swap(deque<_Tp, _Alloc>&& __lhs, deque<_Tp, _Alloc>& __rhs)
- { __lhs.swap(__rhs); }
-
- template<typename _Tp, typename _Alloc>
- inline void
- swap(deque<_Tp, _Alloc>& __lhs, deque<_Tp, _Alloc>&& __rhs)
- { __lhs.swap(__rhs); }
-#endif
-
} // namespace __debug
} // namespace std
diff --git a/libstdc++-v3/include/debug/formatter.h b/libstdc++-v3/include/debug/formatter.h
index 6dffc6b786d..b4b43896d04 100644
--- a/libstdc++-v3/include/debug/formatter.h
+++ b/libstdc++-v3/include/debug/formatter.h
@@ -1,6 +1,7 @@
// Debug-mode error formatting implementation -*- C++ -*-
-// Copyright (C) 2003, 2004, 2005, 2006, 2007, 2009 Free Software Foundation, Inc.
+// Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009
+// 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
@@ -211,13 +212,21 @@ namespace __gnu_debug
{
_M_variant._M_iterator._M_name = __name;
_M_variant._M_iterator._M_address = &__it;
+#ifdef __GXX_RTTI
_M_variant._M_iterator._M_type = &typeid(__it);
+#else
+ _M_variant._M_iterator._M_type = 0;
+#endif
_M_variant._M_iterator._M_constness =
__is_same<_Safe_iterator<_Iterator, _Sequence>,
typename _Sequence::iterator>::
value? __mutable_iterator : __const_iterator;
_M_variant._M_iterator._M_sequence = __it._M_get_sequence();
+#ifdef __GXX_RTTI
_M_variant._M_iterator._M_seq_type = &typeid(_Sequence);
+#else
+ _M_variant._M_iterator._M_seq_type = 0;
+#endif
if (__it._M_singular())
_M_variant._M_iterator._M_state = __singular;
@@ -240,7 +249,11 @@ namespace __gnu_debug
{
_M_variant._M_iterator._M_name = __name;
_M_variant._M_iterator._M_address = &__it;
+#ifdef __GXX_RTTI
_M_variant._M_iterator._M_type = &typeid(__it);
+#else
+ _M_variant._M_iterator._M_type = 0;
+#endif
_M_variant._M_iterator._M_constness = __mutable_iterator;
_M_variant._M_iterator._M_state = __it? __unknown_state : __singular;
_M_variant._M_iterator._M_sequence = 0;
@@ -253,7 +266,11 @@ namespace __gnu_debug
{
_M_variant._M_iterator._M_name = __name;
_M_variant._M_iterator._M_address = &__it;
+#ifdef __GXX_RTTI
_M_variant._M_iterator._M_type = &typeid(__it);
+#else
+ _M_variant._M_iterator._M_type = 0;
+#endif
_M_variant._M_iterator._M_constness = __const_iterator;
_M_variant._M_iterator._M_state = __it? __unknown_state : __singular;
_M_variant._M_iterator._M_sequence = 0;
@@ -266,7 +283,11 @@ namespace __gnu_debug
{
_M_variant._M_iterator._M_name = __name;
_M_variant._M_iterator._M_address = &__it;
+#ifdef __GXX_RTTI
_M_variant._M_iterator._M_type = &typeid(__it);
+#else
+ _M_variant._M_iterator._M_type = 0;
+#endif
_M_variant._M_iterator._M_constness = __unknown_constness;
_M_variant._M_iterator._M_state =
__gnu_debug::__check_singular(__it)? __singular : __unknown_state;
@@ -282,7 +303,11 @@ namespace __gnu_debug
_M_variant._M_sequence._M_name = __name;
_M_variant._M_sequence._M_address =
static_cast<const _Sequence*>(&__seq);
+#ifdef __GXX_RTTI
_M_variant._M_sequence._M_type = &typeid(_Sequence);
+#else
+ _M_variant._M_sequence._M_type = 0;
+#endif
}
template<typename _Sequence>
@@ -291,7 +316,11 @@ namespace __gnu_debug
{
_M_variant._M_sequence._M_name = __name;
_M_variant._M_sequence._M_address = &__seq;
+#ifdef __GXX_RTTI
_M_variant._M_sequence._M_type = &typeid(_Sequence);
+#else
+ _M_variant._M_sequence._M_type = 0;
+#endif
}
void
diff --git a/libstdc++-v3/include/debug/list b/libstdc++-v3/include/debug/list
index 39f763a33d1..d4904893f22 100644
--- a/libstdc++-v3/include/debug/list
+++ b/libstdc++-v3/include/debug/list
@@ -367,11 +367,7 @@ namespace __debug
}
void
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- swap(list&& __x)
-#else
swap(list& __x)
-#endif
{
_Base::swap(__x);
this->_M_swap(__x);
@@ -635,18 +631,6 @@ namespace __debug
swap(list<_Tp, _Alloc>& __lhs, list<_Tp, _Alloc>& __rhs)
{ __lhs.swap(__rhs); }
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- template<typename _Tp, typename _Alloc>
- inline void
- swap(list<_Tp, _Alloc>&& __lhs, list<_Tp, _Alloc>& __rhs)
- { __lhs.swap(__rhs); }
-
- template<typename _Tp, typename _Alloc>
- inline void
- swap(list<_Tp, _Alloc>& __lhs, list<_Tp, _Alloc>&& __rhs)
- { __lhs.swap(__rhs); }
-#endif
-
} // namespace __debug
} // namespace std
diff --git a/libstdc++-v3/include/debug/map.h b/libstdc++-v3/include/debug/map.h
index de1e5a5e324..c8eec2c4c6f 100644
--- a/libstdc++-v3/include/debug/map.h
+++ b/libstdc++-v3/include/debug/map.h
@@ -260,11 +260,7 @@ namespace __debug
}
void
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- swap(map&& __x)
-#else
swap(map& __x)
-#endif
{
_Base::swap(__x);
this->_M_swap(__x);
@@ -390,22 +386,6 @@ namespace __debug
map<_Key, _Tp, _Compare, _Allocator>& __rhs)
{ __lhs.swap(__rhs); }
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- template<typename _Key, typename _Tp,
- typename _Compare, typename _Allocator>
- inline void
- swap(map<_Key, _Tp, _Compare, _Allocator>&& __lhs,
- map<_Key, _Tp, _Compare, _Allocator>& __rhs)
- { __lhs.swap(__rhs); }
-
- template<typename _Key, typename _Tp,
- typename _Compare, typename _Allocator>
- inline void
- swap(map<_Key, _Tp, _Compare, _Allocator>& __lhs,
- map<_Key, _Tp, _Compare, _Allocator>&& __rhs)
- { __lhs.swap(__rhs); }
-#endif
-
} // namespace __debug
} // namespace std
diff --git a/libstdc++-v3/include/debug/multimap.h b/libstdc++-v3/include/debug/multimap.h
index 42741dac5ae..16841ff8668 100644
--- a/libstdc++-v3/include/debug/multimap.h
+++ b/libstdc++-v3/include/debug/multimap.h
@@ -248,11 +248,7 @@ namespace __debug
}
void
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- swap(multimap&& __x)
-#else
swap(multimap& __x)
-#endif
{
_Base::swap(__x);
this->_M_swap(__x);
@@ -378,22 +374,6 @@ namespace __debug
multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
{ __lhs.swap(__rhs); }
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- template<typename _Key, typename _Tp,
- typename _Compare, typename _Allocator>
- inline void
- swap(multimap<_Key, _Tp, _Compare, _Allocator>&& __lhs,
- multimap<_Key, _Tp, _Compare, _Allocator>& __rhs)
- { __lhs.swap(__rhs); }
-
- template<typename _Key, typename _Tp,
- typename _Compare, typename _Allocator>
- inline void
- swap(multimap<_Key, _Tp, _Compare, _Allocator>& __lhs,
- multimap<_Key, _Tp, _Compare, _Allocator>&& __rhs)
- { __lhs.swap(__rhs); }
-#endif
-
} // namespace __debug
} // namespace std
diff --git a/libstdc++-v3/include/debug/multiset.h b/libstdc++-v3/include/debug/multiset.h
index 3e4ee86a2f5..a952663ea31 100644
--- a/libstdc++-v3/include/debug/multiset.h
+++ b/libstdc++-v3/include/debug/multiset.h
@@ -245,11 +245,7 @@ namespace __debug
}
void
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- swap(multiset&& __x)
-#else
swap(multiset& __x)
-#endif
{
_Base::swap(__x);
this->_M_swap(__x);
@@ -376,20 +372,6 @@ namespace __debug
multiset<_Key, _Compare, _Allocator>& __y)
{ return __x.swap(__y); }
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- template<typename _Key, typename _Compare, typename _Allocator>
- void
- swap(multiset<_Key, _Compare, _Allocator>&& __x,
- multiset<_Key, _Compare, _Allocator>& __y)
- { return __x.swap(__y); }
-
- template<typename _Key, typename _Compare, typename _Allocator>
- void
- swap(multiset<_Key, _Compare, _Allocator>& __x,
- multiset<_Key, _Compare, _Allocator>&& __y)
- { return __x.swap(__y); }
-#endif
-
} // namespace __debug
} // namespace std
diff --git a/libstdc++-v3/include/debug/set.h b/libstdc++-v3/include/debug/set.h
index a025b3dec45..131b817d5fa 100644
--- a/libstdc++-v3/include/debug/set.h
+++ b/libstdc++-v3/include/debug/set.h
@@ -250,11 +250,7 @@ namespace __debug
}
void
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- swap(set&& __x)
-#else
swap(set& __x)
-#endif
{
_Base::swap(__x);
this->_M_swap(__x);
@@ -381,20 +377,6 @@ namespace __debug
set<_Key, _Compare, _Allocator>& __y)
{ return __x.swap(__y); }
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- template<typename _Key, typename _Compare, typename _Allocator>
- void
- swap(set<_Key, _Compare, _Allocator>&& __x,
- set<_Key, _Compare, _Allocator>& __y)
- { return __x.swap(__y); }
-
- template<typename _Key, typename _Compare, typename _Allocator>
- void
- swap(set<_Key, _Compare, _Allocator>& __x,
- set<_Key, _Compare, _Allocator>&& __y)
- { return __x.swap(__y); }
-#endif
-
} // namespace __debug
} // namespace std
diff --git a/libstdc++-v3/include/debug/unordered_map b/libstdc++-v3/include/debug/unordered_map
index fd7c31eff94..93a720653a3 100644
--- a/libstdc++-v3/include/debug/unordered_map
+++ b/libstdc++-v3/include/debug/unordered_map
@@ -129,7 +129,7 @@ namespace __debug
}
void
- swap(unordered_map&& __x)
+ swap(unordered_map& __x)
{
_Base::swap(__x);
_Safe_base::_M_swap(__x);
@@ -314,20 +314,6 @@ namespace __debug
unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
{ __x.swap(__y); }
- template<typename _Key, typename _Tp, typename _Hash,
- typename _Pred, typename _Alloc>
- inline void
- swap(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>&& __x,
- unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
- { __x.swap(__y); }
-
- template<typename _Key, typename _Tp, typename _Hash,
- typename _Pred, typename _Alloc>
- inline void
- swap(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
- unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>&& __y)
- { __x.swap(__y); }
-
template<typename _Key, typename _Tp,
typename _Hash = std::hash<_Key>,
@@ -415,7 +401,7 @@ namespace __debug
}
void
- swap(unordered_multimap&& __x)
+ swap(unordered_multimap& __x)
{
_Base::swap(__x);
_Safe_base::_M_swap(__x);
@@ -588,20 +574,6 @@ namespace __debug
unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
{ __x.swap(__y); }
- template<typename _Key, typename _Tp, typename _Hash,
- typename _Pred, typename _Alloc>
- inline void
- swap(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>&& __x,
- unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
- { __x.swap(__y); }
-
- template<typename _Key, typename _Tp, typename _Hash,
- typename _Pred, typename _Alloc>
- inline void
- swap(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
- unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>&& __y)
- { __x.swap(__y); }
-
} // namespace __debug
} // namespace std
diff --git a/libstdc++-v3/include/debug/unordered_set b/libstdc++-v3/include/debug/unordered_set
index d340442a21c..96d0b0f3e35 100644
--- a/libstdc++-v3/include/debug/unordered_set
+++ b/libstdc++-v3/include/debug/unordered_set
@@ -129,7 +129,7 @@ namespace __debug
}
void
- swap(unordered_set&& __x)
+ swap(unordered_set& __x)
{
_Base::swap(__x);
_Safe_base::_M_swap(__x);
@@ -313,18 +313,6 @@ namespace __debug
unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
{ __x.swap(__y); }
- template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
- inline void
- swap(unordered_set<_Value, _Hash, _Pred, _Alloc>&& __x,
- unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
- { __x.swap(__y); }
-
- template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
- inline void
- swap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
- unordered_set<_Value, _Hash, _Pred, _Alloc>&& __y)
- { __x.swap(__y); }
-
template<typename _Value,
typename _Hash = std::hash<_Value>,
@@ -411,7 +399,7 @@ namespace __debug
}
void
- swap(unordered_multiset&& __x)
+ swap(unordered_multiset& __x)
{
_Base::swap(__x);
_Safe_base::_M_swap(__x);
@@ -583,18 +571,6 @@ namespace __debug
unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
{ __x.swap(__y); }
- template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
- inline void
- swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>&& __x,
- unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
- { __x.swap(__y); }
-
- template<typename _Value, typename _Hash, typename _Pred, typename _Alloc>
- inline void
- swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
- unordered_multiset<_Value, _Hash, _Pred, _Alloc>&& __y)
- { __x.swap(__y); }
-
} // namespace __debug
} // namespace std
diff --git a/libstdc++-v3/include/debug/vector b/libstdc++-v3/include/debug/vector
index 97ab7bf5846..708ee455fe9 100644
--- a/libstdc++-v3/include/debug/vector
+++ b/libstdc++-v3/include/debug/vector
@@ -452,11 +452,7 @@ namespace __debug
}
void
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- swap(vector&& __x)
-#else
swap(vector& __x)
-#endif
{
_Base::swap(__x);
this->_M_swap(__x);
@@ -533,18 +529,6 @@ namespace __debug
swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>& __rhs)
{ __lhs.swap(__rhs); }
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- template<typename _Tp, typename _Alloc>
- inline void
- swap(vector<_Tp, _Alloc>&& __lhs, vector<_Tp, _Alloc>& __rhs)
- { __lhs.swap(__rhs); }
-
- template<typename _Tp, typename _Alloc>
- inline void
- swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>&& __rhs)
- { __lhs.swap(__rhs); }
-#endif
-
} // namespace __debug
} // namespace std
diff --git a/libstdc++-v3/include/ext/memory b/libstdc++-v3/include/ext/memory
index 048ebe6ca6a..7776d730a4a 100644
--- a/libstdc++-v3/include/ext/memory
+++ b/libstdc++-v3/include/ext/memory
@@ -102,9 +102,9 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
template<typename _InputIter, typename _Size, typename _ForwardIter>
inline pair<_InputIter, _ForwardIter>
__uninitialized_copy_n(_InputIter __first, _Size __count,
- _ForwardIter __result)
- { return __uninitialized_copy_n(__first, __count, __result,
- __iterator_category(__first)); }
+ _ForwardIter __result)
+ { return __gnu_cxx::__uninitialized_copy_n(__first, __count, __result,
+ __iterator_category(__first)); }
/**
* @brief Copies the range [first,last) into result.
@@ -120,8 +120,8 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
inline pair<_InputIter, _ForwardIter>
uninitialized_copy_n(_InputIter __first, _Size __count,
_ForwardIter __result)
- { return __uninitialized_copy_n(__first, __count, __result,
- __iterator_category(__first)); }
+ { return __gnu_cxx::__uninitialized_copy_n(__first, __count, __result,
+ __iterator_category(__first)); }
// An alternative version of uninitialized_copy_n that constructs
@@ -154,7 +154,7 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
_ForwardIter __result,
std::allocator<_Tp>)
{
- return uninitialized_copy_n(__first, __count, __result);
+ return __gnu_cxx::uninitialized_copy_n(__first, __count, __result);
}
/**
diff --git a/libstdc++-v3/include/ext/pb_ds/detail/debug_map_base.hpp b/libstdc++-v3/include/ext/pb_ds/detail/debug_map_base.hpp
index 6f2defb648e..2227691feb0 100644
--- a/libstdc++-v3/include/ext/pb_ds/detail/debug_map_base.hpp
+++ b/libstdc++-v3/include/ext/pb_ds/detail/debug_map_base.hpp
@@ -154,8 +154,8 @@ namespace __gnu_pbds
{
_GLIBCXX_DEBUG_ONLY(assert_valid();)
__gnu_cxx::throw_allocator<char> alloc;
- const double orig_throw_prob = alloc.get_throw_prob();
- alloc.set_throw_prob(0);
+ const double orig_throw_prob = alloc.get_probability();
+ alloc.set_probability(0);
if (find(r_key) != m_key_set.end())
{
std::cerr << "insert_new" << r_key << std::endl;
@@ -171,7 +171,7 @@ namespace __gnu_pbds
std::cerr << "insert_new" << r_key << std::endl;
std::abort();
}
- alloc.set_throw_prob(orig_throw_prob);
+ alloc.set_probability(orig_throw_prob);
_GLIBCXX_DEBUG_ONLY(assert_valid();)
}
@@ -315,8 +315,8 @@ namespace __gnu_pbds
split(const_key_reference r_key, Cmp_Fn cmp_fn, PB_DS_CLASS_C_DEC& other)
{
__gnu_cxx::throw_allocator<char> alloc;
- const double orig_throw_prob = alloc.get_throw_prob();
- alloc.set_throw_prob(0);
+ const double orig_throw_prob = alloc.get_probability();
+ alloc.set_probability(0);
other.clear();
key_set_iterator it = m_key_set.begin();
while (it != m_key_set.end())
@@ -327,7 +327,7 @@ namespace __gnu_pbds
}
else
++it;
- alloc.set_throw_prob(orig_throw_prob);
+ alloc.set_probability(orig_throw_prob);
}
PB_DS_CLASS_T_DEC
@@ -336,8 +336,8 @@ namespace __gnu_pbds
join(PB_DS_CLASS_C_DEC& other)
{
__gnu_cxx::throw_allocator<char> alloc;
- const double orig_throw_prob = alloc.get_throw_prob();
- alloc.set_throw_prob(0);
+ const double orig_throw_prob = alloc.get_probability();
+ alloc.set_probability(0);
key_set_iterator it = other.m_key_set.begin();
while (it != other.m_key_set.end())
{
@@ -345,7 +345,7 @@ namespace __gnu_pbds
it = other.m_key_set.erase(it);
}
_GLIBCXX_DEBUG_ASSERT(other.m_key_set.empty());
- alloc.set_throw_prob(orig_throw_prob);
+ alloc.set_probability(orig_throw_prob);
}
#undef PB_DS_CLASS_T_DEC
diff --git a/libstdc++-v3/include/ext/pb_ds/detail/gp_hash_table_map_/resize_fn_imps.hpp b/libstdc++-v3/include/ext/pb_ds/detail/gp_hash_table_map_/resize_fn_imps.hpp
index 82a8ab0d257..0492a47928b 100644
--- a/libstdc++-v3/include/ext/pb_ds/detail/gp_hash_table_map_/resize_fn_imps.hpp
+++ b/libstdc++-v3/include/ext/pb_ds/detail/gp_hash_table_map_/resize_fn_imps.hpp
@@ -79,7 +79,7 @@ PB_DS_CLASS_C_DEC::
resize_imp(size_type new_size)
{
#ifdef PB_DS_REGRESSION
- typename Allocator::group_throw_prob_adjustor adjust(m_num_e);
+ typename Allocator::group_adjustor adjust(m_num_e);
#endif
if (new_size == m_num_e)
diff --git a/libstdc++-v3/include/ext/pb_ds/detail/ov_tree_map_/erase_fn_imps.hpp b/libstdc++-v3/include/ext/pb_ds/detail/ov_tree_map_/erase_fn_imps.hpp
index 618306dce2e..05e7d1a1107 100644
--- a/libstdc++-v3/include/ext/pb_ds/detail/ov_tree_map_/erase_fn_imps.hpp
+++ b/libstdc++-v3/include/ext/pb_ds/detail/ov_tree_map_/erase_fn_imps.hpp
@@ -71,7 +71,7 @@ erase_if(Pred pred)
_GLIBCXX_DEBUG_ONLY(assert_valid();)
#ifdef PB_DS_REGRESSION
- typename Allocator::group_throw_prob_adjustor adjust(m_size);
+ typename Allocator::group_adjustor adjust(m_size);
#endif
size_type new_size = 0;
@@ -133,7 +133,7 @@ erase_imp(It it)
_GLIBCXX_DEBUG_ONLY(PB_DS_CLASS_C_DEC::check_key_exists(PB_DS_V2F(*it));)
#ifdef PB_DS_REGRESSION
- typename Allocator::group_throw_prob_adjustor adjust(m_size);
+ typename Allocator::group_adjustor adjust(m_size);
#endif
_GLIBCXX_DEBUG_ASSERT(m_size > 0);
diff --git a/libstdc++-v3/include/ext/pb_ds/detail/ov_tree_map_/ov_tree_map_.hpp b/libstdc++-v3/include/ext/pb_ds/detail/ov_tree_map_/ov_tree_map_.hpp
index f331f0fb160..7d2ed3f1aaa 100644
--- a/libstdc++-v3/include/ext/pb_ds/detail/ov_tree_map_/ov_tree_map_.hpp
+++ b/libstdc++-v3/include/ext/pb_ds/detail/ov_tree_map_/ov_tree_map_.hpp
@@ -414,7 +414,7 @@ namespace __gnu_pbds
{
_GLIBCXX_DEBUG_ONLY(assert_valid();)
#ifdef PB_DS_REGRESSION
- typename Allocator::group_throw_prob_adjustor adjust(m_size);
+ typename Allocator::group_adjustor adjust(m_size);
#endif
_GLIBCXX_DEBUG_ONLY(debug_base::check_key_does_not_exist(PB_DS_V2F(r_value)));
diff --git a/libstdc++-v3/include/ext/throw_allocator.h b/libstdc++-v3/include/ext/throw_allocator.h
index 21e235c1200..69daa15f5db 100644
--- a/libstdc++-v3/include/ext/throw_allocator.h
+++ b/libstdc++-v3/include/ext/throw_allocator.h
@@ -51,39 +51,19 @@
#include <ostream>
#include <stdexcept>
#include <utility>
-#include <tr1/random>
#include <bits/functexcept.h>
#include <bits/move.h>
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+# include <functional>
+# include <random>
+#else
+# include <tr1/functional>
+# include <tr1/random>
+#endif
_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
- class twister_rand_gen
- {
- private:
- std::tr1::mt19937 _M_generator;
-
- public:
- twister_rand_gen(unsigned int seed =
- static_cast<unsigned int>(std::time(0)))
- : _M_generator(seed) { }
-
- void
- init(unsigned int seed)
- { _M_generator.seed(seed); }
-
- double
- get_prob()
- {
- const double min = _M_generator.min();
- const double res = static_cast<const double>(_M_generator() - min);
- const double range = static_cast<const double>(_M_generator.max() - min);
- const double ret = res / range;
- _GLIBCXX_DEBUG_ASSERT(ret >= 0 && ret <= 1);
- return ret;
- }
- };
-
- /**
+ /**
* @brief Thown by throw_allocator.
* @ingroup exceptions
*/
@@ -101,22 +81,18 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
#endif
}
- /// Base class.
- class throw_allocator_base
+ // Base class for checking address and label information about
+ // allocations. Create a std::map between the allocated address
+ // (void*) and a datum for annotations, which are a pair of numbers
+ // corresponding to label and allocated size.
+ struct annotate_base
{
- public:
- void
- init(unsigned long seed)
- { rand_gen().init(seed); }
-
- static void
- set_throw_prob(double t_p)
- { throw_prob() = t_p; }
-
- static double
- get_throw_prob()
- { return throw_prob(); }
-
+ annotate_base()
+ {
+ label();
+ map();
+ }
+
static void
set_label(size_t l)
{ label() = l; }
@@ -125,101 +101,121 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
get_label()
{ return label(); }
- static bool
- empty()
- { return map().empty(); }
-
- struct group_throw_prob_adjustor
- {
- group_throw_prob_adjustor(size_t size)
- : _M_throw_prob_orig(get_throw_prob())
- {
- set_throw_prob(1 - std::pow(double(1 - get_throw_prob()),
- double(0.5 / (size + 1))));
- }
-
- ~group_throw_prob_adjustor()
- { set_throw_prob(_M_throw_prob_orig); }
-
- private:
- const double _M_throw_prob_orig;
- };
-
- struct zero_throw_prob_adjustor
- {
- zero_throw_prob_adjustor()
- : _M_throw_prob_orig(get_throw_prob())
- { set_throw_prob(0); }
-
- ~zero_throw_prob_adjustor()
- { set_throw_prob(_M_throw_prob_orig); }
-
- private:
- const double _M_throw_prob_orig;
- };
-
- protected:
- static void
+ void
insert(void* p, size_t size)
{
- const_iterator found_it = map().find(p);
- if (found_it != map().end())
+ if (p == NULL)
+ {
+ std::string error("throw_allocator_base::insert null insert!\n");
+ log_to_string(error, make_entry(p, size));
+ std::__throw_logic_error(error.c_str());
+ }
+
+ const_iterator found = map().find(p);
+ if (found != map().end())
{
std::string error("throw_allocator_base::insert double insert!\n");
- print_to_string(error, make_entry(p, size));
- print_to_string(error, *found_it);
+ log_to_string(error, make_entry(p, size));
+ log_to_string(error, *found);
std::__throw_logic_error(error.c_str());
}
+
map().insert(make_entry(p, size));
}
- static void
+ void
erase(void* p, size_t size)
{
check_allocated(p, size);
map().erase(p);
- }
-
- static void
- throw_conditionally()
- {
- if (rand_gen().get_prob() < get_throw_prob())
- __throw_forced_exception_error();
- }
+ }
- // See if a particular address and size has been allocated by this
- // allocator.
- static void
+ // See if a particular address and size has been allocated.
+ inline void
check_allocated(void* p, size_t size)
- { do_check_allocated(map().find(p), map().end(), p, size); }
+ {
+ const_iterator found = map().find(p);
+ if (found == map().end())
+ {
+ std::string error("annotate_base::check_allocated by value "
+ "null erase!\n");
+ log_to_string(error, make_entry(p, size));
+ std::__throw_logic_error(error.c_str());
+ }
+
+ if (found->second.second != size)
+ {
+ std::string error("annotate_base::check_allocated by value "
+ "wrong-size erase!\n");
+ log_to_string(error, make_entry(p, size));
+ log_to_string(error, *found);
+ std::__throw_logic_error(error.c_str());
+ }
+ }
- // See if a given label has been allocated by this allocator.
- static void
+ // See if a given label has been allocated.
+ inline void
check_allocated(size_t label)
- { do_check_allocated(map().begin(), map().end(), label); }
+ {
+ const_iterator beg = map().begin();
+ const_iterator end = map().end();
+ std::string found;
+ while (beg != end)
+ {
+ if (beg->second.first == label)
+ log_to_string(found, *beg);
+ ++beg;
+ }
+
+ if (!found.empty())
+ {
+ std::string error("annotate_base::check_allocated by label\n");
+ error += found;
+ std::__throw_logic_error(error.c_str());
+ }
+ }
private:
- typedef std::pair<size_t, size_t> alloc_data_type;
- typedef std::map<void*, alloc_data_type> map_type;
+ typedef std::pair<size_t, size_t> data_type;
+ typedef std::map<void*, data_type> map_type;
typedef map_type::value_type entry_type;
typedef map_type::const_iterator const_iterator;
typedef map_type::const_reference const_reference;
- friend std::ostream&
- operator<<(std::ostream&, const throw_allocator_base&);
+ friend std::ostream&
+ operator<<(std::ostream&, const annotate_base&);
- static entry_type
+ entry_type
make_entry(void* p, size_t size)
- { return std::make_pair(p, alloc_data_type(get_label(), size)); }
-
- static void
- do_check_allocated(const_iterator, const_iterator, void*, size_t);
+ { return std::make_pair(p, data_type(get_label(), size)); }
- static void
- do_check_allocated(const_iterator, const_iterator, size_t);
+ void
+ log_to_string(std::string& s, const_reference ref) const
+ {
+ char buf[40];
+ const char tab('\t');
+ s += "label: ";
+ unsigned long l = static_cast<unsigned long>(ref.second.first);
+ __builtin_sprintf(buf, "%lu", l);
+ s += buf;
+ s += tab;
+ s += "size: ";
+ l = static_cast<unsigned long>(ref.second.second);
+ __builtin_sprintf(buf, "%lu", l);
+ s += buf;
+ s += tab;
+ s += "address: ";
+ __builtin_sprintf(buf, "%p", ref.first);
+ s += buf;
+ s += '\n';
+ }
- static void
- print_to_string(std::string&, const_reference);
+ static size_t&
+ label()
+ {
+ static size_t ll;
+ return ll;
+ }
static map_type&
map()
@@ -227,47 +223,144 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
static map_type mp;
return mp;
}
+ };
+
+ inline std::ostream&
+ operator<<(std::ostream& os, const annotate_base& __b)
+ {
+ std::string error;
+ typedef annotate_base base_type;
+ base_type::const_iterator beg = __b.map().begin();
+ base_type::const_iterator end = __b.map().end();
+ for (; beg != end; ++beg)
+ __b.log_to_string(error, *beg);
+ return os << error;
+ }
+
+ /// Base class for probability control and throw.
+ struct probability_base
+ {
+ // Scope-level probability adjustor objects: set probability for
+ // throw at the beginning of a scope block, and restores to
+ // previous probability when object is destroyed on exiting the
+ // block.
+ struct adjustor_base
+ {
+ private:
+ const double _M_prob;
+
+ public:
+ adjustor_base() : _M_prob(get_probability()) { }
+
+ virtual ~adjustor_base()
+ { set_probability(_M_prob); }
+ };
+
+ // Group condition.
+ struct group_adjustor : public adjustor_base
+ {
+ group_adjustor(size_t size)
+ { set_probability(1 - std::pow(double(1 - get_probability()),
+ double(0.5 / (size + 1))));
+ }
+ };
- static twister_rand_gen&
- rand_gen()
+ // Never enter the condition.
+ struct never_adjustor : public adjustor_base
{
- static twister_rand_gen rg;
- return rg;
+ never_adjustor() { set_probability(0); }
+ };
+
+ // Always enter the condition.
+ struct always_adjustor : public adjustor_base
+ {
+ always_adjustor() { set_probability(1); }
+ };
+
+ probability_base()
+ {
+ probability();
+ engine();
}
+ static void
+ set_probability(double __p)
+ { probability() = __p; }
+
static double&
- throw_prob()
+ get_probability()
+ { return probability(); }
+
+ void
+ throw_conditionally()
{
- static double tp;
- return tp;
+ if (generate() < get_probability())
+ __throw_forced_exception_error();
}
- static size_t&
- label()
+ void
+ seed(unsigned long __s)
+ { engine().seed(__s); }
+
+ private:
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ typedef std::uniform_real_distribution<double> distribution_type;
+ typedef std::mt19937 engine_type;
+#else
+ typedef std::tr1::uniform_real<double> distribution_type;
+ typedef std::tr1::mt19937 engine_type;
+#endif
+
+ double
+ generate()
{
- static size_t ll;
- return ll;
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ const distribution_type distribution(0, 1);
+ static auto generator = std::bind(distribution, engine());
+#else
+ // Use variate_generator to get normalized results.
+ typedef std::tr1::variate_generator<engine_type, distribution_type> gen_t;
+ distribution_type distribution(0, 1);
+ static gen_t generator(engine(), distribution);
+#endif
+
+ double random = generator();
+ if (random < distribution.min() || random > distribution.max())
+ {
+ std::string __s("throw_allocator::throw_conditionally");
+ __s += "\n";
+ __s += "random number generated is: ";
+ char buf[40];
+ __builtin_sprintf(buf, "%f", random);
+ __s += buf;
+ std::__throw_out_of_range(__s.c_str());
+ }
+
+ return random;
}
- };
- inline std::ostream&
- operator<<(std::ostream& os, const throw_allocator_base&)
- {
- std::string error;
- typedef throw_allocator_base alloc_type;
- alloc_type::const_iterator beg = alloc_type::map().begin();
- alloc_type::const_iterator end = alloc_type::map().end();
- for (; beg != end; ++beg)
- alloc_type::print_to_string(error, *beg);
- return os << error;
- }
+ static double&
+ probability()
+ {
+ static double __p;
+ return __p;
+ }
+
+ static engine_type&
+ engine()
+ {
+ static engine_type __e;
+ return __e;
+ }
+ };
- /**
+ /**
* @brief Allocator class with logging and exception control.
* @ingroup allocators
*/
template<typename T>
- class throw_allocator : public throw_allocator_base
+ class throw_allocator
+ : public probability_base, public annotate_base
{
public:
typedef size_t size_type;
@@ -278,11 +371,14 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
typedef value_type& reference;
typedef const value_type& const_reference;
+ private:
+ std::allocator<value_type> _M_allocator;
+ public:
template<typename U>
struct rebind
{
- typedef throw_allocator<U> other;
+ typedef throw_allocator<U> other;
};
throw_allocator() throw() { }
@@ -290,13 +386,13 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
throw_allocator(const throw_allocator&) throw() { }
template<typename U>
- throw_allocator(const throw_allocator<U>&) throw() { }
+ throw_allocator(const throw_allocator<U>&) throw() { }
~throw_allocator() throw() { }
size_type
max_size() const throw()
- { return std::allocator<value_type>().max_size(); }
+ { return _M_allocator.max_size(); }
pointer
allocate(size_type __n, std::allocator<void>::const_pointer hint = 0)
@@ -305,43 +401,41 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
std::__throw_bad_alloc();
throw_conditionally();
- value_type* const a = std::allocator<value_type>().allocate(__n, hint);
+ pointer const a = _M_allocator.allocate(__n, hint);
insert(a, sizeof(value_type) * __n);
return a;
}
void
construct(pointer __p, const T& val)
- { return std::allocator<value_type>().construct(__p, val); }
+ { return _M_allocator.construct(__p, val); }
#ifdef __GXX_EXPERIMENTAL_CXX0X__
template<typename... _Args>
- void
- construct(pointer __p, _Args&&... __args)
- {
- return std::allocator<value_type>().
- construct(__p, std::forward<_Args>(__args)...);
- }
+ void
+ construct(pointer __p, _Args&&... __args)
+ { return _M_allocator.construct(__p, std::forward<_Args>(__args)...); }
#endif
void
destroy(pointer __p)
- { std::allocator<value_type>().destroy(__p); }
+ { _M_allocator.destroy(__p); }
void
deallocate(pointer __p, size_type __n)
{
erase(__p, sizeof(value_type) * __n);
- std::allocator<value_type>().deallocate(__p, __n);
+ _M_allocator.deallocate(__p, __n);
}
void
check_allocated(pointer __p, size_type __n)
- { throw_allocator_base::check_allocated(__p, sizeof(value_type) * __n); }
+ {
+ size_type __t = sizeof(value_type) * __n;
+ annotate_base::check_allocated(__p, __t);
+ }
- void
- check_allocated(size_type label)
- { throw_allocator_base::check_allocated(label); }
+ using annotate_base::check_allocated;
};
template<typename T>
@@ -356,4 +450,4 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
_GLIBCXX_END_NAMESPACE
-#endif
+#endif
diff --git a/libstdc++-v3/include/ext/vstring.h b/libstdc++-v3/include/ext/vstring.h
index f15d6c674fe..cfce575dc72 100644
--- a/libstdc++-v3/include/ext/vstring.h
+++ b/libstdc++-v3/include/ext/vstring.h
@@ -1439,11 +1439,7 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
* constant time.
*/
void
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- swap(__versa_string&& __s)
-#else
swap(__versa_string& __s)
-#endif
{ this->_M_swap(__s); }
// String operations:
@@ -2335,22 +2331,6 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
__versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
{ __lhs.swap(__rhs); }
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- template<typename _CharT, typename _Traits, typename _Alloc,
- template <typename, typename, typename> class _Base>
- inline void
- swap(__versa_string<_CharT, _Traits, _Alloc, _Base>&& __lhs,
- __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
- { __lhs.swap(__rhs); }
-
- template<typename _CharT, typename _Traits, typename _Alloc,
- template <typename, typename, typename> class _Base>
- inline void
- swap(__versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
- __versa_string<_CharT, _Traits, _Alloc, _Base>&& __rhs)
- { __lhs.swap(__rhs); }
-#endif
-
_GLIBCXX_END_NAMESPACE
_GLIBCXX_BEGIN_NAMESPACE(std)
diff --git a/libstdc++-v3/include/std/istream b/libstdc++-v3/include/std/istream
index 521be7fd506..1979a51327f 100644
--- a/libstdc++-v3/include/std/istream
+++ b/libstdc++-v3/include/std/istream
@@ -631,6 +631,9 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
template<typename _CharT, typename _Traits>
class basic_istream<_CharT, _Traits>::sentry
{
+ // Data Members.
+ bool _M_ok;
+
public:
/// Easy access to dependant types.
typedef _Traits traits_type;
@@ -670,11 +673,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
* For ease of use, sentries may be converted to booleans. The
* return value is that of the sentry state (true == okay).
*/
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ explicit
+#endif
operator bool() const
{ return _M_ok; }
-
- private:
- bool _M_ok;
};
// [27.6.1.2.3] character extraction templates
diff --git a/libstdc++-v3/include/std/mutex b/libstdc++-v3/include/std/mutex
index c090608cb53..b3a04380641 100644
--- a/libstdc++-v3/include/std/mutex
+++ b/libstdc++-v3/include/std/mutex
@@ -386,18 +386,6 @@ namespace std
extern const try_to_lock_t try_to_lock;
extern const adopt_lock_t adopt_lock;
- /**
- * @brief Thrown to indicate errors with lock operations.
- *
- * @ingroup exceptions
- */
- class lock_error : public exception
- {
- public:
- virtual const char*
- _GLIBCXX_CONST what() const throw();
- };
-
/// @brief Scoped lock idiom.
// Acquire the mutex here with a constructor call, then release with
// the destructor call in accordance with RAII style.
@@ -567,7 +555,7 @@ namespace std
}
void
- swap(unique_lock&& __u)
+ swap(unique_lock& __u)
{
std::swap(_M_device, __u._M_device);
std::swap(_M_owns, __u._M_owns);
@@ -586,7 +574,7 @@ namespace std
owns_lock() const
{ return _M_owns; }
- /* explicit */ operator bool () const
+ explicit operator bool() const
{ return owns_lock(); }
mutex_type*
@@ -603,16 +591,6 @@ namespace std
swap(unique_lock<_Mutex>& __x, unique_lock<_Mutex>& __y)
{ __x.swap(__y); }
- template<typename _Mutex>
- inline void
- swap(unique_lock<_Mutex>&& __x, unique_lock<_Mutex>& __y)
- { __x.swap(__y); }
-
- template<typename _Mutex>
- inline void
- swap(unique_lock<_Mutex>& __x, unique_lock<_Mutex>&& __y)
- { __x.swap(__y); }
-
template<int _Idx>
struct __unlock_impl
{
diff --git a/libstdc++-v3/include/std/ostream b/libstdc++-v3/include/std/ostream
index c49b36fc77f..b9ea4a8ce19 100644
--- a/libstdc++-v3/include/std/ostream
+++ b/libstdc++-v3/include/std/ostream
@@ -376,7 +376,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
template <typename _CharT, typename _Traits>
class basic_ostream<_CharT, _Traits>::sentry
{
- // Data Members:
+ // Data Members.
bool _M_ok;
basic_ostream<_CharT, _Traits>& _M_os;
@@ -420,6 +420,9 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
* For ease of use, sentries may be converted to booleans. The
* return value is that of the sentry state (true == okay).
*/
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ explicit
+#endif
operator bool() const
{ return _M_ok; }
};
diff --git a/libstdc++-v3/include/std/system_error b/libstdc++-v3/include/std/system_error
index b9902a137c1..7f462a20dff 100644
--- a/libstdc++-v3/include/std/system_error
+++ b/libstdc++-v3/include/std/system_error
@@ -152,15 +152,8 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
message() const
{ return category().message(value()); }
- // Safe bool idiom.
- // explicit operator bool() const throw()
- // { return _M_value != 0; }
- typedef void (*__bool_type)();
-
- static void __not_bool_type() { }
-
- operator __bool_type() const
- { return _M_value != 0 ? &__not_bool_type : false; }
+ explicit operator bool() const
+ { return _M_value != 0 ? true : false; }
// DR 804.
private:
@@ -233,15 +226,8 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
message() const
{ return category().message(value()); }
- // Safe bool idiom.
- // explicit operator bool() const throw()
- // { return _M_value != 0; }
- typedef void (*__bool_type)();
-
- static void __not_bool_type() { }
-
- operator __bool_type() const
- { return _M_value != 0 ? &__not_bool_type : false; }
+ explicit operator bool() const
+ { return _M_value != 0 ? true : false; }
// DR 804.
private:
diff --git a/libstdc++-v3/include/std/thread b/libstdc++-v3/include/std/thread
index 8ce9e5cf6a5..bf282cc0365 100644
--- a/libstdc++-v3/include/std/thread
+++ b/libstdc++-v3/include/std/thread
@@ -88,7 +88,7 @@ namespace std
template<class _CharT, class _Traits>
friend basic_ostream<_CharT, _Traits>&
- operator<<(basic_ostream<_CharT, _Traits>&& __out, thread::id __id);
+ operator<<(basic_ostream<_CharT, _Traits>& __out, thread::id __id);
};
// Simple base type that the templatized, derived class containing
@@ -135,7 +135,7 @@ namespace std
~thread()
{
if (joinable())
- detach();
+ std::terminate();
}
thread& operator=(const thread&) = delete;
@@ -143,13 +143,13 @@ namespace std
thread& operator=(thread&& __t)
{
if (joinable())
- detach();
+ std::terminate();
swap(__t);
return *this;
}
void
- swap(thread&& __t)
+ swap(thread& __t)
{ std::swap(_M_id, __t._M_id); }
bool
@@ -194,14 +194,6 @@ namespace std
swap(thread& __x, thread& __y)
{ __x.swap(__y); }
- inline void
- swap(thread&& __x, thread& __y)
- { __x.swap(__y); }
-
- inline void
- swap(thread& __x, thread&& __y)
- { __x.swap(__y); }
-
inline bool
operator!=(thread::id __x, thread::id __y)
{ return !(__x == __y); }
@@ -220,7 +212,7 @@ namespace std
template<class _CharT, class _Traits>
inline basic_ostream<_CharT, _Traits>&
- operator<<(basic_ostream<_CharT, _Traits>&& __out, thread::id __id)
+ operator<<(basic_ostream<_CharT, _Traits>& __out, thread::id __id)
{
if (__id == thread::id())
return __out << "thread::id of a non-executing thread";
diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple
index c5dbe6bcc82..8dc8dcfc064 100644
--- a/libstdc++-v3/include/std/tuple
+++ b/libstdc++-v3/include/std/tuple
@@ -77,7 +77,7 @@ namespace std
_Head& _M_head() { return *this; }
const _Head& _M_head() const { return *this; }
- void _M_swap_impl(_Head&&) { /* no-op */ }
+ void _M_swap_impl(_Head&) { /* no-op */ }
};
template<std::size_t _Idx, typename _Head>
@@ -97,7 +97,7 @@ namespace std
const _Head& _M_head() const { return _M_head_impl; }
void
- _M_swap_impl(_Head&& __h)
+ _M_swap_impl(_Head& __h)
{
using std::swap;
swap(__h, _M_head_impl);
@@ -125,7 +125,7 @@ namespace std
struct _Tuple_impl<_Idx>
{
protected:
- void _M_swap_impl(_Tuple_impl&&) { /* no-op */ }
+ void _M_swap_impl(_Tuple_impl&) { /* no-op */ }
};
/**
@@ -214,7 +214,7 @@ namespace std
protected:
void
- _M_swap_impl(_Tuple_impl&& __in)
+ _M_swap_impl(_Tuple_impl& __in)
{
_Base::_M_swap_impl(__in._M_head());
_Inherited::_M_swap_impl(__in._M_tail());
@@ -292,7 +292,7 @@ namespace std
}
void
- swap(tuple&& __in)
+ swap(tuple& __in)
{ _Inherited::_M_swap_impl(__in); }
};
@@ -301,7 +301,7 @@ namespace std
class tuple<>
{
public:
- void swap(tuple&&) { /* no-op */ }
+ void swap(tuple&) { /* no-op */ }
};
/// tuple (2-element), with construction and assignment from a pair.
@@ -394,7 +394,7 @@ namespace std
}
void
- swap(tuple&& __in)
+ swap(tuple& __in)
{
using std::swap;
swap(this->_M_head(), __in._M_head());
@@ -665,16 +665,6 @@ namespace std
swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y)
{ __x.swap(__y); }
- template<typename... _Elements>
- inline void
- swap(tuple<_Elements...>&& __x, tuple<_Elements...>& __y)
- { __x.swap(__y); }
-
- template<typename... _Elements>
- inline void
- swap(tuple<_Elements...>& __x, tuple<_Elements...>&& __y)
- { __x.swap(__y); }
-
// A class (and instance) which can be used in 'tie' when an element
// of a tuple is not required
struct _Swallow_assign
diff --git a/libstdc++-v3/include/tr1_impl/functional b/libstdc++-v3/include/tr1_impl/functional
index 7e6eaeb2685..584a403de48 100644
--- a/libstdc++-v3/include/tr1_impl/functional
+++ b/libstdc++-v3/include/tr1_impl/functional
@@ -1557,7 +1557,7 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
template<typename _Signature>
static bool
_M_not_empty_function(const function<_Signature>& __f)
- { return __f; }
+ { return static_cast<bool>(__f); }
template<typename _Tp>
static bool
@@ -1761,6 +1761,7 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
: public _Maybe_unary_or_binary_function<_Res, _ArgTypes...>,
private _Function_base
{
+#ifndef __GXX_EXPERIMENTAL_CXX0X__
/// This class is used to implement the safe_bool idiom.
struct _Hidden_type
{
@@ -1769,6 +1770,7 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
/// This typedef is used to implement the safe_bool idiom.
typedef _Hidden_type* _Hidden_type::* _Safe_bool;
+#endif
typedef _Res _Signature_type(_ArgTypes...);
@@ -1918,6 +1920,10 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
*
* This function will not throw an exception.
*/
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+ explicit operator bool() const
+ { return !_M_empty(); }
+#else
operator _Safe_bool() const
{
if (_M_empty())
@@ -1925,6 +1931,7 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
else
return &_Hidden_type::_M_bool;
}
+#endif
// [3.7.2.4] function invocation
@@ -1982,7 +1989,7 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
function(const function& __x)
: _Function_base()
{
- if (__x)
+ if (static_cast<bool>(__x))
{
_M_invoker = __x._M_invoker;
_M_manager = __x._M_manager;
@@ -2088,13 +2095,13 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
template<typename _Signature>
inline bool
operator==(const function<_Signature>& __f, _M_clear_type*)
- { return !__f; }
+ { return !static_cast<bool>(__f); }
/// @overload
template<typename _Signature>
inline bool
operator==(_M_clear_type*, const function<_Signature>& __f)
- { return !__f; }
+ { return !static_cast<bool>(__f); }
/**
* @brief Compares a polymorphic function object wrapper against 0
@@ -2106,13 +2113,13 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
template<typename _Signature>
inline bool
operator!=(const function<_Signature>& __f, _M_clear_type*)
- { return __f; }
+ { return static_cast<bool>(__f); }
/// @overload
template<typename _Signature>
inline bool
operator!=(_M_clear_type*, const function<_Signature>& __f)
- { return __f; }
+ { return static_cast<bool>(__f); }
// [3.7.2.8] specialized algorithms
diff --git a/libstdc++-v3/include/tr1_impl/hashtable b/libstdc++-v3/include/tr1_impl/hashtable
index 7c90983095f..bce550ff1f1 100644
--- a/libstdc++-v3/include/tr1_impl/hashtable
+++ b/libstdc++-v3/include/tr1_impl/hashtable
@@ -225,11 +225,7 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
~_Hashtable();
-#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
- void swap(_Hashtable&&);
-#else
void swap(_Hashtable&);
-#endif
// Basic container operations
iterator
@@ -732,11 +728,7 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
void
_Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
_H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
-#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
- swap(_Hashtable&& __x)
-#else
swap(_Hashtable& __x)
-#endif
{
// The only base class with member variables is hash_code_base. We
// define _Hash_code_base::_M_swap because different specializations
diff --git a/libstdc++-v3/include/tr1_impl/unordered_map b/libstdc++-v3/include/tr1_impl/unordered_map
index cef6490424d..edf49789fa4 100644
--- a/libstdc++-v3/include/tr1_impl/unordered_map
+++ b/libstdc++-v3/include/tr1_impl/unordered_map
@@ -340,31 +340,5 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
{ __x.swap(__y); }
-#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
- template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
- inline void
- swap(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>&& __x,
- unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
- { __x.swap(__y); }
-
- template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
- inline void
- swap(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
- unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>&& __y)
- { __x.swap(__y); }
-
- template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
- inline void
- swap(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>&& __x,
- unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y)
- { __x.swap(__y); }
-
- template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc>
- inline void
- swap(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x,
- unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>&& __y)
- { __x.swap(__y); }
-#endif
-
_GLIBCXX_END_NAMESPACE_TR1
}
diff --git a/libstdc++-v3/include/tr1_impl/unordered_set b/libstdc++-v3/include/tr1_impl/unordered_set
index fc2ce2b1eb4..d52b1517d91 100644
--- a/libstdc++-v3/include/tr1_impl/unordered_set
+++ b/libstdc++-v3/include/tr1_impl/unordered_set
@@ -330,31 +330,5 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
{ __x.swap(__y); }
-#ifdef _GLIBCXX_INCLUDE_AS_CXX0X
- template<class _Value, class _Hash, class _Pred, class _Alloc>
- inline void
- swap(unordered_set<_Value, _Hash, _Pred, _Alloc>&& __x,
- unordered_set<_Value, _Hash, _Pred, _Alloc>& __y)
- { __x.swap(__y); }
-
- template<class _Value, class _Hash, class _Pred, class _Alloc>
- inline void
- swap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x,
- unordered_set<_Value, _Hash, _Pred, _Alloc>&& __y)
- { __x.swap(__y); }
-
- template<class _Value, class _Hash, class _Pred, class _Alloc>
- inline void
- swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>&& __x,
- unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y)
- { __x.swap(__y); }
-
- template<class _Value, class _Hash, class _Pred, class _Alloc>
- inline void
- swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x,
- unordered_multiset<_Value, _Hash, _Pred, _Alloc>&& __y)
- { __x.swap(__y); }
-#endif
-
_GLIBCXX_END_NAMESPACE_TR1
}
diff --git a/libstdc++-v3/libsupc++/Makefile.am b/libstdc++-v3/libsupc++/Makefile.am
index 5c86a1efd7e..b84b5e46728 100644
--- a/libstdc++-v3/libsupc++/Makefile.am
+++ b/libstdc++-v3/libsupc++/Makefile.am
@@ -33,7 +33,7 @@ noinst_LTLIBRARIES = libsupc++convenience.la
headers = \
exception new typeinfo cxxabi.h cxxabi-forced.h exception_defines.h \
- initializer_list exception_ptr.h
+ initializer_list exception_ptr.h nested_exception.h
if GLIBCXX_HOSTED
c_sources = \
diff --git a/libstdc++-v3/libsupc++/Makefile.in b/libstdc++-v3/libsupc++/Makefile.in
index 26fbd541f59..50ede6abf64 100644
--- a/libstdc++-v3/libsupc++/Makefile.in
+++ b/libstdc++-v3/libsupc++/Makefile.in
@@ -367,7 +367,7 @@ toolexeclib_LTLIBRARIES = libsupc++.la
noinst_LTLIBRARIES = libsupc++convenience.la
headers = \
exception new typeinfo cxxabi.h cxxabi-forced.h exception_defines.h \
- initializer_list exception_ptr.h
+ initializer_list exception_ptr.h nested_exception.h
@GLIBCXX_HOSTED_TRUE@c_sources = \
@GLIBCXX_HOSTED_TRUE@ cp-demangle.c
diff --git a/libstdc++-v3/libsupc++/eh_ptr.cc b/libstdc++-v3/libsupc++/eh_ptr.cc
index bbe5f8f13f9..8d5a1b9b295 100644
--- a/libstdc++-v3/libsupc++/eh_ptr.cc
+++ b/libstdc++-v3/libsupc++/eh_ptr.cc
@@ -26,6 +26,8 @@
#ifdef _GLIBCXX_ATOMIC_BUILTINS_4
+#define _GLIBCXX_EH_PTR_COMPAT
+
#include <exception>
#include <exception_ptr.h>
#include "unwind-cxx.h"
@@ -127,6 +129,7 @@ std::__exception_ptr::exception_ptr::swap(exception_ptr &other) throw()
}
+// Retained for compatibility with CXXABI_1.3.
bool
std::__exception_ptr::exception_ptr::operator!() const throw()
{
@@ -134,6 +137,7 @@ std::__exception_ptr::exception_ptr::operator!() const throw()
}
+// Retained for compatibility with CXXABI_1.3.
std::__exception_ptr::exception_ptr::operator __safe_bool() const throw()
{
return _M_exception_object ? &exception_ptr::_M_safe_bool_dummy : 0;
@@ -235,4 +239,6 @@ std::rethrow_exception(std::exception_ptr ep)
std::terminate ();
}
+#undef _GLIBCXX_EH_PTR_COMPAT
+
#endif
diff --git a/libstdc++-v3/libsupc++/exception b/libstdc++-v3/libsupc++/exception
index c8b334fe945..be7dec69ab7 100644
--- a/libstdc++-v3/libsupc++/exception
+++ b/libstdc++-v3/libsupc++/exception
@@ -146,6 +146,7 @@ _GLIBCXX_END_NAMESPACE
#if (defined(__GXX_EXPERIMENTAL_CXX0X__) \
&& defined(_GLIBCXX_ATOMIC_BUILTINS_4))
#include <exception_ptr.h>
+#include <nested_exception.h>
#endif
#endif
diff --git a/libstdc++-v3/libsupc++/exception_ptr.h b/libstdc++-v3/libsupc++/exception_ptr.h
index 56997221f25..23477c9c3a6 100644
--- a/libstdc++-v3/libsupc++/exception_ptr.h
+++ b/libstdc++-v3/libsupc++/exception_ptr.h
@@ -77,10 +77,12 @@ namespace std
namespace __exception_ptr
{
bool
- operator==(const exception_ptr&, const exception_ptr&) throw() __attribute__ ((__pure__));
+ operator==(const exception_ptr&, const exception_ptr&)
+ throw() __attribute__ ((__pure__));
bool
- operator!=(const exception_ptr&, const exception_ptr&) throw() __attribute__ ((__pure__));
+ operator!=(const exception_ptr&, const exception_ptr&)
+ throw() __attribute__ ((__pure__));
class exception_ptr
{
@@ -121,7 +123,7 @@ namespace std
exception_ptr&
operator=(exception_ptr&& __o) throw()
{
- exception_ptr(__o).swap(*this);
+ exception_ptr(static_cast<exception_ptr&&>(__o)).swap(*this);
return *this;
}
#endif
@@ -131,21 +133,15 @@ namespace std
void
swap(exception_ptr&) throw();
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
- void
- swap(exception_ptr &&__o) throw()
- {
- void *__tmp = _M_exception_object;
- _M_exception_object = __o._M_exception_object;
- __o._M_exception_object = __tmp;
- }
-#endif
-
+#ifdef _GLIBCXX_EH_PTR_COMPAT
+ // Retained for compatibility with CXXABI_1.3.
bool operator!() const throw() __attribute__ ((__pure__));
operator __safe_bool() const throw();
+#endif
friend bool
- operator==(const exception_ptr&, const exception_ptr&) throw() __attribute__ ((__pure__));
+ operator==(const exception_ptr&, const exception_ptr&)
+ throw() __attribute__ ((__pure__));
const type_info*
__cxa_exception_type() const throw() __attribute__ ((__pure__));
diff --git a/libstdc++-v3/libsupc++/initializer_list b/libstdc++-v3/libsupc++/initializer_list
index 6b8a2021b64..20e29000d56 100644
--- a/libstdc++-v3/libsupc++/initializer_list
+++ b/libstdc++-v3/libsupc++/initializer_list
@@ -8,12 +8,12 @@
// 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.
@@ -27,8 +27,8 @@
* This is a Standard C++ Library header.
*/
-#ifndef __CXX_INITIALIZER_LIST
-#define __CXX_INITIALIZER_LIST
+#ifndef _INITIALIZER_LIST
+#define _INITIALIZER_LIST
#ifdef __GXX_EXPERIMENTAL_CXX0X__
@@ -42,31 +42,39 @@ namespace std
template<class _E>
class initializer_list
{
- const _E* __array;
- size_t __len;
+ public:
+ typedef _E value_type;
+ typedef const _E& reference;
+ typedef const _E& const_reference;
+ typedef size_t size_type;
+ typedef const _E* iterator;
+ typedef const _E* const_iterator;
+
+ private:
+ iterator _M_array;
+ size_type _M_len;
// The compiler can call a private constructor.
- initializer_list(const _E* __a, size_t __l)
- : __array(__a), __len(__l) { }
+ initializer_list(const_iterator __a, size_type __l)
+ : _M_array(__a), _M_len(__l) { }
public:
- initializer_list()
- : __array(NULL), __len(0) { }
+ initializer_list() : _M_array(NULL), _M_len(0) { }
// Number of elements.
- size_t size() const
- { return __len; }
+ size_type
+ size() const { return _M_len; }
// First element.
- const _E* begin() const
- { return __array; }
+ const_iterator
+ begin() const { return _M_array; }
// One past the last element.
- const _E* end() const
- { return begin() + size(); }
+ const_iterator
+ end() const { return begin() + size(); }
};
}
#pragma GCC visibility pop
#endif // C++0x
-#endif // __CXX_INITIALIZER_LIST
+#endif // _INITIALIZER_LIST
diff --git a/libstdc++-v3/libsupc++/nested_exception.h b/libstdc++-v3/libsupc++/nested_exception.h
new file mode 100644
index 00000000000..752c595b49b
--- /dev/null
+++ b/libstdc++-v3/libsupc++/nested_exception.h
@@ -0,0 +1,177 @@
+// Nested Exception support header (nested_exception class) for -*- C++ -*-
+
+// Copyright (C) 2009 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file nested_exception.h
+ * This is an internal header file, included by other headers and the
+ * implementation. You should not attempt to use it directly.
+ */
+
+#ifndef _GLIBCXX_NESTED_EXCEPTION_H
+#define _GLIBCXX_NESTED_EXCEPTION_H 1
+
+#pragma GCC visibility push(default)
+
+#ifndef __GXX_EXPERIMENTAL_CXX0X__
+# include <c++0x_warning.h>
+#else
+
+#include <bits/c++config.h>
+
+#if !defined(_GLIBCXX_ATOMIC_BUILTINS_4)
+# error This platform does not support exception propagation.
+#endif
+
+extern "C++" {
+
+namespace std
+{
+ /**
+ * @addtogroup exceptions
+ * @{
+ */
+
+ /// nested_exception
+ class nested_exception
+ {
+ public:
+ nested_exception() throw() : _M_ptr(current_exception()) { }
+
+ nested_exception(const nested_exception&) throw() = default;
+
+ nested_exception& operator=(const nested_exception&) throw() = default;
+
+ virtual ~nested_exception() = default;
+
+ void
+ rethrow_nested() const __attribute__ ((__noreturn__))
+ { rethrow_exception(_M_ptr); }
+
+ exception_ptr
+ nested_ptr() const
+ { return _M_ptr; }
+
+ private:
+ exception_ptr _M_ptr;
+ };
+
+ template<typename _Except>
+ struct _Nested_exception : public _Except, public nested_exception
+ {
+ explicit
+ _Nested_exception(_Except&& __ex)
+ : _Except(static_cast<_Except&&>(__ex))
+ { }
+ };
+
+ template<typename _Ex>
+ struct __get_nested_helper
+ {
+ static const nested_exception*
+ _S_get(const _Ex& __ex)
+ {
+ return dynamic_cast<const nested_exception*>(&__ex);
+ }
+ };
+
+ template<typename _Ex>
+ struct __get_nested_helper<_Ex*>
+ {
+ static const nested_exception*
+ _S_get(const _Ex* __ex)
+ {
+ return dynamic_cast<const nested_exception*>(__ex);
+ }
+ };
+
+ template<typename _Ex>
+ inline const nested_exception*
+ __get_nested_exception(const _Ex& __ex)
+ {
+ return __get_nested_helper<_Ex>::_S_get(__ex);
+ }
+
+ template<typename _Ex>
+ void
+ __throw_with_nested(_Ex&&, const nested_exception* = 0)
+ __attribute__ ((__noreturn__));
+
+ template<typename _Ex>
+ void
+ __throw_with_nested(_Ex&&, ...) __attribute__ ((__noreturn__));
+
+ // This function should never be called, but is needed to avoid a warning
+ // about ambiguous base classes when instantiating throw_with_nested<_Ex>()
+ // with a type that has an accessible nested_exception base.
+ template<typename _Ex>
+ inline void
+ __throw_with_nested(_Ex&& __ex, const nested_exception* = 0)
+ {
+ throw __ex;
+ }
+
+ template<typename _Ex>
+ inline void
+ __throw_with_nested(_Ex&& __ex, ...)
+ {
+ throw _Nested_exception<_Ex>(static_cast<_Ex&&>(__ex));
+ }
+
+ template<typename _Ex>
+ void
+ throw_with_nested(_Ex __ex) __attribute__ ((__noreturn__));
+
+ template<typename _Ex>
+ inline void
+ throw_with_nested(_Ex __ex)
+ {
+ if (__get_nested_exception(__ex))
+ throw __ex;
+ __throw_with_nested(static_cast<_Ex&&>(__ex), &__ex);
+ }
+
+ template<typename _Ex>
+ inline void
+ rethrow_if_nested(const _Ex& __ex)
+ {
+ if (const nested_exception* __nested = __get_nested_exception(__ex))
+ __nested->rethrow_nested();
+ }
+
+ // see n2619
+ inline void
+ rethrow_if_nested(const nested_exception& __ex)
+ {
+ __ex.rethrow_nested();
+ }
+
+ // @} group exceptions
+} // namespace std
+
+} // extern "C++"
+
+#endif // __GXX_EXPERIMENTAL_CXX0X__
+
+#pragma GCC visibility pop
+
+#endif // _GLIBCXX_NESTED_EXCEPTION_H
diff --git a/libstdc++-v3/python/Makefile.am b/libstdc++-v3/python/Makefile.am
new file mode 100644
index 00000000000..50cc6d94541
--- /dev/null
+++ b/libstdc++-v3/python/Makefile.am
@@ -0,0 +1,60 @@
+## Makefile for the python subdirectory of the GNU C++ Standard library.
+##
+## Copyright (C) 2009 Free Software Foundation, Inc.
+##
+## This file is part of the libstdc++ version 3 distribution.
+## Process this file with automake to produce Makefile.in.
+
+## 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 2, 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 COPYING. If not, write to the Free
+## Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+## USA.
+
+include $(top_srcdir)/fragment.am
+
+## Where to install the module code.
+pythondir = $(datadir)/gcc-$(gcc_version)/python
+
+all-local: gdb.py
+
+nobase_python_DATA = \
+ libstdcxx/v6/printers.py \
+ libstdcxx/v6/__init__.py \
+ libstdcxx/__init__.py
+
+gdb.py: hook.in Makefile
+ sed -e 's,@pythondir@,$(pythondir),' \
+ -e 's,@toolexeclibdir@,$(toolexeclibdir),' < $(srcdir)/hook.in > $@
+
+install-data-local: gdb.py
+ @$(mkdir_p) $(DESTDIR)$(toolexeclibdir)
+## We want to install gdb.py as SOMETHING-gdb.py. SOMETHING is the
+## full name of the final library. We want to ignore symlinks, the
+## .la file, and any previous -gdb.py file. This is inherently
+## fragile, but there does not seem to be a better option, because
+## libtool hides the real names from us.
+ @here=`pwd`; cd $(toolexeclibdir); \
+ for file in libstdc++*; do \
+ case $$file in \
+ *-gdb.py) ;; \
+ *.la) ;; \
+ *) if test -h $$file; then \
+ continue; \
+ fi; \
+ libname=$$file;; \
+ esac; \
+ done; \
+ cd $$here; \
+ echo " $(INSTALL_DATA) gdb.py $(DESTDIR)$(toolexeclibdir)/$$libname-gdb.py"; \
+ $(INSTALL_DATA) gdb.py $(DESTDIR)$(toolexeclibdir)/$$libname-gdb.py
diff --git a/libstdc++-v3/python/Makefile.in b/libstdc++-v3/python/Makefile.in
new file mode 100644
index 00000000000..88cc7ea34c3
--- /dev/null
+++ b/libstdc++-v3/python/Makefile.in
@@ -0,0 +1,516 @@
+# Makefile.in generated by automake 1.9.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005 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.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+ $(top_srcdir)/fragment.am
+subdir = python
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/../config/enable.m4 \
+ $(top_srcdir)/../config/futex.m4 \
+ $(top_srcdir)/../config/iconv.m4 \
+ $(top_srcdir)/../config/lead-dot.m4 \
+ $(top_srcdir)/../config/lib-ld.m4 \
+ $(top_srcdir)/../config/lib-link.m4 \
+ $(top_srcdir)/../config/lib-prefix.m4 \
+ $(top_srcdir)/../config/multi.m4 \
+ $(top_srcdir)/../config/no-executables.m4 \
+ $(top_srcdir)/../config/override.m4 \
+ $(top_srcdir)/../config/proginstall.m4 \
+ $(top_srcdir)/../config/stdint.m4 \
+ $(top_srcdir)/../config/unwind_ipinfo.m4 \
+ $(top_srcdir)/../libtool.m4 $(top_srcdir)/../ltoptions.m4 \
+ $(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \
+ $(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/crossconfig.m4 \
+ $(top_srcdir)/linkage.m4 $(top_srcdir)/acinclude.m4 \
+ $(top_srcdir)/../config/tls.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+depcomp =
+am__depfiles_maybe =
+SOURCES =
+DIST_SOURCES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(pythondir)"
+nobase_pythonDATA_INSTALL = $(install_sh_DATA)
+DATA = $(nobase_python_DATA)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ABI_TWEAKS_SRCDIR = @ABI_TWEAKS_SRCDIR@
+ACLOCAL = @ACLOCAL@
+ALLOCATOR_H = @ALLOCATOR_H@
+ALLOCATOR_NAME = @ALLOCATOR_NAME@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+ATOMICITY_SRCDIR = @ATOMICITY_SRCDIR@
+ATOMIC_FLAGS = @ATOMIC_FLAGS@
+ATOMIC_WORD_SRCDIR = @ATOMIC_WORD_SRCDIR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BASIC_FILE_CC = @BASIC_FILE_CC@
+BASIC_FILE_H = @BASIC_FILE_H@
+CC = @CC@
+CCODECVT_CC = @CCODECVT_CC@
+CCOLLATE_CC = @CCOLLATE_CC@
+CCTYPE_CC = @CCTYPE_CC@
+CFLAGS = @CFLAGS@
+CLOCALE_CC = @CLOCALE_CC@
+CLOCALE_H = @CLOCALE_H@
+CLOCALE_INTERNAL_H = @CLOCALE_INTERNAL_H@
+CMESSAGES_CC = @CMESSAGES_CC@
+CMESSAGES_H = @CMESSAGES_H@
+CMONEY_CC = @CMONEY_CC@
+CNUMERIC_CC = @CNUMERIC_CC@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CPU_DEFINES_SRCDIR = @CPU_DEFINES_SRCDIR@
+CSTDIO_H = @CSTDIO_H@
+CTIME_CC = @CTIME_CC@
+CTIME_H = @CTIME_H@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+C_INCLUDE_DIR = @C_INCLUDE_DIR@
+DEBUG_FLAGS = @DEBUG_FLAGS@
+DEFS = @DEFS@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+ENABLE_PARALLEL_FALSE = @ENABLE_PARALLEL_FALSE@
+ENABLE_PARALLEL_TRUE = @ENABLE_PARALLEL_TRUE@
+ENABLE_SYMVERS_DARWIN_FALSE = @ENABLE_SYMVERS_DARWIN_FALSE@
+ENABLE_SYMVERS_DARWIN_TRUE = @ENABLE_SYMVERS_DARWIN_TRUE@
+ENABLE_SYMVERS_FALSE = @ENABLE_SYMVERS_FALSE@
+ENABLE_SYMVERS_GNU_FALSE = @ENABLE_SYMVERS_GNU_FALSE@
+ENABLE_SYMVERS_GNU_NAMESPACE_FALSE = @ENABLE_SYMVERS_GNU_NAMESPACE_FALSE@
+ENABLE_SYMVERS_GNU_NAMESPACE_TRUE = @ENABLE_SYMVERS_GNU_NAMESPACE_TRUE@
+ENABLE_SYMVERS_GNU_TRUE = @ENABLE_SYMVERS_GNU_TRUE@
+ENABLE_SYMVERS_TRUE = @ENABLE_SYMVERS_TRUE@
+ENABLE_VISIBILITY_FALSE = @ENABLE_VISIBILITY_FALSE@
+ENABLE_VISIBILITY_TRUE = @ENABLE_VISIBILITY_TRUE@
+ERROR_CONSTANTS_SRCDIR = @ERROR_CONSTANTS_SRCDIR@
+EXEEXT = @EXEEXT@
+EXTRA_CXX_FLAGS = @EXTRA_CXX_FLAGS@
+FGREP = @FGREP@
+GLIBCXX_BUILD_DEBUG_FALSE = @GLIBCXX_BUILD_DEBUG_FALSE@
+GLIBCXX_BUILD_DEBUG_TRUE = @GLIBCXX_BUILD_DEBUG_TRUE@
+GLIBCXX_BUILD_PCH_FALSE = @GLIBCXX_BUILD_PCH_FALSE@
+GLIBCXX_BUILD_PCH_TRUE = @GLIBCXX_BUILD_PCH_TRUE@
+GLIBCXX_C_HEADERS_COMPATIBILITY_FALSE = @GLIBCXX_C_HEADERS_COMPATIBILITY_FALSE@
+GLIBCXX_C_HEADERS_COMPATIBILITY_TRUE = @GLIBCXX_C_HEADERS_COMPATIBILITY_TRUE@
+GLIBCXX_C_HEADERS_C_FALSE = @GLIBCXX_C_HEADERS_C_FALSE@
+GLIBCXX_C_HEADERS_C_GLOBAL_FALSE = @GLIBCXX_C_HEADERS_C_GLOBAL_FALSE@
+GLIBCXX_C_HEADERS_C_GLOBAL_TRUE = @GLIBCXX_C_HEADERS_C_GLOBAL_TRUE@
+GLIBCXX_C_HEADERS_C_STD_FALSE = @GLIBCXX_C_HEADERS_C_STD_FALSE@
+GLIBCXX_C_HEADERS_C_STD_TRUE = @GLIBCXX_C_HEADERS_C_STD_TRUE@
+GLIBCXX_C_HEADERS_C_TRUE = @GLIBCXX_C_HEADERS_C_TRUE@
+GLIBCXX_C_HEADERS_EXTRA_FALSE = @GLIBCXX_C_HEADERS_EXTRA_FALSE@
+GLIBCXX_C_HEADERS_EXTRA_TRUE = @GLIBCXX_C_HEADERS_EXTRA_TRUE@
+GLIBCXX_HOSTED_FALSE = @GLIBCXX_HOSTED_FALSE@
+GLIBCXX_HOSTED_TRUE = @GLIBCXX_HOSTED_TRUE@
+GLIBCXX_INCLUDES = @GLIBCXX_INCLUDES@
+GLIBCXX_LDBL_COMPAT_FALSE = @GLIBCXX_LDBL_COMPAT_FALSE@
+GLIBCXX_LDBL_COMPAT_TRUE = @GLIBCXX_LDBL_COMPAT_TRUE@
+GLIBCXX_LIBS = @GLIBCXX_LIBS@
+GREP = @GREP@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBICONV = @LIBICONV@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBSUPCXX_PICFLAGS = @LIBSUPCXX_PICFLAGS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
+MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
+MAKEINFO = @MAKEINFO@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OPTIMIZE_CXXFLAGS = @OPTIMIZE_CXXFLAGS@
+OPT_LDFLAGS = @OPT_LDFLAGS@
+OS_INC_SRCDIR = @OS_INC_SRCDIR@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SECTION_FLAGS = @SECTION_FLAGS@
+SECTION_LDFLAGS = @SECTION_LDFLAGS@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SYMVER_FILE = @SYMVER_FILE@
+TOPLEVEL_INCLUDES = @TOPLEVEL_INCLUDES@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WARN_FLAGS = @WARN_FLAGS@
+WERROR = @WERROR@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_AS = @ac_ct_AS@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DSYMUTIL = @ac_ct_DSYMUTIL@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+ac_ct_LIPO = @ac_ct_LIPO@
+ac_ct_NMEDIT = @ac_ct_NMEDIT@
+ac_ct_OBJDUMP = @ac_ct_OBJDUMP@
+ac_ct_OTOOL = @ac_ct_OTOOL@
+ac_ct_OTOOL64 = @ac_ct_OTOOL64@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__leading_dot = @am__leading_dot@
+am__tar = @am__tar@
+am__untar = @am__untar@
+baseline_dir = @baseline_dir@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+check_msgfmt = @check_msgfmt@
+datadir = @datadir@
+enable_shared = @enable_shared@
+enable_static = @enable_static@
+exec_prefix = @exec_prefix@
+glibcxx_MOFILES = @glibcxx_MOFILES@
+glibcxx_PCHFLAGS = @glibcxx_PCHFLAGS@
+glibcxx_POFILES = @glibcxx_POFILES@
+glibcxx_builddir = @glibcxx_builddir@
+glibcxx_localedir = @glibcxx_localedir@
+glibcxx_prefixdir = @glibcxx_prefixdir@
+glibcxx_srcdir = @glibcxx_srcdir@
+glibcxx_thread_h = @glibcxx_thread_h@
+glibcxx_toolexecdir = @glibcxx_toolexecdir@
+glibcxx_toolexeclibdir = @glibcxx_toolexeclibdir@
+gxx_include_dir = @gxx_include_dir@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libtool_VERSION = @libtool_VERSION@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+multi_basedir = @multi_basedir@
+oldincludedir = @oldincludedir@
+port_specific_symbol_files = @port_specific_symbol_files@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+toplevel_srcdir = @toplevel_srcdir@
+
+# May be used by various substitution variables.
+gcc_version := $(shell cat $(top_srcdir)/../gcc/BASE-VER)
+MAINT_CHARSET = latin1
+mkinstalldirs = $(SHELL) $(toplevel_srcdir)/mkinstalldirs
+PWD_COMMAND = $${PWDCMD-pwd}
+STAMP = echo timestamp >
+toolexecdir = $(glibcxx_toolexecdir)
+toolexeclibdir = $(glibcxx_toolexeclibdir)
+
+# These bits are all figured out from configure. Look in acinclude.m4
+# or configure.ac to see how they are set. See GLIBCXX_EXPORT_FLAGS.
+CONFIG_CXXFLAGS = \
+ $(SECTION_FLAGS) $(EXTRA_CXX_FLAGS)
+
+WARN_CXXFLAGS = \
+ $(WARN_FLAGS) $(WERROR) -fdiagnostics-show-location=once
+
+
+# -I/-D flags to pass when compiling.
+AM_CPPFLAGS = $(GLIBCXX_INCLUDES)
+pythondir = $(datadir)/gcc-$(gcc_version)/python
+nobase_python_DATA = \
+ libstdcxx/v6/printers.py \
+ libstdcxx/v6/__init__.py \
+ libstdcxx/__init__.py
+
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/fragment.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign --ignore-deps python/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --foreign --ignore-deps python/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+ -rm -f libtool
+uninstall-info-am:
+install-nobase_pythonDATA: $(nobase_python_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(pythondir)" || $(mkdir_p) "$(DESTDIR)$(pythondir)"
+ @$(am__vpath_adj_setup) \
+ list='$(nobase_python_DATA)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ $(am__vpath_adj) \
+ echo " $(nobase_pythonDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(pythondir)/$$f'"; \
+ $(nobase_pythonDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(pythondir)/$$f"; \
+ done
+
+uninstall-nobase_pythonDATA:
+ @$(NORMAL_UNINSTALL)
+ @$(am__vpath_adj_setup) \
+ list='$(nobase_python_DATA)'; for p in $$list; do \
+ $(am__vpath_adj) \
+ echo " rm -f '$(DESTDIR)$(pythondir)/$$f'"; \
+ rm -f "$(DESTDIR)$(pythondir)/$$f"; \
+ done
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+distdir: $(DISTFILES)
+ $(mkdir_p) $(distdir)/..
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+ list='$(DISTFILES)'; for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+ esac; \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ dir="/$$dir"; \
+ $(mkdir_p) "$(distdir)$$dir"; \
+ else \
+ dir=''; \
+ fi; \
+ if test -d $$d/$$file; then \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(DATA) all-local
+installdirs:
+ for dir in "$(DESTDIR)$(pythondir)"; do \
+ test -z "$$dir" || $(mkdir_p) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-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
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-libtool
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-data-local install-nobase_pythonDATA
+
+install-exec-am:
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-info-am uninstall-nobase_pythonDATA
+
+.PHONY: all all-am all-local check check-am clean clean-generic \
+ clean-libtool distclean distclean-generic distclean-libtool \
+ distdir dvi dvi-am html html-am info info-am install \
+ install-am install-data install-data-am install-data-local \
+ install-exec install-exec-am install-info install-info-am \
+ install-man install-nobase_pythonDATA install-strip \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-generic \
+ mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am \
+ uninstall-info-am uninstall-nobase_pythonDATA
+
+
+all-local: gdb.py
+
+gdb.py: hook.in Makefile
+ sed -e 's,@pythondir@,$(pythondir),' \
+ -e 's,@toolexeclibdir@,$(toolexeclibdir),' < $(srcdir)/hook.in > $@
+
+install-data-local: gdb.py
+ @$(mkdir_p) $(DESTDIR)$(toolexeclibdir)
+ @here=`pwd`; cd $(toolexeclibdir); \
+ for file in libstdc++*; do \
+ case $$file in \
+ *-gdb.py) ;; \
+ *.la) ;; \
+ *) if test -h $$file; then \
+ continue; \
+ fi; \
+ libname=$$file;; \
+ esac; \
+ done; \
+ cd $$here; \
+ echo " $(INSTALL_DATA) gdb.py $(DESTDIR)$(toolexeclibdir)/$$libname-gdb.py"; \
+ $(INSTALL_DATA) gdb.py $(DESTDIR)$(toolexeclibdir)/$$libname-gdb.py
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/libstdc++-v3/python/hook.in b/libstdc++-v3/python/hook.in
new file mode 100644
index 00000000000..f7bf1afb44d
--- /dev/null
+++ b/libstdc++-v3/python/hook.in
@@ -0,0 +1,55 @@
+# -*- python -*-
+# Copyright (C) 2009 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import sys
+import gdb
+import os
+import os.path
+
+pythondir = '@pythondir@'
+libdir = '@toolexeclibdir@'
+
+# Update module path. We want to find the relative path from libdir
+# to pythondir, and then we want to apply that relative path to the
+# directory holding the objfile with which this file is associated.
+# This preserves relocatability of the gcc tree.
+
+# Do a simple normalization that removes duplicate separators.
+pythondir = os.path.join (*['/'] + pythondir.split (os.sep))
+libdir = os.path.join (*['/'] + libdir.split (os.sep))
+
+prefix = os.path.commonprefix ([libdir, pythondir])
+# In some bizarre configuration we might have found a match in the
+# middle of a directory name.
+if prefix[-1] != '/':
+ prefix = os.path.dirname (prefix)
+
+# Strip off the prefix.
+pythondir = pythondir[len (prefix):]
+libdir = libdir[len (prefix):]
+
+# Compute the ".."s needed to get from libdir to the prefix.
+dotdots = ('..' + os.sep) * len (libdir.split (os.sep))
+
+objfile = gdb.current_objfile ().filename
+dir = os.path.join (os.path.dirname (objfile), dotdots, pythondir)
+
+if not dir in sys.path:
+ sys.path.insert(0, dir)
+
+# Load the pretty-printers.
+from libstdcxx.v6.printers import register_libstdcxx_printers
+register_libstdcxx_printers (gdb.current_objfile ())
diff --git a/libstdc++-v3/python/libstdcxx/__init__.py b/libstdc++-v3/python/libstdcxx/__init__.py
new file mode 100644
index 00000000000..8b137891791
--- /dev/null
+++ b/libstdc++-v3/python/libstdcxx/__init__.py
@@ -0,0 +1 @@
+
diff --git a/libstdc++-v3/python/libstdcxx/v6/__init__.py b/libstdc++-v3/python/libstdcxx/v6/__init__.py
new file mode 100644
index 00000000000..8b137891791
--- /dev/null
+++ b/libstdc++-v3/python/libstdcxx/v6/__init__.py
@@ -0,0 +1 @@
+
diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py
new file mode 100644
index 00000000000..e2bb231e15a
--- /dev/null
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -0,0 +1,640 @@
+# Pretty-printers for libstc++.
+
+# Copyright (C) 2008, 2009 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import gdb
+import itertools
+import re
+
+class StdPointerPrinter:
+ "Print a smart pointer of some kind"
+
+ def __init__ (self, typename, val):
+ self.typename = typename
+ self.val = val
+
+ def to_string (self):
+ if self.val['_M_refcount']['_M_pi'] == 0:
+ return '%s (empty) %s' % (self.typename, self.val['_M_ptr'])
+ return '%s (count %d) %s' % (self.typename,
+ self.val['_M_refcount']['_M_pi']['_M_use_count'],
+ self.val['_M_ptr'])
+
+class UniquePointerPrinter:
+ "Print a unique_ptr"
+
+ def __init__ (self, val):
+ self.val = val
+
+ def to_string (self):
+ return self.val['_M_t']
+
+class StdListPrinter:
+ "Print a std::list"
+
+ class _iterator:
+ def __init__(self, nodetype, head):
+ self.nodetype = nodetype
+ self.base = head['_M_next']
+ self.head = head.address
+ self.count = 0
+
+ def __iter__(self):
+ return self
+
+ def next(self):
+ if self.base == self.head:
+ raise StopIteration
+ elt = self.base.cast(self.nodetype).dereference()
+ self.base = elt['_M_next']
+ count = self.count
+ self.count = self.count + 1
+ return ('[%d]' % count, elt['_M_data'])
+
+ def __init__(self, val):
+ self.val = val
+
+ def children(self):
+ itype = self.val.type.template_argument(0)
+ nodetype = gdb.lookup_type('std::_List_node<%s>' % itype).pointer()
+ return self._iterator(nodetype, self.val['_M_impl']['_M_node'])
+
+ def to_string(self):
+ if self.val['_M_impl']['_M_node'].address == self.val['_M_impl']['_M_node']['_M_next']:
+ return 'empty std::list'
+ return 'std::list'
+
+class StdListIteratorPrinter:
+ "Print std::list::iterator"
+
+ def __init__(self, val):
+ self.val = val
+
+ def to_string(self):
+ itype = self.val.type.template_argument(0)
+ nodetype = gdb.lookup_type('std::_List_node<%s>' % itype).pointer()
+ return self.val['_M_node'].cast(nodetype).dereference()['_M_data']
+
+class StdSlistPrinter:
+ "Print a __gnu_cxx::slist"
+
+ class _iterator:
+ def __init__(self, nodetype, head):
+ self.nodetype = nodetype
+ self.base = head['_M_head']['_M_next']
+ self.count = 0
+
+ def __iter__(self):
+ return self
+
+ def next(self):
+ if self.base == 0:
+ raise StopIteration
+ elt = self.base.cast(self.nodetype).dereference()
+ self.base = elt['_M_next']
+ count = self.count
+ self.count = self.count + 1
+ return ('[%d]' % count, elt['_M_data'])
+
+ def __init__(self, val):
+ self.val = val
+
+ def children(self):
+ itype = self.val.type.template_argument(0)
+ nodetype = gdb.lookup_type('__gnu_cxx::_Slist_node<%s>' % itype).pointer()
+ return self._iterator(nodetype, self.val)
+
+ def to_string(self):
+ if self.val['_M_head']['_M_next'] == 0:
+ return 'empty __gnu_cxx::slist'
+ return '__gnu_cxx::slist'
+
+class StdSlistIteratorPrinter:
+ "Print __gnu_cxx::slist::iterator"
+
+ def __init__(self, val):
+ self.val = val
+
+ def to_string(self):
+ itype = self.val.type.template_argument(0)
+ nodetype = gdb.lookup_type('__gnu_cxx::_Slist_node<%s>' % itype).pointer()
+ return self.val['_M_node'].cast(nodetype).dereference()['_M_data']
+
+class StdVectorPrinter:
+ "Print a std::vector"
+
+ class _iterator:
+ def __init__ (self, start, finish):
+ self.item = start
+ self.finish = finish
+ self.count = 0
+
+ def __iter__(self):
+ return self
+
+ def next(self):
+ if self.item == self.finish:
+ raise StopIteration
+ count = self.count
+ self.count = self.count + 1
+ elt = self.item.dereference()
+ self.item = self.item + 1
+ return ('[%d]' % count, elt)
+
+ def __init__(self, val):
+ self.val = val
+
+ def children(self):
+ return self._iterator(self.val['_M_impl']['_M_start'],
+ self.val['_M_impl']['_M_finish'])
+
+ def to_string(self):
+ start = self.val['_M_impl']['_M_start']
+ finish = self.val['_M_impl']['_M_finish']
+ end = self.val['_M_impl']['_M_end_of_storage']
+ return ('std::vector of length %d, capacity %d'
+ % (int (finish - start), int (end - start)))
+
+ def display_hint(self):
+ return 'array'
+
+class StdVectorIteratorPrinter:
+ "Print std::vector::iterator"
+
+ def __init__(self, val):
+ self.val = val
+
+ def to_string(self):
+ return self.val['_M_current'].dereference()
+
+class StdStackOrQueuePrinter:
+ "Print a std::stack or std::queue"
+
+ def __init__ (self, typename, val):
+ self.typename = typename
+ self.visualizer = gdb.default_visualizer(val['c'])
+
+ def children (self):
+ return self.visualizer.children()
+
+ def to_string (self):
+ return '%s wrapping: %s' % (self.typename,
+ self.visualizer.to_string())
+
+ def display_hint (self):
+ if hasattr (self.visualizer, 'display_hint'):
+ return self.visualizer.display_hint ()
+ return None
+
+class RbtreeIterator:
+ def __init__(self, rbtree):
+ self.size = rbtree['_M_t']['_M_impl']['_M_node_count']
+ self.node = rbtree['_M_t']['_M_impl']['_M_header']['_M_left']
+ self.count = 0
+
+ def __iter__(self):
+ return self
+
+ def __len__(self):
+ return int (self.size)
+
+ def next(self):
+ if self.count == self.size:
+ raise StopIteration
+ result = self.node
+ self.count = self.count + 1
+ if self.count < self.size:
+ # Compute the next node.
+ node = self.node
+ if node.dereference()['_M_right']:
+ node = node.dereference()['_M_right']
+ while node.dereference()['_M_left']:
+ node = node.dereference()['_M_left']
+ else:
+ parent = node.dereference()['_M_parent']
+ while node == parent.dereference()['_M_right']:
+ node = parent
+ parent = parent.dereference()['_M_parent']
+ if node.dereference()['_M_right'] != parent:
+ node = parent
+ self.node = node
+ return result
+
+# This is a pretty printer for std::_Rb_tree_iterator (which is
+# std::map::iterator), and has nothing to do with the RbtreeIterator
+# class above.
+class StdRbtreeIteratorPrinter:
+ "Print std::map::iterator"
+
+ def __init__ (self, val):
+ self.val = val
+
+ def to_string (self):
+ valuetype = self.val.type.template_argument(0)
+ nodetype = gdb.lookup_type('std::_Rb_tree_node < %s >' % valuetype)
+ nodetype = nodetype.pointer()
+ return self.val.cast(nodetype).dereference()['_M_value_field']
+
+
+class StdMapPrinter:
+ "Print a std::map or std::multimap"
+
+ # Turn an RbtreeIterator into a pretty-print iterator.
+ class _iter:
+ def __init__(self, rbiter, type):
+ self.rbiter = rbiter
+ self.count = 0
+ self.type = type
+
+ def __iter__(self):
+ return self
+
+ def next(self):
+ if self.count % 2 == 0:
+ n = self.rbiter.next()
+ n = n.cast(self.type).dereference()['_M_value_field']
+ self.pair = n
+ item = n['first']
+ else:
+ item = self.pair['second']
+ result = ('[%d]' % self.count, item)
+ self.count = self.count + 1
+ return result
+
+ def __init__ (self, typename, val):
+ self.typename = typename
+ self.val = val
+
+ def to_string (self):
+ return '%s with %d elements' % (self.typename,
+ len (RbtreeIterator (self.val)))
+
+ def children (self):
+ keytype = self.val.type.template_argument(0).const()
+ valuetype = self.val.type.template_argument(1)
+ nodetype = gdb.lookup_type('std::_Rb_tree_node< std::pair< %s, %s > >' % (keytype, valuetype))
+ nodetype = nodetype.pointer()
+ return self._iter (RbtreeIterator (self.val), nodetype)
+
+ def display_hint (self):
+ return 'map'
+
+class StdSetPrinter:
+ "Print a std::set or std::multiset"
+
+ # Turn an RbtreeIterator into a pretty-print iterator.
+ class _iter:
+ def __init__(self, rbiter, type):
+ self.rbiter = rbiter
+ self.count = 0
+ self.type = type
+
+ def __iter__(self):
+ return self
+
+ def next(self):
+ item = self.rbiter.next()
+ item = item.cast(self.type).dereference()['_M_value_field']
+ # FIXME: this is weird ... what to do?
+ # Maybe a 'set' display hint?
+ result = ('[%d]' % self.count, item)
+ self.count = self.count + 1
+ return result
+
+ def __init__ (self, typename, val):
+ self.typename = typename
+ self.val = val
+
+ def to_string (self):
+ return '%s with %d elements' % (self.typename,
+ len (RbtreeIterator (self.val)))
+
+ def children (self):
+ keytype = self.val.type.template_argument(0)
+ nodetype = gdb.lookup_type('std::_Rb_tree_node< %s >' % keytype).pointer()
+ return self._iter (RbtreeIterator (self.val), nodetype)
+
+class StdBitsetPrinter:
+ "Print a std::bitset"
+
+ def __init__(self, val):
+ self.val = val
+
+ def to_string (self):
+ # If template_argument handled values, we could print the
+ # size. Or we could use a regexp on the type.
+ return 'std::bitset'
+
+ def children (self):
+ words = self.val['_M_w']
+ wtype = words.type
+
+ # The _M_w member can be either an unsigned long, or an
+ # array. This depends on the template specialization used.
+ # If it is a single long, convert to a single element list.
+ if wtype.code == gdb.TYPE_CODE_ARRAY:
+ tsize = wtype.target ().sizeof
+ else:
+ words = [words]
+ tsize = wtype.sizeof
+
+ nwords = wtype.sizeof / tsize
+ result = []
+ byte = 0
+ while byte < nwords:
+ w = words[byte]
+ bit = 0
+ while w != 0:
+ if (w & 1) != 0:
+ # Another spot where we could use 'set'?
+ result.append(('[%d]' % (byte * tsize * 8 + bit), 1))
+ bit = bit + 1
+ w = w >> 1
+ byte = byte + 1
+ return result
+
+class StdDequePrinter:
+ "Print a std::deque"
+
+ class _iter:
+ def __init__(self, node, start, end, last, buffer_size):
+ self.node = node
+ self.p = start
+ self.end = end
+ self.last = last
+ self.buffer_size = buffer_size
+ self.count = 0
+
+ def __iter__(self):
+ return self
+
+ def next(self):
+ if self.p == self.last:
+ raise StopIteration
+
+ result = ('[%d]' % self.count, self.p.dereference())
+ self.count = self.count + 1
+
+ # Advance the 'cur' pointer.
+ self.p = self.p + 1
+ if self.p == self.end:
+ # If we got to the end of this bucket, move to the
+ # next bucket.
+ self.node = self.node + 1
+ self.p = self.node[0]
+ self.end = self.p + self.buffer_size
+
+ return result
+
+ def __init__(self, val):
+ self.val = val
+ self.elttype = val.type.template_argument(0)
+ size = self.elttype.sizeof
+ if size < 512:
+ self.buffer_size = int (512 / size)
+ else:
+ self.buffer_size = 1
+
+ def to_string(self):
+ start = self.val['_M_impl']['_M_start']
+ end = self.val['_M_impl']['_M_finish']
+
+ delta_n = end['_M_node'] - start['_M_node'] - 1
+ delta_s = start['_M_last'] - start['_M_cur']
+ delta_e = end['_M_cur'] - end['_M_first']
+
+ size = self.buffer_size * delta_n + delta_s + delta_e
+
+ return 'std::deque with %d elements' % long (size)
+
+ def children(self):
+ start = self.val['_M_impl']['_M_start']
+ end = self.val['_M_impl']['_M_finish']
+ return self._iter(start['_M_node'], start['_M_cur'], start['_M_last'],
+ end['_M_cur'], self.buffer_size)
+
+ def display_hint (self):
+ return 'array'
+
+class StdDequeIteratorPrinter:
+ "Print std::deque::iterator"
+
+ def __init__(self, val):
+ self.val = val
+
+ def to_string(self):
+ return self.val['_M_cur'].dereference()
+
+class StdStringPrinter:
+ "Print a std::basic_string of some kind"
+
+ def __init__(self, encoding, val):
+ self.encoding = encoding
+ self.val = val
+
+ def to_string(self):
+ # Look up the target encoding as late as possible.
+ encoding = self.encoding
+ if encoding == 0:
+ encoding = gdb.parameter('target-charset')
+ elif encoding == 1:
+ encoding = gdb.parameter('target-wide-charset')
+ return self.val['_M_dataplus']['_M_p'].string(encoding)
+
+ def display_hint (self):
+ return 'string'
+
+class Tr1HashtableIterator:
+ def __init__ (self, hash):
+ self.count = 0
+ self.n_buckets = hash['_M_element_count']
+ if self.n_buckets == 0:
+ self.node = False
+ else:
+ self.bucket = hash['_M_buckets']
+ self.node = self.bucket[0]
+ self.update ()
+
+ def __iter__ (self):
+ return self
+
+ def update (self):
+ # If we advanced off the end of the chain, move to the next
+ # bucket.
+ while self.node == 0:
+ self.bucket = self.bucket + 1
+ self.node = self.bucket[0]
+
+ # If we advanced off the end of the bucket array, then
+ # we're done.
+ if self.count == self.n_buckets:
+ self.node = False
+ else:
+ self.count = self.count + 1
+
+ def next (self):
+ if not self.node:
+ raise StopIteration
+ result = self.node.dereference()['_M_v']
+ self.node = self.node.dereference()['_M_next']
+ self.update ()
+ return result
+
+class Tr1UnorderedSetPrinter:
+ "Print a tr1::unordered_set"
+
+ def __init__ (self, typename, val):
+ self.typename = typename
+ self.val = val
+
+ def to_string (self):
+ return '%s with %d elements' % (self.typename, self.val['_M_element_count'])
+
+ @staticmethod
+ def format_count (i):
+ return '[%d]' % i
+
+ def children (self):
+ counter = itertools.imap (self.format_count, itertools.count())
+ return itertools.izip (counter, Tr1HashtableIterator (self.val))
+
+class Tr1UnorderedMapPrinter:
+ "Print a tr1::unordered_map"
+
+ def __init__ (self, typename, val):
+ self.typename = typename
+ self.val = val
+
+ def to_string (self):
+ return '%s with %d elements' % (self.typename, self.val['_M_element_count'])
+
+ @staticmethod
+ def flatten (list):
+ for elt in list:
+ for i in elt:
+ yield i
+
+ @staticmethod
+ def format_one (elt):
+ return (elt['first'], elt['second'])
+
+ @staticmethod
+ def format_count (i):
+ return '[%d]' % i
+
+ def children (self):
+ counter = itertools.imap (self.format_count, itertools.count())
+ # Map over the hash table and flatten the result.
+ data = self.flatten (itertools.imap (self.format_one, Tr1HashtableIterator (self.val)))
+ # Zip the two iterators together.
+ return itertools.izip (counter, data)
+
+ def display_hint (self):
+ return 'map'
+
+def register_libstdcxx_printers (obj):
+ "Register libstdc++ pretty-printers with objfile Obj."
+
+ if obj == None:
+ obj = gdb
+
+ obj.pretty_printers.append (lookup_function)
+
+def lookup_function (val):
+ "Look-up and return a pretty-printer that can print val."
+
+ # Get the type.
+ type = val.type
+
+ # If it points to a reference, get the reference.
+ if type.code == gdb.TYPE_CODE_REF:
+ type = type.target ()
+
+ # Get the unqualified type, stripped of typedefs.
+ type = type.unqualified ().strip_typedefs ()
+
+ # Get the type name.
+ typename = type.tag
+ if typename == None:
+ return None
+
+ # Iterate over local dictionary of types to determine
+ # if a printer is registered for that type. Return an
+ # instantiation of the printer if found.
+ for function in pretty_printers_dict:
+ if function.search (typename):
+ return pretty_printers_dict[function] (val)
+
+ # Cannot find a pretty printer. Return None.
+ return None
+
+def build_libstdcxx_dictionary ():
+ # libstdc++ objects requiring pretty-printing.
+ # In order from:
+ # http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/a01847.html
+ pretty_printers_dict[re.compile('^std::basic_string<char(,.*)?>$')] = lambda val: StdStringPrinter(0, val)
+ pretty_printers_dict[re.compile('^std::basic_string<wchar_t(,.*)?>$')] = lambda val: StdStringPrinter(1, val)
+ pretty_printers_dict[re.compile('^std::basic_string<char16_t(,.*)?>$')] = lambda val: StdStringPrinter('UTF-16', val)
+ pretty_printers_dict[re.compile('^std::basic_string<char32_t(,.*)?>$')] = lambda val: StdStringPrinter('UTF-32', val)
+ pretty_printers_dict[re.compile('^std::bitset<.*>$')] = StdBitsetPrinter
+ pretty_printers_dict[re.compile('^std::deque<.*>$')] = StdDequePrinter
+ pretty_printers_dict[re.compile('^std::list<.*>$')] = StdListPrinter
+ pretty_printers_dict[re.compile('^std::map<.*>$')] = lambda val: StdMapPrinter("std::map", val)
+ pretty_printers_dict[re.compile('^std::multimap<.*>$')] = lambda val: StdMapPrinter("std::multimap", val)
+ pretty_printers_dict[re.compile('^std::multiset<.*>$')] = lambda val: StdSetPrinter("std::multiset", val)
+ pretty_printers_dict[re.compile('^std::priority_queue<.*>$')] = lambda val: StdStackOrQueuePrinter("std::priority_queue", val)
+ pretty_printers_dict[re.compile('^std::queue<.*>$')] = lambda val: StdStackOrQueuePrinter("std::queue", val)
+ pretty_printers_dict[re.compile('^std::set<.*>$')] = lambda val: StdSetPrinter("std::set", val)
+ pretty_printers_dict[re.compile('^std::stack<.*>$')] = lambda val: StdStackOrQueuePrinter("std::stack", val)
+ pretty_printers_dict[re.compile('^std::unique_ptr<.*>$')] = UniquePointerPrinter
+ pretty_printers_dict[re.compile('^std::vector<.*>$')] = StdVectorPrinter
+ # vector<bool>
+
+ # These are the TR1 and C++0x printers.
+ # For array - the default GDB pretty-printer seems reasonable.
+ pretty_printers_dict[re.compile('^std::shared_ptr<.*>$')] = lambda val: StdPointerPrinter ('std::shared_ptr', val)
+ pretty_printers_dict[re.compile('^std::weak_ptr<.*>$')] = lambda val: StdPointerPrinter ('std::weak_ptr', val)
+ pretty_printers_dict[re.compile('^std::unordered_map<.*>$')] = lambda val: Tr1UnorderedMapPrinter ('std::unordered_map', val)
+ pretty_printers_dict[re.compile('^std::unordered_set<.*>$')] = lambda val: Tr1UnorderedSetPrinter ('std::unordered_set', val)
+ pretty_printers_dict[re.compile('^std::unordered_multimap<.*>$')] = lambda val: Tr1UnorderedMapPrinter ('std::unordered_multimap', val)
+ pretty_printers_dict[re.compile('^std::unordered_multiset<.*>$')] = lambda val: Tr1UnorderedSetPrinter ('std::unordered_multiset', val)
+
+ pretty_printers_dict[re.compile('^std::tr1::shared_ptr<.*>$')] = lambda val: StdPointerPrinter ('std::tr1::shared_ptr', val)
+ pretty_printers_dict[re.compile('^std::tr1::weak_ptr<.*>$')] = lambda val: StdPointerPrinter ('std::tr1::weak_ptr', val)
+ pretty_printers_dict[re.compile('^std::tr1::unordered_map<.*>$')] = lambda val: Tr1UnorderedMapPrinter ('std::tr1::unordered_map', val)
+ pretty_printers_dict[re.compile('^std::tr1::unordered_set<.*>$')] = lambda val: Tr1UnorderedSetPrinter ('std::tr1::unordered_set', val)
+ pretty_printers_dict[re.compile('^std::tr1::unordered_multimap<.*>$')] = lambda val: Tr1UnorderedMapPrinter ('std::tr1::unordered_multimap', val)
+ pretty_printers_dict[re.compile('^std::tr1::unordered_multiset<.*>$')] = lambda val: Tr1UnorderedSetPrinter ('std::tr1::unordered_multiset', val)
+
+
+ # Extensions.
+ pretty_printers_dict[re.compile('^__gnu_cxx::slist<.*>$')] = StdSlistPrinter
+
+ if True:
+ # These shouldn't be necessary, if GDB "print *i" worked.
+ # But it often doesn't, so here they are.
+ pretty_printers_dict[re.compile('^std::_List_iterator<.*>$')] = lambda val: StdListIteratorPrinter(val)
+ pretty_printers_dict[re.compile('^std::_List_const_iterator<.*>$')] = lambda val: StdListIteratorPrinter(val)
+ pretty_printers_dict[re.compile('^std::_Rb_tree_iterator<.*>$')] = lambda val: StdRbtreeIteratorPrinter(val)
+ pretty_printers_dict[re.compile('^std::_Rb_tree_const_iterator<.*>$')] = lambda val: StdRbtreeIteratorPrinter(val)
+ pretty_printers_dict[re.compile('^std::_Deque_iterator<.*>$')] = lambda val: StdDequeIteratorPrinter(val)
+ pretty_printers_dict[re.compile('^std::_Deque_const_iterator<.*>$')] = lambda val: StdDequeIteratorPrinter(val)
+ pretty_printers_dict[re.compile('^__gnu_cxx::__normal_iterator<.*>$')] = lambda val: StdVectorIteratorPrinter(val)
+ pretty_printers_dict[re.compile('^__gnu_cxx::_Slist_iterator<.*>$')] = lambda val: StdSlistIteratorPrinter(val)
+
+pretty_printers_dict = {}
+
+build_libstdcxx_dictionary ()
diff --git a/libstdc++-v3/src/Makefile.am b/libstdc++-v3/src/Makefile.am
index 288243aab26..d218ceaa9ca 100644
--- a/libstdc++-v3/src/Makefile.am
+++ b/libstdc++-v3/src/Makefile.am
@@ -182,7 +182,6 @@ sources = \
streambuf-inst.cc \
streambuf.cc \
string-inst.cc \
- throw_allocator.cc \
valarray-inst.cc \
wlocale-inst.cc \
wstring-inst.cc \
diff --git a/libstdc++-v3/src/Makefile.in b/libstdc++-v3/src/Makefile.in
index 24187af1dae..9ee5275198b 100644
--- a/libstdc++-v3/src/Makefile.in
+++ b/libstdc++-v3/src/Makefile.in
@@ -85,13 +85,12 @@ am__libstdc___la_SOURCES_DIST = atomic.cc bitmap_allocator.cc \
fstream-inst.cc ext-inst.cc ios-inst.cc iostream-inst.cc \
istream-inst.cc istream.cc locale-inst.cc misc-inst.cc \
ostream-inst.cc sstream-inst.cc streambuf-inst.cc streambuf.cc \
- string-inst.cc throw_allocator.cc valarray-inst.cc \
- wlocale-inst.cc wstring-inst.cc mutex.cc condition_variable.cc \
- chrono.cc thread.cc atomicity.cc codecvt_members.cc \
- collate_members.cc ctype_members.cc messages_members.cc \
- monetary_members.cc numeric_members.cc time_members.cc \
- basic_file.cc c++locale.cc compatibility-ldbl.cc \
- parallel_list.cc parallel_settings.cc
+ string-inst.cc valarray-inst.cc wlocale-inst.cc \
+ wstring-inst.cc mutex.cc condition_variable.cc chrono.cc \
+ thread.cc atomicity.cc codecvt_members.cc collate_members.cc \
+ ctype_members.cc messages_members.cc monetary_members.cc \
+ numeric_members.cc time_members.cc basic_file.cc c++locale.cc \
+ compatibility-ldbl.cc parallel_list.cc parallel_settings.cc
am__objects_1 = atomicity.lo codecvt_members.lo collate_members.lo \
ctype_members.lo messages_members.lo monetary_members.lo \
numeric_members.lo time_members.lo
@@ -112,9 +111,9 @@ am__objects_5 = atomic.lo bitmap_allocator.lo pool_allocator.lo \
fstream-inst.lo ext-inst.lo ios-inst.lo iostream-inst.lo \
istream-inst.lo istream.lo locale-inst.lo misc-inst.lo \
ostream-inst.lo sstream-inst.lo streambuf-inst.lo streambuf.lo \
- string-inst.lo throw_allocator.lo valarray-inst.lo \
- wlocale-inst.lo wstring-inst.lo mutex.lo condition_variable.lo \
- chrono.lo thread.lo $(am__objects_1) $(am__objects_4)
+ string-inst.lo valarray-inst.lo wlocale-inst.lo \
+ wstring-inst.lo mutex.lo condition_variable.lo chrono.lo \
+ thread.lo $(am__objects_1) $(am__objects_4)
am_libstdc___la_OBJECTS = $(am__objects_5)
libstdc___la_OBJECTS = $(am_libstdc___la_OBJECTS)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
@@ -435,7 +434,6 @@ sources = \
streambuf-inst.cc \
streambuf.cc \
string-inst.cc \
- throw_allocator.cc \
valarray-inst.cc \
wlocale-inst.cc \
wstring-inst.cc \
diff --git a/libstdc++-v3/src/compatibility.cc b/libstdc++-v3/src/compatibility.cc
index 1e1897cd12f..6b3c19b31e4 100644
--- a/libstdc++-v3/src/compatibility.cc
+++ b/libstdc++-v3/src/compatibility.cc
@@ -502,17 +502,34 @@ extern void *_ZTVN10__cxxabiv119__pointer_type_infoE[];
extern __attribute__((used, weak)) const char _ZTSe[2] = "e";
extern __attribute__((used, weak)) const char _ZTSPe[3] = "Pe";
extern __attribute__((used, weak)) const char _ZTSPKe[4] = "PKe";
-extern __attribute__((used, weak)) const void *_ZTIe[2]
+extern __attribute__((used, weak)) const void * const _ZTIe[2]
= { (void *) &_ZTVN10__cxxabiv123__fundamental_type_infoE[2],
(void *) _ZTSe };
-extern __attribute__((used, weak)) const void *_ZTIPe[4]
+extern __attribute__((used, weak)) const void * const _ZTIPe[4]
= { (void *) &_ZTVN10__cxxabiv119__pointer_type_infoE[2],
(void *) _ZTSPe, (void *) 0L, (void *) _ZTIe };
-extern __attribute__((used, weak)) const void *_ZTIPKe[4]
+extern __attribute__((used, weak)) const void * const _ZTIPKe[4]
= { (void *) &_ZTVN10__cxxabiv119__pointer_type_infoE[2],
(void *) _ZTSPKe, (void *) 1L, (void *) _ZTIe };
#endif // _GLIBCXX_LONG_DOUBLE_COMPAT
+// gcc-4.4.0
+// <mutex> exported std::lock_error
+#if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1)
+namespace std
+{
+ class lock_error : public exception
+ {
+ public:
+ virtual const char*
+ _GLIBCXX_CONST what() const throw();
+ };
+
+ const char*
+ lock_error::what() const throw()
+ { return "std::lock_error"; }
+}
+#endif
#ifdef _GLIBCXX_SYMVER_DARWIN
diff --git a/libstdc++-v3/src/debug.cc b/libstdc++-v3/src/debug.cc
index 6ce2e101f25..bb0aebe433a 100644
--- a/libstdc++-v3/src/debug.cc
+++ b/libstdc++-v3/src/debug.cc
@@ -1,6 +1,6 @@
// Debugging mode support code -*- C++ -*-
-// Copyright (C) 2003, 2004, 2005, 2006, 2007, 2009
+// Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@@ -298,9 +298,12 @@ namespace __gnu_debug
}
else if (strcmp(__name, "type") == 0)
{
- assert(_M_variant._M_iterator._M_type);
- // TBD: demangle!
- __formatter->_M_print_word(_M_variant._M_iterator._M_type->name());
+ if (!_M_variant._M_iterator._M_type)
+ __formatter->_M_print_word("<unknown type>");
+ else
+ // TBD: demangle!
+ __formatter->_M_print_word(_M_variant._M_iterator.
+ _M_type->name());
}
else if (strcmp(__name, "constness") == 0)
{
@@ -310,7 +313,9 @@ namespace __gnu_debug
"constant",
"mutable"
};
- __formatter->_M_print_word(__constness_names[_M_variant._M_iterator._M_constness]);
+ __formatter->_M_print_word(__constness_names[_M_variant.
+ _M_iterator.
+ _M_constness]);
}
else if (strcmp(__name, "state") == 0)
{
@@ -322,7 +327,8 @@ namespace __gnu_debug
"dereferenceable",
"past-the-end"
};
- __formatter->_M_print_word(__state_names[_M_variant._M_iterator._M_state]);
+ __formatter->_M_print_word(__state_names[_M_variant.
+ _M_iterator._M_state]);
}
else if (strcmp(__name, "sequence") == 0)
{
@@ -333,9 +339,12 @@ namespace __gnu_debug
}
else if (strcmp(__name, "seq_type") == 0)
{
- // TBD: demangle!
- assert(_M_variant._M_iterator._M_seq_type);
- __formatter->_M_print_word(_M_variant._M_iterator._M_seq_type->name());
+ if (!_M_variant._M_iterator._M_seq_type)
+ __formatter->_M_print_word("<unknown seq_type>");
+ else
+ // TBD: demangle!
+ __formatter->_M_print_word(_M_variant._M_iterator.
+ _M_seq_type->name());
}
else
assert(false);
@@ -356,9 +365,12 @@ namespace __gnu_debug
}
else if (strcmp(__name, "type") == 0)
{
- // TBD: demangle!
- assert(_M_variant._M_sequence._M_type);
- __formatter->_M_print_word(_M_variant._M_sequence._M_type->name());
+ if (!_M_variant._M_sequence._M_type)
+ __formatter->_M_print_word("<unknown type>");
+ else
+ // TBD: demangle!
+ __formatter->_M_print_word(_M_variant._M_sequence.
+ _M_type->name());
}
else
assert(false);
diff --git a/libstdc++-v3/src/localename.cc b/libstdc++-v3/src/localename.cc
index ae932a3a7e0..98f6020533c 100644
--- a/libstdc++-v3/src/localename.cc
+++ b/libstdc++-v3/src/localename.cc
@@ -180,6 +180,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
// see if the given name is valid.
__c_locale __cloc;
locale::facet::_S_create_c_locale(__cloc, __s);
+ __c_locale __clocm = __cloc;
__try
{
@@ -194,15 +195,19 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
_M_names[__k] = 0;
// Name the categories.
+ const char* __smon = __s;
const size_t __len = std::strlen(__s);
if (!std::memchr(__s, ';', __len))
{
_M_names[0] = new char[__len + 1];
- std::memcpy(_M_names[0], __s, __len + 1);
+ std::memcpy(_M_names[0], __s, __len + 1);
}
else
{
const char* __end = __s;
+ bool __found_ctype = false;
+ bool __found_monetary = false;
+ size_t __ci = 0, __mi = 0;
for (size_t __i = 0; __i < _S_categories_size; ++__i)
{
const char* __beg = std::strchr(__end + 1, '=') + 1;
@@ -212,6 +217,24 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
_M_names[__i] = new char[__end - __beg + 1];
std::memcpy(_M_names[__i], __beg, __end - __beg);
_M_names[__i][__end - __beg] = '\0';
+ if (!__found_ctype
+ && *(__beg - 2) == 'E' && *(__beg - 3) == 'P')
+ {
+ __found_ctype = true;
+ __ci = __i;
+ }
+ else if (!__found_monetary && *(__beg - 2) == 'Y')
+ {
+ __found_monetary = true;
+ __mi = __i;
+ }
+ }
+
+ if (std::strcmp(_M_names[__ci], _M_names[__mi]))
+ {
+ __smon = _M_names[__mi];
+ __clocm = locale::facet::_S_lc_ctype_c_locale(__cloc,
+ __smon);
}
}
@@ -222,8 +245,8 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
_M_init_facet(new num_get<char>);
_M_init_facet(new num_put<char>);
_M_init_facet(new std::collate<char>(__cloc));
- _M_init_facet(new moneypunct<char, false>(__cloc, __s));
- _M_init_facet(new moneypunct<char, true>(__cloc, __s));
+ _M_init_facet(new moneypunct<char, false>(__cloc, 0));
+ _M_init_facet(new moneypunct<char, true>(__cloc, 0));
_M_init_facet(new money_get<char>);
_M_init_facet(new money_put<char>);
_M_init_facet(new __timepunct<char>(__cloc, __s));
@@ -238,8 +261,8 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
_M_init_facet(new num_get<wchar_t>);
_M_init_facet(new num_put<wchar_t>);
_M_init_facet(new std::collate<wchar_t>(__cloc));
- _M_init_facet(new moneypunct<wchar_t, false>(__cloc, __s));
- _M_init_facet(new moneypunct<wchar_t, true>(__cloc, __s));
+ _M_init_facet(new moneypunct<wchar_t, false>(__clocm, __smon));
+ _M_init_facet(new moneypunct<wchar_t, true>(__clocm, __smon));
_M_init_facet(new money_get<wchar_t>);
_M_init_facet(new money_put<wchar_t>);
_M_init_facet(new __timepunct<wchar_t>(__cloc, __s));
@@ -248,10 +271,14 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
_M_init_facet(new std::messages<wchar_t>(__cloc, __s));
#endif
locale::facet::_S_destroy_c_locale(__cloc);
+ if (__clocm != __cloc)
+ locale::facet::_S_destroy_c_locale(__clocm);
}
__catch(...)
{
locale::facet::_S_destroy_c_locale(__cloc);
+ if (__clocm != __cloc)
+ locale::facet::_S_destroy_c_locale(__clocm);
this->~_Impl();
__throw_exception_again;
}
diff --git a/libstdc++-v3/src/mutex.cc b/libstdc++-v3/src/mutex.cc
index fcc1eb97a89..74a82c8aa82 100644
--- a/libstdc++-v3/src/mutex.cc
+++ b/libstdc++-v3/src/mutex.cc
@@ -43,10 +43,6 @@ namespace std
const try_to_lock_t try_to_lock = try_to_lock_t();
const adopt_lock_t adopt_lock = adopt_lock_t();
- const char*
- lock_error::what() const throw()
- { return "std::lock_error"; }
-
#ifdef _GLIBCXX_HAVE_TLS
__thread void* __once_callable;
__thread void (*__once_call)();
diff --git a/libstdc++-v3/src/throw_allocator.cc b/libstdc++-v3/src/throw_allocator.cc
deleted file mode 100644
index a8247ad9782..00000000000
--- a/libstdc++-v3/src/throw_allocator.cc
+++ /dev/null
@@ -1,95 +0,0 @@
-// Throw Allocator. Out of line function definitions. -*- C++ -*-
-
-// Copyright (C) 2009 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library. This library is free
-// software; you can redistribute it and/or modify it under the
-// terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 3, or (at your option)
-// any later version.
-
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-
-// Under Section 7 of GPL version 3, you are granted additional
-// permissions described in the GCC Runtime Library Exception, version
-// 3.1, as published by the Free Software Foundation.
-
-// You should have received a copy of the GNU General Public License and
-// a copy of the GCC Runtime Library Exception along with this program;
-// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
-// <http://www.gnu.org/licenses/>.
-
-#include <ext/throw_allocator.h>
-
-_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
-
- void
- throw_allocator_base::do_check_allocated(const_iterator found,
- const_iterator end,
- void* p, size_t size)
- {
- if (found == end)
- {
- std::string error("throw_allocator_base::check_allocated by value "
- "null erase!\n");
- print_to_string(error, make_entry(p, size));
- std::__throw_logic_error(error.c_str());
- }
-
- if (found->second.second != size)
- {
- std::string error("throw_allocator_base::check_allocated by value "
- "wrong-size erase!\n");
- print_to_string(error, make_entry(p, size));
- print_to_string(error, *found);
- std::__throw_logic_error(error.c_str());
- }
- }
-
- void
- throw_allocator_base::do_check_allocated(const_iterator beg,
- const_iterator end,
- size_t label)
- {
- std::string found;
- while (beg != end)
- {
- if (beg->second.first == label)
- print_to_string(found, *beg);
- ++beg;
- }
-
- if (!found.empty())
- {
- std::string error("throw_allocator_base::check_allocated by label \n");
- error += found;
- std::__throw_logic_error(error.c_str());
- }
- }
-
- void
- throw_allocator_base::print_to_string(std::string& s,
- const_reference ref)
- {
- char buf[40];
- const char tab('\t');
- s += "address: ";
- __builtin_sprintf(buf, "%p", ref.first);
- s += buf;
- s += tab;
- s += "label: ";
- unsigned long l = static_cast<unsigned long>(ref.second.first);
- __builtin_sprintf(buf, "%lu", l);
- s += buf;
- s += tab;
- s += "size: ";
- l = static_cast<unsigned long>(ref.second.second);
- __builtin_sprintf(buf, "%lu", l);
- s += buf;
- s += '\n';
- }
-
-_GLIBCXX_END_NAMESPACE
diff --git a/libstdc++-v3/testsuite/18_support/exception_ptr/40296.cc b/libstdc++-v3/testsuite/18_support/exception_ptr/40296.cc
new file mode 100644
index 00000000000..933f4136956
--- /dev/null
+++ b/libstdc++-v3/testsuite/18_support/exception_ptr/40296.cc
@@ -0,0 +1,30 @@
+// { dg-do compile }
+// { dg-options "-std=gnu++0x" }
+// { dg-require-atomic-builtins "" }
+
+// Copyright (C) 2009 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <exception>
+
+// libstdc++/40296
+bool test01()
+{
+ std::exception_ptr p;
+
+ return (p == 0);
+}
diff --git a/libstdc++-v3/testsuite/18_support/exception_ptr/current_exception.cc b/libstdc++-v3/testsuite/18_support/exception_ptr/current_exception.cc
index ec06b336f1e..4029eaf69e3 100644
--- a/libstdc++-v3/testsuite/18_support/exception_ptr/current_exception.cc
+++ b/libstdc++-v3/testsuite/18_support/exception_ptr/current_exception.cc
@@ -31,7 +31,7 @@ void test01()
using namespace std;
exception_ptr ep = current_exception();
- VERIFY( !ep );
+ VERIFY( ep == 0 );
}
void test02()
@@ -43,7 +43,7 @@ void test02()
throw 0;
} catch(...) {
exception_ptr ep = current_exception();
- VERIFY( ep );
+ VERIFY( ep != 0 );
}
}
@@ -56,7 +56,7 @@ void test03()
throw exception();
} catch(std::exception&) {
exception_ptr ep = current_exception();
- VERIFY( ep );
+ VERIFY( ep != 0 );
}
}
diff --git a/libstdc++-v3/testsuite/18_support/exception_ptr/move.cc b/libstdc++-v3/testsuite/18_support/exception_ptr/move.cc
new file mode 100644
index 00000000000..ce97bc28c25
--- /dev/null
+++ b/libstdc++-v3/testsuite/18_support/exception_ptr/move.cc
@@ -0,0 +1,45 @@
+// { dg-options "-std=gnu++0x" }
+// { dg-require-atomic-builtins "" }
+
+// Copyright (C) 2009 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <exception>
+#include <utility>
+#include <testsuite_hooks.h>
+
+// Verify move construction and assignment are efficient and do not copy.
+// This behaviour is a GNU extension provided for efficiency.
+void test01()
+{
+ bool test = true;
+
+ std::exception_ptr p1 = std::copy_exception(test);
+ std::exception_ptr p2 = std::move(p1);
+ VERIFY( p1 == 0 );
+ VERIFY( !(p2 == 0) );
+
+ p1 = std::move(p2);
+ VERIFY( !(p1 == 0) );
+ VERIFY( p2 == 0 );
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/18_support/initializer_list/requirements/explicit_instantiation.cc b/libstdc++-v3/testsuite/18_support/initializer_list/requirements/explicit_instantiation.cc
new file mode 100644
index 00000000000..651ec0ef11b
--- /dev/null
+++ b/libstdc++-v3/testsuite/18_support/initializer_list/requirements/explicit_instantiation.cc
@@ -0,0 +1,24 @@
+// { dg-do compile }
+// { dg-options "-std=gnu++0x" }
+// 2009-05-27 Benjamin Kosnik <bkoz@redhat.com>
+
+// Copyright (C) 2009 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <initializer_list>
+
+template class std::initializer_list<int>;
diff --git a/libstdc++-v3/testsuite/18_support/initializer_list/requirements/typedefs.cc b/libstdc++-v3/testsuite/18_support/initializer_list/requirements/typedefs.cc
new file mode 100644
index 00000000000..1f9939260c5
--- /dev/null
+++ b/libstdc++-v3/testsuite/18_support/initializer_list/requirements/typedefs.cc
@@ -0,0 +1,34 @@
+// { dg-do compile }
+// { dg-options "-std=gnu++0x" }
+// 2009-05-27 Benjamin Kosnik <bkoz@redhat.com>
+
+// Copyright (C) 2009 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <initializer_list>
+
+void test01()
+{
+ // Check for required typedefs
+ typedef std::initializer_list<int> test_type;
+ typedef test_type::value_type type1;
+ typedef test_type::size_type type2;
+ typedef test_type::reference type3;
+ typedef test_type::const_reference type4;
+ typedef test_type::iterator type5;
+ typedef test_type::const_iterator type5;
+}
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/modifiers/swap_rvalue.cc b/libstdc++-v3/testsuite/18_support/nested_exception/cons.cc
index 0ace59b1cc7..3dc67fb98b1 100644
--- a/libstdc++-v3/testsuite/20_util/shared_ptr/modifiers/swap_rvalue.cc
+++ b/libstdc++-v3/testsuite/18_support/nested_exception/cons.cc
@@ -1,7 +1,7 @@
// { dg-options "-std=gnu++0x" }
-// { dg-do compile }
+// { dg-require-atomic-builtins "" }
-// Copyright (C) 2008, 2009 Free Software Foundation
+// Copyright (C) 2009 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -18,30 +18,36 @@
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-// 20.7.12.2 Template class shared_ptr [util.smartptr.shared]
-
-#include <memory>
+#include <exception>
#include <testsuite_hooks.h>
-struct A { };
+void test01()
+{
+ bool test __attribute__((unused)) = true;
-// 20.7.12.2.4 shared_ptr modifiers [util.smartptr.shared.mod]
+ std::nested_exception e;
-// swap
-int
-test01()
+ VERIFY( e.nested_ptr() == 0 );
+}
+
+void test02()
{
bool test __attribute__((unused)) = true;
- std::shared_ptr<A> p(new A);
- p.swap(std::shared_ptr<A>(new A));
-
- return 0;
+ try
+ {
+ throw 42;
+ }
+ catch (...)
+ {
+ std::nested_exception e;
+ VERIFY( e.nested_ptr() == std::current_exception() );
+ }
}
-int
-main()
+int main()
{
test01();
+ test02();
return 0;
}
diff --git a/libstdc++-v3/testsuite/18_support/nested_exception/nested_ptr.cc b/libstdc++-v3/testsuite/18_support/nested_exception/nested_ptr.cc
new file mode 100644
index 00000000000..d016436d017
--- /dev/null
+++ b/libstdc++-v3/testsuite/18_support/nested_exception/nested_ptr.cc
@@ -0,0 +1,71 @@
+// { dg-options "-std=gnu++0x" }
+// { dg-require-atomic-builtins "" }
+
+// Copyright (C) 2009 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <exception>
+#include <testsuite_hooks.h>
+
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ try
+ {
+ throw std::nested_exception();
+ }
+ catch (const std::nested_exception& e)
+ {
+ VERIFY( e.nested_ptr() == 0 );
+ }
+}
+
+void test02()
+{
+ bool test __attribute__((unused)) = true;
+
+ try
+ {
+ throw 42;
+ }
+ catch (...)
+ {
+ try
+ {
+ throw std::nested_exception();
+ }
+ catch (const std::nested_exception& e)
+ {
+ try
+ {
+ std::rethrow_exception( e.nested_ptr() );
+ }
+ catch(const int& i)
+ {
+ VERIFY( i == 42 );
+ }
+ }
+ }
+}
+
+int main()
+{
+ test01();
+ test02();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/18_support/nested_exception/rethrow_if_nested.cc b/libstdc++-v3/testsuite/18_support/nested_exception/rethrow_if_nested.cc
new file mode 100644
index 00000000000..37d1d80f8e8
--- /dev/null
+++ b/libstdc++-v3/testsuite/18_support/nested_exception/rethrow_if_nested.cc
@@ -0,0 +1,110 @@
+// { dg-options "-std=gnu++0x" }
+// { dg-require-atomic-builtins "" }
+
+// Copyright (C) 2009 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <exception>
+#include <testsuite_hooks.h>
+
+struct derived : std::nested_exception { };
+
+struct base { virtual ~base() = default; };
+
+struct derived2 : base, std::nested_exception { };
+
+void test01()
+{
+ bool test __attribute__((unused)) = false;
+
+ try
+ {
+ throw 42;
+ }
+ catch (...)
+ {
+ derived d;
+ try
+ {
+ std::rethrow_if_nested(d);
+ }
+ catch (const int& i)
+ {
+ test = true;
+ VERIFY( i == 42 );
+ }
+ }
+
+ VERIFY( test );
+}
+
+void test02()
+{
+ bool test __attribute__((unused)) = false;
+
+ try
+ {
+ throw base();
+ }
+ catch (const base& b)
+ {
+ std::rethrow_if_nested(b);
+ test = true;
+ }
+
+ VERIFY( test );
+}
+
+void test03()
+{
+ bool test __attribute__((unused)) = false;
+
+ try
+ {
+ throw 42;
+ }
+ catch (...)
+ {
+ try
+ {
+ throw derived2();
+ }
+ catch (const base& b)
+ {
+ try
+ {
+ std::rethrow_if_nested(b);
+ }
+ catch (const int& i)
+ {
+ VERIFY( i == 42 );
+ test = true;
+ }
+ }
+ }
+
+ VERIFY( test );
+}
+
+
+int main()
+{
+ test01();
+ test02();
+ test03();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/18_support/nested_exception/rethrow_nested.cc b/libstdc++-v3/testsuite/18_support/nested_exception/rethrow_nested.cc
new file mode 100644
index 00000000000..fca9c4c8038
--- /dev/null
+++ b/libstdc++-v3/testsuite/18_support/nested_exception/rethrow_nested.cc
@@ -0,0 +1,53 @@
+// { dg-options "-std=gnu++0x" }
+// { dg-require-atomic-builtins "" }
+
+// Copyright (C) 2009 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <exception>
+#include <testsuite_hooks.h>
+
+void test01()
+{
+ bool test __attribute__((unused)) = false;
+
+ try
+ {
+ try
+ {
+ throw 42;
+ }
+ catch (...)
+ {
+ std::nested_exception e;
+ e.rethrow_nested();
+ }
+ }
+ catch(const int& i)
+ {
+ test = true;
+ VERIFY( i == 42 );
+ }
+
+ VERIFY( test );
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/18_support/nested_exception/throw_with_nested.cc b/libstdc++-v3/testsuite/18_support/nested_exception/throw_with_nested.cc
new file mode 100644
index 00000000000..9ce31f06f03
--- /dev/null
+++ b/libstdc++-v3/testsuite/18_support/nested_exception/throw_with_nested.cc
@@ -0,0 +1,79 @@
+// { dg-options "-std=gnu++0x" }
+// { dg-require-atomic-builtins "" }
+
+// Copyright (C) 2009 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <exception>
+#include <testsuite_hooks.h>
+
+struct derived : std::nested_exception { };
+
+struct not_derived { virtual ~not_derived() = default; };
+
+void test01()
+{
+ bool test __attribute__((unused)) = false;
+
+ try
+ {
+ std::throw_with_nested(derived());
+ }
+ catch (const std::nested_exception& e)
+ {
+ VERIFY( e.nested_ptr() == 0 );
+ try
+ {
+ throw;
+ }
+ catch (const derived&)
+ {
+ test = true;
+ }
+ }
+ VERIFY( test );
+}
+
+void test02()
+{
+ bool test __attribute__((unused)) = false;
+
+ try
+ {
+ std::throw_with_nested(not_derived());
+ }
+ catch (const std::nested_exception& e)
+ {
+ VERIFY( e.nested_ptr() == 0 );
+ try
+ {
+ throw;
+ }
+ catch (const not_derived&)
+ {
+ test = true;
+ }
+ }
+ VERIFY( test );
+}
+
+int main()
+{
+ test01();
+ test02();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/19_diagnostics/error_code/operators/bool.cc b/libstdc++-v3/testsuite/19_diagnostics/error_code/operators/bool.cc
index 51536032728..2562b8dc582 100644
--- a/libstdc++-v3/testsuite/19_diagnostics/error_code/operators/bool.cc
+++ b/libstdc++-v3/testsuite/19_diagnostics/error_code/operators/bool.cc
@@ -28,14 +28,14 @@ int main()
// 1
std::error_code e1;
- if (e1)
+ if (static_cast<bool>(e1))
{
VERIFY( false );
}
// 2
std::error_code e2(std::make_error_code(std::errc::operation_not_supported));
- if (e2)
+ if (static_cast<bool>(e2))
{
VERIFY( true );
}
diff --git a/libstdc++-v3/testsuite/19_diagnostics/error_code/operators/bool_neg.cc b/libstdc++-v3/testsuite/19_diagnostics/error_code/operators/bool_neg.cc
index fed1cdcb1aa..539dd891cd5 100644
--- a/libstdc++-v3/testsuite/19_diagnostics/error_code/operators/bool_neg.cc
+++ b/libstdc++-v3/testsuite/19_diagnostics/error_code/operators/bool_neg.cc
@@ -30,4 +30,4 @@ int main()
return i;
}
-// { dg-error "invalid conversion" "" { target *-*-* } 28 }
+// { dg-error "cannot convert" "" { target *-*-* } 28 }
diff --git a/libstdc++-v3/testsuite/19_diagnostics/error_condition/operators/bool.cc b/libstdc++-v3/testsuite/19_diagnostics/error_condition/operators/bool.cc
index 17a9553d71b..62490fd2e30 100644
--- a/libstdc++-v3/testsuite/19_diagnostics/error_condition/operators/bool.cc
+++ b/libstdc++-v3/testsuite/19_diagnostics/error_condition/operators/bool.cc
@@ -27,14 +27,14 @@ void test01()
// 1
std::error_condition e1;
- if (e1)
+ if (static_cast<bool>(e1))
{
VERIFY( false );
}
// 2
std::error_condition e2(std::errc::operation_not_supported);
- if (e2)
+ if (static_cast<bool>(e2))
{
VERIFY( true );
}
diff --git a/libstdc++-v3/testsuite/19_diagnostics/error_condition/operators/bool_neg.cc b/libstdc++-v3/testsuite/19_diagnostics/error_condition/operators/bool_neg.cc
index 5e8ed96f1ae..6b8d129d2ff 100644
--- a/libstdc++-v3/testsuite/19_diagnostics/error_condition/operators/bool_neg.cc
+++ b/libstdc++-v3/testsuite/19_diagnostics/error_condition/operators/bool_neg.cc
@@ -29,4 +29,4 @@ int test01()
return i;
}
-// { dg-error "invalid conversion" "" { target *-*-* } 27 }
+// { dg-error "cannot convert" "" { target *-*-* } 27 }
diff --git a/libstdc++-v3/testsuite/20_util/function/null_pointer_comparisons.cc b/libstdc++-v3/testsuite/20_util/function/null_pointer_comparisons.cc
new file mode 100644
index 00000000000..7f446d7d60a
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/function/null_pointer_comparisons.cc
@@ -0,0 +1,44 @@
+// { dg-options "-std=gnu++0x" }
+// { dg-do compile }
+
+// Copyright (C) 2009 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <functional>
+
+// libstdc++/40273
+int main()
+{
+ std::function<void* ()> f = 0;
+ if (f != 0)
+ {
+ }
+
+ if (0 != f)
+ {
+ }
+
+ if (f == 0)
+ {
+ }
+
+ if (0 == f)
+ {
+ }
+ return 0;
+}
+
diff --git a/libstdc++-v3/testsuite/20_util/function/requirements/explicit_instantiation.cc b/libstdc++-v3/testsuite/20_util/function/requirements/explicit_instantiation.cc
new file mode 100644
index 00000000000..dbd8be6303a
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/function/requirements/explicit_instantiation.cc
@@ -0,0 +1,26 @@
+// { dg-options "-std=gnu++0x" }
+// { dg-do compile }
+
+// Copyright (C) 2009 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <functional>
+
+namespace std
+{
+ template class function<void* ()>;
+}
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/observers/bool_conv.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/observers/bool_conv.cc
index f57284fa275..dc2d53386cd 100644
--- a/libstdc++-v3/testsuite/20_util/shared_ptr/observers/bool_conv.cc
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/observers/bool_conv.cc
@@ -33,9 +33,9 @@ test01()
bool test __attribute__((unused)) = true;
const std::shared_ptr<A> p1;
- VERIFY( p1 == false );
+ VERIFY( static_cast<bool>(p1) == false );
const std::shared_ptr<A> p2(p1);
- VERIFY( p2 == false );
+ VERIFY( static_cast<bool>(p2) == false );
}
void
@@ -44,12 +44,12 @@ test02()
bool test __attribute__((unused)) = true;
std::shared_ptr<A> p1(new A);
- VERIFY( p1 );
+ VERIFY( static_cast<bool>(p1) );
std::shared_ptr<A> p2(p1);
- VERIFY( p2 );
+ VERIFY( static_cast<bool>(p2) );
p1.reset();
- VERIFY( !p1 );
- VERIFY( p2 );
+ VERIFY( !static_cast<bool>(p1) );
+ VERIFY( static_cast<bool>(p2) );
}
void
@@ -60,8 +60,8 @@ test03()
std::shared_ptr<A> p1(new A);
std::shared_ptr<A> p2(p1);
p2.reset(new A);
- VERIFY( p1 );
- VERIFY( p2 );
+ VERIFY( static_cast<bool>(p1) );
+ VERIFY( static_cast<bool>(p2) );
}
diff --git a/libstdc++-v3/testsuite/20_util/unique_ptr/assign/assign_neg.cc b/libstdc++-v3/testsuite/20_util/unique_ptr/assign/assign_neg.cc
index af4641b2c9a..f0236eb2637 100644
--- a/libstdc++-v3/testsuite/20_util/unique_ptr/assign/assign_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/unique_ptr/assign/assign_neg.cc
@@ -52,7 +52,7 @@ test03()
// { dg-error "used here" "" { target *-*-* } 42 }
// { dg-error "no matching" "" { target *-*-* } 48 }
// { dg-error "used here" "" { target *-*-* } 49 }
-// { dg-error "candidates are" "" { target *-*-* } 214 }
-// { dg-error "deleted function" "" { target *-*-* } 214 }
-// { dg-error "deleted function" "" { target *-*-* } 360 }
+// { dg-error "candidates are" "" { target *-*-* } 213 }
+// { dg-error "deleted function" "" { target *-*-* } 213 }
+// { dg-error "deleted function" "" { target *-*-* } 358 }
// { dg-excess-errors "note" }
diff --git a/libstdc++-v3/testsuite/20_util/unique_ptr/modifiers/reset_neg.cc b/libstdc++-v3/testsuite/20_util/unique_ptr/modifiers/reset_neg.cc
index fbf3e7712de..ae3d3946338 100644
--- a/libstdc++-v3/testsuite/20_util/unique_ptr/modifiers/reset_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/unique_ptr/modifiers/reset_neg.cc
@@ -36,4 +36,4 @@ void test01()
}
// { dg-error "used here" "" { target *-*-* } 35 }
-// { dg-error "deleted function" "" { target *-*-* } 350 }
+// { dg-error "deleted function" "" { target *-*-* } 348 }
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/40160.cc b/libstdc++-v3/testsuite/21_strings/basic_string/40160.cc
new file mode 100644
index 00000000000..5472a753e6b
--- /dev/null
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/40160.cc
@@ -0,0 +1,24 @@
+// -*- C++ -*-
+
+// Copyright (C) 2009 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 "-fno-rtti -D_GLIBCXX_DEBUG" }
+// { dg-do compile }
+
+// libstdc++/40160
+#include <string>
diff --git a/libstdc++-v3/testsuite/22_locale/locale/cons/40184.cc b/libstdc++-v3/testsuite/22_locale/locale/cons/40184.cc
new file mode 100644
index 00000000000..d7e30eba1c3
--- /dev/null
+++ b/libstdc++-v3/testsuite/22_locale/locale/cons/40184.cc
@@ -0,0 +1,60 @@
+// { dg-require-namedlocale "" }
+
+// Copyright (C) 2009 Free Software Foundation
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// 22.1.1.2 locale constructors and destructors [lib.locale.cons]
+
+#include <locale>
+#include <testsuite_hooks.h>
+
+// libstdc++/40184
+void test01()
+{
+#ifdef _GLIBCXX_USE_WCHAR_T
+ using namespace std;
+ bool test __attribute__((unused)) = true;
+
+ locale locf(locale("C"), "ja_JP.eucjp", locale::monetary);
+
+ const moneypunct<wchar_t, false>& mpf =
+ use_facet<moneypunct<wchar_t, false> >(locf);
+
+ locale locf_copy(locf.name().c_str());
+ const moneypunct<wchar_t, false>& mpf_copy =
+ use_facet<moneypunct<wchar_t, false> >(locf_copy);
+
+ VERIFY( mpf.curr_symbol() == mpf_copy.curr_symbol() );
+
+ locale loct(locale("C"), "ja_JP.eucjp", locale::monetary);
+
+ const moneypunct<wchar_t, true>& mpt =
+ use_facet<moneypunct<wchar_t, true> >(loct);
+
+ locale loct_copy(loct.name().c_str());
+ const moneypunct<wchar_t, true>& mpt_copy =
+ use_facet<moneypunct<wchar_t, true> >(loct_copy);
+
+ VERIFY( mpt.curr_symbol() == mpt_copy.curr_symbol() );
+#endif
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/deque/cons/1.cc b/libstdc++-v3/testsuite/23_containers/deque/cons/1.cc
index 3d86fd806d3..579521582c7 100644
--- a/libstdc++-v3/testsuite/23_containers/deque/cons/1.cc
+++ b/libstdc++-v3/testsuite/23_containers/deque/cons/1.cc
@@ -26,7 +26,7 @@
#include <testsuite_allocator.h>
#include <testsuite_hooks.h>
-typedef std::deque<__gnu_test::counter> gdeque;
+typedef std::deque<__gnu_test::object_counter> gdeque;
bool test __attribute__((unused)) = true;
diff --git a/libstdc++-v3/testsuite/23_containers/deque/cons/2.cc b/libstdc++-v3/testsuite/23_containers/deque/cons/2.cc
index 4d6e1308db8..23600284e72 100644
--- a/libstdc++-v3/testsuite/23_containers/deque/cons/2.cc
+++ b/libstdc++-v3/testsuite/23_containers/deque/cons/2.cc
@@ -31,10 +31,10 @@ using __gnu_test::tracker_allocator_counter;
using __gnu_test::tracker_allocator;
using __gnu_test::copy_constructor;
using __gnu_test::assignment_operator;
-using __gnu_test::counter;
+using __gnu_test::object_counter;
using __gnu_test::destructor;
-typedef std::deque<counter> gdeque;
+typedef std::deque<object_counter> gdeque;
bool test __attribute__((unused)) = true;
diff --git a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/assign_neg.cc b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/assign_neg.cc
index 9ec59fe693e..f7439944837 100644
--- a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/assign_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/assign_neg.cc
@@ -18,7 +18,7 @@
// <http://www.gnu.org/licenses/>.
// { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1498 }
+// { dg-error "no matching" "" { target *-*-* } 1494 }
// { dg-excess-errors "" }
#include <deque>
diff --git a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc
index 3bccae48034..b1136f59cf7 100644
--- a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc
@@ -18,7 +18,7 @@
// <http://www.gnu.org/licenses/>.
// { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1437 }
+// { dg-error "no matching" "" { target *-*-* } 1433 }
// { dg-excess-errors "" }
#include <deque>
diff --git a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc
index 3c401f1241e..8752a7e7b10 100644
--- a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc
@@ -18,7 +18,7 @@
// <http://www.gnu.org/licenses/>.
// { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1437 }
+// { dg-error "no matching" "" { target *-*-* } 1433 }
// { dg-excess-errors "" }
#include <deque>
diff --git a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/insert_neg.cc b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/insert_neg.cc
index 2e812d0a840..8cf322e8219 100644
--- a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/insert_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/insert_neg.cc
@@ -18,7 +18,7 @@
// <http://www.gnu.org/licenses/>.
// { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1582 }
+// { dg-error "no matching" "" { target *-*-* } 1578 }
// { dg-excess-errors "" }
#include <deque>
diff --git a/libstdc++-v3/testsuite/23_containers/headers/forward_list/synopsis.cc b/libstdc++-v3/testsuite/23_containers/headers/forward_list/synopsis.cc
index 759cea86fee..21d80cbb24b 100644
--- a/libstdc++-v3/testsuite/23_containers/headers/forward_list/synopsis.cc
+++ b/libstdc++-v3/testsuite/23_containers/headers/forward_list/synopsis.cc
@@ -43,10 +43,4 @@ namespace std {
template <class T, class Allocator>
void swap(forward_list<T,Allocator>& x, forward_list<T,Allocator>& y);
-
- template <class T, class Allocator>
- void swap(forward_list<T,Allocator>&& x, forward_list<T,Allocator>& y);
-
- template <class T, class Allocator>
- void swap(forward_list<T,Allocator>& x, forward_list<T,Allocator>&& y);
}
diff --git a/libstdc++-v3/testsuite/23_containers/list/14340.cc b/libstdc++-v3/testsuite/23_containers/list/14340.cc
index 2d2d683786c..26b5df6d059 100644
--- a/libstdc++-v3/testsuite/23_containers/list/14340.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/14340.cc
@@ -27,7 +27,7 @@
// libstdc++/14340
int main()
{
- typedef std::list<int> container;
- __gnu_test::conversion<container>::iterator_to_const_iterator();
+ typedef std::list<int> list_type;
+ __gnu_test::conversion<list_type>::iterator_to_const_iterator();
return 0;
}
diff --git a/libstdc++-v3/testsuite/23_containers/list/23781.cc b/libstdc++-v3/testsuite/23_containers/list/23781.cc
index 4dded91769c..ca275bda5ad 100644
--- a/libstdc++-v3/testsuite/23_containers/list/23781.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/23781.cc
@@ -23,5 +23,6 @@
// libstdc++/23781
#include <list>
-std::list<int>::iterator it = NULL; // { dg-error "conversion" }
-std::list<int>::const_iterator cit = NULL; // { dg-error "conversion" }
+typedef std::list<int> list_type;
+list_type::iterator it = NULL; // { dg-error "conversion" }
+list_type::const_iterator cit = NULL; // { dg-error "conversion" }
diff --git a/libstdc++-v3/testsuite/23_containers/list/capacity/1.cc b/libstdc++-v3/testsuite/23_containers/list/capacity/1.cc
index a8f4249769d..d820776e3a8 100644
--- a/libstdc++-v3/testsuite/23_containers/list/capacity/1.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/capacity/1.cc
@@ -20,8 +20,6 @@
#include <list>
#include <testsuite_hooks.h>
-bool test __attribute__((unused)) = true;
-
// This test verifies the following.
//
// 23.2.2 bool empty() const
@@ -32,10 +30,15 @@ bool test __attribute__((unused)) = true;
// 23.2.2 size_type max_size() const
// 23.2.2.2 void resize(size_type s, T c = T())
//
+template<typename _Tp>
void
-test01()
+capacity01()
{
- std::list<int> list0101;
+ bool test __attribute__((unused)) = true;
+ typedef _Tp list_type;
+ typedef typename list_type::iterator iterator_type;
+
+ list_type list0101;
VERIFY(list0101.empty());
VERIFY(list0101.size() == 0);
@@ -47,7 +50,7 @@ test01()
VERIFY(!list0101.empty());
VERIFY(list0101.size() == 3);
- std::list<int>::iterator i = list0101.begin();
+ iterator_type i = list0101.begin();
VERIFY(*i == 1); ++i;
VERIFY(*i == 2); ++i;
VERIFY(*i == 2); ++i;
@@ -61,8 +64,6 @@ test01()
int
main()
{
- test01();
+ capacity01<std::list<int> >();
return 0;
}
-
-// vi:set sw=2 ts=2:
diff --git a/libstdc++-v3/testsuite/23_containers/list/capacity/29134.cc b/libstdc++-v3/testsuite/23_containers/list/capacity/29134.cc
index 717c3eae070..48394079750 100644
--- a/libstdc++-v3/testsuite/23_containers/list/capacity/29134.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/capacity/29134.cc
@@ -25,7 +25,8 @@ void test01()
{
bool test __attribute__((unused)) = true;
- std::list<int> l;
+ typedef std::list<int> list_type;
+ list_type l;
#ifndef _GLIBCXX_DEBUG
using std::_List_node;
diff --git a/libstdc++-v3/testsuite/23_containers/list/check_construct_destroy.cc b/libstdc++-v3/testsuite/23_containers/list/check_construct_destroy.cc
index f6e19907c2e..a223bc85007 100644
--- a/libstdc++-v3/testsuite/23_containers/list/check_construct_destroy.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/check_construct_destroy.cc
@@ -22,17 +22,21 @@
#include <iterator>
#include <testsuite_allocator.h>
-using namespace __gnu_test;
-int main()
+template<typename _Tp>
+bool
+construct_destroy()
{
- typedef std::list<int, tracker_allocator<int> > Container;
+ typedef _Tp list_type;
+ typedef typename list_type::iterator iterator_type;
+
+ using namespace __gnu_test;
const int arr10[10] = { 2, 4, 1, 7, 3, 8, 10, 5, 9, 6 };
bool ok = true;
tracker_allocator_counter::reset();
{
- Container c;
+ list_type c;
ok = check_construct_destroy("empty container", 0, 0) && ok;
}
ok = check_construct_destroy("empty container", 0, 0) && ok;
@@ -40,13 +44,13 @@ int main()
tracker_allocator_counter::reset();
{
- Container c(arr10, arr10 + 10);
+ list_type c(arr10, arr10 + 10);
ok = check_construct_destroy("Construct from range", 10, 0) && ok;
}
ok = check_construct_destroy("Construct from range", 10, 10) && ok;
{
- Container c(arr10, arr10 + 10);
+ list_type c(arr10, arr10 + 10);
tracker_allocator_counter::reset();
c.insert(c.begin(), arr10[0]);
ok = check_construct_destroy("Insert element", 1, 0) && ok;
@@ -54,9 +58,9 @@ int main()
ok = check_construct_destroy("Insert element", 1, 11) && ok;
{
- Container c(arr10, arr10 + 10);
+ list_type c(arr10, arr10 + 10);
tracker_allocator_counter::reset();
- Container::iterator i5 = c.begin();
+ iterator_type i5 = c.begin();
std::advance(i5, 5);
c.insert(i5, arr10, arr10+3);
ok = check_construct_destroy("Insert short range", 3, 0) && ok;
@@ -64,9 +68,9 @@ int main()
ok = check_construct_destroy("Insert short range", 3, 13) && ok;
{
- Container c(arr10, arr10 + 10);
+ list_type c(arr10, arr10 + 10);
tracker_allocator_counter::reset();
- Container::iterator i7 = c.begin();
+ iterator_type i7 = c.begin();
std::advance(i7, 5);
c.insert(i7, arr10, arr10+10);
ok = check_construct_destroy("Insert long range", 10, 0) && ok;
@@ -76,3 +80,8 @@ int main()
return ok ? 0 : 1;
}
+int main()
+{
+ construct_destroy<std::list<int, __gnu_test::tracker_allocator<int> > >();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/list/cons/1.cc b/libstdc++-v3/testsuite/23_containers/list/cons/1.cc
index 343767637c1..2228a506fe9 100644
--- a/libstdc++-v3/testsuite/23_containers/list/cons/1.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/cons/1.cc
@@ -20,8 +20,6 @@
#include <list>
#include <testsuite_hooks.h>
-bool test __attribute__((unused)) = true;
-
// A nontrivial type.
template<typename T>
struct A { };
@@ -29,13 +27,6 @@ template<typename T>
// Another nontrivial type
struct B { };
-// A nontrivial type convertible from an int
-struct C {
- C(int i) : i_(i) { }
- bool operator==(const C& rhs) { return i_ == rhs.i_; }
- int i_;
-};
-
// Default constructor, basic properties
//
// This test verifies the following.
@@ -46,32 +37,36 @@ struct C {
// 23.2.2 size_type size() const
// 23.2.2 existence of required typedefs
//
+template<typename _Tp>
void
-test01()
+cons01()
{
- std::list< A<B> > list0101;
+ bool test __attribute__((unused)) = true;
+ typedef _Tp list_type;
+
+ list_type list0101;
VERIFY(list0101.begin() == list0101.end());
VERIFY(list0101.size() == 0);
// check type definitions -- will fail compile if missing
- typedef std::list< A<B> >::reference reference;
- typedef std::list< A<B> >::const_reference const_reference;
- typedef std::list< A<B> >::iterator iterator;
- typedef std::list< A<B> >::const_iterator const_iterator;
- typedef std::list< A<B> >::size_type size_type;
- typedef std::list< A<B> >::difference_type difference_type;
- typedef std::list< A<B> >::value_type value_type;
- typedef std::list< A<B> >::allocator_type allocator_type;
- typedef std::list< A<B> >::pointer pointer;
- typedef std::list< A<B> >::const_pointer const_pointer;
- typedef std::list< A<B> >::reverse_iterator reverse_iterator;
- typedef std::list< A<B> >::const_reverse_iterator const_reverse_iterator;
+ typedef typename list_type::reference reference;
+ typedef typename list_type::const_reference const_reference;
+ typedef typename list_type::iterator iterator;
+ typedef typename list_type::const_iterator const_iterator;
+ typedef typename list_type::size_type size_type;
+ typedef typename list_type::difference_type difference_type;
+ typedef typename list_type::value_type value_type;
+ typedef typename list_type::allocator_type allocator_type;
+ typedef typename list_type::pointer pointer;
+ typedef typename list_type::const_pointer const_pointer;
+ typedef typename list_type::reverse_iterator reverse_iterator;
+ typedef typename list_type::const_reverse_iterator const_reverse_iterator;
// allocator checks?
}
int main()
{
- test01();
+ cons01<std::list< A<B> > >();
return 0;
}
diff --git a/libstdc++-v3/testsuite/23_containers/list/cons/2.cc b/libstdc++-v3/testsuite/23_containers/list/cons/2.cc
index ee6864e0333..a38cf7d1bba 100644
--- a/libstdc++-v3/testsuite/23_containers/list/cons/2.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/cons/2.cc
@@ -20,8 +20,6 @@
#include <list>
#include <testsuite_hooks.h>
-bool test __attribute__((unused)) = true;
-
// A nontrivial type.
template<typename T>
struct A { };
@@ -29,34 +27,29 @@ template<typename T>
// Another nontrivial type
struct B { };
-// A nontrivial type convertible from an int
-struct C {
- C(int i) : i_(i) { }
- bool operator==(const C& rhs) { return i_ == rhs.i_; }
- int i_;
-};
-
// Fill constructor
//
// This test verifies the following.
-// 23.2.2.1 explicit list(size_type n, const T& v = T(), const a& = Allocator())
-// 23.2.2 const_iterator begin() const
-// 23.2.2 const_iterator end() const
-// 23.2.2 size_type size() const
+// 23.2.2.1 explicit list(size_type n, const T& v = T(), const a& = Allocator())
+// 23.2.2 const_iterator begin() const
+// 23.2.2 const_iterator end() const
+// 23.2.2 size_type size() const
//
+template<typename _Tp>
void
-test02()
+cons021()
{
+ bool test __attribute__((unused)) = true;
const std::size_t LIST_SIZE = 5;
const int INIT_VALUE = 7;
std::size_t count;
- std::list<int>::const_iterator i;
- // nontrivial value_type
- std::list< A<B> > list0201(LIST_SIZE);
+ typedef _Tp list_type;
+ typedef typename list_type::const_iterator const_iterator;
+ const_iterator i;
// default value
- std::list<int> list0202(LIST_SIZE);
+ list_type list0202(LIST_SIZE);
for (i = list0202.begin(), count = 0;
i != list0202.end();
++i, ++count)
@@ -65,7 +58,7 @@ test02()
VERIFY(list0202.size() == LIST_SIZE);
// explicit value
- std::list<int> list0203(LIST_SIZE, INIT_VALUE);
+ list_type list0203(LIST_SIZE, INIT_VALUE);
for (i = list0203.begin(), count = 0;
i != list0203.end();
++i, ++count)
@@ -74,8 +67,19 @@ test02()
VERIFY(list0203.size() == LIST_SIZE);
}
+template<typename _Tp>
+void
+cons022()
+{
+ // nontrivial value_type
+ typedef _Tp list_type;
+ const std::size_t LIST_SIZE = 5;
+ list_type list0201(LIST_SIZE);
+}
+
int main()
{
- test02();
+ cons021<std::list<int> >();
+ cons022<std::list< A<B> > >();
return 0;
}
diff --git a/libstdc++-v3/testsuite/23_containers/list/cons/3.cc b/libstdc++-v3/testsuite/23_containers/list/cons/3.cc
index c9b1fe887b0..b067ee17bc2 100644
--- a/libstdc++-v3/testsuite/23_containers/list/cons/3.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/cons/3.cc
@@ -20,31 +20,28 @@
#include <list>
#include <testsuite_hooks.h>
-bool test __attribute__((unused)) = true;
-
-// A nontrivial type.
-template<typename T>
- struct A { };
-
-// Another nontrivial type
-struct B { };
-
// A nontrivial type convertible from an int
-struct C {
+struct C
+{
C(int i) : i_(i) { }
bool operator==(const C& rhs) { return i_ == rhs.i_; }
int i_;
};
// Fill constructor disguised as a range constructor
+template<typename _Tp>
void
-test02D()
+cons03()
{
+ bool test __attribute__((unused)) = true;
+ typedef _Tp list_type;
+ typedef typename list_type::iterator iterator;
+
const std::size_t LIST_SIZE = 5;
const int INIT_VALUE = 7;
std::size_t count = 0;
- std::list<C> list0204(LIST_SIZE, INIT_VALUE);
- std::list<C>::iterator i = list0204.begin();
+ list_type list0204(LIST_SIZE, INIT_VALUE);
+ iterator i = list0204.begin();
for (; i != list0204.end(); ++i, ++count)
VERIFY(*i == INIT_VALUE);
VERIFY(count == LIST_SIZE);
@@ -53,7 +50,6 @@ test02D()
int main()
{
- test02D();
+ cons03<std::list<C> >();
return 0;
}
-// vi:set sw=2 ts=2:
diff --git a/libstdc++-v3/testsuite/23_containers/list/cons/4.cc b/libstdc++-v3/testsuite/23_containers/list/cons/4.cc
index 83b674f43c0..0dde9e9eaf4 100644
--- a/libstdc++-v3/testsuite/23_containers/list/cons/4.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/cons/4.cc
@@ -20,26 +20,30 @@
#include <list>
#include <testsuite_hooks.h>
-bool test __attribute__((unused)) = true;
-
// Range constructor
//
// This test verifies the following.
-// 23.2.2.1 template list(InputIterator f, InputIterator l, const Allocator& a = Allocator())
+// 23.2.2.1 template list(InputIterator f, InputIterator l,
+// const Allocator& a = Allocator())
// 23.2.2 const_iterator begin() const
// 23.2.2 const_iterator end() const
// 23.2.2 size_type size() const
//
+template<typename _Tp>
void
-test03()
+cons04()
{
+ bool test __attribute__((unused)) = true;
const int A[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17};
const std::size_t N = sizeof(A) / sizeof(int);
std::size_t count;
- std::list<int>::const_iterator i;
+
+ typedef std::list<int> list_type;
+ typedef typename list_type::const_iterator const_iterator;
+ const_iterator i;
// construct from a dissimilar range
- std::list<int> list0301(A, A + N);
+ list_type list0301(A, A + N);
for (i = list0301.begin(), count = 0;
i != list0301.end();
++i, ++count)
@@ -48,7 +52,7 @@ test03()
VERIFY(list0301.size() == N);
// construct from a similar range
- std::list<int> list0302(list0301.begin(), list0301.end());
+ list_type list0302(list0301.begin(), list0301.end());
for (i = list0302.begin(), count = 0;
i != list0302.end();
++i, ++count)
@@ -59,7 +63,7 @@ test03()
int main()
{
- test03();
+ cons04<std::list<int> >();
return 0;
}
diff --git a/libstdc++-v3/testsuite/23_containers/list/cons/5.cc b/libstdc++-v3/testsuite/23_containers/list/cons/5.cc
index 38498788b13..be8b5921aeb 100644
--- a/libstdc++-v3/testsuite/23_containers/list/cons/5.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/cons/5.cc
@@ -20,8 +20,6 @@
#include <list>
#include <testsuite_hooks.h>
-bool test __attribute__((unused)) = true;
-
// Copy constructor
//
// This test verifies the following.
@@ -30,16 +28,21 @@ bool test __attribute__((unused)) = true;
// 23.2.2 reverse_iterator rend()
// 23.2.2 size_type size() const
//
+template<typename _Tp>
void
-test04()
+cons05()
{
+ bool test __attribute__((unused)) = true;
const int A[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17};
const std::size_t N = sizeof(A) / sizeof(int);
int count;
- std::list<int>::reverse_iterator i;
- std::list<int> list0401(A, A + N);
- std::list<int> list0402(list0401);
+ typedef _Tp list_type;
+ typedef typename list_type::reverse_iterator reverse_iterator;
+ reverse_iterator i;
+ list_type list0401(A, A + N);
+
+ list_type list0402(list0401);
for (i = list0401.rbegin(), count = N - 1;
i != list0401.rend();
++i, --count)
@@ -50,7 +53,7 @@ test04()
int main()
{
- test04();
+ cons05<std::list<int> >();
return 0;
}
diff --git a/libstdc++-v3/testsuite/23_containers/list/cons/6.cc b/libstdc++-v3/testsuite/23_containers/list/cons/6.cc
index 1355629f32a..c2ecc59de25 100644
--- a/libstdc++-v3/testsuite/23_containers/list/cons/6.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/cons/6.cc
@@ -20,8 +20,6 @@
#include <list>
#include <testsuite_hooks.h>
-bool test __attribute__((unused)) = true;
-
// Range assign
//
// This test verifies the following.
@@ -30,17 +28,22 @@ bool test __attribute__((unused)) = true;
// 23.2.2 const_iterator end() const
// 23.2.2 size_type size() const
//
+template<typename _Tp>
void
-test05()
+cons06()
{
+ bool test __attribute__((unused)) = true;
const int A[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17};
const int B[] = {101, 102, 103, 104, 105};
const std::size_t N = sizeof(A) / sizeof(int);
const std::size_t M = sizeof(B) / sizeof(int);
std::size_t count;
- std::list<int>::const_iterator i;
- std::list<int> list0501;
+ typedef _Tp list_type;
+ typedef typename list_type::const_iterator const_iterator;
+ const_iterator i;
+
+ list_type list0501;
// make it bigger
list0501.assign(A, A + N);
@@ -63,7 +66,7 @@ test05()
int main()
{
- test05();
+ cons06<std::list<int> >();
return 0;
}
diff --git a/libstdc++-v3/testsuite/23_containers/list/cons/7.cc b/libstdc++-v3/testsuite/23_containers/list/cons/7.cc
index 6f396edc650..9a626a6234f 100644
--- a/libstdc++-v3/testsuite/23_containers/list/cons/7.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/cons/7.cc
@@ -20,8 +20,6 @@
#include <list>
#include <testsuite_hooks.h>
-bool test __attribute__((unused)) = true;
-
// Fill assign
//
// This test verifies the following.
@@ -30,17 +28,22 @@ bool test __attribute__((unused)) = true;
// 23.2.2 const_iterator end() const
// 23.2.2 size_type size() const
//
+template<typename _Tp>
void
-test06()
+cons07()
{
+ bool test __attribute__((unused)) = true;
const std::size_t BIG_LIST_SIZE = 11;
const int BIG_INIT_VALUE = 7;
const std::size_t SMALL_LIST_SIZE = 5;
const int SMALL_INIT_VALUE = 17;
std::size_t count;
- std::list<int>::const_iterator i;
- std::list<int> list0601;
+ typedef _Tp list_type;
+ typedef typename list_type::const_iterator const_iterator;
+ const_iterator i;
+
+ list_type list0601;
VERIFY(list0601.size() == 0);
// make it bigger
@@ -64,7 +67,7 @@ test06()
int main()
{
- test06();
+ cons07<std::list<int> >();
return 0;
}
diff --git a/libstdc++-v3/testsuite/23_containers/list/cons/8.cc b/libstdc++-v3/testsuite/23_containers/list/cons/8.cc
index d20a8a71cd3..f93520c5406 100644
--- a/libstdc++-v3/testsuite/23_containers/list/cons/8.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/cons/8.cc
@@ -20,35 +20,31 @@
#include <list>
#include <testsuite_hooks.h>
-bool test __attribute__((unused)) = true;
-
-
-// A nontrivial type.
-template<typename T>
- struct A { };
-
-// Another nontrivial type
-struct B { };
-
// A nontrivial type convertible from an int
-struct C {
+struct C
+{
C(int i) : i_(i) { }
bool operator==(const C& rhs) { return i_ == rhs.i_; }
int i_;
};
// Fill Assignment disguised as a Range Assignment
+template<typename _Tp>
void
-test06D()
+cons08()
{
+ typedef _Tp list_type;
+ typedef typename list_type::iterator iterator;
+ bool test __attribute__((unused)) = true;
const std::size_t LIST_SIZE = 5;
const int INIT_VALUE = 7;
std::size_t count = 0;
- std::list<C> list0604;
+
+ list_type list0604;
VERIFY(list0604.size() == 0);
list0604.assign(LIST_SIZE, INIT_VALUE);
- std::list<C>::iterator i = list0604.begin();
+ iterator i = list0604.begin();
for (; i != list0604.end(); ++i, ++count)
VERIFY(*i == INIT_VALUE);
VERIFY(count == LIST_SIZE);
@@ -57,7 +53,7 @@ test06D()
int main()
{
- test06D();
+ cons08<std::list<C> >();
return 0;
}
diff --git a/libstdc++-v3/testsuite/23_containers/list/cons/9.cc b/libstdc++-v3/testsuite/23_containers/list/cons/9.cc
index c25da98a785..87cb0270c40 100644
--- a/libstdc++-v3/testsuite/23_containers/list/cons/9.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/cons/9.cc
@@ -20,8 +20,6 @@
#include <list>
#include <testsuite_hooks.h>
-bool test __attribute__((unused)) = true;
-
// Assignment operator
//
// This test verifies the following.
@@ -31,18 +29,24 @@ bool test __attribute__((unused)) = true;
// 23.2.2 size_type size() const
// 23.2.2 bool operator==(const list& x, const list& y)
//
+template<typename _Tp>
void
-test07()
+cons09()
{
+ bool test __attribute__((unused)) = true;
+ typedef _Tp list_type;
+ typedef typename list_type::iterator iterator;
+
const int A[] = {701, 702, 703, 704, 705};
const std::size_t N = sizeof(A) / sizeof(int);
std::size_t count;
- std::list<int>::iterator i;
- std::list<int> list0701(A, A + N);
+ iterator i;
+
+ list_type list0701(A, A + N);
VERIFY(list0701.size() == N);
- std::list<int> list0702;
+ list_type list0702;
VERIFY(list0702.size() == 0);
list0702 = list0701;
@@ -57,7 +61,6 @@ test07()
int main()
{
- test07();
+ cons09<std::list<int> >();
return 0;
}
-// vi:set sw=2 ts=2:
diff --git a/libstdc++-v3/testsuite/23_containers/list/cons/clear_allocator.cc b/libstdc++-v3/testsuite/23_containers/list/cons/clear_allocator.cc
index 6a52bb70f1b..82a47ade754 100644
--- a/libstdc++-v3/testsuite/23_containers/list/cons/clear_allocator.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/cons/clear_allocator.cc
@@ -81,7 +81,8 @@ template<typename Container>
int main()
{
- Check_Container<std::list<int, clear_alloc<int> > >();
+ typedef std::list<int, clear_alloc<int> > list_type;
+ Check_Container<list_type>();
return 0;
}
diff --git a/libstdc++-v3/testsuite/23_containers/list/init-list.cc b/libstdc++-v3/testsuite/23_containers/list/init-list.cc
index b611067ba11..261ef084f09 100644
--- a/libstdc++-v3/testsuite/23_containers/list/init-list.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/init-list.cc
@@ -21,28 +21,31 @@
#include <list>
#include <testsuite_allocator.h>
-using namespace __gnu_test;
-
-int main()
+template<typename _Tp>
+bool
+init_list()
{
- typedef std::list<int, tracker_allocator<int> > Container;
+ using namespace __gnu_test;
+ typedef _Tp list_type;
+ typedef typename list_type::iterator iterator;
+
const int arr10[10] = { 2, 4, 1, 7, 3, 8, 10, 5, 9, 6 };
bool ok = true;
tracker_allocator_counter::reset();
{
- Container c({ 2, 4, 1 });
+ list_type c({ 2, 4, 1 });
ok = check_construct_destroy("Construct from init-list", 3, 0) && ok;
- Container::iterator i = c.begin();
+ iterator i = c.begin();
ok &= (*i++ == 2);
ok &= (*i++ == 4);
}
ok = check_construct_destroy("Construct from init-list", 3, 3) && ok;
{
- Container c(arr10, arr10 + 10);
+ list_type c(arr10, arr10 + 10);
tracker_allocator_counter::reset();
- Container::iterator i = c.begin();
+ iterator i = c.begin();
++i; ++i; ++i; ++i; ++i; ++i; ++i;
c.insert(i, { 234, 42, 1 });
ok = check_construct_destroy("Insert init-list", 3, 0) && ok;
@@ -52,14 +55,23 @@ int main()
ok = check_construct_destroy("Insert init-list", 3, 13) && ok;
{
- Container c;
+ list_type c;
tracker_allocator_counter::reset();
c = { 13, 0, 42 };
ok = check_construct_destroy("Assign init-list", 3, 0) && ok;
- Container::iterator i = c.begin();
+ iterator i = c.begin();
ok &= (*i++ == 13);
}
ok = check_construct_destroy("Assign init-list", 3, 3) && ok;
- return ok ? 0 : 1;;
+ return ok ? 0 : 1;
+}
+
+int main()
+{
+ typedef int value_type;
+ typedef __gnu_test::tracker_allocator<int> allocator_type;
+ typedef std::list<value_type, allocator_type> list_type;
+ init_list<list_type>();
+ return 0;
}
diff --git a/libstdc++-v3/testsuite/23_containers/list/invalidation/1.cc b/libstdc++-v3/testsuite/23_containers/list/invalidation/1.cc
index 61cc3f2873a..04267c253c7 100644
--- a/libstdc++-v3/testsuite/23_containers/list/invalidation/1.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/invalidation/1.cc
@@ -21,21 +21,21 @@
#include <iterator>
#include <testsuite_hooks.h>
-using __gnu_debug::list;
-using std::advance;
-
-bool test = true;
-
// Assignment
void test01()
{
- list<int> v1;
- list<int> v2;
+ using std::advance;
+
+ bool test = true;
+
+ typedef __gnu_debug::list<int> list_type;
+ list_type v1;
+ list_type v2;
v1.push_front(17);
- list<int>::iterator start = v1.begin();
- list<int>::iterator finish = v1.end();
+ list_type::iterator start = v1.begin();
+ list_type::iterator finish = v1.end();
VERIFY(start._M_dereferenceable());
VERIFY(!finish._M_dereferenceable() && !finish._M_singular());
diff --git a/libstdc++-v3/testsuite/23_containers/list/invalidation/2.cc b/libstdc++-v3/testsuite/23_containers/list/invalidation/2.cc
index c841be3df68..a141f2cdc82 100644
--- a/libstdc++-v3/testsuite/23_containers/list/invalidation/2.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/invalidation/2.cc
@@ -21,23 +21,24 @@
#include <iterator>
#include <testsuite_hooks.h>
-using __gnu_debug::list;
-using std::advance;
-
-bool test = true;
-
// Resize
void test02()
{
- list<int> v(10, 17);
+ using std::advance;
+
+ bool test = true;
+
+ typedef __gnu_debug::list<int> list_type;
+
+ list_type v(10, 17);
- list<int>::iterator before = v.begin();
+ list_type::iterator before = v.begin();
advance(before, 6);
- list<int>::iterator at = before;
+ list_type::iterator at = before;
advance(at, 1);
- list<int>::iterator after = at;
+ list_type::iterator after = at;
advance(after, 1);
- list<int>::iterator finish = v.end();
+ list_type::iterator finish = v.end();
// Shrink
v.resize(7);
diff --git a/libstdc++-v3/testsuite/23_containers/list/invalidation/3.cc b/libstdc++-v3/testsuite/23_containers/list/invalidation/3.cc
index 243dfeb67b5..770d4597484 100644
--- a/libstdc++-v3/testsuite/23_containers/list/invalidation/3.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/invalidation/3.cc
@@ -21,21 +21,21 @@
#include <iterator>
#include <testsuite_hooks.h>
-using __gnu_debug::list;
-using std::advance;
-
-bool test = true;
-
// Erase
void test03()
{
- list<int> v(20, 42);
+ using std::advance;
+
+ bool test = true;
+ typedef __gnu_debug::list<int> list_type;
+
+ list_type v(20, 42);
// Single element erase (middle)
- list<int>::iterator before = v.begin();
- list<int>::iterator at = before;
+ list_type::iterator before = v.begin();
+ list_type::iterator at = before;
advance(at, 3);
- list<int>::iterator after = at;
+ list_type::iterator after = at;
at = v.erase(at);
VERIFY(before._M_dereferenceable());
VERIFY(at._M_dereferenceable());
@@ -63,7 +63,7 @@ void test03()
// clear()
before = v.begin();
- list<int>::iterator finish = v.end();
+ list_type::iterator finish = v.end();
VERIFY(before._M_dereferenceable());
v.clear();
VERIFY(before._M_singular());
diff --git a/libstdc++-v3/testsuite/23_containers/list/invalidation/4.cc b/libstdc++-v3/testsuite/23_containers/list/invalidation/4.cc
index d8a86ca9639..11e4394fa7d 100644
--- a/libstdc++-v3/testsuite/23_containers/list/invalidation/4.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/invalidation/4.cc
@@ -21,21 +21,22 @@
#include <iterator>
#include <testsuite_hooks.h>
-using __gnu_debug::list;
-using std::advance;
-
-bool test = true;
-
// Splice
void test04()
{
- list<int> l1(10, 17);
- list<int> l2(10, 42);
+ using std::advance;
+
+ bool test = true;
+
+ typedef __gnu_debug::list<int> list_type;
+
+ list_type l1(10, 17);
+ list_type l2(10, 42);
- list<int>::iterator start2 = l2.begin();
- list<int>::iterator end2 = start2;
+ list_type::iterator start2 = l2.begin();
+ list_type::iterator end2 = start2;
advance(end2, 5);
- list<int>::iterator after2 = end2;
+ list_type::iterator after2 = end2;
advance(after2, 2);
l1.splice(l1.begin(), l2, start2, end2);
diff --git a/libstdc++-v3/testsuite/23_containers/list/modifiers/1.cc b/libstdc++-v3/testsuite/23_containers/list/modifiers/1.cc
index d250db8c907..b1c85f0511c 100644
--- a/libstdc++-v3/testsuite/23_containers/list/modifiers/1.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/modifiers/1.cc
@@ -20,99 +20,101 @@
#include <list>
#include <testsuite_hooks.h>
-typedef __gnu_test::copy_tracker T;
-
-bool test __attribute__((unused)) = true;
-
// range and fill insert/erase + clear
// missing: o fill insert disguised as a range insert in all its variants
// o exception effects
+template<typename _Tp>
void
-test03()
+modifiers1()
{
- std::list<T> list0301;
- T::reset();
+ bool test __attribute__((unused)) = true;
+ typedef _Tp list_type;
+ typedef typename list_type::iterator iterator;
+ typedef typename list_type::value_type value_type;
+
+ list_type list0301;
+ value_type::reset();
// fill insert at beginning of list / empty list
- list0301.insert(list0301.begin(), 3, T(11)); // should be [11 11 11]
+ list0301.insert(list0301.begin(), 3, value_type(11)); // should be [11 11 11]
VERIFY(list0301.size() == 3);
- VERIFY(T::copyCount() == 3);
+ VERIFY(value_type::copyCount() == 3);
// save iterators to verify post-insert validity
- std::list<T>::iterator b = list0301.begin();
- std::list<T>::iterator m = list0301.end(); --m;
- std::list<T>::iterator e = list0301.end();
+ iterator b = list0301.begin();
+ iterator m = list0301.end(); --m;
+ iterator e = list0301.end();
// fill insert at end of list
- T::reset();
- list0301.insert(list0301.end(), 3, T(13)); // should be [11 11 11 13 13 13]
+ value_type::reset();
+ list0301.insert(list0301.end(), 3, value_type(13)); // should be [11 11 11 13 13 13]
VERIFY(list0301.size() == 6);
- VERIFY(T::copyCount() == 3);
+ VERIFY(value_type::copyCount() == 3);
VERIFY(b == list0301.begin() && b->id() == 11);
VERIFY(e == list0301.end());
VERIFY(m->id() == 11);
// fill insert in the middle of list
++m;
- T::reset();
- list0301.insert(m, 3, T(12)); // should be [11 11 11 12 12 12 13 13 13]
+ value_type::reset();
+ list0301.insert(m, 3, value_type(12)); // should be [11 11 11 12 12 12 13 13 13]
VERIFY(list0301.size() == 9);
- VERIFY(T::copyCount() == 3);
+ VERIFY(value_type::copyCount() == 3);
VERIFY(b == list0301.begin() && b->id() == 11);
VERIFY(e == list0301.end());
VERIFY(m->id() == 13);
// single erase
- T::reset();
+ value_type::reset();
m = list0301.erase(m); // should be [11 11 11 12 12 12 13 13]
VERIFY(list0301.size() == 8);
- VERIFY(T::dtorCount() == 1);
+ VERIFY(value_type::dtorCount() == 1);
VERIFY(b == list0301.begin() && b->id() == 11);
VERIFY(e == list0301.end());
VERIFY(m->id() == 13);
// range erase
- T::reset();
+ value_type::reset();
m = list0301.erase(list0301.begin(), m); // should be [13 13]
VERIFY(list0301.size() == 2);
- VERIFY(T::dtorCount() == 6);
+ VERIFY(value_type::dtorCount() == 6);
VERIFY(m->id() == 13);
// range fill at beginning
const int A[] = {321, 322, 333};
const int N = sizeof(A) / sizeof(int);
- T::reset();
- b = list0301.begin();
+ value_type::reset();
+ b = list0301.begin();
list0301.insert(b, A, A + N); // should be [321 322 333 13 13]
VERIFY(list0301.size() == 5);
- VERIFY(T::copyCount() == 3);
+ VERIFY(value_type::copyCount() == 3);
VERIFY(m->id() == 13);
-
+
// range fill at end
- T::reset();
+ value_type::reset();
list0301.insert(e, A, A + N); // should be [321 322 333 13 13 321 322 333]
VERIFY(list0301.size() == 8);
- VERIFY(T::copyCount() == 3);
+ VERIFY(value_type::copyCount() == 3);
VERIFY(e == list0301.end());
VERIFY(m->id() == 13);
-
+
// range fill in middle
- T::reset();
- list0301.insert(m, A, A + N);
+ value_type::reset();
+ list0301.insert(m, A, A + N);
VERIFY(list0301.size() == 11);
- VERIFY(T::copyCount() == 3);
+ VERIFY(value_type::copyCount() == 3);
VERIFY(e == list0301.end());
VERIFY(m->id() == 13);
- T::reset();
+ value_type::reset();
list0301.clear();
VERIFY(list0301.size() == 0);
- VERIFY(T::dtorCount() == 11);
+ VERIFY(value_type::dtorCount() == 11);
VERIFY(e == list0301.end());
}
int main()
{
- test03();
+ modifiers1<std::list<__gnu_test::copy_tracker> >();
return 0;
}
diff --git a/libstdc++-v3/testsuite/23_containers/list/modifiers/2.cc b/libstdc++-v3/testsuite/23_containers/list/modifiers/2.cc
index 648b2757f71..da39397d098 100644
--- a/libstdc++-v3/testsuite/23_containers/list/modifiers/2.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/modifiers/2.cc
@@ -20,71 +20,74 @@
#include <list>
#include <testsuite_hooks.h>
-typedef __gnu_test::copy_tracker T;
-
-bool test __attribute__((unused)) = true;
-
// general single insert/erase + swap
+template<typename _Tp>
void
-test02()
+modifiers2()
{
- std::list<T> list0201;
- T::reset();
+ bool test __attribute__((unused)) = true;
+ typedef _Tp list_type;
+ typedef typename list_type::value_type value_type;
+ typedef typename list_type::iterator iterator;
+ typedef typename list_type::const_iterator const_iterator;
+
+ list_type list0201;
+ value_type::reset();
- list0201.insert(list0201.begin(), T(1)); // list should be [1]
+ list0201.insert(list0201.begin(), value_type(1)); // list should be [1]
VERIFY(list0201.size() == 1);
- VERIFY(T::copyCount() == 1);
+ VERIFY(value_type::copyCount() == 1);
- list0201.insert(list0201.end(), T(2)); // list should be [1 2]
+ list0201.insert(list0201.end(), value_type(2)); // list should be [1 2]
VERIFY(list0201.size() == 2);
- VERIFY(T::copyCount() == 2);
+ VERIFY(value_type::copyCount() == 2);
- std::list<T>::iterator i = list0201.begin();
- std::list<T>::const_iterator j = i;
+ iterator i = list0201.begin();
+ const_iterator j = i;
VERIFY(i->id() == 1); ++i;
VERIFY(i->id() == 2);
- list0201.insert(i, T(3)); // list should be [1 3 2]
+ list0201.insert(i, value_type(3)); // list should be [1 3 2]
VERIFY(list0201.size() == 3);
- VERIFY(T::copyCount() == 3);
+ VERIFY(value_type::copyCount() == 3);
- std::list<T>::const_iterator k = i;
+ const_iterator k = i;
VERIFY(i->id() == 2); --i;
VERIFY(i->id() == 3); --i;
- VERIFY(i->id() == 1);
- VERIFY(j->id() == 1);
+ VERIFY(i->id() == 1);
+ VERIFY(j->id() == 1);
++i; // will point to '3'
- T::reset();
+ value_type::reset();
list0201.erase(i); // should be [1 2]
VERIFY(list0201.size() == 2);
- VERIFY(T::dtorCount() == 1);
+ VERIFY(value_type::dtorCount() == 1);
VERIFY(k->id() == 2);
- VERIFY(j->id() == 1);
+ VERIFY(j->id() == 1);
- std::list<T> list0202;
- T::reset();
+ list_type list0202;
+ value_type::reset();
VERIFY(list0202.size() == 0);
- VERIFY(T::copyCount() == 0);
- VERIFY(T::dtorCount() == 0);
+ VERIFY(value_type::copyCount() == 0);
+ VERIFY(value_type::dtorCount() == 0);
// member swap
list0202.swap(list0201);
VERIFY(list0201.size() == 0);
VERIFY(list0202.size() == 2);
- VERIFY(T::copyCount() == 0);
- VERIFY(T::dtorCount() == 0);
+ VERIFY(value_type::copyCount() == 0);
+ VERIFY(value_type::dtorCount() == 0);
// specialized swap
swap(list0201, list0202);
VERIFY(list0201.size() == 2);
VERIFY(list0202.size() == 0);
- VERIFY(T::copyCount() == 0);
- VERIFY(T::dtorCount() == 0);
+ VERIFY(value_type::copyCount() == 0);
+ VERIFY(value_type::dtorCount() == 0);
}
int main()
{
- test02();
+ modifiers2<std::list<__gnu_test::copy_tracker> >();
return 0;
}
diff --git a/libstdc++-v3/testsuite/23_containers/list/modifiers/3.cc b/libstdc++-v3/testsuite/23_containers/list/modifiers/3.cc
index 995ce7be757..b6a41e3dc45 100644
--- a/libstdc++-v3/testsuite/23_containers/list/modifiers/3.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/modifiers/3.cc
@@ -20,44 +20,47 @@
#include <list>
#include <testsuite_hooks.h>
-typedef __gnu_test::copy_tracker T;
-
-bool test __attribute__((unused)) = true;
-
-
// This test verifies the following.
//
// 23.2.2.3 void push_front(const T& x)
// 23.2.2.3 void push_back(const T& x)
-// 23.2.2.3 (1) iterator and reference non-invalidation
+// 23.2.2.3 (1) iterator and reference non-invalidation
// 23.2.2.3 (1) exception effects
// 23.2.2.3 (2) complexity requirements
//
// 23.2.2.3 void pop_front()
// 23.2.2.3 void pop_back()
-// 23.2.2.3 (3) iterator and reference non-invalidation
+// 23.2.2.3 (3) iterator and reference non-invalidation
// 23.2.2.3 (5) complexity requirements
//
// 23.2.2 const_iterator begin() const
-// 23.2.2 iterator end()
+// 23.2.2 iterator end()
// 23.2.2 const_reverse_iterator rbegin() const
-// 23.2.2 _reference front()
+// 23.2.2 _reference front()
// 23.2.2 const_reference front() const
-// 23.2.2 reference back()
+// 23.2.2 reference back()
// 23.2.2 const_reference back() const
//
+template<typename _Tp>
void
-test01()
+modifiers3()
{
- std::list<T> list0101;
- std::list<T>::const_iterator i;
- std::list<T>::const_reverse_iterator j;
- std::list<T>::iterator k;
- T::reset();
-
- list0101.push_back(T(1)); // list should be [1]
+ bool test __attribute__((unused)) = true;
+ typedef _Tp list_type;
+ typedef typename list_type::iterator iterator;
+ typedef typename list_type::value_type value_type;
+ typedef typename list_type::const_iterator const_iterator;
+ typedef typename list_type::const_reverse_iterator const_reverse_iterator;
+
+ list_type list0101;
+ const_iterator i;
+ const_reverse_iterator j;
+ iterator k;
+ value_type::reset();
+
+ list0101.push_back(value_type(1)); // list should be [1]
VERIFY(list0101.size() == 1);
- VERIFY(T::copyCount() == 1);
+ VERIFY(value_type::copyCount() == 1);
k = list0101.end();
--k;
@@ -65,25 +68,25 @@ test01()
VERIFY(k->id() == list0101.front().id());
VERIFY(k->id() == list0101.back().id());
- list0101.push_front(T(2)); // list should be [2 1]
+ list0101.push_front(value_type(2)); // list should be [2 1]
VERIFY(list0101.size() == 2);
- VERIFY(T::copyCount() == 2);
+ VERIFY(value_type::copyCount() == 2);
VERIFY(k->id() == 1);
- list0101.push_back(T(3)); // list should be [2 1 3]
+ list0101.push_back(value_type(3)); // list should be [2 1 3]
VERIFY(list0101.size() == 3);
- VERIFY(T::copyCount() == 3);
+ VERIFY(value_type::copyCount() == 3);
VERIFY(k->id() == 1);
try
{
- list0101.push_back(T(4, true));
+ list0101.push_back(value_type(4, true));
VERIFY(false);
}
catch (...)
{
VERIFY(list0101.size() == 3);
- VERIFY(T::copyCount() == 4);
+ VERIFY(value_type::copyCount() == 4);
}
i = list0101.begin();
@@ -100,23 +103,23 @@ test01()
++j;
VERIFY(j->id() == 1);
- T::reset();
+ value_type::reset();
list0101.pop_back(); // list should be [2 1]
VERIFY(list0101.size() == 2);
- VERIFY(T::dtorCount() == 1);
+ VERIFY(value_type::dtorCount() == 1);
VERIFY(i->id() == 1);
VERIFY(k->id() == 1);
list0101.pop_front(); // list should be [1]
VERIFY(list0101.size() == 1);
- VERIFY(T::dtorCount() == 2);
+ VERIFY(value_type::dtorCount() == 2);
VERIFY(i->id() == 1);
VERIFY(k->id() == 1);
}
int main()
{
- test01();
+ modifiers3<std::list<__gnu_test::copy_tracker> >();
return 0;
}
diff --git a/libstdc++-v3/testsuite/23_containers/list/modifiers/insert/25288.cc b/libstdc++-v3/testsuite/23_containers/list/modifiers/insert/25288.cc
index a2a145c27e2..e108288586e 100644
--- a/libstdc++-v3/testsuite/23_containers/list/modifiers/insert/25288.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/modifiers/insert/25288.cc
@@ -24,19 +24,21 @@
#include <ext/throw_allocator.h>
// libstdc++/25288
-void test01()
+template<typename _Tp>
+void insert1()
{
bool test __attribute__((unused)) = true;
- typedef int value_type;
- typedef __gnu_cxx::throw_allocator<value_type> allocator_type;
- typedef std::list<value_type, allocator_type> list_type;
+ typedef _Tp list_type;
+ typedef typename _Tp::value_type value_type;
+ typedef typename _Tp::allocator_type allocator_type;
+ typedef typename _Tp::size_type size_type;
for (int j = 0; j < 10; ++j)
for (int i = 0; i < 10; ++i)
{
allocator_type alloc1;
- allocator_type::zero_throw_prob_adjustor adjust1;
+ typename allocator_type::never_adjustor adjust1;
list_type list1(alloc1);
for (int k = 0; k < j; ++k)
@@ -44,7 +46,7 @@ void test01()
try
{
- alloc1.set_throw_prob(1);
+ typename allocator_type::always_adjustor adjust2;
list1.insert(list1.begin(), 10, 99);
VERIFY( false );
}
@@ -54,15 +56,14 @@ void test01()
}
catch (...)
{
- VERIFY( false );
+ __throw_exception_again;
}
- VERIFY( list1.size() == list_type::size_type(j) );
+ VERIFY( list1.size() == size_type(j) );
VERIFY( list1.size() == 0 || list1.back() == -j );
VERIFY( list1.size() == 0 || list1.front() == -1 );
allocator_type alloc2;
- allocator_type::zero_throw_prob_adjustor adjust2;
list_type list2(alloc2);
const int data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
@@ -72,7 +73,7 @@ void test01()
try
{
- alloc2.set_throw_prob(1);
+ typename allocator_type::always_adjustor adjust3;
list2.insert(list2.begin(), data, data + 10);
VERIFY( false );
}
@@ -85,7 +86,7 @@ void test01()
VERIFY( false );
}
- VERIFY( list2.size() == list_type::size_type(j) );
+ VERIFY( list2.size() == size_type(j) );
VERIFY( list2.size() == 0 || list2.back() == -j );
VERIFY( list2.size() == 0 || list2.front() == -1 );
}
@@ -93,6 +94,10 @@ void test01()
int main()
{
- test01();
+ typedef int value_type;
+ typedef __gnu_cxx::throw_allocator<value_type> allocator_type;
+ typedef std::list<value_type, allocator_type> list_type;
+
+ insert1<list_type>();
return 0;
}
diff --git a/libstdc++-v3/testsuite/23_containers/list/modifiers/swap/1.cc b/libstdc++-v3/testsuite/23_containers/list/modifiers/swap/1.cc
index ea37be032d7..c66ead57c76 100644
--- a/libstdc++-v3/testsuite/23_containers/list/modifiers/swap/1.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/modifiers/swap/1.cc
@@ -31,23 +31,31 @@ namespace std
}
// Should use list specialization for swap.
-void test01()
+template<typename _Tp>
+void
+swap11()
{
bool test __attribute__((unused)) = true;
- std::list<T> A;
- std::list<T> B;
+ typedef _Tp list_type;
+
+ list_type A;
+ list_type B;
swap_calls = 0;
std::swap(A, B);
VERIFY(1 == swap_calls);
}
// Should use list specialization for swap.
-void test02()
+template<typename _Tp>
+void
+swap12()
{
- bool test __attribute__((unused)) = true;
using namespace std;
- list<T> A;
- list<T> B;
+ bool test __attribute__((unused)) = true;
+ typedef _Tp list_type;
+
+ list_type A;
+ list_type B;
swap_calls = 0;
swap(A, B);
VERIFY(1 == swap_calls);
@@ -60,7 +68,7 @@ template class __gnu_cxx::__mt_alloc<std::_List_node<T> >;
// See c++/13658 for background info.
int main()
{
- test01();
- test02();
+ swap11<std::list<T> >();
+ swap12<std::list<T> >();
return 0;
}
diff --git a/libstdc++-v3/testsuite/23_containers/list/modifiers/swap/2.cc b/libstdc++-v3/testsuite/23_containers/list/modifiers/swap/2.cc
index 5ae95915861..e31c0fb5924 100644
--- a/libstdc++-v3/testsuite/23_containers/list/modifiers/swap/2.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/modifiers/swap/2.cc
@@ -24,14 +24,16 @@
#include <testsuite_allocator.h>
// uneq_allocator as a non-empty allocator.
+template<typename _Tp>
void
-test01()
+swap2()
{
bool test __attribute__((unused)) = true;
using namespace std;
- typedef __gnu_test::uneq_allocator<char> my_alloc;
- typedef list<char, my_alloc> my_list;
+ typedef _Tp list_type;
+ typedef typename list_type::allocator_type allocator_type;
+ typedef typename list_type::size_type size_type;
const char title01[] = "Rivers of sand";
const char title02[] = "Concret PH";
@@ -43,13 +45,13 @@ test01()
const size_t N3 = sizeof(title03);
const size_t N4 = sizeof(title04);
- my_list::size_type size01, size02;
+ size_type size01, size02;
- my_alloc alloc01(1);
+ allocator_type alloc01(1);
- my_list lis01(alloc01);
+ list_type lis01(alloc01);
size01 = lis01.size();
- my_list lis02(alloc01);
+ list_type lis02(alloc01);
size02 = lis02.size();
lis01.swap(lis02);
@@ -58,9 +60,9 @@ test01()
VERIFY( lis02.size() == size01 );
VERIFY( lis02.empty() );
- my_list lis03(alloc01);
+ list_type lis03(alloc01);
size01 = lis03.size();
- my_list lis04(title02, title02 + N2, alloc01);
+ list_type lis04(title02, title02 + N2, alloc01);
size02 = lis04.size();
lis03.swap(lis04);
@@ -69,9 +71,9 @@ test01()
VERIFY( lis04.size() == size01 );
VERIFY( lis04.empty() );
- my_list lis05(title01, title01 + N1, alloc01);
+ list_type lis05(title01, title01 + N1, alloc01);
size01 = lis05.size();
- my_list lis06(title02, title02 + N2, alloc01);
+ list_type lis06(title02, title02 + N2, alloc01);
size02 = lis06.size();
lis05.swap(lis06);
@@ -80,9 +82,9 @@ test01()
VERIFY( lis06.size() == size01 );
VERIFY( equal(lis06.begin(), lis06.end(), title01) );
- my_list lis07(title01, title01 + N1, alloc01);
+ list_type lis07(title01, title01 + N1, alloc01);
size01 = lis07.size();
- my_list lis08(title03, title03 + N3, alloc01);
+ list_type lis08(title03, title03 + N3, alloc01);
size02 = lis08.size();
lis07.swap(lis08);
@@ -91,9 +93,9 @@ test01()
VERIFY( lis08.size() == size01 );
VERIFY( equal(lis08.begin(), lis08.end(), title01) );
- my_list lis09(title03, title03 + N3, alloc01);
+ list_type lis09(title03, title03 + N3, alloc01);
size01 = lis09.size();
- my_list lis10(title04, title04 + N4, alloc01);
+ list_type lis10(title04, title04 + N4, alloc01);
size02 = lis10.size();
lis09.swap(lis10);
@@ -102,9 +104,9 @@ test01()
VERIFY( lis10.size() == size01 );
VERIFY( equal(lis10.begin(), lis10.end(), title03) );
- my_list lis11(title04, title04 + N4, alloc01);
+ list_type lis11(title04, title04 + N4, alloc01);
size01 = lis11.size();
- my_list lis12(title01, title01 + N1, alloc01);
+ list_type lis12(title01, title01 + N1, alloc01);
size02 = lis12.size();
lis11.swap(lis12);
@@ -113,9 +115,9 @@ test01()
VERIFY( lis12.size() == size01 );
VERIFY( equal(lis12.begin(), lis12.end(), title04) );
- my_list lis13(title03, title03 + N3, alloc01);
+ list_type lis13(title03, title03 + N3, alloc01);
size01 = lis13.size();
- my_list lis14(title03, title03 + N3, alloc01);
+ list_type lis14(title03, title03 + N3, alloc01);
size02 = lis14.size();
lis13.swap(lis14);
@@ -127,6 +129,10 @@ test01()
int main()
{
- test01();
+ typedef char value_type;
+ typedef __gnu_test::uneq_allocator<value_type> allocator_type;
+ typedef std::list<value_type, allocator_type> list_type;
+
+ swap2<list_type>();
return 0;
}
diff --git a/libstdc++-v3/testsuite/23_containers/list/modifiers/swap/3.cc b/libstdc++-v3/testsuite/23_containers/list/modifiers/swap/3.cc
index ed7f24a07fe..c0e0f65bf64 100644
--- a/libstdc++-v3/testsuite/23_containers/list/modifiers/swap/3.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/modifiers/swap/3.cc
@@ -24,14 +24,16 @@
#include <testsuite_allocator.h>
// uneq_allocator, two different personalities.
+template<typename _Tp>
void
-test01()
+swap3()
{
bool test __attribute__((unused)) = true;
using namespace std;
- typedef __gnu_test::uneq_allocator<char> my_alloc;
- typedef list<char, my_alloc> my_list;
+ typedef _Tp list_type;
+ typedef typename list_type::allocator_type allocator_type;
+ typedef typename list_type::size_type size_type;
const char title01[] = "Rivers of sand";
const char title02[] = "Concret PH";
@@ -43,15 +45,15 @@ test01()
const size_t N3 = sizeof(title03);
const size_t N4 = sizeof(title04);
- my_list::size_type size01, size02;
+ size_type size01, size02;
- my_alloc alloc01(1), alloc02(2);
+ allocator_type alloc01(1), alloc02(2);
int personality01, personality02;
- my_list lis01(alloc01);
+ list_type lis01(alloc01);
size01 = lis01.size();
personality01 = lis01.get_allocator().get_personality();
- my_list lis02(alloc02);
+ list_type lis02(alloc02);
size02 = lis02.size();
personality02 = lis02.get_allocator().get_personality();
@@ -63,10 +65,10 @@ test01()
VERIFY( lis01.get_allocator().get_personality() == personality02 );
VERIFY( lis02.get_allocator().get_personality() == personality01 );
- my_list lis03(alloc02);
+ list_type lis03(alloc02);
size01 = lis03.size();
personality01 = lis03.get_allocator().get_personality();
- my_list lis04(title02, title02 + N2, alloc01);
+ list_type lis04(title02, title02 + N2, alloc01);
size02 = lis04.size();
personality02 = lis04.get_allocator().get_personality();
@@ -78,10 +80,10 @@ test01()
VERIFY( lis03.get_allocator().get_personality() == personality02 );
VERIFY( lis04.get_allocator().get_personality() == personality01 );
- my_list lis05(title01, title01 + N1, alloc01);
+ list_type lis05(title01, title01 + N1, alloc01);
size01 = lis05.size();
personality01 = lis05.get_allocator().get_personality();
- my_list lis06(title02, title02 + N2, alloc02);
+ list_type lis06(title02, title02 + N2, alloc02);
size02 = lis06.size();
personality02 = lis06.get_allocator().get_personality();
@@ -93,10 +95,10 @@ test01()
VERIFY( lis05.get_allocator().get_personality() == personality02 );
VERIFY( lis06.get_allocator().get_personality() == personality01 );
- my_list lis07(title01, title01 + N1, alloc02);
+ list_type lis07(title01, title01 + N1, alloc02);
size01 = lis07.size();
personality01 = lis07.get_allocator().get_personality();
- my_list lis08(title03, title03 + N3, alloc01);
+ list_type lis08(title03, title03 + N3, alloc01);
size02 = lis08.size();
personality02 = lis08.get_allocator().get_personality();
@@ -108,10 +110,10 @@ test01()
VERIFY( lis07.get_allocator().get_personality() == personality02 );
VERIFY( lis08.get_allocator().get_personality() == personality01 );
- my_list lis09(title03, title03 + N3, alloc01);
+ list_type lis09(title03, title03 + N3, alloc01);
size01 = lis09.size();
personality01 = lis09.get_allocator().get_personality();
- my_list lis10(title04, title04 + N4, alloc02);
+ list_type lis10(title04, title04 + N4, alloc02);
size02 = lis10.size();
personality02 = lis10.get_allocator().get_personality();
@@ -123,10 +125,10 @@ test01()
VERIFY( lis09.get_allocator().get_personality() == personality02 );
VERIFY( lis10.get_allocator().get_personality() == personality01 );
- my_list lis11(title04, title04 + N4, alloc02);
+ list_type lis11(title04, title04 + N4, alloc02);
size01 = lis11.size();
personality01 = lis11.get_allocator().get_personality();
- my_list lis12(title01, title01 + N1, alloc01);
+ list_type lis12(title01, title01 + N1, alloc01);
size02 = lis12.size();
personality02 = lis12.get_allocator().get_personality();
@@ -138,10 +140,10 @@ test01()
VERIFY( lis11.get_allocator().get_personality() == personality02 );
VERIFY( lis12.get_allocator().get_personality() == personality01 );
- my_list lis13(title03, title03 + N3, alloc01);
+ list_type lis13(title03, title03 + N3, alloc01);
size01 = lis13.size();
personality01 = lis13.get_allocator().get_personality();
- my_list lis14(title03, title03 + N3, alloc02);
+ list_type lis14(title03, title03 + N3, alloc02);
size02 = lis14.size();
personality02 = lis14.get_allocator().get_personality();
@@ -156,6 +158,10 @@ test01()
int main()
{
- test01();
+ typedef char value_type;
+ typedef __gnu_test::uneq_allocator<value_type> allocator_type;
+ typedef std::list<value_type, allocator_type> list_type;
+
+ swap3<list_type>();
return 0;
}
diff --git a/libstdc++-v3/testsuite/23_containers/list/moveable.cc b/libstdc++-v3/testsuite/23_containers/list/moveable.cc
index 647e2609400..dc245b1ca00 100644
--- a/libstdc++-v3/testsuite/23_containers/list/moveable.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/moveable.cc
@@ -1,6 +1,6 @@
// { dg-options "-std=gnu++0x" }
-// Copyright (C) 2005, 2007, 2009 Free Software Foundation, Inc.
+// Copyright (C) 2009 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
@@ -17,7 +17,6 @@
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-
// NOTE: This makes use of the fact that we know how moveable
// is implemented on list (via swap). If the implementation changed
// this test may begin to fail.
@@ -26,17 +25,26 @@
#include <utility>
#include <testsuite_hooks.h>
+template<typename _Tp>
+ void
+ test_moveable()
+ {
+ bool test __attribute__((unused)) = true;
+
+ typedef _Tp list_type;
+
+ list_type a,b;
+ a.push_back(1);
+ b = std::move(a);
+ VERIFY( b.size() == 1 && *b.begin() == 1 && a.size() == 0 );
+
+ list_type c(std::move(b));
+ VERIFY( c.size() == 1 && *c.begin() == 1 );
+ VERIFY( b.size() == 0 );
+ }
+
int main()
{
- bool test __attribute__((unused)) = true;
-
- std::list<int> a,b;
- a.push_back(1);
- b = std::move(a);
- VERIFY( b.size() == 1 && *b.begin() == 1 && a.size() == 0 );
-
- std::list<int> c(std::move(b));
- VERIFY( c.size() == 1 && *c.begin() == 1 );
- VERIFY( b.size() == 0 );
+ test_moveable<std::list<int> >();
return 0;
}
diff --git a/libstdc++-v3/testsuite/23_containers/list/operations/1.cc b/libstdc++-v3/testsuite/23_containers/list/operations/1.cc
index 750167c4df4..d44e1c70612 100644
--- a/libstdc++-v3/testsuite/23_containers/list/operations/1.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/operations/1.cc
@@ -20,21 +20,24 @@
#include <list>
#include <testsuite_hooks.h>
-bool test __attribute__((unused)) = true;
-
// splice(p, x) + remove + reverse
+template<typename _Tp>
void
-test01()
+operations01()
{
+ bool test __attribute__((unused)) = true;
+ typedef _Tp list_type;
+ typedef typename list_type::iterator iterator;
+
const int K = 417;
const int A[] = {1, 2, 3, 4, 5};
const int B[] = {K, K, K, K, K};
const std::size_t N = sizeof(A) / sizeof(int);
const std::size_t M = sizeof(B) / sizeof(int);
- std::list<int> list0101(A, A + N);
- std::list<int> list0102(B, B + M);
- std::list<int>::iterator p = list0101.begin();
+ list_type list0101(A, A + N);
+ list_type list0102(B, B + M);
+ iterator p = list0101.begin();
VERIFY(list0101.size() == N);
VERIFY(list0102.size() == M);
@@ -65,9 +68,9 @@ test01()
VERIFY(p == list0101.end());
}
-int main(void)
+int main()
{
- test01();
+ operations01<std::list<int> >();
return 0;
}
diff --git a/libstdc++-v3/testsuite/23_containers/list/operations/2.cc b/libstdc++-v3/testsuite/23_containers/list/operations/2.cc
index e36b08ef414..743b176b38f 100644
--- a/libstdc++-v3/testsuite/23_containers/list/operations/2.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/operations/2.cc
@@ -20,21 +20,24 @@
#include <list>
#include <testsuite_hooks.h>
-bool test __attribute__((unused)) = true;
-
// splice(p, x, i) + remove_if + operator==
+template<typename _Tp>
void
-test02()
+operations02()
{
+ bool test __attribute__((unused)) = true;
+ typedef _Tp list_type;
+ typedef typename list_type::iterator iterator;
+
const int A[] = {1, 2, 3, 4, 5};
const int B[] = {2, 1, 3, 4, 5};
const int C[] = {1, 3, 4, 5, 2};
const int N = sizeof(A) / sizeof(int);
- std::list<int> list0201(A, A + N);
- std::list<int> list0202(A, A + N);
- std::list<int> list0203(B, B + N);
- std::list<int> list0204(C, C + N);
- std::list<int>::iterator i = list0201.begin();
+ list_type list0201(A, A + N);
+ list_type list0202(A, A + N);
+ list_type list0203(B, B + N);
+ list_type list0204(C, C + N);
+ iterator i = list0201.begin();
// result should be unchanged
list0201.splice(list0201.begin(), list0201, i);
@@ -53,6 +56,6 @@ test02()
int main()
{
- test02();
+ operations02<std::list<int> >();
return 0;
}
diff --git a/libstdc++-v3/testsuite/23_containers/list/operations/3.cc b/libstdc++-v3/testsuite/23_containers/list/operations/3.cc
index 0f0999c32eb..83d00133c49 100644
--- a/libstdc++-v3/testsuite/23_containers/list/operations/3.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/operations/3.cc
@@ -20,12 +20,15 @@
#include <list>
#include <testsuite_hooks.h>
-bool test __attribute__((unused)) = true;
-
// splice(p, x, f, l) + sort + merge + unique
+template<typename _Tp>
void
-test03()
+operations03()
{
+ bool test __attribute__((unused)) = true;
+ typedef _Tp list_type;
+ typedef typename list_type::iterator iterator;
+
const int A[] = {103, 203, 603, 303, 403, 503};
const int B[] = {417, 417, 417, 417, 417};
const int E[] = {103, 417, 417, 203, 603, 303, 403, 503};
@@ -38,14 +41,14 @@ test03()
const int Q = sizeof(D) / sizeof(int);
const int R = sizeof(E) / sizeof(int);
- std::list<int> list0301(A, A + N);
- std::list<int> list0302(B, B + M);
- std::list<int> list0303(C, C + P);
- std::list<int> list0304(D, D + Q);
- std::list<int> list0305(E, E + R);
- std::list<int> list0306(F, F + R);
- std::list<int>::iterator p = list0301.begin();
- std::list<int>::iterator q = list0302.begin();
+ list_type list0301(A, A + N);
+ list_type list0302(B, B + M);
+ list_type list0303(C, C + P);
+ list_type list0304(D, D + Q);
+ list_type list0305(E, E + R);
+ list_type list0306(F, F + R);
+ iterator p = list0301.begin();
+ iterator q = list0302.begin();
++p; ++q; ++q;
list0301.splice(p, list0302, list0302.begin(), q);
@@ -67,6 +70,6 @@ test03()
int main(void)
{
- test03();
+ operations03<std::list<int> >();
return 0;
}
diff --git a/libstdc++-v3/testsuite/23_containers/list/operations/4.cc b/libstdc++-v3/testsuite/23_containers/list/operations/4.cc
index 59c047bab7c..37b983a39a2 100644
--- a/libstdc++-v3/testsuite/23_containers/list/operations/4.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/operations/4.cc
@@ -20,10 +20,8 @@
#include <list>
#include <testsuite_hooks.h>
-bool test __attribute__((unused)) = true;
-
-// A comparison predicate to order by rightmost digit. Tracks call counts for
-// performance checks.
+// A comparison predicate to order by rightmost digit. Tracks call
+// counts for performance checks.
struct CompLastLt
{
bool operator()(const int x, const int y)
@@ -48,9 +46,13 @@ int CompLastEq::itsCount;
// sort(pred) + merge(pred) + unique(pred)
// also checks performance requirements
+template<typename _Tp>
void
-test04()
+operations04()
{
+ bool test __attribute__((unused)) = true;
+ typedef _Tp list_type;
+
const int A[] = {1, 2, 3, 4, 5, 6};
const int B[] = {12, 15, 13, 14, 11};
const int C[] = {11, 12, 13, 14, 15};
@@ -59,11 +61,11 @@ test04()
const int M = sizeof(B) / sizeof(int);
const int Q = sizeof(D) / sizeof(int);
- std::list<int> list0401(A, A + N);
- std::list<int> list0402(B, B + M);
- std::list<int> list0403(C, C + M);
- std::list<int> list0404(D, D + Q);
- std::list<int> list0405(A, A + N);
+ list_type list0401(A, A + N);
+ list_type list0402(B, B + M);
+ list_type list0403(C, C + M);
+ list_type list0404(D, D + Q);
+ list_type list0405(A, A + N);
// sort B
CompLastLt lt;
@@ -91,7 +93,7 @@ test04()
int main()
{
- test04();
+ operations04<std::list<int> >();
return 0;
}
diff --git a/libstdc++-v3/testsuite/23_containers/list/operations/5.cc b/libstdc++-v3/testsuite/23_containers/list/operations/5.cc
index 6e9012e0bd9..ae1939c8824 100644
--- a/libstdc++-v3/testsuite/23_containers/list/operations/5.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/operations/5.cc
@@ -25,26 +25,27 @@
#include <testsuite_allocator.h>
// Check the splice (and merge) bits of N1599.
+template<typename _Tp>
void
-test01()
+operations05()
{
bool test __attribute__((unused)) = true;
- typedef __gnu_test::uneq_allocator<int> my_alloc;
- typedef std::list<int, my_alloc> my_list;
+ typedef _Tp list_type;
+ typedef typename list_type::allocator_type allocator_type;
const int data1[] = {1, 2, 3, 4, 5};
const int data2[] = {6, 7, 8, 9, 10};
const size_t N1 = sizeof(data1) / sizeof(int);
const size_t N2 = sizeof(data2) / sizeof(int);
- my_alloc alloc01(1), alloc02(2);
+ allocator_type alloc01(1), alloc02(2);
- my_list l01(data1, data1 + N1, alloc01);
- const my_list l01_ref = l01;
+ list_type l01(data1, data1 + N1, alloc01);
+ const list_type l01_ref = l01;
- my_list l02(data2, data2 + N2, alloc02);
- const my_list l02_ref = l02;
+ list_type l02(data2, data2 + N2, alloc02);
+ const list_type l02_ref = l02;
bool catched = false;
@@ -135,6 +136,10 @@ test01()
int main()
{
- test01();
+ typedef int value_type;
+ typedef __gnu_test::uneq_allocator<value_type> allocator_type;
+ typedef std::list<value_type, allocator_type> list_type;
+
+ operations05<list_type>();
return 0;
}
diff --git a/libstdc++-v3/testsuite/23_containers/list/pthread1.cc b/libstdc++-v3/testsuite/23_containers/list/pthread1.cc
index 63198fab096..fcbb039dce3 100644
--- a/libstdc++-v3/testsuite/23_containers/list/pthread1.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/pthread1.cc
@@ -33,8 +33,6 @@
#include <cstdlib>
#include <pthread.h>
-using namespace std;
-
const int thread_cycles = 10;
const int thread_pairs = 10;
const unsigned max_size = 100;
@@ -42,6 +40,8 @@ const int iters = 10000;
class task_queue
{
+ typedef std::list<int> list_type;
+
public:
task_queue ()
{
@@ -55,14 +55,15 @@ public:
pthread_cond_destroy (&fooCond1);
pthread_cond_destroy (&fooCond2);
}
- list<int> foo;
- pthread_mutex_t fooLock;
- pthread_cond_t fooCond1;
- pthread_cond_t fooCond2;
+
+ list_type foo;
+ pthread_mutex_t fooLock;
+ pthread_cond_t fooCond1;
+ pthread_cond_t fooCond2;
};
void*
-produce (void* t)
+produce(void* t)
{
task_queue& tq = *(static_cast<task_queue*> (t));
int num = 0;
@@ -79,7 +80,7 @@ produce (void* t)
}
void*
-consume (void* t)
+consume(void* t)
{
task_queue& tq = *(static_cast<task_queue*> (t));
int num = 0;
@@ -98,7 +99,7 @@ consume (void* t)
}
int
-main ()
+main()
{
pthread_t prod[thread_pairs];
pthread_t cons[thread_pairs];
diff --git a/libstdc++-v3/testsuite/23_containers/list/pthread5.cc b/libstdc++-v3/testsuite/23_containers/list/pthread5.cc
index 8501e323b1b..57411eef3f0 100644
--- a/libstdc++-v3/testsuite/23_containers/list/pthread5.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/pthread5.cc
@@ -34,8 +34,6 @@
#include <unistd.h> // To test for _POSIX_THREAD_PRIORITY_SCHEDULING
#endif
-using namespace std;
-
#define NTHREADS 8
#define LOOPS 20
@@ -48,19 +46,22 @@ struct tt_t
void*
thread_function (void* arg)
{
+ typedef std::vector<tt_t> vector_type;
+ typedef std::list<std::string*> list_type;
+
int myid __attribute__((unused)) = *(int*) arg;
for (int i = 0; i < LOOPS; i++)
{
- vector<tt_t> myvect1;
+ vector_type myvect1;
for (int j = 0; j < 2000; j++)
{
- vector<tt_t> myvect2;
+ vector_type myvect2;
tt_t v;
v.i = j;
myvect1.push_back (v);
myvect2.push_back (v);
- list<std::string *> mylist;
+ list_type mylist;
std::string string_array[4];
string_array[0] = "toto";
string_array[1] = "titi";
@@ -70,7 +71,7 @@ thread_function (void* arg)
{
if (mylist.size ())
{
- list<std::string *>::iterator aIt;
+ list_type::iterator aIt;
for (aIt = mylist.begin (); aIt != mylist.end (); ++aIt)
{
if ((*aIt) == &(string_array[k]))
diff --git a/libstdc++-v3/testsuite/23_containers/list/requirements/citerators.cc b/libstdc++-v3/testsuite/23_containers/list/requirements/citerators.cc
index 90d6e8c911b..6bcffbb05ee 100644
--- a/libstdc++-v3/testsuite/23_containers/list/requirements/citerators.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/requirements/citerators.cc
@@ -28,7 +28,9 @@ test01()
{
bool test __attribute__((unused)) = true;
- std::list<int> l(7);
+ typedef std::list<int> list_type;
+ list_type l(7);
+
VERIFY( l.cbegin() == l.begin() );
VERIFY( l.cend() == l.end() );
VERIFY( l.crbegin() == l.rbegin() );
diff --git a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/assign_neg.cc b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/assign_neg.cc
index a32840fe859..cd2b2994807 100644
--- a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/assign_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/assign_neg.cc
@@ -18,7 +18,7 @@
// <http://www.gnu.org/licenses/>.
// { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1383 }
+// { dg-error "no matching" "" { target *-*-* } 1379 }
// { dg-excess-errors "" }
#include <list>
@@ -30,6 +30,7 @@ struct A
void f()
{
- std::list<A> l;
+ typedef std::list<A> list_type;
+ list_type l;
l.assign(10, 1);
}
diff --git a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor.cc b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor.cc
index 11e0022e5b5..5c0bf6f72ce 100644
--- a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor.cc
@@ -23,5 +23,6 @@
void f()
{
- std::list<int> l(10, 1);
+ typedef std::list<int> list_type;
+ list_type l(10, 1);
}
diff --git a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_1_neg.cc b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_1_neg.cc
index f8ab970a0dc..cc2b419bd4e 100644
--- a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_1_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_1_neg.cc
@@ -18,12 +18,13 @@
// <http://www.gnu.org/licenses/>.
// { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1352 }
+// { dg-error "no matching" "" { target *-*-* } 1348 }
// { dg-excess-errors "" }
#include <list>
void f()
{
- std::list<std::list<int> > l(10, 1);
+ typedef std::list<std::list<int> > list_type;
+ list_type l(10, 1);
}
diff --git a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_2_neg.cc b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_2_neg.cc
index 56460a2faa5..d650a9ec102 100644
--- a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_2_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_2_neg.cc
@@ -18,7 +18,7 @@
// <http://www.gnu.org/licenses/>.
// { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1352 }
+// { dg-error "no matching" "" { target *-*-* } 1348 }
// { dg-excess-errors "" }
#include <list>
@@ -26,5 +26,6 @@
void f()
{
- std::list<std::list<std::pair<char, char> > > l('a', 'b');
+ typedef std::list<std::list<std::pair<char, char> > > list_type;
+ list_type l('a', 'b');
}
diff --git a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/insert_neg.cc b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/insert_neg.cc
index 9c4aba66d37..ae9e63f704e 100644
--- a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/insert_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/insert_neg.cc
@@ -18,7 +18,7 @@
// <http://www.gnu.org/licenses/>.
// { dg-do compile }
-// { dg-error "no matching" "" { target *-*-* } 1352 }
+// { dg-error "no matching" "" { target *-*-* } 1348 }
// { dg-excess-errors "" }
#include <list>
@@ -30,6 +30,7 @@ struct A
void f()
{
- std::list<A> l;
+ typedef std::list<A> list_type;
+ list_type l;
l.insert(l.begin(), 10, 1);
}
diff --git a/libstdc++-v3/testsuite/23_containers/list/requirements/partial_specialization/1.cc b/libstdc++-v3/testsuite/23_containers/list/requirements/partial_specialization/1.cc
index 13cf83645d7..69d25cf704e 100644
--- a/libstdc++-v3/testsuite/23_containers/list/requirements/partial_specialization/1.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/requirements/partial_specialization/1.cc
@@ -29,5 +29,5 @@ struct user_type {};
namespace std
{
template<typename Allocator>
- class list<user_type, Allocator> {};
+ class list<user_type, Allocator> { };
}
diff --git a/libstdc++-v3/testsuite/23_containers/vector/40192.cc b/libstdc++-v3/testsuite/23_containers/vector/40192.cc
new file mode 100644
index 00000000000..eff88d422bd
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/vector/40192.cc
@@ -0,0 +1,28 @@
+// Copyright (C) 2009 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-do compile }
+
+// libstdc++/40192
+
+#include <vector>
+
+void test01()
+{
+ typedef float float4[4];
+ std::vector<float4> vals;
+}
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 9cf809b63b8..5bff1fec07b 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 *-*-* } 1051 }
+// { dg-error "no matching" "" { target *-*-* } 1047 }
// { dg-excess-errors "" }
#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 42b538599c1..a50f5226c07 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 *-*-* } 991 }
+// { dg-error "no matching" "" { target *-*-* } 987 }
// { dg-excess-errors "" }
#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 5d2b1558cab..a871cec9b56 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 *-*-* } 991 }
+// { dg-error "no matching" "" { target *-*-* } 987 }
// { dg-excess-errors "" }
#include <vector>
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 89b020b588f..d079335f7ae 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 *-*-* } 1092 }
+// { dg-error "no matching" "" { target *-*-* } 1088 }
// { dg-excess-errors "" }
#include <vector>
diff --git a/libstdc++-v3/testsuite/26_numerics/random/discrete_distribution/cons/num_xbound_fun.cc b/libstdc++-v3/testsuite/26_numerics/random/discrete_distribution/cons/num_xbound_fun.cc
index bab3609dbb6..13974837255 100644
--- a/libstdc++-v3/testsuite/26_numerics/random/discrete_distribution/cons/num_xbound_fun.cc
+++ b/libstdc++-v3/testsuite/26_numerics/random/discrete_distribution/cons/num_xbound_fun.cc
@@ -40,7 +40,10 @@ struct cosine_distribution
else if (x - _M_x0 > _M_lambda / 4)
return 0.0;
else
- return std::cos(2 * M_PI * (x - _M_x0) / _M_lambda);
+ {
+ const double pi = 3.14159265358979323846;
+ return std::cos(2 * pi * (x - _M_x0) / _M_lambda);
+ }
}
private:
diff --git a/libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/cons/initlist_fun.cc b/libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/cons/initlist_fun.cc
index 4c9a6e50975..aded49d13da 100644
--- a/libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/cons/initlist_fun.cc
+++ b/libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/cons/initlist_fun.cc
@@ -19,7 +19,8 @@
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-// 26.4.8.5.2 Class template piecewise_constant_distribution [rand.dist.samp.pconst]
+// 26.4.8.5.2 Class template piecewise_constant_distribution
+// [rand.dist.samp.pconst]
// 26.4.2.4 Concept RandomNumberDistribution [rand.concept.dist]
#include <random>
@@ -40,7 +41,10 @@ struct cosine_distribution
else if (x - _M_x0 > _M_lambda / 4)
return 0.0;
else
- return std::cos(2 * M_PI * (x - _M_x0) / _M_lambda);
+ {
+ const double pi = 3.14159265358979323846;
+ return std::cos(2 * pi * (x - _M_x0) / _M_lambda);
+ }
}
private:
diff --git a/libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/cons/num_xbound_fun.cc b/libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/cons/num_xbound_fun.cc
index 3234b080782..bc0f1923711 100644
--- a/libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/cons/num_xbound_fun.cc
+++ b/libstdc++-v3/testsuite/26_numerics/random/piecewise_constant_distribution/cons/num_xbound_fun.cc
@@ -19,7 +19,8 @@
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-// 26.4.8.5.2 Class template piecewise_constant_distribution [rand.dist.samp.pconst]
+// 26.4.8.5.2 Class template piecewise_constant_distribution
+// [rand.dist.samp.pconst]
// 26.4.2.4 Concept RandomNumberDistribution [rand.concept.dist]
#include <random>
@@ -40,7 +41,10 @@ struct cosine_distribution
else if (x - _M_x0 > _M_lambda / 4)
return 0.0;
else
- return std::cos(2 * M_PI * (x - _M_x0) / _M_lambda);
+ {
+ const double pi = 3.14159265358979323846;
+ return std::cos(2 * pi * (x - _M_x0) / _M_lambda);
+ }
}
private:
diff --git a/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/cons/initlist_fun.cc b/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/cons/initlist_fun.cc
index 3f049896983..a00e41e4f27 100644
--- a/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/cons/initlist_fun.cc
+++ b/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/cons/initlist_fun.cc
@@ -19,7 +19,8 @@
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-// 26.4.8.5.3 Class template piecewise_linear_distribution [rand.dist.samp.plinear]
+// 26.4.8.5.3 Class template piecewise_linear_distribution
+// [rand.dist.samp.plinear]
// 26.4.2.4 Concept RandomNumberDistribution [rand.concept.dist]
#include <random>
@@ -40,7 +41,10 @@ struct cosine_distribution
else if (x - _M_x0 > _M_lambda / 4)
return 0.0;
else
- return std::cos(2 * M_PI * (x - _M_x0) / _M_lambda);
+ {
+ const double pi = 3.14159265358979323846;
+ return std::cos(2 * pi * (x - _M_x0) / _M_lambda);
+ }
}
private:
diff --git a/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/cons/num_xbound_fun.cc b/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/cons/num_xbound_fun.cc
index b8b1a023f6c..f9025183b44 100644
--- a/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/cons/num_xbound_fun.cc
+++ b/libstdc++-v3/testsuite/26_numerics/random/piecewise_linear_distribution/cons/num_xbound_fun.cc
@@ -19,7 +19,8 @@
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-// 26.4.8.5.3 Class template piecewise_linear_distribution [rand.dist.samp.plinear]
+// 26.4.8.5.3 Class template piecewise_linear_distribution
+// [rand.dist.samp.plinear]
// 26.4.2.4 Concept RandomNumberDistribution [rand.concept.dist]
#include <random>
@@ -40,7 +41,10 @@ struct cosine_distribution
else if (x - _M_x0 > _M_lambda / 4)
return 0.0;
else
- return std::cos(2 * M_PI * (x - _M_x0) / _M_lambda);
+ {
+ const double pi = 3.14159265358979323846;
+ return std::cos(2 * pi * (x - _M_x0) / _M_lambda);
+ }
}
private:
diff --git a/libstdc++-v3/testsuite/29_atomics/atomic_address/cons/aggregate.cc b/libstdc++-v3/testsuite/29_atomics/atomic_address/cons/aggregate.cc
index 82a2ce354be..8fbcef74e14 100644
--- a/libstdc++-v3/testsuite/29_atomics/atomic_address/cons/aggregate.cc
+++ b/libstdc++-v3/testsuite/29_atomics/atomic_address/cons/aggregate.cc
@@ -1,5 +1,5 @@
// { dg-options "-std=gnu++0x" }
-// { dg-do compile { xfail *-*-* } }
+// { dg-do compile }
// Copyright (C) 2008, 2009 Free Software Foundation, Inc.
//
@@ -23,6 +23,6 @@
int main()
{
- std::atomic_address a = { { NULL } }; // { dg-excess-errors "braces around" }
+ std::atomic_address a = { { NULL } };
return 0;
}
diff --git a/libstdc++-v3/testsuite/30_threads/headers/mutex/types_std_c++0x.cc b/libstdc++-v3/testsuite/30_threads/headers/mutex/types_std_c++0x.cc
index 5ce994f7d12..604569b2641 100644
--- a/libstdc++-v3/testsuite/30_threads/headers/mutex/types_std_c++0x.cc
+++ b/libstdc++-v3/testsuite/30_threads/headers/mutex/types_std_c++0x.cc
@@ -35,7 +35,8 @@ void test01()
using std::try_to_lock;
using std::adopt_lock;
- typedef std::lock_error error_t;
+ typedef std::lock_guard<mutext_t> lock_t;
+ typedef std::unique_lock<rmutext_t> ulock_t;
typedef std::once_flag once_t;
}
diff --git a/libstdc++-v3/testsuite/30_threads/thread/swap/1.cc b/libstdc++-v3/testsuite/30_threads/thread/swap/1.cc
index a30bf5129e9..2a820ad0799 100644
--- a/libstdc++-v3/testsuite/30_threads/thread/swap/1.cc
+++ b/libstdc++-v3/testsuite/30_threads/thread/swap/1.cc
@@ -30,21 +30,48 @@
void f() { }
-int main()
+void test01()
{
bool test __attribute__((unused)) = true;
- try
+ try
{
std::thread t1(f);
std::thread::id t1_id = t1.get_id();
std::thread t2;
- t2.swap(std::move(t1));
+ t2.swap(t1);
VERIFY( t1.get_id() == std::thread::id() );
VERIFY( t2.get_id() == t1_id );
+
+ t2.join();
+ }
+ catch (const std::system_error&)
+ {
+ VERIFY( false );
+ }
+ catch (...)
+ {
+ VERIFY( false );
+ }
+}
+
+void test02()
+{
+ bool test __attribute__((unused)) = true;
+
+ try
+ {
+ std::thread t1(f);
+ std::thread::id t1_id = t1.get_id();
+
+ std::thread t2;
+ std::swap(t1, t2);
+ VERIFY( t1.get_id() == std::thread::id() );
+ VERIFY( t2.get_id() == t1_id );
+
t2.join();
}
catch (const std::system_error&)
@@ -55,6 +82,12 @@ int main()
{
VERIFY( false );
}
+}
+
+int main()
+{
+ test01();
+ test02();
return 0;
}
diff --git a/libstdc++-v3/testsuite/30_threads/thread/swap/2.cc b/libstdc++-v3/testsuite/30_threads/thread/swap/2.cc
deleted file mode 100644
index 62e6651f7d6..00000000000
--- a/libstdc++-v3/testsuite/30_threads/thread/swap/2.cc
+++ /dev/null
@@ -1,112 +0,0 @@
-// { dg-do run { target *-*-freebsd* *-*-netbsd* *-*-linux* *-*-solaris* *-*-cygwin *-*-darwin* alpha*-*-osf* mips-sgi-irix6* } }
-// { dg-options " -std=gnu++0x -pthread" { target *-*-freebsd* *-*-netbsd* *-*-linux* alpha*-*-osf* mips-sgi-irix6* } }
-// { dg-options " -std=gnu++0x -pthreads" { target *-*-solaris* } }
-// { dg-options " -std=gnu++0x " { target *-*-cygwin *-*-darwin* } }
-// { dg-require-cstdint "" }
-// { dg-require-gthreads "" }
-
-// Copyright (C) 2008, 2009 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library. This library is free
-// software; you can redistribute it and/or modify it under the
-// terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 3, or (at your option)
-// any later version.
-
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License along
-// with this library; see the file COPYING3. If not see
-// <http://www.gnu.org/licenses/>.
-
-
-#include <thread>
-#include <system_error>
-#include <bits/move.h> // std::move
-#include <testsuite_hooks.h>
-
-void f() { }
-
-void test01()
-{
- try
- {
- std::thread t1(f);
- std::thread::id t1_id = t1.get_id();
-
- std::thread t2;
- std::swap(t1, t2);
-
- VERIFY( t1.get_id() == std::thread::id() );
- VERIFY( t2.get_id() == t1_id );
-
- t2.join();
- }
- catch (const std::system_error&)
- {
- VERIFY( false );
- }
- catch (...)
- {
- VERIFY( false );
- }
-}
-
-void test02()
-{
- try
- {
- std::thread t1(f);
- std::thread::id t1_id = t1.get_id();
-
- std::thread t2;
- std::swap(std::move(t1), t2);
-
- VERIFY( t2.get_id() == t1_id );
-
- t2.join();
- }
- catch (const std::system_error&)
- {
- VERIFY( false );
- }
- catch (...)
- {
- VERIFY( false );
- }
-}
-
-void test03()
-{
- try
- {
- std::thread t1(f);
- std::thread::id t1_id = t1.get_id();
-
- std::thread t2;
- std::swap(t2, std::move(t1));
-
- VERIFY( t2.get_id() == t1_id );
-
- t2.join();
- }
- catch (const std::system_error&)
- {
- VERIFY( false );
- }
- catch (...)
- {
- VERIFY( false );
- }
-}
-
-int main()
-{
- test01();
- test02();
- test03();
- return 0;
-}
diff --git a/libstdc++-v3/testsuite/ext/array_allocator/check_delete.cc b/libstdc++-v3/testsuite/ext/array_allocator/check_delete.cc
index 6a1214e63fe..9e6f32d13fa 100644
--- a/libstdc++-v3/testsuite/ext/array_allocator/check_delete.cc
+++ b/libstdc++-v3/testsuite/ext/array_allocator/check_delete.cc
@@ -21,40 +21,15 @@
#include <cstdlib>
#include <ext/array_allocator.h>
-#include <testsuite_hooks.h>
-#include <testsuite_allocator.h>
+#include <replacement_memory_operators.h>
-using __gnu_cxx::array_allocator;
-
-void*
-operator new(std::size_t n) throw(std::bad_alloc)
-{
- new_called = true;
- return std::malloc(n);
-}
-
-void
-operator delete(void *v) throw()
-{
- delete_called = true;
- return std::free(v);
-}
-
-// These just help tracking down error messages.
-void test01()
+int main()
{
- bool test __attribute__((unused)) = true;
typedef unsigned int value_type;
typedef std::tr1::array<value_type, 15> array_type;
- typedef array_allocator<value_type, array_type> allocator_type;
+ typedef __gnu_cxx::array_allocator<value_type, array_type> allocator_type;
array_type store;
allocator_type a(&store);
- VERIFY( bool(__gnu_test::check_delete<allocator_type, false>(a)) );
-}
-
-int main()
-{
- test01();
+ __gnu_test::check_delete<allocator_type, false>(a);
return 0;
}
-
diff --git a/libstdc++-v3/testsuite/ext/array_allocator/check_new.cc b/libstdc++-v3/testsuite/ext/array_allocator/check_new.cc
index ea75ee75f71..2d51a025064 100644
--- a/libstdc++-v3/testsuite/ext/array_allocator/check_new.cc
+++ b/libstdc++-v3/testsuite/ext/array_allocator/check_new.cc
@@ -21,40 +21,15 @@
#include <cstdlib>
#include <ext/array_allocator.h>
-#include <testsuite_hooks.h>
-#include <testsuite_allocator.h>
+#include <replacement_memory_operators.h>
-using __gnu_cxx::array_allocator;
-
-void*
-operator new(std::size_t n) throw(std::bad_alloc)
-{
- new_called = true;
- return std::malloc(n);
-}
-
-void
-operator delete(void *v) throw()
-{
- delete_called = true;
- return std::free(v);
-}
-
-// These just help tracking down error messages.
-void test01()
+int main()
{
- bool test __attribute__((unused)) = true;
typedef unsigned int value_type;
typedef std::tr1::array<value_type, 15> array_type;
- typedef array_allocator<value_type, array_type> allocator_type;
+ typedef __gnu_cxx::array_allocator<value_type, array_type> allocator_type;
array_type store;
allocator_type a(&store);
- VERIFY( bool(__gnu_test::check_new<allocator_type, false>(a)) );
-}
-
-int main()
-{
- test01();
+ __gnu_test::check_new<allocator_type, false>(a);
return 0;
}
-
diff --git a/libstdc++-v3/testsuite/ext/bitmap_allocator/check_delete.cc b/libstdc++-v3/testsuite/ext/bitmap_allocator/check_delete.cc
index 9cff3851307..a82bcc7f948 100644
--- a/libstdc++-v3/testsuite/ext/bitmap_allocator/check_delete.cc
+++ b/libstdc++-v3/testsuite/ext/bitmap_allocator/check_delete.cc
@@ -19,35 +19,11 @@
#include <cstdlib>
#include <ext/bitmap_allocator.h>
-#include <testsuite_hooks.h>
-#include <testsuite_allocator.h>
-
-using __gnu_cxx::bitmap_allocator;
-
-void*
-operator new(std::size_t n) throw(std::bad_alloc)
-{
- new_called = true;
- return std::malloc(n);
-}
-
-void
-operator delete(void *v) throw()
-{
- delete_called = true;
- return std::free(v);
-}
-
-// These just help tracking down error messages.
-void test01()
-{
- bool test __attribute__((unused)) = true;
- typedef bitmap_allocator<unsigned int> allocator_type;
- VERIFY( bool(__gnu_test::check_delete<allocator_type, true>()) );
-}
+#include <replacement_memory_operators.h>
int main()
-{
- test01();
+{
+ typedef __gnu_cxx::bitmap_allocator<unsigned int> allocator_type;
+ __gnu_test::check_delete<allocator_type, true>();
return 0;
}
diff --git a/libstdc++-v3/testsuite/ext/bitmap_allocator/check_new.cc b/libstdc++-v3/testsuite/ext/bitmap_allocator/check_new.cc
index 24ee3f08b0c..205fa3a1786 100644
--- a/libstdc++-v3/testsuite/ext/bitmap_allocator/check_new.cc
+++ b/libstdc++-v3/testsuite/ext/bitmap_allocator/check_new.cc
@@ -19,35 +19,11 @@
#include <cstdlib>
#include <ext/bitmap_allocator.h>
-#include <testsuite_hooks.h>
-#include <testsuite_allocator.h>
-
-using __gnu_cxx::bitmap_allocator;
-
-void*
-operator new(std::size_t n) throw(std::bad_alloc)
-{
- new_called = true;
- return std::malloc(n);
-}
-
-void
-operator delete(void *v) throw()
-{
- delete_called = true;
- return std::free(v);
-}
-
-// These just help tracking down error messages.
-void test01()
-{
- bool test __attribute__((unused)) = true;
- typedef bitmap_allocator<unsigned int> allocator_type;
- VERIFY( bool(__gnu_test::check_new<allocator_type, true>()) );
-}
+#include <replacement_memory_operators.h>
int main()
-{
- test01();
+{
+ typedef __gnu_cxx::bitmap_allocator<unsigned int> allocator_type;
+ __gnu_test::check_new<allocator_type, true>();
return 0;
}
diff --git a/libstdc++-v3/testsuite/ext/debug_allocator/check_delete.cc b/libstdc++-v3/testsuite/ext/debug_allocator/check_delete.cc
index 04f0997cc34..5b9d06142b6 100644
--- a/libstdc++-v3/testsuite/ext/debug_allocator/check_delete.cc
+++ b/libstdc++-v3/testsuite/ext/debug_allocator/check_delete.cc
@@ -22,37 +22,12 @@
#include <cstdlib>
#include <ext/debug_allocator.h>
#include <ext/malloc_allocator.h>
-#include <testsuite_hooks.h>
-#include <testsuite_allocator.h>
+#include <replacement_memory_operators.h>
-using __gnu_cxx::malloc_allocator;
-using __gnu_cxx::debug_allocator;
-
-void*
-operator new(std::size_t n) throw(std::bad_alloc)
-{
- new_called = true;
- return std::malloc(n);
-}
-
-void
-operator delete(void *v) throw()
-{
- delete_called = true;
- return std::free(v);
-}
-
-// These just help tracking down error messages.
-void test01()
+int main()
{
- bool test __attribute__((unused)) = true;
+ using namespace __gnu_cxx;
typedef debug_allocator<malloc_allocator<unsigned int> > allocator_type;
- VERIFY( bool(__gnu_test::check_delete<allocator_type, false>()) );
-}
-
-int main()
-{
- test01();
+ __gnu_test::check_delete<allocator_type, false>();
return 0;
}
-
diff --git a/libstdc++-v3/testsuite/ext/debug_allocator/check_new.cc b/libstdc++-v3/testsuite/ext/debug_allocator/check_new.cc
index 9169637902a..105bf288912 100644
--- a/libstdc++-v3/testsuite/ext/debug_allocator/check_new.cc
+++ b/libstdc++-v3/testsuite/ext/debug_allocator/check_new.cc
@@ -22,37 +22,12 @@
#include <cstdlib>
#include <ext/debug_allocator.h>
#include <ext/malloc_allocator.h>
-#include <testsuite_hooks.h>
-#include <testsuite_allocator.h>
+#include <replacement_memory_operators.h>
-using __gnu_cxx::malloc_allocator;
-using __gnu_cxx::debug_allocator;
-
-void*
-operator new(std::size_t n) throw(std::bad_alloc)
-{
- new_called = true;
- return std::malloc(n);
-}
-
-void
-operator delete(void *v) throw()
-{
- delete_called = true;
- return std::free(v);
-}
-
-// These just help tracking down error messages.
-void test01()
+int main()
{
- bool test __attribute__((unused)) = true;
+ using namespace __gnu_cxx;
typedef debug_allocator<malloc_allocator<unsigned int> > allocator_type;
- VERIFY( bool(__gnu_test::check_new<allocator_type, false>()) );
-}
-
-int main()
-{
- test01();
+ __gnu_test::check_new<allocator_type, false>();
return 0;
}
-
diff --git a/libstdc++-v3/testsuite/ext/malloc_allocator/check_delete.cc b/libstdc++-v3/testsuite/ext/malloc_allocator/check_delete.cc
index 2b9f8bcf861..2ed8d0454c0 100644
--- a/libstdc++-v3/testsuite/ext/malloc_allocator/check_delete.cc
+++ b/libstdc++-v3/testsuite/ext/malloc_allocator/check_delete.cc
@@ -21,36 +21,11 @@
#include <cstdlib>
#include <ext/malloc_allocator.h>
-#include <testsuite_hooks.h>
-#include <testsuite_allocator.h>
-
-using __gnu_cxx::malloc_allocator;
-
-void*
-operator new(std::size_t n) throw(std::bad_alloc)
-{
- new_called = true;
- return std::malloc(n);
-}
-
-void
-operator delete(void *v) throw()
-{
- delete_called = true;
- return std::free(v);
-}
-
-// These just help tracking down error messages.
-void test01()
-{
- bool test __attribute__((unused)) = true;
- typedef malloc_allocator<unsigned int> allocator_type;
- VERIFY( bool(__gnu_test::check_delete<allocator_type, false>()) );
-}
+#include <replacement_memory_operators.h>
int main()
-{
- test01();
+{
+ typedef __gnu_cxx::malloc_allocator<unsigned int> allocator_type;
+ __gnu_test::check_delete<allocator_type, false>();
return 0;
}
-
diff --git a/libstdc++-v3/testsuite/ext/malloc_allocator/check_new.cc b/libstdc++-v3/testsuite/ext/malloc_allocator/check_new.cc
index 51acf697ecb..fac139f2b0c 100644
--- a/libstdc++-v3/testsuite/ext/malloc_allocator/check_new.cc
+++ b/libstdc++-v3/testsuite/ext/malloc_allocator/check_new.cc
@@ -21,36 +21,11 @@
#include <cstdlib>
#include <ext/malloc_allocator.h>
-#include <testsuite_hooks.h>
-#include <testsuite_allocator.h>
-
-using __gnu_cxx::malloc_allocator;
-
-void*
-operator new(std::size_t n) throw(std::bad_alloc)
-{
- new_called = true;
- return std::malloc(n);
-}
-
-void
-operator delete(void *v) throw()
-{
- delete_called = true;
- return std::free(v);
-}
-
-// These just help tracking down error messages.
-void test01()
-{
- bool test __attribute__((unused)) = true;
- typedef malloc_allocator<unsigned int> allocator_type;
- VERIFY( bool(__gnu_test::check_new<allocator_type, false>()) );
-}
+#include <replacement_memory_operators.h>
int main()
-{
- test01();
+{
+ typedef __gnu_cxx::malloc_allocator<unsigned int> allocator_type;
+ __gnu_test::check_new<allocator_type, false>();
return 0;
}
-
diff --git a/libstdc++-v3/testsuite/ext/malloc_allocator/deallocate_global.cc b/libstdc++-v3/testsuite/ext/malloc_allocator/deallocate_global.cc
index 2d1ded83d3b..67041f5483f 100644
--- a/libstdc++-v3/testsuite/ext/malloc_allocator/deallocate_global.cc
+++ b/libstdc++-v3/testsuite/ext/malloc_allocator/deallocate_global.cc
@@ -17,56 +17,15 @@
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-// 20.4.1.1 allocator members
-
#include <string>
#include <stdexcept>
-#include <cstdio>
#include <ext/malloc_allocator.h>
-#include <testsuite_hooks.h>
-
-static size_t count;
-
-struct count_check
-{
- count_check() {}
- ~count_check()
- {
- if (count != 0)
- throw std::runtime_error("count isn't zero");
- }
-};
-
-static count_check check;
-
-void* operator new(size_t size) throw(std::bad_alloc)
-{
- printf("operator new is called \n");
- void* p = malloc(size);
- if (p == NULL)
- throw std::bad_alloc();
- count++;
- return p;
-}
-
-void operator delete(void* p) throw()
-{
- printf("operator delete is called \n");
- if (p == NULL)
- return;
- count--;
- if (count == 0)
- printf("All memory released \n");
- else
- printf("%lu allocations to be released \n",
- static_cast<unsigned long>(count));
- free(p);
-}
+#include <replacement_memory_operators.h>
typedef char char_t;
typedef std::char_traits<char_t> traits_t;
typedef __gnu_cxx::malloc_allocator<char_t> allocator_t;
-typedef std::basic_string<char_t, traits_t, allocator_t> string_t;
+typedef std::basic_string<char_t, traits_t, allocator_t> string_t;
string_t s("bayou bend");
diff --git a/libstdc++-v3/testsuite/ext/malloc_allocator/deallocate_local.cc b/libstdc++-v3/testsuite/ext/malloc_allocator/deallocate_local.cc
index f9cd80d2375..76ae1995f55 100644
--- a/libstdc++-v3/testsuite/ext/malloc_allocator/deallocate_local.cc
+++ b/libstdc++-v3/testsuite/ext/malloc_allocator/deallocate_local.cc
@@ -1,5 +1,5 @@
//
-// Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009
+// Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@@ -17,51 +17,23 @@
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-// 20.4.1.1 allocator members
-
#include <string>
-#include <cstdio>
#include <ext/malloc_allocator.h>
-#include <testsuite_hooks.h>
-
-static size_t alloc_cnt;
-
-void* operator new(size_t size) throw(std::bad_alloc)
-{
- printf("operator new is called \n");
- void* p = malloc(size);
- if (p == NULL)
- throw std::bad_alloc();
- alloc_cnt++;
- return p;
-}
-
-void operator delete(void* p) throw()
-{
- printf("operator delete is called \n");
- if (p == NULL)
- return;
- alloc_cnt--;
- if (alloc_cnt == 0)
- printf("All memory released \n");
- else
- printf("%lu allocations to be released \n",
- static_cast<unsigned long>(alloc_cnt));
- free(p);
-}
+#include <replacement_memory_operators.h>
typedef char char_t;
typedef std::char_traits<char_t> traits_t;
typedef __gnu_cxx::malloc_allocator<char_t> allocator_t;
-typedef std::basic_string<char_t, traits_t, allocator_t> string_t;
+typedef std::basic_string<char_t, traits_t, allocator_t> string_t;
int main()
{
- bool test __attribute__((unused)) = true;
{
string_t s;
s += "bayou bend";
}
- VERIFY( alloc_cnt == 0 );
+
+ if (__gnu_test::counter::count() != 0)
+ throw std::runtime_error("count not zero");
return 0;
}
diff --git a/libstdc++-v3/testsuite/ext/mt_allocator/check_delete.cc b/libstdc++-v3/testsuite/ext/mt_allocator/check_delete.cc
index 470b66f5cf6..374c567060a 100644
--- a/libstdc++-v3/testsuite/ext/mt_allocator/check_delete.cc
+++ b/libstdc++-v3/testsuite/ext/mt_allocator/check_delete.cc
@@ -21,34 +21,11 @@
#include <cstdlib>
#include <ext/mt_allocator.h>
-#include <testsuite_hooks.h>
-#include <testsuite_allocator.h>
-
-using __gnu_cxx::__mt_alloc;
-
-void*
-operator new(std::size_t n) throw(std::bad_alloc)
-{
- new_called = true;
- return std::malloc(n);
-}
-
-void
-operator delete(void* v) throw()
-{
- delete_called = true;
- return std::free(v);
-}
-
-void test01()
-{
- bool test __attribute__((unused)) = true;
- typedef __mt_alloc<unsigned int> allocator_type;
- VERIFY( bool(__gnu_test::check_delete<allocator_type, false>()) );
-}
+#include <replacement_memory_operators.h>
int main()
-{
- test01();
+{
+ typedef __gnu_cxx::__mt_alloc<unsigned int> allocator_type;
+ __gnu_test::check_delete<allocator_type, false>();
return 0;
}
diff --git a/libstdc++-v3/testsuite/ext/mt_allocator/check_new.cc b/libstdc++-v3/testsuite/ext/mt_allocator/check_new.cc
index 171a2073f3c..52793264063 100644
--- a/libstdc++-v3/testsuite/ext/mt_allocator/check_new.cc
+++ b/libstdc++-v3/testsuite/ext/mt_allocator/check_new.cc
@@ -21,35 +21,12 @@
#include <cstdlib>
#include <ext/mt_allocator.h>
-#include <testsuite_hooks.h>
-#include <testsuite_allocator.h>
+#include <replacement_memory_operators.h>
-using __gnu_cxx::__mt_alloc;
-
-void*
-operator new(std::size_t n) throw(std::bad_alloc)
-{
- new_called = true;
- return std::malloc(n);
-}
-
-void
-operator delete(void* v) throw()
-{
- delete_called = true;
- return std::free(v);
-}
-
-void test01()
+int main()
{
// Uses new but delete only optionally.
- bool test __attribute__((unused)) = true;
- typedef __mt_alloc<unsigned int> allocator_type;
- VERIFY( bool(__gnu_test::check_new<allocator_type, true>()) );
-}
-
-int main()
-{
- test01();
+ typedef __gnu_cxx::__mt_alloc<unsigned int> allocator_type;
+ __gnu_test::check_new<allocator_type, true>();
return 0;
}
diff --git a/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_global-2.cc b/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_global-2.cc
index a75f38a0724..fcc5006bd3c 100644
--- a/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_global-2.cc
+++ b/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_global-2.cc
@@ -24,43 +24,7 @@
#include <stdexcept>
#include <cstdio>
#include <ext/mt_allocator.h>
-
-static size_t count;
-
-struct count_check
-{
- count_check() { }
- ~count_check()
- {
- // NB: __mt_allocator doesn't clean itself up. Thus, this will not
- // be zero.
- if (count != 0)
- {
- //throw std::runtime_error("allocation/deallocation count isn't zero");
- printf("allocation/deallocation count is %zu \n", count);
- }
- }
-};
-
-static count_check check;
-
-void* operator new(size_t size) throw(std::bad_alloc)
-{
- printf("operator new is called \n");
- void* p = malloc(size);
- if (p == NULL)
- throw std::bad_alloc();
- count++;
- return p;
-}
-
-void operator delete(void* p) throw()
-{
- printf("operator delete is called \n");
- if (p == NULL)
- return;
- count--;
-}
+#include <replacement_memory_operators.h>
typedef std::string value_type;
using __gnu_cxx::__pool;
@@ -74,6 +38,9 @@ list_type l;
int main()
{
+ // NB: __mt_allocator doesn't clean itself up. Thus, the count will
+ // not be zero.
+ __gnu_test::counter::exceptions(false);
l.push_back("bayou bend");
return 0;
}
diff --git a/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_global-4.cc b/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_global-4.cc
index bc9c2c7d477..cafbffb3494 100644
--- a/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_global-4.cc
+++ b/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_global-4.cc
@@ -24,43 +24,7 @@
#include <stdexcept>
#include <cstdio>
#include <ext/mt_allocator.h>
-
-static size_t count;
-
-struct count_check
-{
- count_check() { }
- ~count_check()
- {
- // NB: __mt_allocator doesn't clean itself up. Thus, this will not
- // be zero.
- if (count != 0)
- {
- //throw std::runtime_error("allocation/deallocation count isn't zero");
- printf("allocation/deallocation count is %zu \n", count);
- }
- }
-};
-
-static count_check check;
-
-void* operator new(size_t size) throw(std::bad_alloc)
-{
- printf("operator new is called \n");
- void* p = malloc(size);
- if (p == NULL)
- throw std::bad_alloc();
- count++;
- return p;
-}
-
-void operator delete(void* p) throw()
-{
- printf("operator delete is called \n");
- if (p == NULL)
- return;
- count--;
-}
+#include <replacement_memory_operators.h>
typedef std::string value_t;
using __gnu_cxx::__pool;
@@ -74,6 +38,9 @@ list_type l;
int main()
{
+ // NB: __mt_allocator doesn't clean itself up. Thus, the count will
+ // not be zero.
+ __gnu_test::counter::exceptions(false);
l.push_back("bayou bend");
return 0;
}
diff --git a/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_global_thread-1.cc b/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_global_thread-1.cc
index 6881c9f3d1a..f61cd38b790 100644
--- a/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_global_thread-1.cc
+++ b/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_global_thread-1.cc
@@ -24,43 +24,7 @@
#include <stdexcept>
#include <cstdio>
#include <ext/mt_allocator.h>
-
-static size_t count;
-
-struct count_check
-{
- count_check() { }
- ~count_check()
- {
- // NB: __mt_allocator doesn't clean itself up. Thus, this will not
- // be zero.
- if (count != 0)
- {
- //throw std::runtime_error("allocation/deallocation count isn't zero");
- printf("allocation/deallocation count is %zu \n", count);
- }
- }
-};
-
-static count_check check;
-
-void* operator new(size_t size) throw(std::bad_alloc)
-{
- printf("operator new is called \n");
- void* p = malloc(size);
- if (p == NULL)
- throw std::bad_alloc();
- count++;
- return p;
-}
-
-void operator delete(void* p) throw()
-{
- printf("operator delete is called \n");
- if (p == NULL)
- return;
- count--;
-}
+#include <replacement_memory_operators.h>
typedef std::string value_type;
using __gnu_cxx::__pool;
@@ -74,6 +38,9 @@ list_type l;
int main()
{
+ // NB: __mt_allocator doesn't clean itself up. Thus, the count will
+ // not be zero.
+ __gnu_test::counter::exceptions(false);
l.push_back("bayou bend");
return 0;
}
diff --git a/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_global_thread-3.cc b/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_global_thread-3.cc
index 2724d36392f..62074f0a426 100644
--- a/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_global_thread-3.cc
+++ b/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_global_thread-3.cc
@@ -24,43 +24,7 @@
#include <stdexcept>
#include <cstdio>
#include <ext/mt_allocator.h>
-
-static size_t count;
-
-struct count_check
-{
- count_check() { }
- ~count_check()
- {
- // NB: __mt_allocator doesn't clean itself up. Thus, this will not
- // be zero.
- if (count != 0)
- {
- //throw std::runtime_error("allocation/deallocation count isn't zero");
- printf("allocation/deallocation count is %zu \n", count);
- }
- }
-};
-
-static count_check check;
-
-void* operator new(size_t size) throw(std::bad_alloc)
-{
- printf("operator new is called \n");
- void* p = malloc(size);
- if (p == NULL)
- throw std::bad_alloc();
- count++;
- return p;
-}
-
-void operator delete(void* p) throw()
-{
- printf("operator delete is called \n");
- if (p == NULL)
- return;
- count--;
-}
+#include <replacement_memory_operators.h>
typedef std::string value_type;
using __gnu_cxx::__pool;
@@ -74,6 +38,9 @@ list_type l;
int main()
{
+ // NB: __mt_allocator doesn't clean itself up. Thus, the count will
+ // not be zero.
+ __gnu_test::counter::exceptions(false);
l.push_back("bayou bend");
return 0;
}
diff --git a/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local-2.cc b/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local-2.cc
index eec6dea8c1b..9ccebd57ed0 100644
--- a/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local-2.cc
+++ b/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local-2.cc
@@ -23,43 +23,7 @@
#include <stdexcept>
#include <cstdio>
#include <ext/mt_allocator.h>
-
-static size_t count;
-
-struct count_check
-{
- count_check() { }
- ~count_check()
- {
- // NB: __mt_allocator doesn't clean itself up. Thus, this will not
- // be zero.
- if (count != 0)
- {
- //throw std::runtime_error("allocation/deallocation count isn't zero");
- printf("allocation/deallocation count is %zu \n", count);
- }
- }
-};
-
-static count_check check;
-
-void* operator new(size_t size) throw(std::bad_alloc)
-{
- printf("operator new is called \n");
- void* p = malloc(size);
- if (p == NULL)
- throw std::bad_alloc();
- count++;
- return p;
-}
-
-void operator delete(void* p) throw()
-{
- printf("operator delete is called \n");
- if (p == NULL)
- return;
- count--;
-}
+#include <replacement_memory_operators.h>
typedef char value_type;
typedef std::char_traits<value_type> traits_type;
@@ -70,6 +34,9 @@ typedef std::basic_string<value_type, traits_type, allocator_type> string_type;
int main()
{
+ // NB: __mt_allocator doesn't clean itself up. Thus, the count will
+ // not be zero.
+ __gnu_test::counter::exceptions(false);
string_type s;
s += "bayou bend";
return 0;
diff --git a/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local-4.cc b/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local-4.cc
index 793f6406164..9265a15a98b 100644
--- a/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local-4.cc
+++ b/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local-4.cc
@@ -23,43 +23,7 @@
#include <stdexcept>
#include <cstdio>
#include <ext/mt_allocator.h>
-
-static size_t count;
-
-struct count_check
-{
- count_check() { }
- ~count_check()
- {
- // NB: __mt_allocator doesn't clean itself up. Thus, this will not
- // be zero.
- if (count != 0)
- {
- printf("allocation/deallocation count is %zu \n", count);
- //throw std::runtime_error("allocation/deallocation count isn't zero");
- }
- }
-};
-
-static count_check check;
-
-void* operator new(size_t size) throw(std::bad_alloc)
-{
- printf("operator new is called \n");
- void* p = malloc(size);
- if (p == NULL)
- throw std::bad_alloc();
- count++;
- return p;
-}
-
-void operator delete(void* p) throw()
-{
- printf("operator delete is called \n");
- if (p == NULL)
- return;
- count--;
-}
+#include <replacement_memory_operators.h>
typedef char value_type;
typedef std::char_traits<value_type> traits_type;
@@ -71,6 +35,9 @@ typedef std::basic_string<value_type, traits_type, allocator_type> string_type;
int main()
{
+ // NB: __mt_allocator doesn't clean itself up. Thus, the count will
+ // not be zero.
+ __gnu_test::counter::exceptions(false);
string_type s;
s += "bayou bend";
return 0;
diff --git a/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local-6.cc b/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local-6.cc
index fd1da97a53b..01755713885 100644
--- a/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local-6.cc
+++ b/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local-6.cc
@@ -24,42 +24,7 @@
#include <stdexcept>
#include <cstdio>
#include <ext/mt_allocator.h>
-
-static size_t count;
-
-struct count_check
-{
- count_check() { }
- ~count_check()
- {
- // NB: Using a pool that attempts to clean up resource use.
- if (count != 0)
- {
- printf("allocation/deallocation count is %zu \n", count);
- throw std::runtime_error("allocation/deallocation count isn't zero");
- }
- }
-};
-
-static count_check check;
-
-void* operator new(size_t size) throw(std::bad_alloc)
-{
- printf("operator new is called \n");
- void* p = malloc(size);
- if (p == NULL)
- throw std::bad_alloc();
- count++;
- return p;
-}
-
-void operator delete(void* p) throw()
-{
- printf("operator delete is called \n");
- if (p == NULL)
- return;
- count--;
-}
+#include <replacement_memory_operators.h>
template<bool _Thread>
struct cleanup_pool : public __gnu_cxx::__pool<false>
@@ -81,6 +46,9 @@ typedef std::basic_string<value_type, traits_type, allocator_type> string_type;
int main()
{
+ // NB: __mt_allocator doesn't clean itself up. Thus, the count will
+ // not be zero.
+ __gnu_test::counter::exceptions(false);
string_type s;
s += "bayou bend";
return 0;
diff --git a/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local-8.cc b/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local-8.cc
index 1574e8cb473..34005e4b091 100644
--- a/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local-8.cc
+++ b/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local-8.cc
@@ -24,42 +24,7 @@
#include <stdexcept>
#include <cstdio>
#include <ext/mt_allocator.h>
-
-static size_t count;
-
-struct count_check
-{
- count_check() { }
- ~count_check()
- {
- // NB: Using a pool that attempts to clean up resource use.
- if (count != 0)
- {
- printf("allocation/deallocation count is %zu \n", count);
- throw std::runtime_error("allocation/deallocation count isn't zero");
- }
- }
-};
-
-static count_check check;
-
-void* operator new(size_t size) throw(std::bad_alloc)
-{
- printf("operator new is called \n");
- void* p = malloc(size);
- if (p == NULL)
- throw std::bad_alloc();
- count++;
- return p;
-}
-
-void operator delete(void* p) throw()
-{
- printf("operator delete is called \n");
- if (p == NULL)
- return;
- count--;
-}
+#include <replacement_memory_operators.h>
template<bool _Thread>
struct cleanup_pool : public __gnu_cxx::__pool<false>
@@ -82,6 +47,9 @@ typedef std::basic_string<value_type, traits_type, allocator_type> string_type;
int main()
{
+ // NB: __mt_allocator doesn't clean itself up. Thus, the count will
+ // not be zero.
+ __gnu_test::counter::exceptions(false);
string_type s;
s += "bayou bend";
return 0;
diff --git a/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local_thread-1.cc b/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local_thread-1.cc
index 399d57686f1..012a7585acf 100644
--- a/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local_thread-1.cc
+++ b/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local_thread-1.cc
@@ -23,43 +23,7 @@
#include <stdexcept>
#include <cstdio>
#include <ext/mt_allocator.h>
-
-static size_t count;
-
-struct count_check
-{
- count_check() { }
- ~count_check()
- {
- // NB: __mt_allocator doesn't clean itself up. Thus, this will not
- // be zero.
- if (count != 0)
- {
- //throw std::runtime_error("allocation/deallocation count isn't zero");
- printf("allocation/deallocation count is %zu \n", count);
- }
- }
-};
-
-static count_check check;
-
-void* operator new(size_t size) throw(std::bad_alloc)
-{
- printf("operator new is called \n");
- void* p = malloc(size);
- if (p == NULL)
- throw std::bad_alloc();
- count++;
- return p;
-}
-
-void operator delete(void* p) throw()
-{
- printf("operator delete is called \n");
- if (p == NULL)
- return;
- count--;
-}
+#include <replacement_memory_operators.h>
typedef char value_type;
typedef std::char_traits<value_type> traits_type;
@@ -70,6 +34,9 @@ typedef std::basic_string<value_type, traits_type, allocator_type> string_type;
int main()
{
+ // NB: __mt_allocator doesn't clean itself up. Thus, the count will
+ // not be zero.
+ __gnu_test::counter::exceptions(false);
string_type s;
s += "bayou bend";
return 0;
diff --git a/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local_thread-3.cc b/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local_thread-3.cc
index 38977c569dd..0a9fde02b12 100644
--- a/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local_thread-3.cc
+++ b/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local_thread-3.cc
@@ -23,43 +23,7 @@
#include <stdexcept>
#include <cstdio>
#include <ext/mt_allocator.h>
-
-static size_t count;
-
-struct count_check
-{
- count_check() { }
- ~count_check()
- {
- // NB: __mt_allocator doesn't clean itself up. Thus, this will not
- // be zero.
- if (count != 0)
- {
- //throw std::runtime_error("allocation/deallocation count isn't zero");
- printf("allocation/deallocation count is %zu \n", count);
- }
- }
-};
-
-static count_check check;
-
-void* operator new(size_t size) throw(std::bad_alloc)
-{
- printf("operator new is called \n");
- void* p = malloc(size);
- if (p == NULL)
- throw std::bad_alloc();
- count++;
- return p;
-}
-
-void operator delete(void* p) throw()
-{
- printf("operator delete is called \n");
- if (p == NULL)
- return;
- count--;
-}
+#include <replacement_memory_operators.h>
typedef char value_type;
typedef std::char_traits<value_type> traits_type;
@@ -71,6 +35,9 @@ typedef std::basic_string<value_type, traits_type, allocator_type> string_type;
int main()
{
+ // NB: __mt_allocator doesn't clean itself up. Thus, the count will
+ // not be zero.
+ __gnu_test::counter::exceptions(false);
string_type s;
s += "bayou bend";
return 0;
diff --git a/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local_thread-5.cc b/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local_thread-5.cc
index 49701c09bbc..a812aecf26c 100644
--- a/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local_thread-5.cc
+++ b/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local_thread-5.cc
@@ -24,42 +24,7 @@
#include <stdexcept>
#include <cstdio>
#include <ext/mt_allocator.h>
-
-static size_t count;
-
-struct count_check
-{
- count_check() { }
- ~count_check()
- {
- // NB: Using a pool that attempts to clean up resource use.
- if (count != 0)
- {
- printf("allocation/deallocation count is %zu \n", count);
- throw std::runtime_error("allocation/deallocation count isn't zero");
- }
- }
-};
-
-static count_check check;
-
-void* operator new(size_t size) throw(std::bad_alloc)
-{
- printf("operator new is called \n");
- void* p = malloc(size);
- if (p == NULL)
- throw std::bad_alloc();
- count++;
- return p;
-}
-
-void operator delete(void* p) throw()
-{
- printf("operator delete is called \n");
- if (p == NULL)
- return;
- count--;
-}
+#include <replacement_memory_operators.h>
template<bool _Thread>
struct cleanup_pool : public __gnu_cxx::__pool<true>
@@ -72,7 +37,6 @@ template<bool _Thread>
~cleanup_pool() throw() { this->_M_destroy(); }
};
-
typedef char value_type;
typedef std::char_traits<value_type> traits_type;
typedef __gnu_cxx::__common_pool_policy<cleanup_pool, true> policy_type;
@@ -81,6 +45,9 @@ typedef std::basic_string<value_type, traits_type, allocator_type> string_type;
int main()
{
+ // NB: __mt_allocator doesn't clean itself up. Thus, the count will
+ // not be zero.
+ __gnu_test::counter::exceptions(false);
string_type s;
s += "bayou bend";
return 0;
diff --git a/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local_thread-7.cc b/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local_thread-7.cc
index 5bdfd0db8bb..ac8426ee9fc 100644
--- a/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local_thread-7.cc
+++ b/libstdc++-v3/testsuite/ext/mt_allocator/deallocate_local_thread-7.cc
@@ -24,42 +24,7 @@
#include <stdexcept>
#include <cstdio>
#include <ext/mt_allocator.h>
-
-static size_t count;
-
-struct count_check
-{
- count_check() { }
- ~count_check()
- {
- // NB: Using a pool that attempts to clean up resource use.
- if (count != 0)
- {
- printf("allocation/deallocation count is %zu \n", count);
- throw std::runtime_error("allocation/deallocation count isn't zero");
- }
- }
-};
-
-static count_check check;
-
-void* operator new(size_t size) throw(std::bad_alloc)
-{
- printf("operator new is called \n");
- void* p = malloc(size);
- if (p == NULL)
- throw std::bad_alloc();
- count++;
- return p;
-}
-
-void operator delete(void* p) throw()
-{
- printf("operator delete is called \n");
- if (p == NULL)
- return;
- count--;
-}
+#include <replacement_memory_operators.h>
template<bool _Thread>
struct cleanup_pool : public __gnu_cxx::__pool<true>
@@ -82,6 +47,9 @@ typedef std::basic_string<value_type, traits_type, allocator_type> string_type;
int main()
{
+ // NB: __mt_allocator doesn't clean itself up. Thus, the count will
+ // not be zero.
+ __gnu_test::counter::exceptions(false);
string_type s;
s += "bayou bend";
return 0;
diff --git a/libstdc++-v3/testsuite/ext/new_allocator/check_delete.cc b/libstdc++-v3/testsuite/ext/new_allocator/check_delete.cc
index f97903719ed..cff31c8926d 100644
--- a/libstdc++-v3/testsuite/ext/new_allocator/check_delete.cc
+++ b/libstdc++-v3/testsuite/ext/new_allocator/check_delete.cc
@@ -21,36 +21,11 @@
#include <cstdlib>
#include <ext/new_allocator.h>
-#include <testsuite_hooks.h>
-#include <testsuite_allocator.h>
-
-using __gnu_cxx::new_allocator;
-
-void*
-operator new(std::size_t n) throw(std::bad_alloc)
-{
- new_called = true;
- return std::malloc(n);
-}
-
-void
-operator delete(void *v) throw()
-{
- delete_called = true;
- return std::free(v);
-}
-
-// These just help tracking down error messages.
-void test01()
-{
- bool test __attribute__((unused)) = true;
- typedef new_allocator<unsigned int> allocator_type;
- VERIFY( bool(__gnu_test::check_delete<allocator_type, true>()) );
-}
+#include <replacement_memory_operators.h>
int main()
-{
- test01();
+{
+ typedef __gnu_cxx::new_allocator<unsigned int> allocator_type;
+ __gnu_test::check_delete<allocator_type, true>();
return 0;
}
-
diff --git a/libstdc++-v3/testsuite/ext/new_allocator/check_new.cc b/libstdc++-v3/testsuite/ext/new_allocator/check_new.cc
index 9fa0c04d7f2..098b624d146 100644
--- a/libstdc++-v3/testsuite/ext/new_allocator/check_new.cc
+++ b/libstdc++-v3/testsuite/ext/new_allocator/check_new.cc
@@ -21,36 +21,11 @@
#include <cstdlib>
#include <ext/new_allocator.h>
-#include <testsuite_hooks.h>
-#include <testsuite_allocator.h>
-
-using __gnu_cxx::new_allocator;
-
-void*
-operator new(std::size_t n) throw(std::bad_alloc)
-{
- new_called = true;
- return std::malloc(n);
-}
-
-void
-operator delete(void *v) throw()
-{
- delete_called = true;
- return std::free(v);
-}
-
-// These just help tracking down error messages.
-void test01()
-{
- bool test __attribute__((unused)) = true;
- typedef new_allocator<unsigned int> allocator_type;
- VERIFY( bool(__gnu_test::check_new<allocator_type, true>()) );
-}
+#include <replacement_memory_operators.h>
int main()
-{
- test01();
+{
+ typedef __gnu_cxx::new_allocator<unsigned int> allocator_type;
+ __gnu_test::check_new<allocator_type, true>();
return 0;
}
-
diff --git a/libstdc++-v3/testsuite/ext/new_allocator/deallocate_global.cc b/libstdc++-v3/testsuite/ext/new_allocator/deallocate_global.cc
index 014141bf639..783be483da8 100644
--- a/libstdc++-v3/testsuite/ext/new_allocator/deallocate_global.cc
+++ b/libstdc++-v3/testsuite/ext/new_allocator/deallocate_global.cc
@@ -17,50 +17,15 @@
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-// 20.4.1.1 allocator members
-
#include <string>
#include <stdexcept>
-#include <cstdlib>
-#include <cstdio>
#include <ext/new_allocator.h>
-
-static size_t count;
-
-struct count_check
-{
- count_check() { }
- ~count_check()
- {
- if (count != 0)
- throw std::runtime_error("allocation/deallocation count isn't zero");
- }
-};
-
-static count_check check;
-
-void* operator new(size_t size) throw(std::bad_alloc)
-{
- std::printf("operator new is called \n");
- void* p = std::malloc(size);
- if (p == NULL)
- throw std::bad_alloc();
- count++;
- return p;
-}
-
-void operator delete(void* p) throw()
-{
- std::printf("operator delete is called \n");
- if (p == NULL)
- return;
- count--;
-}
+#include <replacement_memory_operators.h>
typedef char char_t;
typedef std::char_traits<char_t> traits_t;
typedef __gnu_cxx::new_allocator<char_t> allocator_t;
-typedef std::basic_string<char_t, traits_t, allocator_t> string_t;
+typedef std::basic_string<char_t, traits_t, allocator_t> string_t;
string_t s("bayou bend");
diff --git a/libstdc++-v3/testsuite/ext/new_allocator/deallocate_local.cc b/libstdc++-v3/testsuite/ext/new_allocator/deallocate_local.cc
index 7f224a5cb8a..dd7c634e06c 100644
--- a/libstdc++-v3/testsuite/ext/new_allocator/deallocate_local.cc
+++ b/libstdc++-v3/testsuite/ext/new_allocator/deallocate_local.cc
@@ -1,5 +1,5 @@
//
-// Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009
+// Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@@ -17,54 +17,23 @@
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-// 20.4.1.1 allocator members
-
#include <string>
-#include <stdexcept>
-#include <cstdlib>
-#include <cstdio>
#include <ext/new_allocator.h>
-
-static size_t count;
-
-struct count_check
-{
- count_check() { }
- ~count_check()
- {
- if (count != 0)
- throw std::runtime_error("allocation/deallocation count isn't zero");
- }
-};
-
-static count_check check;
-
-void* operator new(size_t size) throw(std::bad_alloc)
-{
- std::printf("operator new is called \n");
- void* p = std::malloc(size);
- if (p == NULL)
- throw std::bad_alloc();
- count++;
- return p;
-}
-
-void operator delete(void* p) throw()
-{
- std::printf("operator delete is called \n");
- if (p == NULL)
- return;
- count--;
-}
+#include <replacement_memory_operators.h>
typedef char char_t;
typedef std::char_traits<char_t> traits_t;
typedef __gnu_cxx::new_allocator<char_t> allocator_t;
-typedef std::basic_string<char_t, traits_t, allocator_t> string_t;
+typedef std::basic_string<char_t, traits_t, allocator_t> string_t;
int main()
{
- string_t s;
- s += "bayou bend";
+ {
+ string_t s;
+ s += "bayou bend";
+ }
+
+ if (__gnu_test::counter::count() != 0)
+ throw std::runtime_error("count not zero");
return 0;
}
diff --git a/libstdc++-v3/testsuite/ext/pool_allocator/check_delete.cc b/libstdc++-v3/testsuite/ext/pool_allocator/check_delete.cc
index b24550ee3de..ecc399df638 100644
--- a/libstdc++-v3/testsuite/ext/pool_allocator/check_delete.cc
+++ b/libstdc++-v3/testsuite/ext/pool_allocator/check_delete.cc
@@ -21,36 +21,12 @@
#include <cstdlib>
#include <ext/pool_allocator.h>
-#include <testsuite_hooks.h>
-#include <testsuite_allocator.h>
-
-using __gnu_cxx::__pool_alloc;
-
-void*
-operator new(std::size_t n) throw(std::bad_alloc)
-{
- new_called = true;
- return std::malloc(n);
-}
-
-void
-operator delete(void *v) throw()
-{
- delete_called = true;
- return std::free(v);
-}
-
-void test01()
-{
- // Uses new, but delete only sometimes.
- bool test __attribute__((unused)) = true;
- typedef __pool_alloc<unsigned int> allocator_type;
- VERIFY( bool(__gnu_test::check_delete<allocator_type, false>()) );
-}
+#include <replacement_memory_operators.h>
int main()
{
- test01();
+ // Uses new, but delete only sometimes.
+ typedef __gnu_cxx::__pool_alloc<unsigned int> allocator_type;
+ __gnu_test::check_delete<allocator_type, false>();
return 0;
}
-
diff --git a/libstdc++-v3/testsuite/ext/pool_allocator/check_new.cc b/libstdc++-v3/testsuite/ext/pool_allocator/check_new.cc
index a4fad95d5ad..f1bdb77bb86 100644
--- a/libstdc++-v3/testsuite/ext/pool_allocator/check_new.cc
+++ b/libstdc++-v3/testsuite/ext/pool_allocator/check_new.cc
@@ -21,35 +21,11 @@
#include <cstdlib>
#include <ext/pool_allocator.h>
-#include <testsuite_hooks.h>
-#include <testsuite_allocator.h>
-
-using __gnu_cxx::__pool_alloc;
-
-void*
-operator new(std::size_t n) throw(std::bad_alloc)
-{
- new_called = true;
- return std::malloc(n);
-}
-
-void
-operator delete(void *v) throw()
-{
- delete_called = true;
- return std::free(v);
-}
-
-void test01()
-{
- bool test __attribute__((unused)) = true;
- typedef __pool_alloc<unsigned int> allocator_type;
- VERIFY( bool(__gnu_test::check_new<allocator_type, true>()) );
-}
+#include <replacement_memory_operators.h>
int main()
-{
- test01();
+{
+ typedef __gnu_cxx::__pool_alloc<unsigned int> allocator_type;
+ __gnu_test::check_new<allocator_type, true>();
return 0;
}
-
diff --git a/libstdc++-v3/testsuite/ext/rope/40299.cc b/libstdc++-v3/testsuite/ext/rope/40299.cc
new file mode 100644
index 00000000000..4d83fc98ce4
--- /dev/null
+++ b/libstdc++-v3/testsuite/ext/rope/40299.cc
@@ -0,0 +1,27 @@
+// { dg-options "-std=gnu++0x" }
+// { dg-do compile }
+
+// Copyright (C) 2009 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <ext/rope>
+
+// libstdc++/40299
+void test01()
+{
+ __gnu_cxx::crope asdf;
+}
diff --git a/libstdc++-v3/testsuite/ext/throw_allocator/check_delete.cc b/libstdc++-v3/testsuite/ext/throw_allocator/check_delete.cc
index a33493181bb..cfc38ee02f6 100644
--- a/libstdc++-v3/testsuite/ext/throw_allocator/check_delete.cc
+++ b/libstdc++-v3/testsuite/ext/throw_allocator/check_delete.cc
@@ -20,36 +20,11 @@
#include <cstdlib>
#include <ext/throw_allocator.h>
-#include <testsuite_hooks.h>
-#include <testsuite_allocator.h>
-
-using __gnu_cxx::throw_allocator;
-
-void*
-operator new(std::size_t n) throw(std::bad_alloc)
-{
- new_called = true;
- return std::malloc(n);
-}
-
-void
-operator delete(void *v) throw()
-{
- delete_called = true;
- return std::free(v);
-}
-
-// These just help tracking down error messages.
-void test01()
-{
- bool test __attribute__((unused)) = true;
- typedef throw_allocator<unsigned int> allocator_type;
- VERIFY( bool(__gnu_test::check_delete<allocator_type, true>()) );
-}
+#include <replacement_memory_operators.h>
int main()
-{
- test01();
+{
+ typedef __gnu_cxx::throw_allocator<unsigned int> allocator_type;
+ __gnu_test::check_delete<allocator_type, true>();
return 0;
}
-
diff --git a/libstdc++-v3/testsuite/ext/throw_allocator/check_new.cc b/libstdc++-v3/testsuite/ext/throw_allocator/check_new.cc
index f0579fbf642..2d42891766b 100644
--- a/libstdc++-v3/testsuite/ext/throw_allocator/check_new.cc
+++ b/libstdc++-v3/testsuite/ext/throw_allocator/check_new.cc
@@ -20,36 +20,11 @@
#include <cstdlib>
#include <ext/throw_allocator.h>
-#include <testsuite_hooks.h>
-#include <testsuite_allocator.h>
-
-using __gnu_cxx::throw_allocator;
-
-void*
-operator new(std::size_t n) throw(std::bad_alloc)
-{
- new_called = true;
- return std::malloc(n);
-}
-
-void
-operator delete(void *v) throw()
-{
- delete_called = true;
- return std::free(v);
-}
-
-// These just help tracking down error messages.
-void test01()
-{
- bool test __attribute__((unused)) = true;
- typedef throw_allocator<unsigned int> allocator_type;
- VERIFY( bool(__gnu_test::check_new<allocator_type, true>()) );
-}
+#include <replacement_memory_operators.h>
int main()
-{
- test01();
+{
+ typedef __gnu_cxx::throw_allocator<unsigned int> allocator_type;
+ __gnu_test::check_new<allocator_type, true>();
return 0;
}
-
diff --git a/libstdc++-v3/testsuite/ext/throw_allocator/deallocate_global.cc b/libstdc++-v3/testsuite/ext/throw_allocator/deallocate_global.cc
index d298fe42b55..c53517ebc13 100644
--- a/libstdc++-v3/testsuite/ext/throw_allocator/deallocate_global.cc
+++ b/libstdc++-v3/testsuite/ext/throw_allocator/deallocate_global.cc
@@ -21,50 +21,12 @@
#include <string>
#include <stdexcept>
#include <ext/throw_allocator.h>
-#include <testsuite_hooks.h>
-
-static size_t count;
-
-struct count_check
-{
- count_check() {}
- ~count_check()
- {
- if (count != 0)
- throw std::runtime_error("count isn't zero");
- }
-};
-
-static count_check check;
-
-void* operator new(size_t size) throw(std::bad_alloc)
-{
- printf("operator new is called \n");
- void* p = malloc(size);
- if (p == NULL)
- throw std::bad_alloc();
- count++;
- return p;
-}
-
-void operator delete(void* p) throw()
-{
- printf("operator delete is called \n");
- if (p == NULL)
- return;
- count--;
- if (count == 0)
- printf("All memory released \n");
- else
- printf("%lu allocations to be released \n",
- static_cast<unsigned long>(count));
- free(p);
-}
+#include <replacement_memory_operators.h>
typedef char char_t;
typedef std::char_traits<char_t> traits_t;
typedef __gnu_cxx::throw_allocator<char_t> allocator_t;
-typedef std::basic_string<char_t, traits_t, allocator_t> string_t;
+typedef std::basic_string<char_t, traits_t, allocator_t> string_t;
string_t s("bayou bend");
diff --git a/libstdc++-v3/testsuite/ext/throw_allocator/deallocate_local.cc b/libstdc++-v3/testsuite/ext/throw_allocator/deallocate_local.cc
index 45fd6dcdde0..c2e918ccc25 100644
--- a/libstdc++-v3/testsuite/ext/throw_allocator/deallocate_local.cc
+++ b/libstdc++-v3/testsuite/ext/throw_allocator/deallocate_local.cc
@@ -20,46 +20,21 @@
#include <string>
#include <ext/throw_allocator.h>
-#include <testsuite_hooks.h>
-
-static size_t alloc_cnt;
-
-void* operator new(size_t size) throw(std::bad_alloc)
-{
- printf("operator new is called \n");
- void* p = malloc(size);
- if (p == NULL)
- throw std::bad_alloc();
- alloc_cnt++;
- return p;
-}
-
-void operator delete(void* p) throw()
-{
- printf("operator delete is called \n");
- if (p == NULL)
- return;
- alloc_cnt--;
- if (alloc_cnt == 0)
- printf("All memory released \n");
- else
- printf("%lu allocations to be released \n",
- static_cast<unsigned long>(alloc_cnt));
- free(p);
-}
+#include <replacement_memory_operators.h>
typedef char char_t;
typedef std::char_traits<char_t> traits_t;
typedef __gnu_cxx::throw_allocator<char_t> allocator_t;
-typedef std::basic_string<char_t, traits_t, allocator_t> string_t;
+typedef std::basic_string<char_t, traits_t, allocator_t> string_t;
int main()
{
- bool test __attribute__((unused)) = true;
{
string_t s;
s += "bayou bend";
}
- VERIFY( alloc_cnt == 0 );
+
+ if (__gnu_test::counter::count() != 0)
+ throw std::runtime_error("count not zero");
return 0;
}
diff --git a/libstdc++-v3/testsuite/lib/libstdc++.exp b/libstdc++-v3/testsuite/lib/libstdc++.exp
index 3adf91c7718..45e92d756ec 100644
--- a/libstdc++-v3/testsuite/lib/libstdc++.exp
+++ b/libstdc++-v3/testsuite/lib/libstdc++.exp
@@ -402,8 +402,7 @@ proc v3_target_compile { source dest type options } {
# Flag setting based on type argument.
if { $type == "executable" } {
# Link the support objects into executables.
- set cxx_final [concat $cxx_final $cxxldflags]
- lappend options "additional_flags=./libtestc++.a"
+ lappend options "additional_flags=./libtestc++.a $cxxldflags"
} else {
if { $type == "sharedlib" } {
# Don't link in anything.
diff --git a/libstdc++-v3/testsuite/util/common_type/assoc/common_type.hpp b/libstdc++-v3/testsuite/util/common_type/assoc/common_type.hpp
index 755d986655b..562f418fa22 100644
--- a/libstdc++-v3/testsuite/util/common_type/assoc/common_type.hpp
+++ b/libstdc++-v3/testsuite/util/common_type/assoc/common_type.hpp
@@ -674,9 +674,7 @@ namespace __gnu_pbds
typedef typename __gnu_cxx::typelist::create1<cnt_5_u>::type lu_policy1;
typedef
- typename __gnu_cxx::typelist::create2<
- lu_policy0,
- lu_policy1>::type
+ typename __gnu_cxx::typelist::create2<lu_policy0, lu_policy1>::type
lu_policies;
template<typename Policy_Tl>
@@ -684,18 +682,12 @@ namespace __gnu_pbds
{
private:
typedef
- typename __gnu_cxx::typelist::at_index<
- Policy_Tl, 0>::type
+ typename __gnu_cxx::typelist::at_index<Policy_Tl, 0>::type
update_policy_t;
public:
typedef
- __gnu_pbds::list_update<
- Key,
- Data,
- Eq_Fn,
- update_policy_t,
- Allocator>
+ __gnu_pbds::list_update<Key, Data, Eq_Fn, update_policy_t, Allocator>
type;
};
diff --git a/libstdc++-v3/testsuite/util/regression/rand/assoc/container_rand_regression_test.tcc b/libstdc++-v3/testsuite/util/regression/rand/assoc/container_rand_regression_test.tcc
index 9bc0faad89d..d995a049ed6 100644
--- a/libstdc++-v3/testsuite/util/regression/rand/assoc/container_rand_regression_test.tcc
+++ b/libstdc++-v3/testsuite/util/regression/rand/assoc/container_rand_regression_test.tcc
@@ -60,7 +60,7 @@ default_constructor()
{
PB_DS_TRACE("default_constructor");
bool done = true;
- m_alloc.set_throw_prob(m_tp);
+ m_alloc.set_probability(m_tp);
try
{
@@ -82,9 +82,9 @@ PB_DS_CLASS_C_DEC::
swap()
{
PB_DS_TRACE("swap");
- m_alloc.set_throw_prob(0);
+ m_alloc.set_probability(0);
Cntnr* p_c = new Cntnr;
- m_alloc.set_throw_prob(1);
+ m_alloc.set_probability(1);
p_c->swap(*m_p_c);
std::swap(p_c, m_p_c);
delete p_c;
@@ -99,8 +99,8 @@ copy_constructor()
PB_DS_TRACE("copy_constructor");
bool done = true;
Cntnr* p_c = NULL;
- m_alloc.set_throw_prob(m_tp);
- typename alloc_t::group_throw_prob_adjustor adjust(m_p_c->size());
+ m_alloc.set_probability(m_tp);
+ typename alloc_t::group_adjustor adjust(m_p_c->size());
try
{
@@ -125,8 +125,8 @@ assignment_operator()
PB_DS_TRACE("assignment operator");
bool done = true;
Cntnr* p_c = NULL;
- m_alloc.set_throw_prob(m_tp);
- typename alloc_t::group_throw_prob_adjustor adjust(m_p_c->size());
+ m_alloc.set_probability(m_tp);
+ typename alloc_t::group_adjustor adjust(m_p_c->size());
try
{
@@ -160,8 +160,8 @@ it_constructor_imp(__gnu_pbds::cc_hash_tag)
{
bool done = true;
Cntnr* p_c = NULL;
- m_alloc.set_throw_prob(m_tp);
- typename alloc_t::group_throw_prob_adjustor adjust(m_p_c->size());
+ m_alloc.set_probability(m_tp);
+ typename alloc_t::group_adjustor adjust(m_p_c->size());
try
{
@@ -227,8 +227,8 @@ it_constructor_imp(__gnu_pbds::gp_hash_tag)
{
bool done = true;
Cntnr* p_c = NULL;
- m_alloc.set_throw_prob(m_tp);
- typename alloc_t::group_throw_prob_adjustor adjust(m_p_c->size());
+ m_alloc.set_probability(m_tp);
+ typename alloc_t::group_adjustor adjust(m_p_c->size());
try
{
@@ -310,8 +310,8 @@ it_constructor_imp(__gnu_pbds::tree_tag)
{
bool done = true;
Cntnr* p_c = NULL;
- m_alloc.set_throw_prob(m_tp);
- typename alloc_t::group_throw_prob_adjustor adjust(m_p_c->size());
+ m_alloc.set_probability(m_tp);
+ typename alloc_t::group_adjustor adjust(m_p_c->size());
try
{
@@ -346,8 +346,8 @@ it_constructor_imp(__gnu_pbds::list_update_tag)
{
bool done = true;
Cntnr* p_c = NULL;
- m_alloc.set_throw_prob(m_tp);
- typename alloc_t::group_throw_prob_adjustor adjust(m_p_c->size());
+ m_alloc.set_probability(m_tp);
+ typename alloc_t::group_adjustor adjust(m_p_c->size());
try
{
@@ -371,8 +371,8 @@ it_constructor_imp(__gnu_pbds::pat_trie_tag)
{
bool done = true;
Cntnr* p_c = NULL;
- m_alloc.set_throw_prob(m_tp);
- typename alloc_t::group_throw_prob_adjustor adjust(m_p_c->size());
+ m_alloc.set_probability(m_tp);
+ typename alloc_t::group_adjustor adjust(m_p_c->size());
try
{
@@ -409,7 +409,7 @@ PB_DS_CLASS_C_DEC::
cmp(const Cntnr& r_c, const native_type& r_native_c,
const std::string& r_call_fn)
{
- m_alloc.set_throw_prob(1);
+ m_alloc.set_probability(1);
const size_t size = r_c.size();
const size_t native_size = r_native_c.size();
PB_DS_THROW_IF_FAILED(size == native_size,
@@ -447,9 +447,9 @@ basic_cmp_(const Cntnr& r_c, const native_type& r_native_c)
{
typename native_type::key_type native_key = test_traits::extract_native_key(*it);
- m_alloc.set_throw_prob(0);
+ m_alloc.set_probability(0);
const key_type k = native_key;
- m_alloc.set_throw_prob(1);
+ m_alloc.set_probability(1);
typename cntnr::const_point_iterator found_it = r_c.find(k);
PB_DS_THROW_IF_FAILED(found_it != r_c.end(),
test_traits::native_val_to_string(*it),
@@ -622,9 +622,9 @@ PB_DS_CLASS_C_DEC::
order_statistics_cmp_imp(const Cntnr& r_c, const native_type& r_native_c, __gnu_pbds::detail::true_type)
{
{
- m_alloc.set_throw_prob(0);
+ m_alloc.set_probability(0);
const key_type k = test_traits::generate_key(m_g, m_m);
- m_alloc.set_throw_prob(1);
+ m_alloc.set_probability(1);
const size_type order = r_c.order_of_key(k);
const size_type native_order = std::distance(r_native_c.begin(),
r_native_c.lower_bound(test_traits::native_key(k)));
@@ -675,9 +675,9 @@ PB_DS_CLASS_C_DEC::
prefix_search_cmp_imp(const Cntnr& r_c, const native_type& r_native_c, __gnu_pbds::detail::true_type)
{
PB_DS_SET_DESTRUCT_PRINT
- m_alloc.set_throw_prob(0);
+ m_alloc.set_probability(0);
const key_type k = test_traits::generate_key(m_g, m_m);
- m_alloc.set_throw_prob(1);
+ m_alloc.set_probability(1);
try
{
typedef
@@ -794,9 +794,9 @@ PB_DS_CLASS_C_DEC::
lower_bound_cmp_imp(const Cntnr& r_c, const native_type& r_native_c, __gnu_pbds::detail::true_type)
{
PB_DS_SET_DESTRUCT_PRINT
- m_alloc.set_throw_prob(0);
+ m_alloc.set_probability(0);
const key_type k = test_traits::generate_key(m_g, m_m);
- m_alloc.set_throw_prob(1);
+ m_alloc.set_probability(1);
typename cntnr::const_iterator it = r_c.lower_bound(k);
typename native_type::key_type native_k = test_traits::native_key(k);
typename native_type::const_iterator native_it = r_native_c.lower_bound(native_k);
@@ -833,9 +833,9 @@ PB_DS_CLASS_C_DEC::
upper_bound_cmp_imp(const Cntnr& r_c, const native_type& r_native_c, __gnu_pbds::detail::true_type)
{
PB_DS_SET_DESTRUCT_PRINT
- m_alloc.set_throw_prob(0);
+ m_alloc.set_probability(0);
const key_type k = test_traits::generate_key(m_g, m_m);
- m_alloc.set_throw_prob(1);
+ m_alloc.set_probability(1);
typename cntnr::const_iterator it = r_c.upper_bound(k);
typename native_type::key_type native_k = test_traits::native_key(k);
typename native_type::const_iterator native_it = r_native_c.upper_bound(native_k);
@@ -879,7 +879,7 @@ operator()()
// Track allocation from this point only.
const size_t memory_label = 775;
- m_alloc.init(m_seed);
+ m_alloc.seed(m_seed);
m_alloc.set_label(memory_label);
prog_bar pb(m_n, std::cout, m_disp);
@@ -1012,7 +1012,7 @@ operator()()
}
// Reset throw probability.
- m_alloc.set_throw_prob(0);
+ m_alloc.set_probability(0);
if (m_disp)
{
@@ -1069,9 +1069,9 @@ insert()
PB_DS_SET_DESTRUCT_PRINT
try
{
- m_alloc.set_throw_prob(0);
+ m_alloc.set_probability(0);
value_type v = test_traits::generate_value(m_g, m_m);
- m_alloc.set_throw_prob(m_tp);
+ m_alloc.set_probability(m_tp);
const_key_reference r_k = test_traits::extract_key(v);
typename cntnr::const_point_iterator found_it = m_p_c->find(r_k);
const bool existed = (found_it != m_p_c->end());
@@ -1130,10 +1130,10 @@ subscript_imp(__gnu_pbds::detail::false_type)
try
{
- m_alloc.set_throw_prob(0);
+ m_alloc.set_probability(0);
value_type v = test_traits::generate_value(m_g, m_m);
- m_alloc.set_throw_prob(m_tp);
+ m_alloc.set_probability(m_tp);
(*m_p_c)[v.first] = v.second;
m_native_c[test_traits::native_value(v).first] =
@@ -1158,9 +1158,9 @@ subscript_imp(__gnu_pbds::detail::true_type)
PB_DS_SET_DESTRUCT_PRINT
try
{
- m_alloc.set_throw_prob(0);
+ m_alloc.set_probability(0);
value_type v = test_traits::generate_value(m_g, m_m);
- m_alloc.set_throw_prob(m_tp);
+ m_alloc.set_probability(m_tp);
(*m_p_c)[v] = __gnu_pbds::null_mapped_type();
m_native_c.insert(test_traits::native_value(v));
}
@@ -1195,9 +1195,9 @@ erase()
PB_DS_TRACE("erase");
bool done = true;
PB_DS_SET_DESTRUCT_PRINT
- m_alloc.set_throw_prob(0);
+ m_alloc.set_probability(0);
const key_type k = test_traits::generate_key(m_g, m_m);
- m_alloc.set_throw_prob(m_tp);
+ m_alloc.set_probability(m_tp);
try
{
@@ -1244,7 +1244,7 @@ erase_if()
typename test_traits::template erase_if_fn<value_type>
erase_if_fn_t;
- m_alloc.set_throw_prob(m_tp);
+ m_alloc.set_probability(m_tp);
const size_t ersd = m_p_c->erase_if(erase_if_fn_t());
const size_t native_ersd = test_traits::erase_if(m_native_c);
@@ -1296,9 +1296,9 @@ erase_it_imp(__gnu_pbds::detail::true_type)
try
{
- m_alloc.set_throw_prob(0);
+ m_alloc.set_probability(0);
const key_type k = test_traits::generate_key(m_g, m_m);
- m_alloc.set_throw_prob(m_tp);
+ m_alloc.set_probability(m_tp);
typename cntnr::iterator found_it = m_p_c->find(k);
@@ -1373,9 +1373,9 @@ erase_rev_it_imp(__gnu_pbds::detail::true_type)
try
{
- m_alloc.set_throw_prob(0);
+ m_alloc.set_probability(0);
const key_type k = test_traits::generate_key(m_g, m_m);
- m_alloc.set_throw_prob(m_tp);
+ m_alloc.set_probability(m_tp);
typename cntnr::iterator found_it = m_p_c->find(k);
typename native_type::iterator native_it = m_native_c.find(test_traits::native_key(k));
@@ -1728,14 +1728,14 @@ split_join_imp(__gnu_pbds::detail::true_type)
try
{
- m_alloc.set_throw_prob(0);
+ m_alloc.set_probability(0);
Cntnr lhs(*m_p_c);
Cntnr rhs;
native_type native_lhs(m_native_c);
native_type native_rhs;
const key_type k = test_traits::generate_key(m_g, m_m);
- m_alloc.set_throw_prob(m_tp);
+ m_alloc.set_probability(m_tp);
lhs.split(k, rhs);
typename native_type::const_iterator it =
@@ -1753,7 +1753,7 @@ split_join_imp(__gnu_pbds::detail::true_type)
PB_DS_COND_COMPARE(lhs, native_lhs);
PB_DS_COND_COMPARE(rhs, native_rhs);
- m_alloc.set_throw_prob(m_tp);
+ m_alloc.set_probability(m_tp);
if (m_g.get_prob() < 0.5)
lhs.swap(rhs);
@@ -1972,8 +1972,8 @@ resize_imp(__gnu_pbds::detail::true_type)
max_new_size = 2000
};
- m_alloc.set_throw_prob(m_tp);
- typename alloc_t::group_throw_prob_adjustor adjust(m_p_c->size());
+ m_alloc.set_probability(m_tp);
+ typename alloc_t::group_adjustor adjust(m_p_c->size());
const size_t new_size = m_g.get_unsigned_long(min_new_size, max_new_size);
m_p_c->resize(new_size);
const size_t actual_new_size = m_p_c->get_actual_size();
@@ -2023,8 +2023,8 @@ get_set_load_imp(__gnu_pbds::detail::true_type)
PB_DS_TRACE("get_set_load");
PB_DS_SET_DESTRUCT_PRINT
m_p_c->get_load();
- m_alloc.set_throw_prob(1);
- typename alloc_t::group_throw_prob_adjustor adjust(m_p_c->size());
+ m_alloc.set_probability(1);
+ typename alloc_t::group_adjustor adjust(m_p_c->size());
const float min_load = static_cast<float>(0.05);
const float max_load = static_cast<float>(0.9);
@@ -2070,9 +2070,9 @@ get_set_loads_imp(__gnu_pbds::detail::true_type)
try
{
- m_alloc.set_throw_prob(m_tp);
+ m_alloc.set_probability(m_tp);
- typename alloc_t::group_throw_prob_adjustor adjust(m_p_c->size());
+ typename alloc_t::group_adjustor adjust(m_p_c->size());
const float min_min_load = static_cast<float>(0.05);
const float max_min_load = static_cast<float>(0.2);
@@ -2107,7 +2107,7 @@ void
PB_DS_CLASS_C_DEC::
print_container(const native_type& r_cnt, std::ostream& r_os) const
{
- m_alloc.set_throw_prob(0);
+ m_alloc.set_probability(0);
typename native_type::const_iterator it = r_cnt.begin();
while (it != r_cnt.end())
{
@@ -2121,7 +2121,7 @@ void
PB_DS_CLASS_C_DEC::
print_container(const cntnr& r_cnt, std::ostream& r_os) const
{
- m_alloc.set_throw_prob(0);
+ m_alloc.set_probability(0);
typename cntnr::const_iterator it = r_cnt.begin();
while (it != r_cnt.end())
{
diff --git a/libstdc++-v3/testsuite/util/regression/rand/assoc/rand_regression_test.hpp b/libstdc++-v3/testsuite/util/regression/rand/assoc/rand_regression_test.hpp
index 55cd3c0b099..d4b395b126a 100644
--- a/libstdc++-v3/testsuite/util/regression/rand/assoc/rand_regression_test.hpp
+++ b/libstdc++-v3/testsuite/util/regression/rand/assoc/rand_regression_test.hpp
@@ -148,7 +148,7 @@ namespace detail
namespace detail
{
- void
+ inline void
usage(const std::string& name)
{
using namespace std;
@@ -179,7 +179,7 @@ namespace detail
cerr << "'t' or 'f' determine whether progress will be displayed" << endl;
}
- void
+ inline void
verify_params(size_t& r_seed, size_t& r_n,
size_t& r_m, double& r_tp, double& r_ip, double& r_ep,
double& r_cp, double& r_mp, bool& r_d)
diff --git a/libstdc++-v3/testsuite/util/regression/rand/priority_queue/container_rand_regression_test.tcc b/libstdc++-v3/testsuite/util/regression/rand/priority_queue/container_rand_regression_test.tcc
index 643c968847c..fe8ae6ba7ed 100644
--- a/libstdc++-v3/testsuite/util/regression/rand/priority_queue/container_rand_regression_test.tcc
+++ b/libstdc++-v3/testsuite/util/regression/rand/priority_queue/container_rand_regression_test.tcc
@@ -60,7 +60,7 @@ default_constructor()
{
PB_DS_TRACE("default_constructor");
bool done = true;
- m_alloc.set_throw_prob(m_tp);
+ m_alloc.set_probability(m_tp);
try
{
@@ -83,9 +83,9 @@ PB_DS_CLASS_C_DEC::
swap()
{
PB_DS_TRACE("swap");
- m_alloc.set_throw_prob(0);
+ m_alloc.set_probability(0);
Cntnr* p_c = new Cntnr;
- m_alloc.set_throw_prob(1);
+ m_alloc.set_probability(1);
p_c->swap(*m_p_c);
std::swap(p_c, m_p_c);
delete p_c;
@@ -100,9 +100,9 @@ copy_constructor()
PB_DS_TRACE("copy_constructor");
bool done = true;
Cntnr* p_c = NULL;
- m_alloc.set_throw_prob(m_tp);
+ m_alloc.set_probability(m_tp);
- typedef typename allocator_type::group_throw_prob_adjustor adjustor;
+ typedef typename allocator_type::group_adjustor adjustor;
adjustor adjust(m_p_c->size());
try
@@ -128,9 +128,9 @@ assignment_operator()
PB_DS_TRACE("assignment operator");
bool done = true;
Cntnr* p_c = NULL;
- m_alloc.set_throw_prob(m_tp);
+ m_alloc.set_probability(m_tp);
- typedef typename allocator_type::group_throw_prob_adjustor adjustor;
+ typedef typename allocator_type::group_adjustor adjustor;
adjustor adjust(m_p_c->size());
try
@@ -156,8 +156,8 @@ it_constructor()
{
bool done = true;
Cntnr* p_c = NULL;
- m_alloc.set_throw_prob(m_tp);
- typedef typename allocator_type::group_throw_prob_adjustor adjustor;
+ m_alloc.set_probability(m_tp);
+ typedef typename allocator_type::group_adjustor adjustor;
adjustor adjust(m_p_c->size());
try
@@ -201,7 +201,7 @@ cmp(const Cntnr& c, const native_type& native, const std::string& callfn)
try
{
- m_alloc.set_throw_prob(1);
+ m_alloc.set_probability(1);
const size_t size = c.size();
const size_t native_size = native.size();
@@ -248,7 +248,7 @@ operator()()
string_form<Cntnr>::desc());
m_g.init(m_seed);
- m_alloc.init(m_seed);
+ m_alloc.seed(m_seed);
// The __throw_allocator::_S_label defaults to 0, so to make things
// easier and more precise when debugging, start at 1.
@@ -363,7 +363,7 @@ operator()()
}
// Reset throw probability.
- m_alloc.set_throw_prob(0);
+ m_alloc.set_probability(0);
if (m_disp)
{
@@ -425,9 +425,9 @@ push()
try
{
- m_alloc.set_throw_prob(0);
+ m_alloc.set_probability(0);
value_type v = test_traits::generate_value(m_g, m_m);
- m_alloc.set_throw_prob(m_tp);
+ m_alloc.set_probability(m_tp);
const typename cntnr::size_type sz = m_p_c->size();
m_p_c->push(v);
_GLIBCXX_THROW_IF(sz != m_p_c->size() - 1, sz, m_p_c, &m_native_c);
@@ -460,10 +460,10 @@ modify()
bool done = true;
try
{
- m_alloc.set_throw_prob(0);
+ m_alloc.set_probability(0);
value_type v = test_traits::generate_value(m_g, m_m);
- m_alloc.set_throw_prob(m_tp);
+ m_alloc.set_probability(m_tp);
typename cntnr::iterator it = m_p_c->begin();
std::advance(it, m_g.get_unsigned_long(0, m_p_c->size()));
if (it != m_p_c->end())
@@ -510,7 +510,7 @@ pop()
bool done = true;
try
{
- m_alloc.set_throw_prob(1);
+ m_alloc.set_probability(1);
if (!m_p_c->empty())
{
m_p_c->pop();
@@ -543,7 +543,7 @@ erase_if()
typename std::iterator_traits<typename cntnr::iterator>::reference
it_const_reference;
- m_alloc.set_throw_prob(1);
+ m_alloc.set_probability(1);
typedef
typename test_traits::template erase_if_fn<value_type>
@@ -582,7 +582,7 @@ erase_it()
bool done = true;
try
{
- m_alloc.set_throw_prob(1);
+ m_alloc.set_probability(1);
typename cntnr::iterator it = m_p_c->begin();
std::advance(it, m_g.get_unsigned_long(0, m_p_c->size()));
@@ -689,11 +689,11 @@ split_join()
bool done = true;
try
{
- m_alloc.set_throw_prob(0);
+ m_alloc.set_probability(0);
Cntnr lhs(*m_p_c);
Cntnr rhs;
native_type native_lhs(m_native_c);
- m_alloc.set_throw_prob(m_tp);
+ m_alloc.set_probability(m_tp);
typedef typename test_traits::template erase_if_fn<value_type> split_fn_t;
lhs.split(split_fn_t(), rhs);
@@ -706,7 +706,7 @@ split_join()
PB_DS_COND_COMPARE(lhs, native_lhs);
PB_DS_COND_COMPARE(rhs, native_rhs);
- m_alloc.set_throw_prob(m_tp);
+ m_alloc.set_probability(m_tp);
if (m_g.get_prob() < 0.5)
lhs.swap(rhs);
@@ -815,7 +815,7 @@ void
PB_DS_CLASS_C_DEC::
print_container(const native_type& cnt, std::ostream& os) const
{
- m_alloc.set_throw_prob(0);
+ m_alloc.set_probability(0);
native_type cpy(cnt);
while (!cpy.empty())
{
@@ -830,7 +830,7 @@ PB_DS_CLASS_C_DEC::
print_container(const cntnr& cnt, std::ostream& os) const
{
typedef typename cntnr::const_iterator const_iterator;
- m_alloc.set_throw_prob(0);
+ m_alloc.set_probability(0);
for (const_iterator it = cnt.begin(); it != cnt.end(); ++it)
os << *it << std::endl;
}
diff --git a/libstdc++-v3/testsuite/util/regression/rand/priority_queue/rand_regression_test.hpp b/libstdc++-v3/testsuite/util/regression/rand/priority_queue/rand_regression_test.hpp
index 7dc8781bed0..1cf86020d45 100644
--- a/libstdc++-v3/testsuite/util/regression/rand/priority_queue/rand_regression_test.hpp
+++ b/libstdc++-v3/testsuite/util/regression/rand/priority_queue/rand_regression_test.hpp
@@ -150,7 +150,7 @@ namespace detail
namespace detail
{
- void
+ inline void
usage(const std::string& name)
{
using namespace std;
@@ -182,7 +182,7 @@ namespace detail
cerr << "'t' or 'f' determine whether progress will be displayed" << endl;
}
- void
+ inline void
verify_params(size_t& r_seed, size_t& r_n,
size_t& r_m, double& r_tp, double& r_ip, double& r_dp,
double& r_ep, double& r_cp, double& r_mp, bool& r_d)
diff --git a/libstdc++-v3/testsuite/util/replacement_memory_operators.h b/libstdc++-v3/testsuite/util/replacement_memory_operators.h
new file mode 100644
index 00000000000..91c8fa3d38a
--- /dev/null
+++ b/libstdc++-v3/testsuite/util/replacement_memory_operators.h
@@ -0,0 +1,110 @@
+//
+// Copyright (C) 2007, 2009 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <exception>
+
+namespace __gnu_test
+{
+ struct counter_error : public std::exception { };
+
+ struct counter
+ {
+ size_t _M_count;
+ bool _M_throw;
+
+ counter() : _M_count(0), _M_throw(true) { }
+
+ ~counter()
+ {
+ if (_M_throw && _M_count != 0)
+ throw counter_error();
+ }
+
+ static void
+ increment() { get()._M_count++; }
+
+ static void
+ decrement() { get()._M_count--; }
+
+ static counter&
+ get()
+ {
+ static counter g;
+ return g;
+ }
+
+ static size_t
+ count() { return get()._M_count; }
+
+ static void
+ exceptions(bool __b) { get()._M_throw = __b; }
+ };
+
+ template<typename Alloc, bool uses_global_new>
+ bool
+ check_new(Alloc a = Alloc())
+ {
+ __gnu_test::counter::exceptions(false);
+ a.allocate(10);
+ const bool __b((__gnu_test::counter::count() > 0) == uses_global_new);
+ if (!__b)
+ throw std::logic_error("counter not incremented");
+ return __b;
+ }
+
+ template<typename Alloc, bool uses_global_delete>
+ bool
+ check_delete(Alloc a = Alloc())
+ {
+ __gnu_test::counter::exceptions(false);
+ typename Alloc::pointer p = a.allocate(10);
+ const std::size_t count1 = __gnu_test::counter::count();
+ a.deallocate(p, 10);
+ const std::size_t count2 = __gnu_test::counter::count();
+ const bool __b((count2 < count1) == uses_global_delete);
+ if (!__b)
+ throw std::logic_error("counter not decremented");
+ return __b;
+ }
+} // namespace __gnu_test
+
+void* operator new(std::size_t size) throw(std::bad_alloc)
+{
+ printf("operator new is called \n");
+ void* p = std::malloc(size);
+ if (p == NULL)
+ throw std::bad_alloc();
+ __gnu_test::counter::increment();
+ return p;
+}
+
+void operator delete(void* p) throw()
+{
+ printf("operator delete is called \n");
+ if (p != NULL)
+ {
+ std::free(p);
+ __gnu_test::counter::decrement();
+
+ std::size_t count = __gnu_test::counter::count();
+ if (count == 0)
+ printf("All memory released \n");
+ else
+ printf("%lu allocations to be released \n", count);
+ }
+}
diff --git a/libstdc++-v3/testsuite/util/testsuite_allocator.h b/libstdc++-v3/testsuite/util/testsuite_allocator.h
index d2759f4653f..96fe546b482 100644
--- a/libstdc++-v3/testsuite/util/testsuite_allocator.h
+++ b/libstdc++-v3/testsuite/util/testsuite_allocator.h
@@ -32,12 +32,6 @@
#include <cassert>
#include <bits/move.h>
-namespace
-{
- bool new_called = false;
- bool delete_called = false;
-}
-
namespace __gnu_test
{
class tracker_allocator_counter
@@ -186,27 +180,6 @@ namespace __gnu_test
bool
check_construct_destroy(const char* tag, int expected_c, int expected_d);
- template<typename Alloc, bool uses_global_new>
- bool
- check_new(Alloc a = Alloc())
- {
- bool test __attribute__((unused)) = true;
- a.allocate(10);
- test &= ( new_called == uses_global_new );
- return test;
- }
-
- template<typename Alloc, bool uses_global_delete>
- bool
- check_delete(Alloc a = Alloc())
- {
- bool test __attribute__((unused)) = true;
- typename Alloc::pointer p = a.allocate(10);
- a.deallocate(p, 10);
- test &= ( delete_called == uses_global_delete );
- return test;
- }
-
template<typename Alloc>
bool
check_deallocate_null()
diff --git a/libstdc++-v3/testsuite/util/testsuite_hooks.cc b/libstdc++-v3/testsuite/util/testsuite_hooks.cc
index 8fb7e15b5e8..6d77d57672f 100644
--- a/libstdc++-v3/testsuite/util/testsuite_hooks.cc
+++ b/libstdc++-v3/testsuite/util/testsuite_hooks.cc
@@ -217,7 +217,7 @@ namespace __gnu_test
#endif
}
- counter::size_type counter::count = 0;
+ object_counter::size_type object_counter::count = 0;
unsigned int copy_constructor::count_ = 0;
unsigned int copy_constructor::throw_on_ = 0;
unsigned int assignment_operator::count_ = 0;
diff --git a/libstdc++-v3/testsuite/util/testsuite_hooks.h b/libstdc++-v3/testsuite/util/testsuite_hooks.h
index add47b60309..88155fa70a9 100644
--- a/libstdc++-v3/testsuite/util/testsuite_hooks.h
+++ b/libstdc++-v3/testsuite/util/testsuite_hooks.h
@@ -34,8 +34,8 @@
// limit in megabytes (a floating-point number). If _GLIBCXX_RES_LIMITS is
// not #defined before including this header, then no limiting is attempted.
//
-// 3) counter
-// This is a POD with a static data member, gnu_counting_struct::count,
+// 3) object_counter
+// This is a POD with a static data member, object_counter::count,
// which starts at zero, increments on instance construction, and decrements
// on instance destruction. "assert_count(n)" can be called to VERIFY()
// that the count equals N.
@@ -135,19 +135,19 @@ namespace __gnu_test
run_tests_wrapped_env(const char*, const char*, const func_callback&);
// Counting.
- struct counter
+ struct object_counter
{
- // Specifically and glaringly-obviously marked 'signed' so that when
- // COUNT mistakenly goes negative, we can track the patterns of
- // deletions more easily.
+ // Specifically and glaringly-obviously marked 'signed' so that
+ // when COUNT mistakenly goes negative, we can track the patterns
+ // of deletions more easily.
typedef signed int size_type;
static size_type count;
- counter() { ++count; }
- counter (const counter&) { ++count; }
- ~counter() { --count; }
+ object_counter() { ++count; }
+ object_counter (const object_counter&) { ++count; }
+ ~object_counter() { --count; }
};
-#define assert_count(n) VERIFY(__gnu_test::counter::count == n)
+#define assert_count(n) VERIFY(__gnu_test::object_counter::count == n)
// A (static) class for counting copy constructors and possibly throwing an
// exception on a desired count.